/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26