/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6791 - (show annotations)
Mon Feb 11 05:42:06 2019 UTC (5 weeks, 1 day ago) by aellery
File size: 33437 byte(s)
Made some changes to prevent errors when using the latest version of the clang compiler (7.0.1)


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

  ViewVC Help
Powered by ViewVC 1.1.26