/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6119 - (show annotations)
Sun Apr 3 23:36:59 2016 UTC (2 years, 5 months ago) by caltinay
File size: 30877 byte(s)
merging trilinos branch to trunk.
We can now build with trilinos and use it instead of paso for single PDEs.
There are some more things to be done...

1 ##############################################################################
2 #
3 # Copyright (c) 2003-2016 by The University of Queensland
4 # http://www.uq.edu.au
5 #
6 # Primary Business: Queensland, Australia
7 # Licensed under the Apache License, version 2.0
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
11 # Development 2012-2013 by School of Earth Sciences
12 # Development from 2014 by Centre for Geoscience Computing (GeoComp)
13 #
14 ##############################################################################
15
16 EnsureSConsVersion(0,98,1)
17 EnsurePythonVersion(2,5)
18
19 import atexit, sys, os, platform, re
20 from distutils import sysconfig
21 from dependencies import *
22 from site_init import *
23
24 # Version number to check for in options file. Increment when new features are
25 # added or existing options changed.
26 REQUIRED_OPTS_VERSION=202
27
28 # MS Windows support, many thanks to PH
29 IS_WINDOWS = (os.name == 'nt')
30
31 IS_OSX = (os.uname()[0] == 'Darwin')
32
33 ########################## Determine options file ############################
34 # 1. command line
35 # 2. scons/<hostname>_options.py
36 # 3. name as part of a cluster
37 options_file=ARGUMENTS.get('options_file', None)
38 if not options_file:
39 ext_dir = os.path.join(os.getcwd(), 'scons')
40 hostname = platform.node().split('.')[0]
41 for name in hostname, effectiveName(hostname):
42 mangledhostname = re.sub('[^0-9a-zA-Z]', '_', hostname)
43 options_file = os.path.join(ext_dir, mangledhostname+'_options.py')
44 if os.path.isfile(options_file): break
45
46 if not os.path.isfile(options_file):
47 print("\nWARNING:\nOptions file %s" % options_file)
48 print("not found! Default options will be used which is most likely suboptimal.")
49 print("We recommend that you copy the most relavent options file in the scons/template/")
50 print("subdirectory and customize it to your needs.\n")
51 options_file = None
52
53 ############################### Build options ################################
54
55 default_prefix='/usr'
56 mpi_flavours=('no', 'none', 'MPT', 'MPICH', 'MPICH2', 'OPENMPI', 'INTELMPI')
57 lapack_flavours=('none', 'clapack', 'mkl')
58 all_domains = ['dudley','finley','ripley','speckley']
59
60 #Note that scons construction vars the the following purposes:
61 # CPPFLAGS -> to the preprocessor
62 # CCFLAGS -> flags for _both_ C and C++
63 # CXXFLAGS -> flags for c++ _only_
64 # CFLAGS -> flags for c only
65
66 vars = Variables(options_file, ARGUMENTS)
67 vars.AddVariables(
68 PathVariable('options_file', 'Path to options file', options_file, PathVariable.PathIsFile),
69 PathVariable('prefix', 'Installation prefix', Dir('#.').abspath, PathVariable.PathIsDirCreate),
70 PathVariable('build_dir', 'Top-level build directory', Dir('#/build').abspath, PathVariable.PathIsDirCreate),
71 BoolVariable('verbose', 'Output full compile/link lines', False),
72 # Compiler/Linker options
73 ('cxx', 'Path to C++ compiler', 'default'),
74 ('cc_flags', 'Base (C and C++) compiler flags', 'default'),
75 ('cc_optim', 'Additional (C and C++) flags for a non-debug build', 'default'),
76 ('cc_debug', 'Additional (C and C++) flags for a debug build', 'default'),
77 ('cxx_extra', 'Extra C++ compiler flags', ''),
78 ('cpp_flags', 'C Pre-processor flags', ''),
79 ('cpp_extra', 'Extra C Pre-processor flags', ''),
80 ('ld_extra', 'Extra linker flags', ''),
81 ('nvcc', 'Path to CUDA compiler', 'default'),
82 ('nvccflags', 'Base CUDA compiler flags', 'default'),
83 BoolVariable('werror','Treat compiler warnings as errors', True),
84 BoolVariable('debug', 'Compile with debug flags', False),
85 BoolVariable('openmp', 'Compile parallel version using OpenMP', False),
86 ('omp_flags', 'OpenMP compiler flags', 'default'),
87 ('omp_ldflags', 'OpenMP linker flags', 'default'),
88 # Mandatory libraries
89 ('boost_prefix', 'Prefix/Paths of boost installation', default_prefix),
90 ('boost_libs', 'Boost libraries to link with', ['boost_python-mt']),
91 # Mandatory for tests
92 ('cppunit_prefix', 'Prefix/Paths of CppUnit installation', default_prefix),
93 ('cppunit_libs', 'CppUnit libraries to link with', ['cppunit']),
94 # Optional libraries and options
95 EnumVariable('mpi', 'Compile parallel version using MPI flavour', 'none', allowed_values=mpi_flavours),
96 ('mpi_prefix', 'Prefix/Paths of MPI installation', default_prefix),
97 ('mpi_libs', 'MPI shared libraries to link with', ['mpi']),
98 BoolVariable('cuda', 'Enable GPU code with CUDA (requires thrust)', False),
99 ('cuda_prefix', 'Prefix/Paths to NVidia CUDA installation', default_prefix),
100 BoolVariable('netcdf', 'Enable netCDF file support', False),
101 ('netcdf_prefix', 'Prefix/Paths of netCDF installation', default_prefix),
102 ('netcdf_libs', 'netCDF libraries to link with', ['netcdf_c++', 'netcdf']),
103 BoolVariable('parmetis', 'Enable ParMETIS (requires MPI)', False),
104 ('parmetis_prefix', 'Prefix/Paths of ParMETIS installation', default_prefix),
105 ('parmetis_libs', 'ParMETIS libraries to link with', ['parmetis', 'metis']),
106 BoolVariable('mkl', 'Enable the Math Kernel Library', False),
107 ('mkl_prefix', 'Prefix/Paths to MKL installation', default_prefix),
108 ('mkl_libs', 'MKL libraries to link with', ['mkl_solver','mkl_em64t','guide','pthread']),
109 BoolVariable('umfpack', 'Enable UMFPACK', False),
110 ('umfpack_prefix', 'Prefix/Paths to UMFPACK installation', default_prefix),
111 ('umfpack_libs', 'UMFPACK libraries to link with', ['umfpack']),
112 BoolVariable('boomeramg', 'Enable BoomerAMG', False),
113 ('boomeramg_prefix', 'Prefix/Paths to BoomerAMG installation', default_prefix),
114 ('boomeramg_libs', 'BoomerAMG libraries to link with', ['boomeramg']),
115 EnumVariable('lapack', 'Set LAPACK flavour', 'none', allowed_values=lapack_flavours),
116 ('lapack_prefix', 'Prefix/Paths to LAPACK installation', default_prefix),
117 ('lapack_libs', 'LAPACK libraries to link with', []),
118 BoolVariable('silo', 'Enable the Silo file format in weipa', False),
119 ('silo_prefix', 'Prefix/Paths to Silo installation', default_prefix),
120 ('silo_libs', 'Silo libraries to link with', ['siloh5', 'hdf5']),
121 BoolVariable('trilinos', 'Enable the Trilinos solvers', False),
122 ('trilinos_prefix', 'Prefix/Paths to Trilinos installation', default_prefix),
123 ('trilinos_libs', 'Trilinos libraries to link with', []),
124 BoolVariable('visit', 'Enable the VisIt simulation interface', False),
125 ('visit_prefix', 'Prefix/Paths to VisIt installation', default_prefix),
126 ('visit_libs', 'VisIt libraries to link with', ['simV2']),
127 ListVariable('domains', 'Which domains to build', 'all', all_domains),
128 BoolVariable('paso', 'Build Paso solver library', True),
129 BoolVariable('weipa', 'Build Weipa data export library', True),
130 # Advanced settings
131 ('launcher', 'Launcher command (e.g. mpirun)', 'default'),
132 ('prelaunch', 'Command to execute before launcher (e.g. mpdboot)', 'default'),
133 ('postlaunch', 'Command to execute after launcher (e.g. mpdexit)', 'default'),
134 #dudley_assemble_flags = -funroll-loops to actually do something
135 ('dudley_assemble_flags', 'compiler flags for some dudley optimisations', ''),
136 # To enable passing function pointers through python
137 BoolVariable('iknowwhatimdoing', 'Allow non-standard C', False),
138 # An option for specifying the compiler tools
139 ('tools_names', 'Compiler tools to use', ['default']),
140 ('env_export', 'Environment variables to be passed to tools',[]),
141 EnumVariable('forcelazy', 'For testing use only - set the default value for autolazy', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
142 EnumVariable('forcecollres', 'For testing use only - set the default value for force resolving collective ops', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
143 BoolVariable('build_shared', 'Build dynamic libraries only (ignored)', True),
144 ('sys_libs', 'Extra libraries to link with', []),
145 ('escript_opts_version', 'Version of options file (do not specify on command line)'),
146 ('SVN_VERSION', 'Do not use from options file', -2),
147 ('pythoncmd', 'which python to compile with','python'),
148 BoolVariable('usepython3', 'Is this a python3 build?', False),
149 ('pythonlibname', 'Name of the python library to link. (This is found automatically for python2.X.)', ''),
150 ('pythonlibpath', 'Path to the python library. (You should not need to set this unless your python has moved)',''),
151 ('pythonincpath','Path to python include files. (You should not need to set this unless your python has moved',''),
152 BoolVariable('longindices', 'use long indices (for very large matrices)', False),
153 BoolVariable('compressed_files','Enables reading from compressed binary files', True),
154 ('compression_libs', 'Compression libraries to link with', ['boost_iostreams']),
155 BoolVariable('papi', 'Enable PAPI', False),
156 ('papi_prefix', 'Prefix/Paths to PAPI installation', default_prefix),
157 ('papi_libs', 'PAPI libraries to link with', ['papi']),
158 BoolVariable('papi_instrument_solver', 'Use PAPI to instrument each iteration of the solver', False),
159 BoolVariable('osx_dependency_fix', 'Fix dependencies for libraries to have absolute paths (OSX)',
160 False),
161 BoolVariable('broken_cppacos', 'Use boost acos instead of std version', False)
162 )
163
164 ##################### Create environment and help text #######################
165
166 # Intel's compiler uses regular expressions improperly and emits a warning
167 # about failing to find the compilers. This warning can be safely ignored.
168
169 # PATH is needed so the compiler, linker and tools are found if they are not
170 # in default locations.
171 env = Environment(tools = ['default'], options = vars,
172 ENV = {'PATH': os.environ['PATH']})
173
174 # set the vars for clang
175 def mkclang(env):
176 env['CXX']='clang++'
177
178 if env['tools_names'] != ['default']:
179 zz=env['tools_names']
180 if 'clang' in zz:
181 zz.remove('clang')
182 zz.insert(0, mkclang)
183 env = Environment(tools = ['default'] + env['tools_names'], options = vars,
184 ENV = {'PATH' : os.environ['PATH']})
185
186 if options_file:
187 opts_valid=False
188 if 'escript_opts_version' in env.Dictionary() and \
189 int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
190 opts_valid=True
191 if opts_valid:
192 print("Using options in %s." % options_file)
193 else:
194 print("\nOptions file %s" % options_file)
195 print("is outdated! Please update the file by examining one of the TEMPLATE")
196 print("files in the scons/ subdirectory and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
197 Exit(1)
198
199 # Generate help text (scons -h)
200 Help(vars.GenerateHelpText(env))
201
202 # Check for superfluous options
203 if len(vars.UnknownVariables())>0:
204 for k in vars.UnknownVariables():
205 print("Unknown option '%s'" % k)
206 Exit(1)
207
208 if env['cuda']:
209 if env['nvcc'] != 'default':
210 env['NVCC'] = env['nvcc']
211 env.Tool('nvcc')
212
213 if 'dudley' in env['domains']:
214 env['domains'].append('finley')
215
216 env['domains'] = sorted(set(env['domains']))
217
218 # create dictionary which will be populated with info for buildvars file
219 env['buildvars'] = {}
220 # create list which will be populated with warnings if there are any
221 env['warnings'] = []
222
223 #################### Make sure install directories exist #####################
224
225 env['BUILD_DIR'] = Dir(env['build_dir']).abspath
226 prefix = Dir(env['prefix']).abspath
227 env['buildvars']['prefix'] = prefix
228 env['incinstall'] = os.path.join(prefix, 'include')
229 env['bininstall'] = os.path.join(prefix, 'bin')
230 env['libinstall'] = os.path.join(prefix, 'lib')
231 env['pyinstall'] = os.path.join(prefix, 'esys')
232 if not os.path.isdir(env['bininstall']):
233 os.makedirs(env['bininstall'])
234 if not os.path.isdir(env['libinstall']):
235 os.makedirs(env['libinstall'])
236 if not os.path.isdir(env['pyinstall']):
237 os.makedirs(env['pyinstall'])
238
239 env.Append(CPPPATH = [env['incinstall']])
240 env.Append(LIBPATH = [env['libinstall']])
241
242 ################# Fill in compiler options if not set above ##################
243
244 if env['cxx'] != 'default':
245 env['CXX'] = env['cxx']
246
247 # default compiler/linker options
248 cc_flags = ''
249 cc_optim = ''
250 cc_debug = ''
251 omp_flags = ''
252 omp_ldflags = ''
253 fatalwarning = '' # switch to turn warnings into errors
254 sysheaderopt = '' # how to indicate that a header is a system header
255
256 # env['CC'] might be a full path
257 cc_name=os.path.basename(env['CXX'])
258
259 if cc_name == 'icpc':
260 # Intel compiler
261 # #1478: class "std::auto_ptr<...>" was declared deprecated
262 # #1875: offsetof applied to non-POD types is nonstandard (in boost)
263 # removed -std=c99 because icpc doesn't like it and we aren't using c anymore
264 cc_flags = "-std=c++11 -fPIC -w2 -wd1875 -wd1478 -Wno-unknown-pragmas"
265 cc_optim = "-O3 -ftz -fno-alias -inline-level=2 -ipo -xHost"
266 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK"
267 omp_flags = "-openmp"
268 omp_ldflags = "-openmp -openmp_report=1"
269 fatalwarning = "-Werror"
270 elif cc_name[:3] == 'g++':
271 # GNU C++ on any system
272 # note that -ffast-math is not used because it breaks isnan(),
273 # see mantis #691
274 cc_flags = "-std=c++11 -pedantic -Wall -fPIC -Wno-unknown-pragmas -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing -finline-functions"
275 cc_optim = "-O3"
276 #max-vartrack-size: avoid vartrack limit being exceeded with escriptcpp.cpp
277 cc_debug = "-g3 -O0 -D_GLIBCXX_DEBUG -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK --param=max-vartrack-size=100000000"
278 omp_flags = "-fopenmp"
279 omp_ldflags = "-fopenmp"
280 fatalwarning = "-Werror"
281 sysheaderopt = "-isystem"
282 elif cc_name == 'cl':
283 # Microsoft Visual C on Windows
284 cc_flags = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
285 cc_optim = "/O2 /Op /W3"
286 cc_debug = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
287 fatalwarning = "/WX"
288 elif cc_name == 'icl':
289 # Intel C on Windows
290 cc_flags = '/EHsc /GR /MD'
291 cc_optim = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
292 cc_debug = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
293 omp_flags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
294 omp_ldflags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
295
296 env['sysheaderopt']=sysheaderopt
297
298 # set defaults if not otherwise specified
299 if env['cc_flags'] == 'default': env['cc_flags'] = cc_flags
300 if env['cc_optim'] == 'default': env['cc_optim'] = cc_optim
301 if env['cc_debug'] == 'default': env['cc_debug'] = cc_debug
302 if env['omp_flags'] == 'default': env['omp_flags'] = omp_flags
303 if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
304 if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
305 if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
306 if env['cpp_flags'] != '': env.Append(CPPFLAGS = env['cpp_flags'])
307 if env['cpp_extra'] != '': env.Append(CPPFLAGS = " "+env['cpp_extra'])
308
309 if env['nvccflags'] != 'default':
310 env['NVCCFLAGS'] = env['nvccflags']
311 env['SHNVCCFLAGS'] = env['nvccflags'] + ' -shared'
312
313 if env['longindices']:
314 env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
315
316 if env['usepython3']:
317 env.Append(CPPDEFINES=['ESPYTHON3'])
318
319 # set up the autolazy values
320 if env['forcelazy'] == 'on':
321 env.Append(CPPDEFINES=['FAUTOLAZYON'])
322 elif env['forcelazy'] == 'off':
323 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
324
325 if env['broken_cppacos']:
326 env.Append(CPPDEFINES=['BROKENACOS'])
327
328 # set up the collective resolve values
329 if env['forcecollres'] == 'on':
330 env.Append(CPPDEFINES=['FRESCOLLECTON'])
331 elif env['forcecollres'] == 'off':
332 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
333
334 # allow non-standard C if requested
335 if env['iknowwhatimdoing']:
336 env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
337
338 # Disable OpenMP if no flags provided
339 if env['openmp'] and env['omp_flags'] == '':
340 env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
341 env['openmp'] = False
342
343 if env['openmp']:
344 env.Append(CCFLAGS = env['omp_flags'])
345 if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
346 else:
347 env['omp_flags']=''
348 env['omp_ldflags']=''
349
350 env['buildvars']['openmp']=int(env['openmp'])
351
352 # add debug/non-debug compiler flags
353 env['buildvars']['debug']=int(env['debug'])
354 if env['debug']:
355 env.Append(CCFLAGS = env['cc_debug'])
356 else:
357 env.Append(CCFLAGS = env['cc_optim'])
358
359 # always add cc_flags
360 env.Append(CCFLAGS = env['cc_flags'])
361
362 # add system libraries
363 env.AppendUnique(LIBS = env['sys_libs'])
364
365 # set defaults for launchers if not otherwise specified
366 if env['prelaunch'] == 'default':
367 if env['mpi'] == 'INTELMPI' and env['openmp']:
368 env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
369 elif env['mpi'] == 'OPENMPI':
370 # transform comma-separated list to '-x a -x b -x c ...'
371 env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
372 elif env['mpi'] == 'MPT':
373 env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
374 elif env['mpi'] == 'MPICH2':
375 env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
376 else:
377 env['prelaunch'] = ""
378
379 if env['launcher'] == 'default':
380 if env['mpi'] == 'INTELMPI':
381 env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
382 elif env['mpi'] == 'OPENMPI':
383 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} --host %h --cpus-per-rank %t -np %N %b"
384 #newer OpenMPI version:
385 #env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} --host %h --map-by node:pe=%t -bind-to core -np %N %b"
386 elif env['mpi'] == 'MPT':
387 env['launcher'] = "mpirun %h -np %p %b"
388 elif env['mpi'] == 'MPICH':
389 env['launcher'] = "mpirun -machinefile %f -np %N %b"
390 elif env['mpi'] == 'MPICH2':
391 env['launcher'] = "mpiexec -genvlist %e -np %N %b"
392 else:
393 env['launcher'] = "%b"
394
395 if env['postlaunch'] == 'default':
396 if env['mpi'] == 'MPICH2':
397 env['postlaunch'] = "mpdallexit"
398 else:
399 env['postlaunch'] = ""
400
401 # determine svn revision
402 global_revision=ARGUMENTS.get('SVN_VERSION', None)
403 if global_revision:
404 global_revision = re.sub(':.*', '', global_revision)
405 global_revision = re.sub('[^0-9]', '', global_revision)
406 if global_revision == '': global_revision='-2'
407 else:
408 # Get the global Subversion revision number for the getVersion() method
409 try:
410 global_revision = os.popen('svnversion -n .').read()
411 global_revision = re.sub(':.*', '', global_revision)
412 global_revision = re.sub('[^0-9]', '', global_revision)
413 if global_revision == '': global_revision='-2'
414 except:
415 global_revision = '-1'
416 env['svn_revision']=global_revision
417 env['buildvars']['svn_revision']=global_revision
418 env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
419
420 env['IS_WINDOWS']=IS_WINDOWS
421 env['IS_OSX']=IS_OSX
422
423 ###################### Copy required environment vars ########################
424
425 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
426 if IS_WINDOWS:
427 LD_LIBRARY_PATH_KEY='PATH'
428 env['ENV']['LD_LIBRARY_PATH']=''
429 else:
430 LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
431
432 env['LD_LIBRARY_PATH_KEY']=LD_LIBRARY_PATH_KEY
433
434 # the following env variables are exported for the unit tests
435
436 for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
437 try:
438 env['ENV'][key] = os.environ[key]
439 except KeyError:
440 env['ENV'][key] = '1'
441
442 env_export=env['env_export']
443 env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','KMP_MONITOR_STACKSIZE','TMPDIR','TEMP','TMP','LD_PRELOAD'])
444
445 for key in set(env_export):
446 try:
447 env['ENV'][key] = os.environ[key]
448 except KeyError:
449 pass
450
451 for key in os.environ.keys():
452 if key.startswith("SLURM_"):
453 env['ENV'][key] = os.environ[key]
454
455 try:
456 env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
457 except KeyError:
458 pass
459
460 if IS_OSX:
461 try:
462 env.PrependENVPath('DYLD_LIBRARY_PATH', os.environ['DYLD_LIBRARY_PATH'])
463 except KeyError:
464 pass
465
466
467 # these shouldn't be needed
468 #for key in 'C_INCLUDE_PATH','CPLUS_INCLUDE_PATH','LIBRARY_PATH':
469 # try:
470 # env['ENV'][key] = os.environ[key]
471 # except KeyError:
472 # pass
473
474 try:
475 env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
476 except KeyError:
477 pass
478
479 ######################## Add some custom builders ############################
480
481 if env['pythoncmd']=='python':
482 py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
483 else:
484 py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
485 env.Append(BUILDERS = {'PyCompile' : py_builder});
486
487 runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
488 env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
489
490 runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
491 env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
492
493 runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
494 env.Append(BUILDERS = {'RunPyExample' : runPyExample_builder});
495
496 epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
497 env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
498
499 ############################ Dependency checks ###############################
500
501 ######## Compiler
502 env=checkCompiler(env)
503
504 ######## Python headers & library (required)
505 env=checkPython(env)
506
507 ######## boost & boost-python (required)
508 env=checkBoost(env)
509
510 ######## numpy (required) and numpy headers (optional)
511 env=checkNumpy(env)
512
513 ######## CppUnit (required for tests)
514 env=checkCppUnit(env)
515
516 ######## NVCC version (optional)
517 if env['cuda'] and 'ripley' in env['domains']:
518 env=checkCudaVersion(env)
519 env=checkCUDA(env)
520
521 ######## optional python modules (sympy, pyproj)
522 env=checkOptionalModules(env)
523
524 ######## optional dependencies (netCDF, PAPI, MKL, UMFPACK, Lapack, Silo, ...)
525 env=checkOptionalLibraries(env)
526
527 ######## PDFLaTeX (for documentation)
528 env=checkPDFLatex(env)
529
530 # dependency sanity checks
531
532 if len(env['domains']) == 0:
533 env['warnings'].append("No domains have been built, escript will not be very useful!")
534
535 # keep some of our install paths first in the list for the unit tests
536 env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
537 env.PrependENVPath('PYTHONPATH', prefix)
538 env['ENV']['ESCRIPT_ROOT'] = prefix
539
540 if not env['verbose']:
541 env['CXXCOMSTR'] = "Compiling $TARGET"
542 env['SHCXXCOMSTR'] = "Compiling $TARGET"
543 env['ARCOMSTR'] = "Linking $TARGET"
544 env['LINKCOMSTR'] = "Linking $TARGET"
545 env['SHLINKCOMSTR'] = "Linking $TARGET"
546 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
547 env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
548 env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
549 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
550 #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
551
552 ########################### Configure the targets ############################
553
554 from grouptest import GroupTest
555 TestGroups=[]
556
557 # keep an environment without warnings-as-errors
558 dodgy_env=env.Clone()
559
560 # now add warnings-as-errors flags. This needs to be done after configuration
561 # because the scons test files have warnings in them
562 if ((fatalwarning != '') and (env['werror'])):
563 env.Append(CCFLAGS = fatalwarning)
564
565 Export(
566 ['env',
567 'dodgy_env',
568 'IS_WINDOWS',
569 'TestGroups'
570 ]
571 )
572
573 target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
574 env.Alias('target_init', [target_init])
575
576 build_all_list = []
577 install_all_list = ['target_init']
578
579 # The order here is important as certain keys in env need to be defined for
580 # certain modules.
581
582 # escript can't be turned off
583 env.SConscript('escriptcore/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/escriptcore', duplicate=0)
584 env.SConscript('escript/py_src/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/escript', duplicate=0)
585 build_all_list += ['build_escript']
586 install_all_list += ['install_escript']
587
588 env.SConscript('pythonMPI/src/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/pythonMPI', duplicate=0)
589 env.SConscript('tools/overlord/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/tools/overlord', duplicate=0)
590 if env['usempi']:
591 build_all_list += ['build_pythonMPI', 'build_overlord']
592 install_all_list += ['install_pythonMPI', 'install_overlord']
593
594 if env['paso']:
595 env.SConscript('paso/src/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/paso', duplicate=0)
596 build_all_list += ['build_paso']
597 install_all_list += ['install_paso']
598
599 if env['trilinos']:
600 env.SConscript('trilinoswrap/src/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/trilinoswrap', duplicate=0)
601 build_all_list += ['build_trilinoswrap']
602 install_all_list += ['install_trilinoswrap']
603
604 env.SConscript('cusplibrary/SConscript')
605
606 for domain in env['domains']:
607 env.SConscript('%s/SConscript'%domain, variant_dir='$BUILD_DIR/$PLATFORM/%s'%domain, duplicate=0)
608 build_all_list += ['build_%s'%domain]
609 install_all_list += ['install_%s'%domain]
610
611 if env['weipa']:
612 env.SConscript('weipa/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/weipa', duplicate=0)
613 build_all_list += ['build_weipa']
614 install_all_list += ['install_weipa']
615 if 'finley' in env['domains']:
616 build_all_list += ['build_escriptreader']
617 install_all_list += ['install_escriptreader']
618
619 env.SConscript(dirs = ['downunder/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/downunder', duplicate=0)
620 env.SConscript(dirs = ['modellib/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/modellib', duplicate=0)
621 env.SConscript(dirs = ['pycad/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/pycad', duplicate=0)
622 env.SConscript('tools/escriptconvert/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/tools/escriptconvert', duplicate=0)
623 env.SConscript('doc/SConscript', variant_dir='$BUILD_DIR/$PLATFORM/doc', duplicate=0)
624
625 env.Alias('build', build_all_list)
626
627 install_all_list += ['install_downunder_py']
628 install_all_list += ['install_modellib_py']
629 install_all_list += ['install_pycad_py']
630 install_all_list += [env.Install(Dir('scripts',env['build_dir']), os.path.join('scripts', 'release_sanity.py'))]
631
632 if env['osx_dependency_fix']:
633 print("Require dependency fix")
634 install_all=env.Command('install', install_all_list, 'scripts/moveall.sh')
635 else:
636 install_all=env.Alias('install', install_all_list)
637
638 sanity=env.Alias('sanity', env.Command('dummy','',os.path.join(env['prefix'], 'bin', 'run-escript')+' '+os.path.join(env['build_dir'],'scripts', 'release_sanity.py')))
639 env.Depends('dummy', install_all)
640 if env['usempi']:
641 #env.Requires('dummy', ['build_pythonMPI', 'install_pythonMPI'])
642 env.Depends('dummy', ['install_pythonMPI'])
643
644 # if all domains are built:
645 if env['domains'] == all_domains:
646 env.AlwaysBuild('sanity')
647 env.Default('sanity')
648 else:
649 env.Default('install')
650
651 ################## Targets to build and run the test suite ###################
652
653 if not env['cppunit']:
654 test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
655 env.Alias('run_tests', test_msg)
656 env.Alias('build_tests', '')
657 env.Alias('run_tests', ['install'])
658 env.Alias('all_tests', ['install', 'run_tests', 'py_tests'])
659 env.Alias('build_full',['install','build_tests','build_py_tests'])
660 Requires('py_tests', 'install')
661
662 ##################### Targets to build the documentation #####################
663
664 env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
665 env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
666 env.Alias('docs', ['basedocs', 'sphinxdoc'])
667 env.Alias('release_prep', ['docs', 'install'])
668 env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install'])
669
670 # The test scripts are always generated, this target allows us to
671 # generate the testscripts without doing a full build
672 env.Alias('testscripts',[])
673
674 if not IS_WINDOWS:
675 generateTestScripts(env, TestGroups)
676
677 ######################## Populate the buildvars file #########################
678
679 write_buildvars(env)
680 # delete buildvars upon cleanup - target_init is default so use it
681 env.Clean('target_init', File('buildvars', env['libinstall']))
682
683 write_launcher(env)
684
685 # remove obsolete files
686 if not env['usempi']:
687 Execute(Delete(File(['pythonMPI','pythonMPIredirect'], env['libinstall'])))
688 Execute(Delete(File('escript-overlord', env['bininstall'])))
689
690 ######################## Summarize our environment ###########################
691 def print_summary():
692 print("")
693 print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
694 print("Escript revision %s"%global_revision)
695 print(" Install prefix: %s"%env['prefix'])
696 print(" Python: %s"%sysconfig.PREFIX)
697 print(" boost: %s (Version %s)"%(env['boost_prefix'],env['boost_version']))
698 if env['numpy_h']:
699 print(" numpy: YES (with headers)")
700 else:
701 print(" numpy: YES (without headers)")
702 if env['usempi']:
703 print(" MPI: YES (flavour: %s)"%env['mpi'])
704 else:
705 print(" MPI: NO")
706 if env['parmetis']:
707 print(" ParMETIS: %s (Version %s)"%(env['parmetis_prefix'],env['parmetis_version']))
708 else:
709 print(" ParMETIS: NO")
710 if env['uselapack']:
711 print(" LAPACK: YES (flavour: %s)"%env['lapack'])
712 else:
713 print(" LAPACK: NO")
714 if env['cuda']:
715 print(" CUDA: YES (nvcc: %s)"%env['nvcc_version'])
716 else:
717 print(" CUDA: NO")
718 d_list=[]
719 e_list=[]
720 for i in 'debug','openmp','boomeramg','cppunit','gdal','mkl','netcdf','papi','pyproj','scipy','silo','sympy','trilinos','umfpack','visit':
721 if env[i]: e_list.append(i)
722 else: d_list.append(i)
723 for i in e_list:
724 print("%16s: YES"%i)
725 for i in d_list:
726 print("%16s: NO"%i)
727 if env['gmshpy']:
728 gmshpy=" + python module"
729 else:
730 gmshpy=""
731 if env['gmsh']=='m':
732 print(" gmsh: YES, MPI-ENABLED"+gmshpy)
733 elif env['gmsh']=='s':
734 print(" gmsh: YES"+gmshpy)
735 else:
736 if env['gmshpy']:
737 print(" gmsh: python module only")
738 else:
739 print(" gmsh: NO")
740 print( " gzip: " + ("YES" if env['compressed_files'] else "NO"))
741
742 if ((fatalwarning != '') and (env['werror'])):
743 print(" Treating warnings as errors")
744 else:
745 print(" NOT treating warnings as errors")
746 print("")
747 for w in env['warnings']:
748 print("WARNING: %s"%w)
749 if len(GetBuildFailures()):
750 print("\nERROR: build stopped due to errors\n")
751 else:
752 print("\nSUCCESS: build complete\n")
753
754 atexit.register(print_summary)
755

  ViewVC Help
Powered by ViewVC 1.1.26