/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6248 - (show annotations)
Thu Jun 2 04:13:21 2016 UTC (2 years, 10 months ago) by caltinay
File size: 30395 byte(s)
more scons changes:
- replaced p.stdout.read... by p.communicate as recommended by doco
- moved python lib name enquiry logic from options file into dependencies.py
- reporting python version in summary now.

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

  ViewVC Help
Powered by ViewVC 1.1.26