/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26