/[escript]/branches/4.0fordebian/SConstruct
ViewVC logotype

Contents of /branches/4.0fordebian/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5577 - (show annotations)
Fri Apr 3 05:26:15 2015 UTC (3 years, 11 months ago) by jfenwick
File size: 32751 byte(s)
Fixes to make us more lintian compliant (copied across from private git)
1 ##############################################################################
2 #
3 # Copyright (c) 2003-2014 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 #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 ('thrust_prefix', 'Prefix/Paths to NVidia thrust 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('BADPYTHONMACROS','Extra \#include to get around a python bug.', True),
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
301 if env['nvccflags'] != 'default':
302 env['NVCCFLAGS'] = env['nvccflags']
303 env['SHNVCCFLAGS'] = env['nvccflags'] + ' -shared'
304
305 if env['BADPYTHONMACROS']:
306 env.Append(CPPDEFINES = ['BADPYTHONMACROS'])
307
308 if env['longindices']:
309 env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
310
311 if env['usepython3']:
312 env.Append(CPPDEFINES=['ESPYTHON3'])
313
314 # set up the autolazy values
315 if env['forcelazy'] == 'on':
316 env.Append(CPPDEFINES=['FAUTOLAZYON'])
317 elif env['forcelazy'] == 'off':
318 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
319
320 # set up the collective resolve values
321 if env['forcecollres'] == 'on':
322 env.Append(CPPDEFINES=['FRESCOLLECTON'])
323 elif env['forcecollres'] == 'off':
324 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
325
326 # allow non-standard C if requested
327 if env['iknowwhatimdoing']:
328 env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
329
330 # Disable OpenMP if no flags provided
331 if env['openmp'] and env['omp_flags'] == '':
332 env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
333 env['openmp'] = False
334
335 if env['openmp']:
336 env.Append(CCFLAGS = env['omp_flags'])
337 if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
338 else:
339 env['omp_flags']=''
340 env['omp_ldflags']=''
341
342 env['buildvars']['openmp']=int(env['openmp'])
343
344 # add debug/non-debug compiler flags
345 env['buildvars']['debug']=int(env['debug'])
346 if env['debug']:
347 env.Append(CCFLAGS = env['cc_debug'])
348 else:
349 env.Append(CCFLAGS = env['cc_optim'])
350
351 # always add cc_flags
352 env.Append(CCFLAGS = env['cc_flags'])
353
354 # add system libraries
355 env.AppendUnique(LIBS = env['sys_libs'])
356
357 # set defaults for launchers if not otherwise specified
358 if env['prelaunch'] == 'default':
359 if env['mpi'] == 'INTELMPI' and env['openmp']:
360 env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
361 elif env['mpi'] == 'OPENMPI':
362 # transform comma-separated list to '-x a -x b -x c ...'
363 env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
364 elif env['mpi'] == 'MPT':
365 env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
366 elif env['mpi'] == 'MPICH2':
367 env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
368 else:
369 env['prelaunch'] = ""
370
371 if env['launcher'] == 'default':
372 if env['mpi'] == 'INTELMPI':
373 env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
374 elif env['mpi'] == 'OPENMPI':
375 env['launcher'] = "mpirun --gmca mpi_warn_on_fork 0 ${EE} --host %h -bynode -bind-to-core --cpus-per-rank %t -np %N %b"
376 elif env['mpi'] == 'MPT':
377 env['launcher'] = "mpirun %h -np %p %b"
378 elif env['mpi'] == 'MPICH':
379 env['launcher'] = "mpirun -machinefile %f -np %N %b"
380 elif env['mpi'] == 'MPICH2':
381 env['launcher'] = "mpiexec -genvlist %e -np %N %b"
382 else:
383 env['launcher'] = "%b"
384
385 if env['postlaunch'] == 'default':
386 if env['mpi'] == 'MPICH2':
387 env['postlaunch'] = "mpdallexit"
388 else:
389 env['postlaunch'] = ""
390
391 # determine svn revision
392 global_revision=ARGUMENTS.get('SVN_VERSION', None)
393 if global_revision:
394 global_revision = re.sub(':.*', '', global_revision)
395 global_revision = re.sub('[^0-9]', '', global_revision)
396 if global_revision == '': global_revision='-2'
397 else:
398 # Get the global Subversion revision number for the getVersion() method
399 try:
400 global_revision = os.popen('svnversion -n .').read()
401 global_revision = re.sub(':.*', '', global_revision)
402 global_revision = re.sub('[^0-9]', '', global_revision)
403 if global_revision == '': global_revision='-2'
404 except:
405 global_revision = '-1'
406 env['svn_revision']=global_revision
407 env['buildvars']['svn_revision']=global_revision
408 env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
409
410 if IS_WINDOWS:
411 if not env['build_shared']:
412 env.Append(CPPDEFINES = ['ESYSUTILS_STATIC_LIB'])
413 env.Append(CPPDEFINES = ['PASO_STATIC_LIB'])
414
415 env['IS_WINDOWS']=IS_WINDOWS
416 env['IS_OSX']=IS_OSX
417
418 ###################### Copy required environment vars ########################
419
420 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
421 if IS_WINDOWS:
422 LD_LIBRARY_PATH_KEY='PATH'
423 env['ENV']['LD_LIBRARY_PATH']=''
424 else:
425 LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
426
427 env['LD_LIBRARY_PATH_KEY']=LD_LIBRARY_PATH_KEY
428
429 # the following env variables are exported for the unit tests
430
431 for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
432 try:
433 env['ENV'][key] = os.environ[key]
434 except KeyError:
435 env['ENV'][key] = '1'
436
437 env_export=env['env_export']
438 env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','KMP_MONITOR_STACKSIZE','TMPDIR','TEMP','TMP','LD_PRELOAD'])
439
440 for key in set(env_export):
441 try:
442 env['ENV'][key] = os.environ[key]
443 except KeyError:
444 pass
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
505 ######## numpy (required) and numpy headers (optional)
506 env=checkNumpy(env)
507
508 ######## CppUnit (required for tests)
509 env=checkCppUnit(env)
510
511 ######## optional python modules (sympy, pyproj)
512 env=checkOptionalModules(env)
513
514 ######## optional dependencies (netCDF, PAPI, MKL, UMFPACK, Lapack, Silo, ...)
515 env=checkOptionalLibraries(env)
516
517 #use gmsh info to set some defines
518 if env['gmsh'] == 's':
519 env.Append(CPPDEFINES=['GMSH'])
520 elif env['gmsh'] == 'm':
521 env.Append(CPPDEFINES=['GMSH','GMSH_MPI'])
522
523 ######## PDFLaTeX (for documentation)
524 env=checkPDFLatex(env)
525
526 # keep some of our install paths first in the list for the unit tests
527 env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
528 env.PrependENVPath('PYTHONPATH', prefix)
529 env['ENV']['ESCRIPT_ROOT'] = prefix
530
531 if not env['verbose']:
532 env['CXXCOMSTR'] = "Compiling $TARGET"
533 env['SHCXXCOMSTR'] = "Compiling $TARGET"
534 env['ARCOMSTR'] = "Linking $TARGET"
535 env['LINKCOMSTR'] = "Linking $TARGET"
536 env['SHLINKCOMSTR'] = "Linking $TARGET"
537 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
538 env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
539 env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
540 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
541 #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
542
543 ####################### Configure the subdirectories #########################
544
545 # remove obsolete files
546 if not env['usempi']:
547 Execute(Delete(os.path.join(env['libinstall'], 'pythonMPI')))
548 Execute(Delete(os.path.join(env['libinstall'], 'pythonMPIredirect')))
549
550 from grouptest import *
551 TestGroups=[]
552
553 # keep an environment without warnings-as-errors
554 dodgy_env=env.Clone()
555
556 # now add warnings-as-errors flags. This needs to be done after configuration
557 # because the scons test files have warnings in them
558 if ((fatalwarning != '') and (env['werror'])):
559 env.Append(CCFLAGS = fatalwarning)
560
561 Export(
562 ['env',
563 'dodgy_env',
564 'IS_WINDOWS',
565 'TestGroups'
566 ]
567 )
568
569 #do not auto build
570 env.SConscript(dirs = ['tools/escriptconvert'], variant_dir='$BUILD_DIR/$PLATFORM/tools/escriptconvert', duplicate=0)
571 env.SConscript(dirs = ['paso/src'], variant_dir='$BUILD_DIR/$PLATFORM/paso', duplicate=0)
572 env.SConscript(dirs = ['weipa/src'], variant_dir='$BUILD_DIR/$PLATFORM/weipa', duplicate=0)
573 env.SConscript(dirs = ['escript/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/escript', duplicate=0)
574
575 env.SConscript(dirs = ['cusplibrary'])
576
577 #This will pull in the escriptcore/py_src and escriptcore/test
578 env.SConscript(dirs = ['escriptcore/src'], variant_dir='$BUILD_DIR/$PLATFORM/escriptcore', duplicate=0)
579 env.SConscript(dirs = ['esysUtils/src'], variant_dir='$BUILD_DIR/$PLATFORM/esysUtils', duplicate=0)
580 env.SConscript(dirs = ['pasowrap/src'], variant_dir='$BUILD_DIR/$PLATFORM/pasowrap', duplicate=0)
581 if 'dudley' in env['domains']:
582 env.SConscript(dirs = ['dudley/src'], variant_dir='$BUILD_DIR/$PLATFORM/dudley', duplicate=0)
583 if 'finley' in env['domains']:
584 env.SConscript(dirs = ['finley/src'], variant_dir='$BUILD_DIR/$PLATFORM/finley', duplicate=0)
585 if 'ripley' in env['domains']:
586 env.SConscript(dirs = ['ripley/src'], variant_dir='$BUILD_DIR/$PLATFORM/ripley', duplicate=0)
587 if 'speckley' in env['domains']:
588 env.SConscript(dirs = ['speckley/src'], variant_dir='$BUILD_DIR/$PLATFORM/speckley', duplicate=0)
589 env.SConscript(dirs = ['downunder/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/downunder', duplicate=0)
590 env.SConscript(dirs = ['modellib/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/modellib', duplicate=0)
591 env.SConscript(dirs = ['pycad/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/pycad', duplicate=0)
592 env.SConscript(dirs = ['pythonMPI/src'], variant_dir='$BUILD_DIR/$PLATFORM/pythonMPI', duplicate=0)
593 env.SConscript(dirs = ['doc'], variant_dir='$BUILD_DIR/$PLATFORM/doc', duplicate=0)
594 env.SConscript(dirs = ['paso/profiling'], variant_dir='$BUILD_DIR/$PLATFORM/paso/profiling', duplicate=0)
595
596
597 ######################## Populate the buildvars file #########################
598
599 write_buildvars(env)
600
601 write_launcher(env)
602
603 ################### Targets to build and install libraries ###################
604
605 target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
606 env.Alias('target_init', [target_init])
607 # delete buildvars upon cleanup
608 env.Clean('target_init', os.path.join(env['libinstall'], 'buildvars'))
609
610 # The headers have to be installed prior to build in order to satisfy
611 # #include <paso/Common.h>
612 env.Alias('build_esysUtils', ['install_esysUtils_headers', 'build_esysUtils_lib'])
613 env.Alias('install_esysUtils', ['build_esysUtils', 'install_esysUtils_lib'])
614
615 env.Alias('build_paso', ['install_paso_headers', 'build_paso_lib'])
616 env.Alias('install_paso', ['build_paso', 'install_paso_lib'])
617
618 env.Alias('build_escript', ['install_escript_headers', 'build_escript_lib', 'build_escriptcpp_lib'])
619 env.Alias('install_escript', ['build_escript', 'install_escript_lib', 'install_escriptcpp_lib', 'install_escriptcore_py', 'install_escript_py'])
620
621 env.Alias('build_pasowrap', ['install_pasowrap_headers', 'build_pasowrap_lib', 'build_pasowrapcpp_lib'])
622 env.Alias('install_pasowrap', ['build_pasowrap', 'install_pasowrap_lib', 'install_pasowrapcpp_lib', 'install_pasowrap_py'])
623
624 if 'dudley' in env['domains']:
625 env.Alias('build_dudley', ['install_dudley_headers', 'build_dudley_lib', 'build_dudleycpp_lib'])
626 env.Alias('install_dudley', ['build_dudley', 'install_dudley_lib', 'install_dudleycpp_lib', 'install_dudley_py'])
627
628 if 'finley' in env['domains']:
629 env.Alias('build_finley', ['install_finley_headers', 'build_finley_lib', 'build_finleycpp_lib'])
630 env.Alias('install_finley', ['build_finley', 'install_finley_lib', 'install_finleycpp_lib', 'install_finley_py'])
631
632 if 'ripley' in env['domains']:
633 env.Alias('build_ripley', ['install_cusp_headers', 'install_ripley_headers', 'build_ripley_lib', 'build_ripleycpp_lib'])
634 env.Alias('install_ripley', ['build_ripley', 'install_ripley_lib', 'install_ripleycpp_lib', 'install_ripley_py'])
635
636 if 'speckley' in env['domains']:
637 env.Alias('build_speckley', ['install_speckley_headers', 'build_speckley_lib', 'build_speckleycpp_lib'])
638 env.Alias('install_speckley', ['build_speckley', 'install_speckley_lib', 'install_speckleycpp_lib', 'install_speckley_py'])
639
640 env.Alias('build_weipa', ['install_weipa_headers', 'build_weipa_lib', 'build_weipacpp_lib'])
641 env.Alias('install_weipa', ['build_weipa', 'install_weipa_lib', 'install_weipacpp_lib', 'install_weipa_py'])
642
643 env.Alias('build_escriptreader', ['install_weipa_headers', 'build_escriptreader_lib'])
644 env.Alias('install_escriptreader', ['build_escriptreader', 'install_escriptreader_lib'])
645
646 # Now gather all the above into some easy targets: build_all and install_all
647 build_all_list = []
648 build_all_list += ['build_esysUtils']
649 build_all_list += ['build_paso']
650 build_all_list += ['build_escript']
651 build_all_list += ['build_pasowrap']
652 if 'dudley' in env['domains']: build_all_list += ['build_dudley']
653 if 'finley' in env['domains']: build_all_list += ['build_finley']
654 if 'ripley' in env['domains']: build_all_list += ['build_ripley']
655 if 'speckley' in env['domains']: build_all_list += ['build_speckley']
656 build_all_list += ['build_weipa']
657 if not IS_WINDOWS and 'finley' in env['domains']:
658 build_all_list += ['build_escriptreader']
659 if env['usempi']: build_all_list += ['build_pythonMPI']
660 env.Alias('build_all', build_all_list)
661
662 install_all_list = []
663 install_all_list += ['target_init']
664 install_all_list += ['install_esysUtils']
665 install_all_list += ['install_paso']
666 install_all_list += ['install_escript']
667 install_all_list += ['install_pasowrap']
668 if 'dudley' in env['domains']: install_all_list += ['install_dudley']
669 if 'finley' in env['domains']: install_all_list += ['install_finley']
670 if 'ripley' in env['domains']: install_all_list += ['install_ripley']
671 if 'speckley' in env['domains']: install_all_list += ['install_speckley']
672 install_all_list += ['install_weipa']
673 if not IS_WINDOWS and 'finley' in env['domains']:
674 install_all_list += ['install_escriptreader']
675 install_all_list += ['install_downunder_py']
676 install_all_list += ['install_modellib_py']
677 install_all_list += ['install_pycad_py']
678 if env['usempi']: install_all_list += ['install_pythonMPI']
679 env.Alias('install_all', install_all_list)
680
681 # Default target is install
682 env.Default('install_all')
683
684 ################## Targets to build and run the test suite ###################
685
686 if not env['cppunit']:
687 test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
688 env.Alias('run_tests', test_msg)
689 env.Alias('build_tests', '')
690 env.Alias('run_tests', ['install_all'])
691 env.Alias('all_tests', ['install_all', 'run_tests', 'py_tests'])
692 env.Alias('build_full',['install_all','build_tests','build_py_tests'])
693 env.Alias('build_PasoTests','$BUILD_DIR/$PLATFORM/paso/profiling/PasoTests')
694
695 ##################### Targets to build the documentation #####################
696
697 env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
698 env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
699 env.Alias('docs', ['basedocs', 'sphinxdoc'])
700 env.Alias('release_prep', ['docs', 'install_all'])
701 env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install_all'])
702
703 # The test scripts are always generated, this target allows us to
704 # generate the testscripts without doing a full build
705 env.Alias('testscripts',[])
706
707 if not IS_WINDOWS:
708 generateTestScripts(env, TestGroups)
709
710
711 ######################## Summarize our environment ###########################
712 def print_summary():
713 print("")
714 print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
715 print("Escript/Finley revision %s"%global_revision)
716 print(" Install prefix: %s"%env['prefix'])
717 print(" Python: %s"%sysconfig.PREFIX)
718 print(" boost: %s"%env['boost_prefix'])
719 if env['numpy_h']:
720 print(" numpy: YES (with headers)")
721 else:
722 print(" numpy: YES (without headers)")
723 if env['usempi']:
724 print(" MPI: YES (flavour: %s)"%env['mpi'])
725 else:
726 print(" MPI: NO")
727 if env['uselapack']:
728 print(" LAPACK: YES (flavour: %s)"%env['lapack'])
729 else:
730 print(" LAPACK: NO")
731 if env['cuda']:
732 print(" CUDA: YES (nvcc: %s)"%env['nvcc_version'])
733 else:
734 print(" CUDA: NO")
735 d_list=[]
736 e_list=[]
737 for i in 'debug','openmp','boomeramg','gdal','mkl','netcdf','papi','parmetis','pyproj','scipy','silo','sympy','umfpack','visit':
738 if env[i]: e_list.append(i)
739 else: d_list.append(i)
740 for i in e_list:
741 print("%16s: YES"%i)
742 for i in d_list:
743 print("%16s: NO"%i)
744 if env['cppunit']:
745 print(" CppUnit: YES")
746 else:
747 print(" CppUnit: NO")
748 if env['gmshpy']:
749 gmshpy=" + python module"
750 else:
751 gmshpy=""
752 if env['gmsh']=='m':
753 print(" gmsh: YES, MPI-ENABLED"+gmshpy)
754 elif env['gmsh']=='s':
755 print(" gmsh: YES"+gmshpy)
756 else:
757 if env['gmshpy']:
758 print(" gmsh: python module only")
759 else:
760 print(" gmsh: NO")
761 print( " gzip: " + ("YES" if env['compressed_files'] else "NO"))
762
763 if ((fatalwarning != '') and (env['werror'])):
764 print(" Treating warnings as errors")
765 else:
766 print(" NOT treating warnings as errors")
767 print("")
768 for w in env['warnings']:
769 print("WARNING: %s"%w)
770 if len(GetBuildFailures()):
771 print("\nERROR: build stopped due to errors\n")
772 else:
773 print("\nSUCCESS: build complete\n")
774
775 atexit.register(print_summary)
776

  ViewVC Help
Powered by ViewVC 1.1.26