/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2721 - (show annotations)
Fri Oct 16 05:40:12 2009 UTC (9 years, 7 months ago) by jfenwick
File size: 36929 byte(s)
minval and maxval are now lazy operations (they weren't before).
Whether or not Lsup, sup and inf resolve their arguments before computing answers is controlled by the escriptParam 'RESOLVE_COLLECTIVE'.
Note: integrate() still forces a resolve.

Added some unit tests for operations which weren't tested before.
Added deepcopy implementations for lazy operations which got missed somehow.
1
2 ########################################################
3 #
4 # Copyright (c) 2003-2009 by University of Queensland
5 # Earth Systems Science Computational Center (ESSCC)
6 # http://www.uq.edu.au/esscc
7 #
8 # Primary Business: Queensland, Australia
9 # Licensed under the Open Software License version 3.0
10 # http://www.opensource.org/licenses/osl-3.0.php
11 #
12 ########################################################
13
14
15 EnsureSConsVersion(0,96,91)
16 EnsurePythonVersion(2,3)
17
18 import sys, os, re, socket, platform, stat
19 # For copy()
20 import shutil
21
22 # Add our extensions
23 if os.path.isdir('scons'): sys.path.append('scons')
24 import scons_extensions
25
26 # Use /usr/lib64 if available, else /usr/lib
27 usr_lib = '/usr/lib'
28 if os.path.isfile('/usr/lib64/libc.so'): usr_lib = '/usr/lib64'
29
30 # The string python2.4 or python2.5
31 python_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
32
33 # MS Windows support, many thanks to PH
34 IS_WINDOWS_PLATFORM = (os.name== "nt")
35
36 prefix = ARGUMENTS.get('prefix', Dir('#.').abspath)
37
38 #Holds names of variables from the calling environment which need to be passed
39 #to tools
40 env_export=[]
41
42 #Determine where to read options from use:
43 #1. command line
44 #2. scons/<hostname>_options.py
45 #3. name as part of a cluster
46 options_file=ARGUMENTS.get('options_file', None)
47 effective_hostname=socket.gethostname().split('.')[0]
48 if not options_file:
49 mangledhostname = re.sub("[^0-9a-zA-Z]", "_", effective_hostname)
50 options_file = os.path.join("scons",mangledhostname+"_options.py")
51 #If there is no options file with that name see if there is a substitute
52 if not os.path.isfile(options_file):
53 effective_hostname = scons_extensions.effectiveName(effective_hostname)
54 mangledhostname = re.sub("[^0-9a-zA-Z]", "_", effective_hostname)
55 options_file = os.path.join("scons",mangledhostname+"_options.py")
56
57 if not os.path.isfile(options_file):
58 print "Options file not found (expected '%s')" % options_file
59 options_file = False
60 else:
61 print "Options file is", options_file
62
63 #Does our scons support the newer Variables class or do we need to use Options?
64
65 try:
66 dummyvar=Variables
67 opts = Variables(options_file, ARGUMENTS)
68 adder = opts.AddVariables
69 except:
70 opts = Options(options_file, ARGUMENTS)
71 adder = opts.AddOptions
72 BoolVariable = BoolOption
73
74 ############ Load build options ################################
75
76 adder(
77 #opts.AddOptions(
78 # Where to install esys stuff
79 ('prefix', 'where everything will be installed', Dir('#.').abspath),
80 ('incinstall', 'where the esys headers will be installed', os.path.join(Dir('#.').abspath,'include')),
81 ('bininstall', 'where the esys binaries will be installed', os.path.join(prefix,'bin')),
82 ('libinstall', 'where the esys libraries will be installed', os.path.join(prefix,'lib')),
83 ('pyinstall', 'where the esys python modules will be installed', os.path.join(prefix,'esys')),
84 # Compilation options
85 BoolVariable('dodebug', 'For backwards compatibility', 'no'),
86 BoolVariable('usedebug', 'Do you want a debug build?', 'no'),
87 BoolVariable('usevtk', 'Do you want to use VTK?', 'yes'),
88 ('options_file', 'File of paths/options. Default: scons/<hostname>_options.py', options_file),
89 ('win_cc_name', 'windows C compiler name if needed', 'msvc'),
90 # The strings -DDEFAULT_ get replaced by scons/<hostname>_options.py or by defaults below
91 ('cc_flags', 'C compiler flags to use', '-DEFAULT_1'),
92 ('cc_optim', 'C compiler optimization flags to use', '-DEFAULT_2'),
93 ('cc_debug', 'C compiler debug flags to use', '-DEFAULT_3'),
94 ('omp_optim', 'OpenMP compiler flags to use (Release build)', '-DEFAULT_4'),
95 ('omp_debug', 'OpenMP compiler flags to use (Debug build)', '-DEFAULT_5'),
96 ('omp_libs', 'OpenMP compiler libraries to link with', '-DEFAULT_6'),
97 ('cc_extra', 'Extra C/C++ flags', ''),
98 ('ld_extra', 'Extra linker flags', ''),
99 ('sys_libs', 'System libraries to link with', []),
100 ('ar_flags', 'Static library archiver flags to use', ''),
101 BoolVariable('useopenmp', 'Compile parallel version using OpenMP', 'no'),
102 BoolVariable('usepedantic', 'Compile with -pedantic if using gcc', 'no'),
103 BoolVariable('usewarnings','Compile with warnings as errors if using gcc','yes'),
104 ('forcelazy','for testing use only - set the default value for autolazy','leave_alone'),
105 ('forcecollres','for testing use only - set the default value for force resolving collective ops','leave_alone'),
106 # Python
107 ('python_path', 'Path to Python includes', '/usr/include/'+python_version),
108 ('python_lib_path', 'Path to Python libs', usr_lib),
109 ('python_libs', 'Python libraries to link with', [python_version]),
110 ('python_cmd', 'Python command', 'python'),
111 # Boost
112 ('boost_path', 'Path to Boost includes', '/usr/include'),
113 ('boost_lib_path', 'Path to Boost libs', usr_lib),
114 ('boost_libs', 'Boost libraries to link with', ['boost_python']),
115 # NetCDF
116 BoolVariable('usenetcdf', 'switch on/off the usage of netCDF', 'yes'),
117 ('netCDF_path', 'Path to netCDF includes', '/usr/include'),
118 ('netCDF_lib_path', 'Path to netCDF libs', usr_lib),
119 ('netCDF_libs', 'netCDF C++ libraries to link with', ['netcdf_c++', 'netcdf']),
120 # MPI
121 BoolVariable('useMPI', 'For backwards compatibility', 'no'),
122 BoolVariable('usempi', 'Compile parallel version using MPI', 'no'),
123 ('MPICH_IGNORE_CXX_SEEK', 'name of macro to ignore MPI settings of C++ SEEK macro (for MPICH)' , 'MPICH_IGNORE_CXX_SEEK'),
124 ('mpi_path', 'Path to MPI includes', '/usr/include'),
125 ('mpi_run', 'mpirun name' , 'mpiexec -np 1'),
126 ('mpi_lib_path', 'Path to MPI libs (needs to be added to the LD_LIBRARY_PATH)', usr_lib),
127 ('mpi_libs', 'MPI libraries to link with (needs to be shared!)', ['mpich' , 'pthread', 'rt']),
128 ('mpi_flavour','Type of MPI execution environment','none'),
129 # ParMETIS
130 BoolVariable('useparmetis', 'Compile parallel version using ParMETIS', 'yes'),
131 ('parmetis_path', 'Path to ParMETIS includes', '/usr/include'),
132 ('parmetis_lib_path', 'Path to ParMETIS library', usr_lib),
133 ('parmetis_libs', 'ParMETIS library to link with', ['parmetis', 'metis']),
134 # PAPI
135 BoolVariable('usepapi', 'switch on/off the usage of PAPI', 'no'),
136 ('papi_path', 'Path to PAPI includes', '/usr/include'),
137 ('papi_lib_path', 'Path to PAPI libs', usr_lib),
138 ('papi_libs', 'PAPI libraries to link with', ['papi']),
139 BoolVariable('papi_instrument_solver', 'use PAPI in Solver.c to instrument each iteration of the solver', False),
140 # MKL
141 BoolVariable('usemkl', 'switch on/off the usage of MKL', 'no'),
142 ('mkl_path', 'Path to MKL includes', '/sw/sdev/cmkl/10.0.2.18/include'),
143 ('mkl_lib_path', 'Path to MKL libs', '/sw/sdev/cmkl/10.0.2.18/lib/em64t'),
144 ('mkl_libs', 'MKL libraries to link with', ['mkl_solver', 'mkl_em64t', 'guide', 'pthread']),
145 # UMFPACK
146 BoolVariable('useumfpack', 'switch on/off the usage of UMFPACK', 'no'),
147 ('ufc_path', 'Path to UFconfig includes', '/usr/include/suitesparse'),
148 ('umf_path', 'Path to UMFPACK includes', '/usr/include/suitesparse'),
149 ('umf_lib_path', 'Path to UMFPACK libs', usr_lib),
150 ('umf_libs', 'UMFPACK libraries to link with', ['umfpack']),
151 # Silo
152 BoolVariable('usesilo', 'switch on/off the usage of Silo', 'yes'),
153 ('silo_path', 'Path to Silo includes', '/usr/include'),
154 ('silo_lib_path', 'Path to Silo libs', usr_lib),
155 ('silo_libs', 'Silo libraries to link with', ['siloh5', 'hdf5']),
156 # AMD (used by UMFPACK)
157 ('amd_path', 'Path to AMD includes', '/usr/include/suitesparse'),
158 ('amd_lib_path', 'Path to AMD libs', usr_lib),
159 ('amd_libs', 'AMD libraries to link with', ['amd']),
160 # BLAS (used by UMFPACK)
161 ('blas_path', 'Path to BLAS includes', '/usr/include/suitesparse'),
162 ('blas_lib_path', 'Path to BLAS libs', usr_lib),
163 ('blas_libs', 'BLAS libraries to link with', ['blas']),
164 # An option for specifying the compiler tools set (see windows branch).
165 ('tools_names', 'allow control over the tools in the env setup', ['intelc']),
166 # finer control over library building, intel aggressive global optimisation
167 # works with dynamic libraries on windows.
168 ('share_esysUtils', 'control static or dynamic esysUtils lib', False),
169 ('share_paso', 'control static or dynamic paso lib', False),
170 ('env_export','Environment variables to be passed to children',[])
171 )
172
173
174
175 ############ Specify which compilers to use ####################
176
177 # intelc uses regular expressions improperly and emits a warning about
178 # failing to find the compilers. This warning can be safely ignored.
179
180 if IS_WINDOWS_PLATFORM:
181 env = Environment(options = opts)
182 env = Environment(tools = ['default'] + env['tools_names'],
183 options = opts)
184 else:
185 if effective_hostname == 'service0':
186 env = Environment(tools = ['default', 'intelc'], options = opts)
187 elif os.uname()[4]=='ia64':
188 env = Environment(tools = ['default', 'intelc'], options = opts)
189 if env['CXX'] == 'icpc':
190 env['LINK'] = env['CXX'] # version >=9 of intel c++ compiler requires use of icpc to link in C++ runtimes (icc does not)
191 else:
192 env = Environment(tools = ['default'], options = opts)
193 Help(opts.GenerateHelpText(env))
194
195
196 ############ Make sure target directories exist ################
197
198 if not os.path.isdir(env['bininstall']):
199 os.makedirs(env['bininstall'])
200 if not os.path.isdir(env['libinstall']):
201 os.makedirs(env['libinstall'])
202 if not os.path.isdir(env['pyinstall']):
203 os.makedirs(env['pyinstall'])
204
205 ########## Copy required environment vars ######################
206
207 for i in env['env_export']:
208 env.Append(ENV = {i:os.environ[i]})
209
210 ############ Fill in compiler options if not set above #########
211
212 # Backwards compatibility: allow dodebug=yes and useMPI=yes
213 if env['dodebug']: env['usedebug'] = 1
214 if env['useMPI']: env['usempi'] = 1
215
216 # Default compiler options (override allowed in hostname_options.py, but should not be necessary)
217 # For both C and C++ you get: cc_flags and either the optim flags or debug flags
218
219 sysheaderopt = "" # how do we indicate that a header is a system header. Use "" for no action.
220
221 if env["CC"] == "icc":
222 # Intel compilers
223 cc_flags = "-fPIC -ansi -wd161 -w1 -vec-report0 -DBLOCKTIMER -DCORE_ID1"
224 cc_optim = "-O3 -ftz -IPF_ftlacc- -IPF_fma -fno-alias"
225 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
226 omp_optim = "-openmp -openmp_report0"
227 omp_debug = "-openmp -openmp_report0"
228 omp_libs = ['guide', 'pthread']
229 pedantic = ""
230 fatalwarning = "" # Switch to turn warnings into errors
231 sysheaderopt = ""
232 elif env["CC"] == "gcc":
233 # GNU C on any system
234 cc_flags = "-pedantic -Wall -fPIC -ansi -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing"
235 #the long long warning occurs on the Mac
236 cc_optim = "-O3"
237 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
238 omp_optim = "-fopenmp"
239 omp_debug = "-fopenmp"
240 omp_libs = ['gomp']
241 pedantic = "-pedantic-errors -Wno-long-long"
242 fatalwarning = "-Werror"
243 sysheaderopt = "-isystem "
244 elif env["CC"] == "cl":
245 # Microsoft Visual C on Windows
246 cc_flags = "/FD /EHsc /GR /wd4068 -D_USE_MATH_DEFINES -DDLL_NETCDF"
247 cc_optim = "/O2 /Op /MT /W3"
248 cc_debug = "/Od /RTC1 /MTd /ZI -DBOUNDS_CHECK"
249 omp_optim = ""
250 omp_debug = ""
251 omp_libs = []
252 pedantic = ""
253 fatalwarning = ""
254 sysheaderopt = ""
255 elif env["CC"] == "icl":
256 # intel C on Windows, see windows_intelc_options.py for a start
257 pedantic = ""
258 fatalwarning = ""
259 sysheaderopt = ""
260
261
262 # If not specified in hostname_options.py then set them here
263 if env["cc_flags"] == "-DEFAULT_1": env['cc_flags'] = cc_flags
264 if env["cc_optim"] == "-DEFAULT_2": env['cc_optim'] = cc_optim
265 if env["cc_debug"] == "-DEFAULT_3": env['cc_debug'] = cc_debug
266 if env["omp_optim"] == "-DEFAULT_4": env['omp_optim'] = omp_optim
267 if env["omp_debug"] == "-DEFAULT_5": env['omp_debug'] = omp_debug
268 if env["omp_libs"] == "-DEFAULT_6": env['omp_libs'] = omp_libs
269
270 #set up the autolazy values
271 if env['forcelazy'] != "leave_alone":
272 if env['forcelazy'] == 'on':
273 env.Append(CPPDEFINES=['FAUTOLAZYON'])
274 else:
275 if env['forcelazy'] == 'off':
276 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
277
278 #set up the colective resolve values
279 if env['forcecollres'] != "leave_alone":
280 print env['forcecollres']
281 if env['forcecollres'] == 'on':
282 env.Append(CPPDEFINES=['FRESCOLLECTON'])
283 else:
284 if env['forcecollres'] == 'off':
285 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
286
287
288 # OpenMP is disabled if useopenmp=no or both variables omp_optim and omp_debug are empty
289 if not env["useopenmp"]:
290 env['omp_optim'] = ""
291 env['omp_debug'] = ""
292 env['omp_libs'] = []
293
294 if env['omp_optim'] == "" and env['omp_debug'] == "": env["useopenmp"] = 0
295
296 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
297 if IS_WINDOWS_PLATFORM:
298 LD_LIBRARY_PATH_KEY='PATH'
299 env['ENV']['LD_LIBRARY_PATH']=''
300 else:
301 LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
302 ############ Copy environment variables into scons env #########
303
304 try: env['ENV']['OMP_NUM_THREADS'] = os.environ['OMP_NUM_THREADS']
305 except KeyError: env['ENV']['OMP_NUM_THREADS'] = 1
306
307 try: env['ENV']['ESCRIPT_NUM_THREADS'] = os.environ['ESCRIPT_NUM_THREADS']
308 except KeyError: pass
309
310 try: env['ENV']['ESCRIPT_NUM_PROCS'] = os.environ['ESCRIPT_NUM_PROCS']
311 except KeyError: env['ENV']['ESCRIPT_NUM_PROCS']=1
312
313 try: env['ENV']['ESCRIPT_NUM_NODES'] = os.environ['ESCRIPT_NUM_NODES']
314 except KeyError: env['ENV']['ESCRIPT_NUM_NODES']=1
315
316 try: env['ENV']['ESCRIPT_HOSTFILE'] = os.environ['ESCRIPT_HOSTFILE']
317 except KeyError: pass
318
319 try: env['ENV']['PATH'] = os.environ['PATH']
320 except KeyError: pass
321
322 try: env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
323 except KeyError: pass
324
325 try: env['ENV']['C_INCLUDE_PATH'] = os.environ['C_INCLUDE_PATH']
326 except KeyError: pass
327
328 try: env['ENV']['CPLUS_INCLUDE_PATH'] = os.environ['CPLUS_INCLUDE_PATH']
329 except KeyError: pass
330
331 try: env.PrependENVPath(LD_LIBRARY_PATH_KEY,os.environ['LD_LIBRARY_PATH'])
332 except KeyError: pass
333
334 try: env['ENV']['LIBRARY_PATH'] = os.environ['LIBRARY_PATH']
335 except KeyError: pass
336
337 try: env['ENV']['DISPLAY'] = os.environ['DISPLAY']
338 except KeyError: pass
339
340 try: env['ENV']['XAUTHORITY'] = os.environ['XAUTHORITY']
341 except KeyError: pass
342
343 try: env['ENV']['HOME'] = os.environ['HOME']
344 except KeyError: pass
345
346 # Configure for test suite
347
348
349 env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
350 env.PrependENVPath('PYTHONPATH', prefix)
351 env['ENV']['ESCRIPT_ROOT'] = prefix
352
353 ############ Set up paths for Configure() ######################
354
355 # Make a copy of an environment
356 # Use env.Clone if available, but fall back on env.Copy for older version of scons
357 def clone_env(env):
358 if 'Clone' in dir(env): return env.Clone() # scons-0.98
359 else: return env.Copy() # scons-0.96
360
361 # Add cc option -I<Escript>/trunk/include
362 env.Append(CPPPATH = [Dir('include')])
363
364 # Add cc option -L<Escript>/trunk/lib
365 env.Append(LIBPATH = [Dir(env['libinstall'])])
366
367 if env['cc_extra'] != '': env.Append(CCFLAGS = env['cc_extra'])
368 if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
369
370 if env['usepedantic']: env.Append(CCFLAGS = pedantic)
371
372 # MS Windows
373 if IS_WINDOWS_PLATFORM:
374 env.AppendENVPath('PATH', [env['boost_lib_path']])
375 env.AppendENVPath('PATH', [env['libinstall']])
376 if not env['share_esysUtils'] :
377 env.Append(CPPDEFINES = ['ESYSUTILS_STATIC_LIB'])
378 if not env['share_paso'] :
379 env.Append(CPPDEFINES = ['PASO_STATIC_LIB'])
380
381 if env['usenetcdf']:
382 env.AppendENVPath('PATH', [env['netCDF_lib_path']])
383
384 env.Append(ARFLAGS = env['ar_flags'])
385
386 # Get the global Subversion revision number for getVersion() method
387 try:
388 global_revision = os.popen("svnversion -n .").read()
389 global_revision = re.sub(":.*", "", global_revision)
390 global_revision = re.sub("[^0-9]", "", global_revision)
391 except:
392 global_revision="-1"
393 if global_revision == "": global_revision="-2"
394 env.Append(CPPDEFINES = ["SVN_VERSION="+global_revision])
395
396 ############ numpy (required) ###############################
397
398 try:
399 from numpy import identity
400 except ImportError:
401 print "Cannot import numpy, you need to set your PYTHONPATH"
402 sys.exit(1)
403
404 ############ C compiler (required) #############################
405
406 # Create a Configure() environment for checking existence of required libraries and headers
407 conf = Configure(clone_env(env))
408
409 # Test that the compiler is working
410 if not conf.CheckFunc('printf'):
411 print "Cannot run C compiler '%s' (or libc is missing)" % (env['CC'])
412 sys.exit(1)
413
414 if conf.CheckFunc('gethostname'):
415 conf.env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])
416
417 ############ python libraries (required) #######################
418
419
420 if not sysheaderopt =="":
421 conf.env.Append(CCFLAGS=sysheaderopt+env['python_path'])
422 else:
423 conf.env.AppendUnique(CPPPATH = [env['python_path']])
424
425 conf.env.AppendUnique(LIBPATH = [env['python_lib_path']])
426 conf.env.AppendUnique(LIBS = [env['python_libs']])
427
428 conf.env.PrependENVPath('PYTHONPATH', prefix)
429 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['python_lib_path']) # The wrapper script needs to find these libs
430 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
431
432 if not conf.CheckCHeader('Python.h'):
433 print "Cannot find python include files (tried 'Python.h' in directory %s)" % (env['python_path'])
434 sys.exit(1)
435 if not conf.CheckFunc('Py_Exit'):
436 print "Cannot find python library method Py_Main (tried lib %s in directory %s)" % (env['python_libs'], env['python_lib_path'])
437 sys.exit(1)
438
439 ############ boost (required) ##################################
440
441 if not sysheaderopt =="":
442 # This is required because we can't -isystem /usr/system because it breaks std includes
443 if os.path.normpath(env['boost_path']) =="/usr/include":
444 conf.env.Append(CCFLAGS=sysheaderopt+os.path.join(env['boost_path'],'boost'))
445 else:
446 conf.env.Append(CCFLAGS=sysheaderopt+env['boost_path'])
447 else:
448 conf.env.AppendUnique(CPPPATH = [env['boost_path']])
449
450 conf.env.AppendUnique(LIBPATH = [env['boost_lib_path']])
451 conf.env.AppendUnique(LIBS = [env['boost_libs']])
452
453 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['boost_lib_path']) # The wrapper script needs to find these libs
454 #ensure that our path entries remain at the front
455 conf.env.PrependENVPath('PYTHONPATH', prefix)
456 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
457
458 if not conf.CheckCXXHeader('boost/python.hpp'):
459 print "Cannot find boost include files (tried boost/python.hpp in directory %s)" % (env['boost_path'])
460 sys.exit(1)
461
462 if not conf.CheckFunc('PyObject_SetAttr'):
463 print "Cannot find boost library method PyObject_SetAttr (tried method PyObject_SetAttr in library %s in directory %s)" % (env['boost_libs'], env['boost_lib_path'])
464 sys.exit(1)
465
466 # Commit changes to environment
467 env = conf.Finish()
468
469 ############ VTK (optional) ####################################
470
471 if env['usevtk']:
472 try:
473 import vtk
474 env['usevtk'] = 1
475 except ImportError:
476 env['usevtk'] = 0
477
478 # Add VTK to environment env if it was found
479 if env['usevtk']:
480 env.Append(CPPDEFINES = ['USE_VTK'])
481
482 ############ NetCDF (optional) #################################
483
484 conf = Configure(clone_env(env))
485
486 if env['usenetcdf']:
487 conf.env.AppendUnique(CPPPATH = [env['netCDF_path']])
488 conf.env.AppendUnique(LIBPATH = [env['netCDF_lib_path']])
489 conf.env.AppendUnique(LIBS = [env['netCDF_libs']])
490 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['netCDF_lib_path']) # The wrapper script needs to find these libs
491 #ensure that our path entries remain at the front
492 conf.env.PrependENVPath('PYTHONPATH', prefix)
493 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
494
495 if env['usenetcdf'] and not conf.CheckCHeader('netcdf.h'): env['usenetcdf'] = 0
496 if env['usenetcdf'] and not conf.CheckFunc('nc_open'): env['usenetcdf'] = 0
497
498 # Add NetCDF to environment env if it was found
499 if env['usenetcdf']:
500 env = conf.Finish()
501 env.Append(CPPDEFINES = ['USE_NETCDF'])
502 else:
503 conf.Finish()
504
505 ############ PAPI (optional) ###################################
506
507 # Start a new configure environment that reflects what we've already found
508 conf = Configure(clone_env(env))
509
510 if env['usepapi']:
511 conf.env.AppendUnique(CPPPATH = [env['papi_path']])
512 conf.env.AppendUnique(LIBPATH = [env['papi_lib_path']])
513 conf.env.AppendUnique(LIBS = [env['papi_libs']])
514 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['papi_lib_path']) # The wrapper script needs to find these libs
515 #ensure that our path entries remain at the front
516 conf.env.PrependENVPath('PYTHONPATH', prefix)
517 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
518
519 if env['usepapi'] and not conf.CheckCHeader('papi.h'): env['usepapi'] = 0
520 if env['usepapi'] and not conf.CheckFunc('PAPI_start_counters'): env['usepapi'] = 0
521
522 # Add PAPI to environment env if it was found
523 if env['usepapi']:
524 env = conf.Finish()
525 env.Append(CPPDEFINES = ['BLOCKPAPI'])
526 else:
527 conf.Finish()
528
529 ############ MKL (optional) ####################################
530
531 # Start a new configure environment that reflects what we've already found
532 conf = Configure(clone_env(env))
533
534 if env['usemkl']:
535 conf.env.AppendUnique(CPPPATH = [env['mkl_path']])
536 conf.env.AppendUnique(LIBPATH = [env['mkl_lib_path']])
537 conf.env.AppendUnique(LIBS = [env['mkl_libs']])
538 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['mkl_lib_path']) # The wrapper script needs to find these libs
539 #ensure that our path entries remain at the front
540 conf.env.PrependENVPath('PYTHONPATH', prefix)
541 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
542
543 if env['usemkl'] and not conf.CheckCHeader('mkl_solver.h'): env['usemkl'] = 0
544 if env['usemkl'] and not conf.CheckFunc('pardiso'): env['usemkl'] = 0
545
546 # Add MKL to environment env if it was found
547 if env['usemkl']:
548 env = conf.Finish()
549 env.Append(CPPDEFINES = ['MKL'])
550 else:
551 conf.Finish()
552
553 ############ UMFPACK (optional) ################################
554
555 # Start a new configure environment that reflects what we've already found
556 conf = Configure(clone_env(env))
557
558 if env['useumfpack']:
559 conf.env.AppendUnique(CPPPATH = [env['ufc_path']])
560 conf.env.AppendUnique(CPPPATH = [env['umf_path']])
561 conf.env.AppendUnique(LIBPATH = [env['umf_lib_path']])
562 conf.env.AppendUnique(LIBS = [env['umf_libs']])
563 conf.env.AppendUnique(CPPPATH = [env['amd_path']])
564 conf.env.AppendUnique(LIBPATH = [env['amd_lib_path']])
565 conf.env.AppendUnique(LIBS = [env['amd_libs']])
566 conf.env.AppendUnique(CPPPATH = [env['blas_path']])
567 conf.env.AppendUnique(LIBPATH = [env['blas_lib_path']])
568 conf.env.AppendUnique(LIBS = [env['blas_libs']])
569 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['umf_lib_path']) # The wrapper script needs to find these libs
570 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['amd_lib_path']) # The wrapper script needs to find these libs
571 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['blas_lib_path']) # The wrapper script needs to find these libs
572 #ensure that our path entries remain at the front
573 conf.env.PrependENVPath('PYTHONPATH', prefix)
574 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
575
576 if env['useumfpack'] and not conf.CheckCHeader('umfpack.h'): env['useumfpack'] = 0
577 if env['useumfpack'] and not conf.CheckFunc('umfpack_di_symbolic'): env['useumfpack'] = 0
578 # if env['useumfpack'] and not conf.CheckFunc('daxpy'): env['useumfpack'] = 0 # this does not work on shake73?
579
580 # Add UMFPACK to environment env if it was found
581 if env['useumfpack']:
582 env = conf.Finish()
583 env.Append(CPPDEFINES = ['UMFPACK'])
584 else:
585 conf.Finish()
586
587 ############ Silo (optional) ###################################
588
589 if env['usesilo']:
590 conf = Configure(clone_env(env))
591 conf.env.AppendUnique(CPPPATH = [env['silo_path']])
592 conf.env.AppendUnique(LIBPATH = [env['silo_lib_path']])
593 conf.env.AppendUnique(LIBS = [env['silo_libs']])
594 if not conf.CheckCHeader('silo.h'): env['usesilo'] = 0
595 if not conf.CheckFunc('DBMkDir'): env['usesilo'] = 0
596 conf.Finish()
597
598 # Add the path to Silo to environment env if it was found.
599 # Note that we do not add the libs since they are only needed for the
600 # escriptreader library and tools.
601 if env['usesilo']:
602 env.AppendUnique(CPPPATH = [env['silo_path']])
603 env.AppendUnique(LIBPATH = [env['silo_lib_path']])
604 env.Append(CPPDEFINES = ['HAVE_SILO'])
605
606 ############ Add the compiler flags ############################
607
608 # Enable debug by choosing either cc_debug or cc_optim
609 if env['usedebug']:
610 env.Append(CCFLAGS = env['cc_debug'])
611 env.Append(CCFLAGS = env['omp_debug'])
612 else:
613 env.Append(CCFLAGS = env['cc_optim'])
614 env.Append(CCFLAGS = env['omp_optim'])
615
616 # Always use cc_flags
617 env.Append(CCFLAGS = env['cc_flags'])
618 env.Append(LIBS = [env['omp_libs']])
619
620 ############ Add some custom builders ##########################
621
622 py_builder = Builder(action = scons_extensions.build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
623 env.Append(BUILDERS = {'PyCompile' : py_builder});
624
625 runUnitTest_builder = Builder(action = scons_extensions.runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
626 env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
627
628 runPyUnitTest_builder = Builder(action = scons_extensions.runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
629 env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
630
631 epstopdfbuilder = Builder(action = scons_extensions.eps2pdf, suffix=".pdf", src_suffix=".eps", single_source=True)
632 env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
633
634 ############ MPI (optional) ####################################
635 if not env['usempi']: env['mpi_flavour']='none'
636
637 # Create a modified environment for MPI programs (identical to env if usempi=no)
638 env_mpi = clone_env(env)
639
640 # Start a new configure environment that reflects what we've already found
641 conf = Configure(clone_env(env_mpi))
642
643 if env_mpi['usempi']:
644 VALID_MPIs=[ "MPT", "MPICH", "MPICH2", "OPENMPI", "INTELMPI" ]
645 if not env_mpi['mpi_flavour'] in VALID_MPIs:
646 raise ValueError,"MPI is enabled but mpi_flavour = %s is not a valid key from %s."%( env_mpi['mpi_flavour'],VALID_MPIs)
647 conf.env.AppendUnique(CPPPATH = [env_mpi['mpi_path']])
648 conf.env.AppendUnique(LIBPATH = [env_mpi['mpi_lib_path']])
649 conf.env.AppendUnique(LIBS = [env_mpi['mpi_libs']])
650 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['mpi_lib_path']) # The wrapper script needs to find these libs
651 #ensure that our path entries remain at the front
652 conf.env.PrependENVPath('PYTHONPATH', prefix)
653 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
654
655 if env_mpi['usempi'] and not conf.CheckCHeader('mpi.h'): env_mpi['usempi'] = 0
656 # if env_mpi['usempi'] and not conf.CheckFunc('MPI_Init'): env_mpi['usempi'] = 0
657
658 # Add MPI to environment env_mpi if it was found
659 if env_mpi['usempi']:
660 env_mpi = conf.Finish()
661 env_mpi.Append(CPPDEFINES = ['PASO_MPI', 'MPI_NO_CPPBIND', env_mpi['MPICH_IGNORE_CXX_SEEK']])
662 else:
663 conf.Finish()
664
665 env['usempi'] = env_mpi['usempi']
666
667
668 ############ ParMETIS (optional) ###############################
669
670 # Start a new configure environment that reflects what we've already found
671 conf = Configure(clone_env(env_mpi))
672
673 if not env_mpi['usempi']: env_mpi['useparmetis'] = 0
674
675 if env_mpi['useparmetis']:
676 conf.env.AppendUnique(CPPPATH = [env_mpi['parmetis_path']])
677 conf.env.AppendUnique(LIBPATH = [env_mpi['parmetis_lib_path']])
678 conf.env.AppendUnique(LIBS = [env_mpi['parmetis_libs']])
679 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['parmetis_lib_path']) # The wrapper script needs to find these libs
680 #ensure that our path entries remain at the front
681 conf.env.PrependENVPath('PYTHONPATH', prefix)
682 conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
683
684 if env_mpi['useparmetis'] and not conf.CheckCHeader('parmetis.h'): env_mpi['useparmetis'] = 0
685 if env_mpi['useparmetis'] and not conf.CheckFunc('ParMETIS_V3_PartGeomKway'): env_mpi['useparmetis'] = 0
686
687 # Add ParMETIS to environment env_mpi if it was found
688 if env_mpi['useparmetis']:
689 env_mpi = conf.Finish()
690 env_mpi.Append(CPPDEFINES = ['USE_PARMETIS'])
691 else:
692 conf.Finish()
693
694 env['useparmetis'] = env_mpi['useparmetis']
695
696 ############ Now we switch on Warnings as errors ###############
697
698 #this needs to be done after configuration because the scons test files have warnings in them
699
700 if ((fatalwarning != "") and (env['usewarnings'])):
701 env.Append(CCFLAGS = fatalwarning)
702 env_mpi.Append(CCFLAGS = fatalwarning)
703
704 ############ Summarize our environment #########################
705
706 print ""
707 print "Summary of configuration (see ./config.log for information)"
708 print " Using python libraries"
709 print " Using numpy"
710 print " Using boost"
711 if env['usenetcdf']: print " Using NetCDF"
712 else: print " Not using NetCDF"
713 if env['usevtk']: print " Using VTK"
714 else: print " Not using VTK"
715 if env['usemkl']: print " Using MKL"
716 else: print " Not using MKL"
717 if env['useumfpack']: print " Using UMFPACK"
718 else: print " Not using UMFPACK"
719 if env['usesilo']: print " Using Silo"
720 else: print " Not using Silo"
721 if env['useopenmp']: print " Using OpenMP"
722 else: print " Not using OpenMP"
723 if env['usempi']: print " Using MPI (flavour = %s)"%env['mpi_flavour']
724 else: print " Not using MPI"
725 if env['useparmetis']: print " Using ParMETIS"
726 else: print " Not using ParMETIS (requires MPI)"
727 if env['usepapi']: print " Using PAPI"
728 else: print " Not using PAPI"
729 if env['usedebug']: print " Compiling for debug"
730 else: print " Not compiling for debug"
731 print " Installing in", prefix
732 if ((fatalwarning != "") and (env['usewarnings'])): print " Treating warnings as errors"
733 else: print " Not treating warnings as errors"
734 print ""
735
736 ############ Delete option-dependent files #####################
737
738 Execute(Delete(os.path.join(env['libinstall'],"Compiled.with.debug")))
739 Execute(Delete(os.path.join(env['libinstall'],"Compiled.with.mpi")))
740 Execute(Delete(os.path.join(env['libinstall'],"Compiled.with.openmp")))
741 Execute(Delete(os.path.join(env['libinstall'],"pyversion")))
742 Execute(Delete(os.path.join(env['libinstall'],"buildvars")))
743 if not env['usempi']: Execute(Delete(os.path.join(env['libinstall'],"pythonMPI")))
744
745
746 ############ Build the subdirectories ##########################
747
748 from grouptest import *
749
750 TestGroups=[]
751
752 Export(
753 ["env",
754 "env_mpi",
755 "clone_env",
756 "IS_WINDOWS_PLATFORM",
757 "TestGroups"
758 ]
759 )
760
761 env.SConscript(dirs = ['tools/CppUnitTest/src'], build_dir='build/$PLATFORM/tools/CppUnitTest', duplicate=0)
762 env.SConscript(dirs = ['tools/libescriptreader/src'], build_dir='build/$PLATFORM/tools/libescriptreader', duplicate=0)
763 env.SConscript(dirs = ['paso/src'], build_dir='build/$PLATFORM/paso', duplicate=0)
764 env.SConscript(dirs = ['escript/src'], build_dir='build/$PLATFORM/escript', duplicate=0)
765 env.SConscript(dirs = ['esysUtils/src'], build_dir='build/$PLATFORM/esysUtils', duplicate=0)
766 env.SConscript(dirs = ['finley/src'], build_dir='build/$PLATFORM/finley', duplicate=0)
767 env.SConscript(dirs = ['modellib/py_src'], build_dir='build/$PLATFORM/modellib', duplicate=0)
768 env.SConscript(dirs = ['doc'], build_dir='build/$PLATFORM/doc', duplicate=0)
769 env.SConscript(dirs = ['pyvisi/py_src'], build_dir='build/$PLATFORM/pyvisi', duplicate=0)
770 env.SConscript(dirs = ['pycad/py_src'], build_dir='build/$PLATFORM/pycad', duplicate=0)
771 env.SConscript(dirs = ['pythonMPI/src'], build_dir='build/$PLATFORM/pythonMPI', duplicate=0)
772 env.SConscript(dirs = ['scripts'], build_dir='build/$PLATFORM/scripts', duplicate=0)
773 env.SConscript(dirs = ['paso/profiling'], build_dir='build/$PLATFORM/paso/profiling', duplicate=0)
774
775
776 ############ Remember what optimizations we used ###############
777
778 remember_list = []
779
780 if env['usedebug']:
781 remember_list += env.Command(os.path.join(env['libinstall'],"Compiled.with.debug"), None, Touch('$TARGET'))
782
783 if env['usempi']:
784 remember_list += env.Command(os.path.join(env['libinstall'],"Compiled.with.mpi"), None, Touch('$TARGET'))
785
786 if env['useopenmp']:
787 remember_list += env.Command(os.path.join(env['libinstall'],"Compiled.with.openmp"), None, Touch('$TARGET'))
788
789 env.Alias('remember_options', remember_list)
790
791
792 ############### Record python interpreter version ##############
793
794 if not IS_WINDOWS_PLATFORM:
795 versionstring="Python "+str(sys.version_info[0])+"."+str(sys.version_info[1])+"."+str(sys.version_info[2])
796 os.system("echo "+versionstring+" > "+os.path.join(env['libinstall'],"pyversion"))
797
798 ############## Populate the buildvars file #####################
799
800 buildvars=open(os.path.join(env['libinstall'],'buildvars'),'w')
801 buildvars.write('python='+str(sys.version_info[0])+"."+str(sys.version_info[1])+"."+str(sys.version_info[2])+'\n')
802
803 # Find the boost version by extracting it from version.hpp
804 boosthpp=open(os.path.join(env['boost_path'],'boost','version.hpp'))
805 boostversion='unknown'
806 try:
807 for line in boosthpp:
808 ver=re.match(r'#define BOOST_VERSION (\d+)',line)
809 if ver:
810 boostversion=ver.group(1)
811 except StopIteration:
812 pass
813 buildvars.write("boost="+boostversion+"\n")
814 buildvars.write("svn_revision="+str(global_revision)+"\n")
815 out="usedebug="
816 if env['usedebug']:
817 out+="y"
818 else:
819 out+="n"
820 out+="\nusempi="
821 if env['usempi']:
822 out+="y"
823 else:
824 out+="n"
825 out+="\nuseopenmp="
826 if env['useopenmp']:
827 out+="y"
828 else:
829 out+="n"
830 buildvars.write(out+"\n")
831 buildvars.write("mpi_flavour="+env['mpi_flavour']+'\n')
832
833 buildvars.close()
834
835
836 ############ Targets to build and install libraries ############
837
838 target_init = env.Command(env['pyinstall']+'/__init__.py', None, Touch('$TARGET'))
839 env.Alias('target_init', [target_init])
840
841 # The headers have to be installed prior to build in order to satisfy #include <paso/Common.h>
842 env.Alias('build_esysUtils', ['target_install_esysUtils_headers', 'target_esysUtils_a'])
843 env.Alias('install_esysUtils', ['build_esysUtils', 'target_install_esysUtils_a'])
844
845 env.Alias('build_paso', ['target_install_paso_headers', 'target_paso_a'])
846 env.Alias('install_paso', ['build_paso', 'target_install_paso_a'])
847
848 env.Alias('build_escript', ['target_install_escript_headers', 'target_escript_so', 'target_escriptcpp_so'])
849 env.Alias('install_escript', ['build_escript', 'target_install_escript_so', 'target_install_escriptcpp_so', 'target_install_escript_py'])
850
851 env.Alias('build_finley', ['target_install_finley_headers', 'target_finley_so', 'target_finleycpp_so'])
852 env.Alias('install_finley', ['build_finley', 'target_install_finley_so', 'target_install_finleycpp_so', 'target_install_finley_py'])
853
854 # Now gather all the above into a couple easy targets: build_all and install_all
855 build_all_list = []
856 build_all_list += ['build_esysUtils']
857 build_all_list += ['build_paso']
858 build_all_list += ['build_escript']
859 build_all_list += ['build_finley']
860 if env['usempi']: build_all_list += ['target_pythonMPI_exe']
861 #if not IS_WINDOWS_PLATFORM: build_all_list += ['target_escript_wrapper']
862 if env['usesilo']: build_all_list += ['target_escript2silo']
863 env.Alias('build_all', build_all_list)
864
865 install_all_list = []
866 install_all_list += ['target_init']
867 install_all_list += ['install_esysUtils']
868 install_all_list += ['install_paso']
869 install_all_list += ['install_escript']
870 install_all_list += ['install_finley']
871 install_all_list += ['target_install_pyvisi_py']
872 install_all_list += ['target_install_modellib_py']
873 install_all_list += ['target_install_pycad_py']
874 if env['usempi']: install_all_list += ['target_install_pythonMPI_exe']
875 #if not IS_WINDOWS_PLATFORM: install_all_list += ['target_install_escript_wrapper']
876 if env['usesilo']: install_all_list += ['target_install_escript2silo']
877 install_all_list += ['remember_options']
878 env.Alias('install_all', install_all_list)
879
880 # Default target is install
881 env.Default('install_all')
882
883 ############ Targets to build and run the test suite ###########
884
885 env.Alias('build_cppunittest', ['target_install_cppunittest_headers', 'target_cppunittest_a'])
886 env.Alias('install_cppunittest', ['build_cppunittest', 'target_install_cppunittest_a'])
887 env.Alias('run_tests', ['install_all', 'target_install_cppunittest_a'])
888 env.Alias('all_tests', ['install_all', 'target_install_cppunittest_a', 'run_tests', 'py_tests'])
889 env.Alias('build_full',['install_all','build_tests','build_py_tests'])
890
891 ############ Targets to build the documentation ################
892
893 env.Alias('api_epydoc','install_all')
894
895 env.Alias('docs', ['examples_tarfile', 'examples_zipfile', 'api_epydoc', 'api_doxygen', 'guide_pdf', 'guide_html','install_pdf'])
896
897 if not IS_WINDOWS_PLATFORM:
898 try:
899 utest=open("utest.sh","w")
900 build_platform=os.name #Sometimes Mac python says it is posix
901 if (build_platform=='posix') and platform.system()=="Darwin":
902 build_platform='darwin'
903 utest.write(GroupTest.makeHeader(build_platform))
904 for tests in TestGroups:
905 utest.write(tests.makeString())
906 utest.close()
907 os.chmod("utest.sh",stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH)
908 print "utest.sh written"
909 except IOError:
910 print "Error attempting to write unittests file."
911 sys.exit(1)
912
913 #Make sure that the escript wrapper is in place
914 if not os.path.isfile(os.path.join(env['bininstall'],'escript')):
915 print "Copying escript wrapper"
916 shutil.copy("bin/escript",os.path.join(env['bininstall'],'escript'))

  ViewVC Help
Powered by ViewVC 1.1.26