/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5696 - (show annotations)
Fri Jun 26 04:00:56 2015 UTC (3 years, 7 months ago) by caltinay
File size: 33184 byte(s)
Added version check to parmetis to get size of index types.
Also reporting boost & parmetis version now in summary.

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

  ViewVC Help
Powered by ViewVC 1.1.26