/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6555 - (show annotations)
Sun May 7 11:44:34 2017 UTC (7 months, 1 week ago) by caltinay
File size: 32692 byte(s)
fixed minor typo.

1 ##############################################################################
2 #
3 # Copyright (c) 2003-2017 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=203
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 netcdf_flavours = ('no', 'off', 'none', 'False', # Must be last of the false alternatives
58 'yes', 'on', 'True', '3', # Must be last of the version 3 alternatives
59 '4')
60 all_domains = ['dudley','finley','ripley','speckley']
61
62 #Note that scons construction vars the the following purposes:
63 # CPPFLAGS -> to the preprocessor
64 # CCFLAGS -> flags for _both_ C and C++
65 # CXXFLAGS -> flags for c++ _only_
66 # CFLAGS -> flags for c only
67
68 vars = Variables(options_file, ARGUMENTS)
69 vars.AddVariables(
70 PathVariable('options_file', 'Path to options file', options_file, PathVariable.PathIsFile),
71 PathVariable('prefix', 'Installation prefix', Dir('#.').abspath, PathVariable.PathIsDirCreate),
72 PathVariable('build_dir', 'Top-level build directory', Dir('#/build').abspath, PathVariable.PathIsDirCreate),
73 BoolVariable('verbose', 'Output full compile/link lines', False),
74 # Compiler/Linker options
75 ('cxx', 'Path to C++ compiler', 'default'),
76 ('cc_flags', 'Base (C and C++) compiler flags', 'default'),
77 ('cc_optim', 'Additional (C and C++) flags for a non-debug build', 'default'),
78 ('cc_debug', 'Additional (C and C++) flags for a debug build', 'default'),
79 ('cxx_extra', 'Extra C++ compiler 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 EnumVariable('netcdf', 'Enable netCDF file support', False, allowed_values=netcdf_flavours),
101 ('netcdf_prefix', 'Prefix/Paths of netCDF installation', default_prefix),
102 ('netcdf_libs', 'netCDF libraries to link with', 'DEFAULT'),
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 TristateVariable('lapack', 'Enable LAPACK', 'auto'),
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 TristateVariable('forcelazy', 'For testing use only - set the default value for autolazy', 'auto'),
142 TristateVariable('forcecollres', 'For testing use only - set the default value for force resolving collective ops', 'auto'),
143 BoolVariable('build_shared', '(deprecated option, 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', sys.executable),
148 ('pythonlibname', 'Name of the python library to link. (This is found automatically for python2.X.)', ''),
149 ('pythonlibpath', 'Path to the python library. (You should not need to set this unless your python has moved)',''),
150 ('pythonincpath','Path to python include files. (You should not need to set this unless your python has moved',''),
151 BoolVariable('longindices', 'use long indices (for very large matrices)', False),
152 BoolVariable('compressed_files','Enables reading from compressed binary files', True),
153 ('compression_libs', 'Compression libraries to link with', ['boost_iostreams']),
154 BoolVariable('papi', 'Enable PAPI', False),
155 ('papi_prefix', 'Prefix/Paths to PAPI installation', default_prefix),
156 ('papi_libs', 'PAPI libraries to link with', ['papi']),
157 BoolVariable('papi_instrument_solver', 'Use PAPI to instrument each iteration of the solver', False),
158 BoolVariable('osx_dependency_fix', 'Fix dependencies for libraries to have absolute paths (OSX)', False),
159 BoolVariable('stdlocationisprefix', 'Set the prefix as escript root in the launcher', False)
160 )
161
162 ##################### Create environment and help text #######################
163
164 # Intel's compiler uses regular expressions improperly and emits a warning
165 # about failing to find the compilers. This warning can be safely ignored.
166
167 # PATH is needed so the compiler, linker and tools are found if they are not
168 # in default locations.
169 env = Environment(tools = ['default'], options = vars,
170 ENV = {'PATH': os.environ['PATH']})
171
172 # set the vars for clang
173 def mkclang(env):
174 env['CXX']='clang++'
175
176 if env['tools_names'] != ['default']:
177 zz=env['tools_names']
178 if 'clang' in zz:
179 zz.remove('clang')
180 zz.insert(0, mkclang)
181 env = Environment(tools = ['default'] + env['tools_names'], options = vars,
182 ENV = {'PATH' : os.environ['PATH']})
183
184 # Covert env['netcdf'] into one of False, 3, 4
185 # Also choose default values for libraries
186 pos1=netcdf_flavours.index('False')
187 pos2=netcdf_flavours.index('3')
188 mypos=netcdf_flavours.index(env['netcdf'])
189 if 0 <= mypos <=pos1:
190 env['netcdf']=0
191 elif pos1 < mypos <= pos2:
192 env['netcdf']=3
193 if env['netcdf_libs']=='DEFAULT':
194 env['netcdf_libs']=['netcdf_c++', 'netcdf']
195 else: # netcdf4
196 env['netcdf']=4
197 if env['netcdf_libs']=='DEFAULT':
198 env['netcdf_libs']=['netcdf_c++4']
199
200 if options_file:
201 opts_valid=False
202 if 'escript_opts_version' in env.Dictionary() and \
203 int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
204 opts_valid=True
205 if opts_valid:
206 print("Using options in %s." % options_file)
207 else:
208 print("\nOptions file %s" % options_file)
209 print("is outdated! Please update the file after reading scons/templates/README_FIRST")
210 print("and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
211 Exit(1)
212
213 # Generate help text (scons -h)
214 Help(vars.GenerateHelpText(env))
215
216 # Check for superfluous options
217 if len(vars.UnknownVariables())>0:
218 for k in vars.UnknownVariables():
219 print("Unknown option '%s'" % k)
220 Exit(1)
221
222 if env['cuda']:
223 if env['nvcc'] != 'default':
224 env['NVCC'] = env['nvcc']
225 env.Tool('nvcc')
226
227 if 'dudley' in env['domains']:
228 env['domains'].append('finley')
229
230 env['domains'] = sorted(set(env['domains']))
231
232 # create dictionary which will be populated with info for buildvars file
233 env['buildvars'] = {}
234 # create list which will be populated with warnings if there are any
235 env['warnings'] = []
236
237 #################### Make sure install directories exist #####################
238
239 env['BUILD_DIR'] = Dir(env['build_dir']).abspath
240 prefix = Dir(env['prefix']).abspath
241 env['buildvars']['prefix'] = prefix
242 env['incinstall'] = os.path.join(prefix, 'include')
243 env['bininstall'] = os.path.join(prefix, 'bin')
244 env['libinstall'] = os.path.join(prefix, 'lib')
245 env['pyinstall'] = os.path.join(prefix, 'esys')
246 if not os.path.isdir(env['bininstall']):
247 os.makedirs(env['bininstall'])
248 if not os.path.isdir(env['libinstall']):
249 os.makedirs(env['libinstall'])
250 if not os.path.isdir(env['pyinstall']):
251 os.makedirs(env['pyinstall'])
252
253 env.Append(CPPPATH = [env['incinstall']])
254 env.Append(LIBPATH = [env['libinstall']])
255
256 ################# Fill in compiler options if not set above ##################
257
258 if env['cxx'] != 'default':
259 env['CXX'] = env['cxx']
260
261 # default compiler/linker options
262 cc_flags = '-std=c++11'
263 cc_optim = ''
264 cc_debug = ''
265 omp_flags = ''
266 omp_ldflags = ''
267 fatalwarning = '' # switch to turn warnings into errors
268 sysheaderopt = '' # how to indicate that a header is a system header
269
270 # env['CC'] might be a full path
271 cc_name=os.path.basename(env['CXX'])
272
273 if cc_name == 'icpc':
274 # Intel compiler
275 # #1478: class "std::auto_ptr<...>" was declared deprecated
276 # #1875: offsetof applied to non-POD types is nonstandard (in boost)
277 # removed -std=c99 because icpc doesn't like it and we aren't using c anymore
278 cc_flags = "-std=c++11 -fPIC -w2 -wd1875 -wd1478 -Wno-unknown-pragmas"
279 cc_optim = "-O3 -ftz -fno-alias -inline-level=2 -ipo -xHost"
280 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK"
281 omp_flags = "-qopenmp"
282 omp_ldflags = "-qopenmp" # removing -openmp-report (which is deprecated) because the replacement outputs to a file
283 fatalwarning = "-Werror"
284 elif cc_name[:3] == 'g++':
285 # GNU C++ on any system
286 # note that -ffast-math is not used because it breaks isnan(),
287 # see mantis #691
288 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"
289 cc_optim = "-O3"
290 #max-vartrack-size: avoid vartrack limit being exceeded with escriptcpp.cpp
291 cc_debug = "-g3 -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK --param=max-vartrack-size=100000000"
292 #Removed because new netcdf doesn't seem to like it
293 #cc_debug += ' -D_GLIBCXX_DEBUG '
294 omp_flags = "-fopenmp"
295 omp_ldflags = "-fopenmp"
296 fatalwarning = "-Werror"
297 sysheaderopt = "-isystem"
298 elif cc_name == 'cl':
299 # Microsoft Visual C on Windows
300 cc_flags = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
301 cc_optim = "/O2 /Op /W3"
302 cc_debug = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
303 fatalwarning = "/WX"
304 elif cc_name == 'icl':
305 # Intel C on Windows
306 cc_flags = '/EHsc /GR /MD'
307 cc_optim = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
308 cc_debug = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
309 omp_flags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
310 omp_ldflags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
311
312 env['sysheaderopt']=sysheaderopt
313
314 # set defaults if not otherwise specified
315 if env['cc_flags'] == 'default': env['cc_flags'] = cc_flags
316 if env['cc_optim'] == 'default': env['cc_optim'] = cc_optim
317 if env['cc_debug'] == 'default': env['cc_debug'] = cc_debug
318 if env['omp_flags'] == 'default': env['omp_flags'] = omp_flags
319 if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
320 if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
321 if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
322
323 if env['nvccflags'] != 'default':
324 env['NVCCFLAGS'] = env['nvccflags']
325 env['SHNVCCFLAGS'] = env['nvccflags'] + ' -shared'
326
327 if env['longindices']:
328 env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
329
330 # set up the autolazy values
331 if env['forcelazy'] == 1:
332 env.Append(CPPDEFINES=['FAUTOLAZYON'])
333 elif env['forcelazy'] == 0:
334 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
335
336 # set up the collective resolve values
337 if env['forcecollres'] == 1:
338 env.Append(CPPDEFINES=['FRESCOLLECTON'])
339 elif env['forcecollres'] == 0:
340 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
341
342 # allow non-standard C if requested
343 if env['iknowwhatimdoing']:
344 env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
345
346 # Disable OpenMP if no flags provided
347 if env['openmp'] and env['omp_flags'] == '':
348 env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
349 env['openmp'] = False
350
351 if env['openmp']:
352 env.Append(CCFLAGS = env['omp_flags'])
353 if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
354 else:
355 env['omp_flags']=''
356 env['omp_ldflags']=''
357
358 env['buildvars']['openmp']=int(env['openmp'])
359
360 # add debug/non-debug compiler flags
361 env['buildvars']['debug']=int(env['debug'])
362 if env['debug']:
363 env.Append(CCFLAGS = env['cc_debug'])
364 else:
365 env.Append(CCFLAGS = env['cc_optim'])
366
367 # always add cc_flags
368 env.Append(CCFLAGS = env['cc_flags'])
369
370 # add system libraries
371 env.AppendUnique(LIBS = env['sys_libs'])
372
373 # determine svn revision
374 global_revision=ARGUMENTS.get('SVN_VERSION', None)
375 if global_revision:
376 global_revision = re.sub(':.*', '', global_revision)
377 global_revision = re.sub('[^0-9]', '', global_revision)
378 if global_revision == '': global_revision='-2'
379 else:
380 # Get the global Subversion revision number for the getVersion() method
381 try:
382 global_revision = os.popen('svnversion -n .').read()
383 global_revision = re.sub(':.*', '', global_revision)
384 global_revision = re.sub('[^0-9]', '', global_revision)
385 if global_revision == '': global_revision='-2'
386 except:
387 global_revision = '-1'
388 env['svn_revision']=global_revision
389 env['buildvars']['svn_revision']=global_revision
390 env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
391
392 env['IS_WINDOWS']=IS_WINDOWS
393 env['IS_OSX']=IS_OSX
394
395 ###################### Copy required environment vars ########################
396
397 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
398 if IS_WINDOWS:
399 LD_LIBRARY_PATH_KEY='PATH'
400 env['ENV']['LD_LIBRARY_PATH']=''
401 else:
402 LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
403
404 env['LD_LIBRARY_PATH_KEY']=LD_LIBRARY_PATH_KEY
405
406 # the following env variables are exported for the unit tests
407
408 for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
409 try:
410 env['ENV'][key] = os.environ[key]
411 except KeyError:
412 env['ENV'][key] = '1'
413
414 env_export=env['env_export']
415 env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','KMP_MONITOR_STACKSIZE','TMPDIR','TEMP','TMP','LD_PRELOAD'])
416
417 for key in set(env_export):
418 try:
419 env['ENV'][key] = os.environ[key]
420 except KeyError:
421 pass
422
423 for key in os.environ.keys():
424 if key.startswith("SLURM_"):
425 env['ENV'][key] = os.environ[key]
426
427 try:
428 env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
429 except KeyError:
430 pass
431
432 if IS_OSX:
433 try:
434 env.PrependENVPath('DYLD_LIBRARY_PATH', os.environ['DYLD_LIBRARY_PATH'])
435 except KeyError:
436 pass
437
438 try:
439 env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
440 except KeyError:
441 pass
442
443 ######################## Add some custom builders ############################
444
445 # Takes care of prefix and suffix for Python modules:
446 def build_python_module(env, target, source):
447 return env.SharedLibrary(target, source, SHLIBPREFIX='', SHLIBSUFFIX='.so')
448 env.AddMethod(build_python_module, "PythonModule")
449
450 if env['pythoncmd']=='python':
451 py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
452 else:
453 py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
454 env.Append(BUILDERS = {'PyCompile' : py_builder});
455
456 runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
457 env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
458
459 runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
460 env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
461
462 runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
463 env.Append(BUILDERS = {'RunPyExample' : runPyExample_builder});
464
465 epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
466 env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
467
468 ############################ Dependency checks ###############################
469
470 ######## Compiler
471 env=checkCompiler(env)
472
473 ######## Python headers & library (required)
474 env=checkPython(env)
475
476 ######## boost & boost-python (required)
477 env=checkBoost(env)
478
479 ######## numpy (required) and numpy headers (optional)
480 env=checkNumpy(env)
481
482 ######## CppUnit (required for tests)
483 env=checkCppUnit(env)
484
485 ######## NVCC version (optional)
486 if env['cuda'] and 'ripley' in env['domains']:
487 env=checkCudaVersion(env)
488 env=checkCUDA(env)
489
490 ######## optional python modules (sympy, pyproj)
491 env=checkOptionalModules(env)
492
493 ######## optional dependencies (netCDF, PAPI, MKL, UMFPACK, Lapack, Silo, ...)
494 env=checkOptionalLibraries(env)
495
496 ######## PDFLaTeX (for documentation)
497 env=checkPDFLatex(env)
498
499 # set defaults for launchers if not otherwise specified
500 if env['prelaunch'] == 'default':
501 if env['mpi'] == 'INTELMPI' and env['openmp']:
502 env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
503 elif env['mpi'] == 'OPENMPI':
504 # transform comma-separated list to '-x a -x b -x c ...'
505 env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
506 elif env['mpi'] == 'MPT':
507 env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
508 elif env['mpi'] == 'MPICH2':
509 env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
510 else:
511 env['prelaunch'] = ""
512
513 if env['launcher'] == 'default':
514 if env['mpi'] == 'INTELMPI':
515 env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
516 elif env['mpi'] == 'OPENMPI':
517 # default to OpenMPI version 1.10 or higher
518 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} --host %h --map-by node:pe=%t -bind-to core -np %N %b"
519 if 'orte_version' in env:
520 major,minor,point = [int(i) for i in env['orte_version'].split('.')]
521 if major == 1 and minor < 10:
522 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} --host %h --cpus-per-rank %t -np %N %b"
523 elif env['mpi'] == 'MPT':
524 env['launcher'] = "mpirun %h -np %p %b"
525 elif env['mpi'] == 'MPICH':
526 env['launcher'] = "mpirun -machinefile %f -np %N %b"
527 elif env['mpi'] == 'MPICH2':
528 env['launcher'] = "mpiexec -genvlist %e -np %N %b"
529 else:
530 env['launcher'] = "%b"
531
532 if env['postlaunch'] == 'default':
533 if env['mpi'] == 'MPICH2':
534 env['postlaunch'] = "mpdallexit"
535 else:
536 env['postlaunch'] = ""
537
538 # dependency sanity checks
539
540 if len(env['domains']) == 0:
541 env['warnings'].append("No domains have been built, escript will not be very useful!")
542
543 # keep some of our install paths first in the list for the unit tests
544 env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
545 env.PrependENVPath('PYTHONPATH', prefix)
546 env['ENV']['ESCRIPT_ROOT'] = prefix
547
548 if not env['verbose']:
549 env['CXXCOMSTR'] = "Compiling $TARGET"
550 env['SHCXXCOMSTR'] = "Compiling $TARGET"
551 env['ARCOMSTR'] = "Linking $TARGET"
552 env['LINKCOMSTR'] = "Linking $TARGET"
553 env['SHLINKCOMSTR'] = "Linking $TARGET"
554 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
555 env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
556 env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
557 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
558 #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
559
560 ########################### Configure the targets ############################
561
562 from grouptest import GroupTest
563 TestGroups=[]
564
565 # keep an environment without warnings-as-errors
566 dodgy_env=env.Clone()
567
568 # now add warnings-as-errors flags. This needs to be done after configuration
569 # because the scons test files have warnings in them
570 if ((fatalwarning != '') and (env['werror'])):
571 env.Append(CCFLAGS = fatalwarning)
572
573 Export(
574 ['env',
575 'dodgy_env',
576 'IS_WINDOWS',
577 'TestGroups'
578 ]
579 )
580
581 target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
582 env.Alias('target_init', [target_init])
583
584 # escript can't be turned off
585 build_all_list = ['build_escript']
586 install_all_list = ['target_init', 'install_escript']
587
588 if env['usempi']:
589 build_all_list += ['build_pythonMPI', 'build_overlord']
590 install_all_list += ['install_pythonMPI', 'install_overlord']
591
592 env['buildvars']['paso'] = int(env['paso'])
593 if env['paso']:
594 env.Append(CPPDEFINES = ['ESYS_HAVE_PASO'])
595 build_all_list += ['build_paso']
596 install_all_list += ['install_paso']
597
598 env['buildvars']['trilinos'] = int(env['trilinos'])
599 if env['trilinos']:
600 build_all_list += ['build_trilinoswrap']
601 install_all_list += ['install_trilinoswrap']
602
603 env['buildvars']['domains'] = ','.join(env['domains'])
604 for domain in env['domains']:
605 env.Append(CPPDEFINES = ['ESYS_HAVE_'+domain.upper()])
606 build_all_list += ['build_%s'%domain]
607 install_all_list += ['install_%s'%domain]
608
609 env['buildvars']['weipa'] = int(env['weipa'])
610 if env['weipa']:
611 env.Append(CPPDEFINES = ['ESYS_HAVE_WEIPA'])
612 build_all_list += ['build_weipa']
613 install_all_list += ['install_weipa']
614 if 'finley' in env['domains'] or 'dudley' in env['domains']:
615 build_all_list += ['build_escriptreader']
616 install_all_list += ['install_escriptreader']
617
618 variant='$BUILD_DIR/$PLATFORM/'
619 env.SConscript('escriptcore/SConscript', variant_dir=variant+'escriptcore', duplicate=0)
620 env.SConscript('escript/py_src/SConscript', variant_dir=variant+'escript', duplicate=0)
621 env.SConscript('pythonMPI/src/SConscript', variant_dir=variant+'pythonMPI', duplicate=0)
622 env.SConscript('tools/overlord/SConscript', variant_dir=variant+'tools/overlord', duplicate=0)
623 env.SConscript('paso/SConscript', variant_dir=variant+'paso', duplicate=0)
624 env.SConscript('trilinoswrap/SConscript', variant_dir=variant+'trilinoswrap', duplicate=0)
625 env.SConscript('cusplibrary/SConscript')
626 env.SConscript('dudley/SConscript', variant_dir=variant+'dudley', duplicate=0)
627 env.SConscript('finley/SConscript', variant_dir=variant+'finley', duplicate=0)
628 env.SConscript('ripley/SConscript', variant_dir=variant+'ripley', duplicate=0)
629 env.SConscript('speckley/SConscript', variant_dir=variant+'speckley', duplicate=0)
630 env.SConscript('weipa/SConscript', variant_dir=variant+'weipa', duplicate=0)
631 env.SConscript(dirs = ['downunder/py_src'], variant_dir=variant+'downunder', duplicate=0)
632 env.SConscript(dirs = ['modellib/py_src'], variant_dir=variant+'modellib', duplicate=0)
633 env.SConscript(dirs = ['pycad/py_src'], variant_dir=variant+'pycad', duplicate=0)
634 env.SConscript('tools/escriptconvert/SConscript', variant_dir=variant+'tools/escriptconvert', duplicate=0)
635 env.SConscript('doc/SConscript', variant_dir=variant+'doc', duplicate=0)
636
637 env.Alias('build', build_all_list)
638
639 install_all_list += ['install_downunder_py']
640 install_all_list += ['install_modellib_py']
641 install_all_list += ['install_pycad_py']
642 install_all_list += [env.Install(Dir('scripts',env['build_dir']), os.path.join('scripts', 'release_sanity.py'))]
643
644 if env['osx_dependency_fix']:
645 print("Require dependency fix")
646 install_all=env.Command('install', install_all_list, 'scripts/moveall.sh')
647 else:
648 install_all=env.Alias('install', install_all_list)
649
650 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')))
651 env.Depends('dummy', install_all)
652 if env['usempi']:
653 env.Depends('dummy', ['install_pythonMPI'])
654
655 # if all domains are built:
656 if env['domains'] == all_domains:
657 env.AlwaysBuild('sanity')
658 env.Default('sanity')
659 else:
660 env.Default('install')
661
662 ################## Targets to build and run the test suite ###################
663
664 if not env['cppunit']:
665 test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
666 env.Alias('run_tests', test_msg)
667 env.Alias('build_tests', '')
668 env.Alias('run_tests', ['install'])
669 env.Alias('all_tests', ['install', 'run_tests', 'py_tests'])
670 env.Alias('build_full',['install','build_tests','build_py_tests'])
671 Requires('py_tests', 'install')
672
673 ##################### Targets to build the documentation #####################
674
675 env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
676 env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
677 env.Alias('docs', ['basedocs', 'sphinxdoc'])
678 env.Alias('release_prep', ['docs', 'install'])
679 env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install'])
680
681 # The test scripts are always generated, this target allows us to
682 # generate the testscripts without doing a full build
683 env.Alias('testscripts',[])
684
685 if not IS_WINDOWS:
686 generateTestScripts(env, TestGroups)
687
688 ######################## Populate the buildvars file #########################
689
690 write_buildvars(env)
691 # delete buildvars upon cleanup - target_init is default so use it
692 env.Clean('target_init', File('buildvars', env['libinstall']))
693
694 write_launcher(env)
695
696 # remove obsolete files
697 if not env['usempi']:
698 Execute(Delete(File(['pythonMPI','pythonMPIredirect'], env['libinstall'])))
699 Execute(Delete(File('escript-overlord', env['bininstall'])))
700
701 ######################## Summarize our environment ###########################
702 def print_summary():
703 d_list=[]
704 print("")
705 print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
706 print("Escript revision %s"%global_revision)
707 print(" Install prefix: %s"%env['prefix'])
708 print(" Python: %s (Version %s)"%(env['pythoncmd'],env['python_version']))
709 print(" boost: %s (Version %s)"%(env['boost_prefix'],env['boost_version']))
710 if env['numpy_h']:
711 print(" numpy: YES (with headers)")
712 else:
713 print(" numpy: YES (without headers)")
714 if env['usempi']:
715 if 'orte_version' in env:
716 print(" MPI: %s (Version %s)"%(env['mpi'], env['orte_version']))
717 else:
718 print(" MPI: YES (flavour: %s)"%env['mpi'])
719 else:
720 d_list.append('mpi')
721 if env['parmetis']:
722 print(" ParMETIS: %s (Version %s)"%(env['parmetis_prefix'],env['parmetis_version']))
723 else:
724 d_list.append('parmetis')
725 if env['uselapack']:
726 print(" LAPACK: YES (flavour: %s)"%env['lapack'])
727 else:
728 d_list.append('lapack')
729 if env['cuda']:
730 print(" CUDA: YES (nvcc: %s)"%env['nvcc_version'])
731 else:
732 d_list.append('cuda')
733 if env['gmshpy']:
734 gmshpy=" + python module"
735 else:
736 gmshpy=""
737 if env['gmsh']=='m':
738 print(" gmsh: YES, MPI-ENABLED"+gmshpy)
739 elif env['gmsh']=='s':
740 print(" gmsh: YES"+gmshpy)
741 else:
742 if env['gmshpy']:
743 print(" gmsh: python module only")
744 else:
745 d_list.append('gmsh')
746 if env['compressed_files']:
747 print(" gzip: YES")
748 else:
749 d_list.append('gzip')
750
751 solvers = []
752 direct = []
753 if env['paso']:
754 solvers.append('paso')
755 if env['mkl']:
756 direct.append('mkl')
757 if env['umfpack']:
758 direct.append('umfpack')
759 else:
760 d_list.append('paso')
761 if env['trilinos']:
762 solvers.append('trilinos')
763 direct.append('trilinos')
764 else:
765 d_list.append('trilinos')
766
767 print(" Solver library: %s"%(", ".join(solvers)))
768 if len(direct) > 0:
769 print(" Direct solver: YES (%s)"%(", ".join(direct)))
770 else:
771 print(" Direct solver: NONE")
772 print(" domains: %s"%(", ".join(env['domains'])))
773 if env['netcdf']==4:
774 print(" netcdf: YES (4 + 3)")
775 elif env['netcdf']==3:
776 print(" netcdf: YES (3)")
777 else:
778 print(" netcdf: NO")
779 e_list=[]
780 for i in ('weipa','debug','openmp','boomeramg','cppunit','gdal','mkl',
781 'papi','pyproj','scipy','silo','sympy','umfpack','visit'):
782 if env[i]: e_list.append(i)
783 else: d_list.append(i)
784
785 d_list += set(all_domains).difference(env['domains'])
786 for i in e_list:
787 print("%16s: YES"%i)
788 print("\n DISABLED features: %s"%(" ".join(sorted(d_list))))
789
790 if ((fatalwarning != '') and (env['werror'])):
791 print(" Treating warnings as errors")
792 else:
793 print(" NOT treating warnings as errors")
794 print("")
795 for w in env['warnings']:
796 print("WARNING: %s"%w)
797 if len(GetBuildFailures()):
798 print("\nERROR: build stopped due to errors\n")
799 else:
800 print("\nSUCCESS: build complete\n")
801
802 atexit.register(print_summary)
803

  ViewVC Help
Powered by ViewVC 1.1.26