/[escript]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6034 - (show annotations)
Wed Mar 9 00:37:57 2016 UTC (3 years, 1 month ago) by caltinay
File size: 33549 byte(s)
a few changes to GroupTest / utest:
GroupTest class now takes a name parameter that is used as (shell) function
name in utest for the test group.
By default all tests are run as before but one can now do:
./utest.sh build '-t2' escriptcpp
to only run the escript c++ unit tests.
Also tweaked a couple things so utest.sh does now work with dash.

1 ##############################################################################
2 #
3 # Copyright (c) 2003-2016 by The University of Queensland
4 # http://www.uq.edu.au
5 #
6 # Primary Business: Queensland, Australia
7 # Licensed under the 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 (ignored)', True),
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 BoolVariable('osx_dependency_fix', 'Fix dependencies for libraries to have absolute paths (OSX)',
155 False)
156 )
157
158 ##################### Create environment and help text #######################
159
160 # Intel's compiler uses regular expressions improperly and emits a warning
161 # about failing to find the compilers. This warning can be safely ignored.
162
163 # PATH is needed so the compiler, linker and tools are found if they are not
164 # in default locations.
165 env = Environment(tools = ['default'], options = vars,
166 ENV = {'PATH': os.environ['PATH']})
167
168 # set the vars for clang
169 def mkclang(env):
170 env['CXX']='clang++'
171
172 if env['tools_names'] != ['default']:
173 zz=env['tools_names']
174 if 'clang' in zz:
175 zz.remove('clang')
176 zz.insert(0, mkclang)
177 env = Environment(tools = ['default'] + env['tools_names'], options = vars,
178 ENV = {'PATH' : os.environ['PATH']})
179
180 if options_file:
181 opts_valid=False
182 if 'escript_opts_version' in env.Dictionary() and \
183 int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
184 opts_valid=True
185 if opts_valid:
186 print("Using options in %s." % options_file)
187 else:
188 print("\nOptions file %s" % options_file)
189 print("is outdated! Please update the file by examining one of the TEMPLATE")
190 print("files in the scons/ subdirectory and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
191 Exit(1)
192
193 # Generate help text (scons -h)
194 Help(vars.GenerateHelpText(env))
195
196 # Check for superfluous options
197 if len(vars.UnknownVariables())>0:
198 for k in vars.UnknownVariables():
199 print("Unknown option '%s'" % k)
200 Exit(1)
201
202 if env['cuda']:
203 if env['nvcc'] != 'default':
204 env['NVCC'] = env['nvcc']
205 env.Tool('nvcc')
206
207 if 'dudley' in env['domains']:
208 env['domains'].append('finley')
209
210 # create dictionary which will be populated with info for buildvars file
211 env['buildvars']={}
212 # create list which will be populated with warnings if there are any
213 env['warnings']=[]
214
215 #################### Make sure install directories exist #####################
216
217 env['BUILD_DIR']=Dir(env['build_dir']).abspath
218 prefix=Dir(env['prefix']).abspath
219 env['buildvars']['prefix']=prefix
220 env['incinstall'] = os.path.join(prefix, 'include')
221 env['bininstall'] = os.path.join(prefix, 'bin')
222 env['libinstall'] = os.path.join(prefix, 'lib')
223 env['pyinstall'] = os.path.join(prefix, 'esys')
224 if not os.path.isdir(env['bininstall']):
225 os.makedirs(env['bininstall'])
226 if not os.path.isdir(env['libinstall']):
227 os.makedirs(env['libinstall'])
228 if not os.path.isdir(env['pyinstall']):
229 os.makedirs(env['pyinstall'])
230
231 env.Append(CPPPATH = [env['incinstall']])
232 env.Append(LIBPATH = [env['libinstall']])
233
234 ################# Fill in compiler options if not set above ##################
235
236 if env['cxx'] != 'default': env['CXX']=env['cxx']
237
238 # version >=9 of intel C++ compiler requires use of icpc to link in C++
239 # runtimes (icc does not)
240 if not IS_WINDOWS and os.uname()[4]=='ia64' and env['CXX']=='icpc':
241 env['LINK'] = env['CXX']
242
243 # default compiler/linker options
244 cc_flags = ''
245 cc_optim = ''
246 cc_debug = ''
247 omp_flags = ''
248 omp_ldflags = ''
249 fatalwarning = '' # switch to turn warnings into errors
250 sysheaderopt = '' # how to indicate that a header is a system header
251
252 # env['CC'] might be a full path
253 cc_name=os.path.basename(env['CXX'])
254
255 if cc_name == 'icpc':
256 # Intel compiler
257 # #1478: class "std::auto_ptr<...>" was declared deprecated
258 # #1875: offsetof applied to non-POD types is nonstandard (in boost)
259 # removed -std=c99 because icpc doesn't like it and we aren't using c anymore
260 cc_flags = "-std=c++11 -fPIC -w2 -wd1875 -wd1478 -Wno-unknown-pragmas"
261 cc_optim = "-O3 -ftz -fno-alias -inline-level=2 -ipo -xHost"
262 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
263 omp_flags = "-openmp"
264 omp_ldflags = "-openmp -openmp_report=1"
265 fatalwarning = "-Werror"
266 elif cc_name[:3] == 'g++':
267 # GNU C++ on any system
268 # note that -ffast-math is not used because it breaks isnan(),
269 # see mantis #691
270 cc_flags = "-std=c++11 -pedantic -Wall -fPIC -Wno-unknown-pragmas -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing -finline-functions"
271 cc_optim = "-O3"
272 #max-vartrack-size: avoid vartrack limit being exceeded with escriptcpp.cpp
273 cc_debug = "-g3 -O0 -D_GLIBCXX_DEBUG -DDOASSERT -DDOPROF -DBOUNDS_CHECK --param=max-vartrack-size=100000000"
274 omp_flags = "-fopenmp"
275 omp_ldflags = "-fopenmp"
276 fatalwarning = "-Werror"
277 sysheaderopt = "-isystem"
278 elif cc_name == 'cl':
279 # Microsoft Visual C on Windows
280 cc_flags = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
281 cc_optim = "/O2 /Op /W3"
282 cc_debug = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
283 fatalwarning = "/WX"
284 elif cc_name == 'icl':
285 # Intel C on Windows
286 cc_flags = '/EHsc /GR /MD'
287 cc_optim = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
288 cc_debug = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
289 omp_flags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
290 omp_ldflags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
291
292 env['sysheaderopt']=sysheaderopt
293
294 # set defaults if not otherwise specified
295 if env['cc_flags'] == 'default': env['cc_flags'] = cc_flags
296 if env['cc_optim'] == 'default': env['cc_optim'] = cc_optim
297 if env['cc_debug'] == 'default': env['cc_debug'] = cc_debug
298 if env['omp_flags'] == 'default': env['omp_flags'] = omp_flags
299 if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
300 if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
301 if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
302 if env['cpp_flags'] != '': env.Append(CPPFLAGS = env['cpp_flags'])
303 if env['cpp_extra'] != '': env.Append(CPPFLAGS = " "+env['cpp_extra'])
304
305 if env['nvccflags'] != 'default':
306 env['NVCCFLAGS'] = env['nvccflags']
307 env['SHNVCCFLAGS'] = env['nvccflags'] + ' -shared'
308
309 if env['longindices']:
310 env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
311
312 if env['usepython3']:
313 env.Append(CPPDEFINES=['ESPYTHON3'])
314
315 # set up the autolazy values
316 if env['forcelazy'] == 'on':
317 env.Append(CPPDEFINES=['FAUTOLAZYON'])
318 elif env['forcelazy'] == 'off':
319 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
320
321 # set up the collective resolve values
322 if env['forcecollres'] == 'on':
323 env.Append(CPPDEFINES=['FRESCOLLECTON'])
324 elif env['forcecollres'] == 'off':
325 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
326
327 # allow non-standard C if requested
328 if env['iknowwhatimdoing']:
329 env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
330
331 # Disable OpenMP if no flags provided
332 if env['openmp'] and env['omp_flags'] == '':
333 env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
334 env['openmp'] = False
335
336 if env['openmp']:
337 env.Append(CCFLAGS = env['omp_flags'])
338 if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
339 else:
340 env['omp_flags']=''
341 env['omp_ldflags']=''
342
343 env['buildvars']['openmp']=int(env['openmp'])
344
345 # add debug/non-debug compiler flags
346 env['buildvars']['debug']=int(env['debug'])
347 if env['debug']:
348 env.Append(CCFLAGS = env['cc_debug'])
349 else:
350 env.Append(CCFLAGS = env['cc_optim'])
351
352 # always add cc_flags
353 env.Append(CCFLAGS = env['cc_flags'])
354
355 # add system libraries
356 env.AppendUnique(LIBS = env['sys_libs'])
357
358 # set defaults for launchers if not otherwise specified
359 if env['prelaunch'] == 'default':
360 if env['mpi'] == 'INTELMPI' and env['openmp']:
361 env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
362 elif env['mpi'] == 'OPENMPI':
363 # transform comma-separated list to '-x a -x b -x c ...'
364 env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
365 elif env['mpi'] == 'MPT':
366 env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
367 elif env['mpi'] == 'MPICH2':
368 env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
369 else:
370 env['prelaunch'] = ""
371
372 if env['launcher'] == 'default':
373 if env['mpi'] == 'INTELMPI':
374 env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
375 elif env['mpi'] == 'OPENMPI':
376 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} --host %h --map-by node:pe=%t -bind-to core -np %N %b"
377 elif env['mpi'] == 'MPT':
378 env['launcher'] = "mpirun %h -np %p %b"
379 elif env['mpi'] == 'MPICH':
380 env['launcher'] = "mpirun -machinefile %f -np %N %b"
381 elif env['mpi'] == 'MPICH2':
382 env['launcher'] = "mpiexec -genvlist %e -np %N %b"
383 else:
384 env['launcher'] = "%b"
385
386 if env['postlaunch'] == 'default':
387 if env['mpi'] == 'MPICH2':
388 env['postlaunch'] = "mpdallexit"
389 else:
390 env['postlaunch'] = ""
391
392 # determine svn revision
393 global_revision=ARGUMENTS.get('SVN_VERSION', None)
394 if global_revision:
395 global_revision = re.sub(':.*', '', global_revision)
396 global_revision = re.sub('[^0-9]', '', global_revision)
397 if global_revision == '': global_revision='-2'
398 else:
399 # Get the global Subversion revision number for the getVersion() method
400 try:
401 global_revision = os.popen('svnversion -n .').read()
402 global_revision = re.sub(':.*', '', global_revision)
403 global_revision = re.sub('[^0-9]', '', global_revision)
404 if global_revision == '': global_revision='-2'
405 except:
406 global_revision = '-1'
407 env['svn_revision']=global_revision
408 env['buildvars']['svn_revision']=global_revision
409 env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
410
411 env['IS_WINDOWS']=IS_WINDOWS
412 env['IS_OSX']=IS_OSX
413
414 ###################### Copy required environment vars ########################
415
416 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
417 if IS_WINDOWS:
418 LD_LIBRARY_PATH_KEY='PATH'
419 env['ENV']['LD_LIBRARY_PATH']=''
420 else:
421 LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
422
423 env['LD_LIBRARY_PATH_KEY']=LD_LIBRARY_PATH_KEY
424
425 # the following env variables are exported for the unit tests
426
427 for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
428 try:
429 env['ENV'][key] = os.environ[key]
430 except KeyError:
431 env['ENV'][key] = '1'
432
433 env_export=env['env_export']
434 env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','KMP_MONITOR_STACKSIZE','TMPDIR','TEMP','TMP','LD_PRELOAD'])
435
436 for key in set(env_export):
437 try:
438 env['ENV'][key] = os.environ[key]
439 except KeyError:
440 pass
441
442 for key in os.environ.keys():
443 if key.startswith("SLURM_"):
444 env['ENV'][key] = os.environ[key]
445
446 try:
447 env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
448 except KeyError:
449 pass
450
451 if IS_OSX:
452 try:
453 env.PrependENVPath('DYLD_LIBRARY_PATH', os.environ['DYLD_LIBRARY_PATH'])
454 except KeyError:
455 pass
456
457
458 # these shouldn't be needed
459 #for key in 'C_INCLUDE_PATH','CPLUS_INCLUDE_PATH','LIBRARY_PATH':
460 # try:
461 # env['ENV'][key] = os.environ[key]
462 # except KeyError:
463 # pass
464
465 try:
466 env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
467 except KeyError:
468 pass
469
470 ######################## Add some custom builders ############################
471
472 if env['pythoncmd']=='python':
473 py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
474 else:
475 py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
476 env.Append(BUILDERS = {'PyCompile' : py_builder});
477
478 runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
479 env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
480
481 runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
482 env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
483
484 runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
485 env.Append(BUILDERS = {'RunPyExample' : runPyExample_builder});
486
487 epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
488 env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
489
490 ############################ Dependency checks ###############################
491
492 ######## Compiler
493 env=checkCompiler(env)
494
495 ######## Python headers & library (required)
496 env=checkPython(env)
497
498 ######## boost & boost-python (required)
499 env=checkBoost(env)
500
501 ######## NVCC version (optional)
502 if env['cuda']:
503 env=checkCudaVersion(env)
504 env=checkCUDA(env)
505
506 ######## numpy (required) and numpy headers (optional)
507 env=checkNumpy(env)
508
509 ######## CppUnit (required for tests)
510 env=checkCppUnit(env)
511
512 ######## optional python modules (sympy, pyproj)
513 env=checkOptionalModules(env)
514
515 ######## optional dependencies (netCDF, PAPI, MKL, UMFPACK, Lapack, Silo, ...)
516 env=checkOptionalLibraries(env)
517
518 #use gmsh info to set some defines
519 if env['gmsh'] == 's':
520 env.Append(CPPDEFINES=['GMSH'])
521 elif env['gmsh'] == 'm':
522 env.Append(CPPDEFINES=['GMSH','GMSH_MPI'])
523
524 ######## PDFLaTeX (for documentation)
525 env=checkPDFLatex(env)
526
527 # keep some of our install paths first in the list for the unit tests
528 env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
529 env.PrependENVPath('PYTHONPATH', prefix)
530 env['ENV']['ESCRIPT_ROOT'] = prefix
531
532 if not env['verbose']:
533 env['CXXCOMSTR'] = "Compiling $TARGET"
534 env['SHCXXCOMSTR'] = "Compiling $TARGET"
535 env['ARCOMSTR'] = "Linking $TARGET"
536 env['LINKCOMSTR'] = "Linking $TARGET"
537 env['SHLINKCOMSTR'] = "Linking $TARGET"
538 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
539 env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
540 env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
541 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
542 #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
543
544 ####################### Configure the subdirectories #########################
545
546 # remove obsolete files
547 if not env['usempi']:
548 Execute(Delete(os.path.join(env['libinstall'], 'pythonMPI')))
549 Execute(Delete(os.path.join(env['bininstall'], 'escript-overlord')))
550 Execute(Delete(os.path.join(env['libinstall'], 'pythonMPIredirect')))
551
552 from grouptest import *
553 TestGroups=[]
554
555 # keep an environment without warnings-as-errors
556 dodgy_env=env.Clone()
557
558 # now add warnings-as-errors flags. This needs to be done after configuration
559 # because the scons test files have warnings in them
560 if ((fatalwarning != '') and (env['werror'])):
561 env.Append(CCFLAGS = fatalwarning)
562
563 Export(
564 ['env',
565 'dodgy_env',
566 'IS_WINDOWS',
567 'TestGroups'
568 ]
569 )
570
571 #do not auto build
572 env.SConscript(dirs = ['tools/escriptconvert'], variant_dir='$BUILD_DIR/$PLATFORM/tools/escriptconvert', duplicate=0)
573 env.SConscript(dirs = ['tools/overlord'], variant_dir='$BUILD_DIR/$PLATFORM/tools/overlord', duplicate=0)
574 env.SConscript(dirs = ['paso/src'], variant_dir='$BUILD_DIR/$PLATFORM/paso', duplicate=0)
575 env.SConscript(dirs = ['weipa/src'], variant_dir='$BUILD_DIR/$PLATFORM/weipa', duplicate=0)
576 env.SConscript(dirs = ['escript/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/escript', duplicate=0)
577
578 env.SConscript(dirs = ['cusplibrary'])
579
580 #This will pull in the escriptcore/py_src and escriptcore/test
581 env.SConscript(dirs = ['escriptcore/src'], variant_dir='$BUILD_DIR/$PLATFORM/escriptcore', duplicate=0)
582 if 'dudley' in env['domains']:
583 env.SConscript(dirs = ['dudley/src'], variant_dir='$BUILD_DIR/$PLATFORM/dudley', duplicate=0)
584 if 'finley' in env['domains']:
585 env.SConscript(dirs = ['finley/src'], variant_dir='$BUILD_DIR/$PLATFORM/finley', duplicate=0)
586 if 'ripley' in env['domains']:
587 env.SConscript(dirs = ['ripley/src'], variant_dir='$BUILD_DIR/$PLATFORM/ripley', duplicate=0)
588 if 'speckley' in env['domains']:
589 env.SConscript(dirs = ['speckley/src'], variant_dir='$BUILD_DIR/$PLATFORM/speckley', duplicate=0)
590 env.SConscript(dirs = ['downunder/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/downunder', duplicate=0)
591 env.SConscript(dirs = ['modellib/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/modellib', duplicate=0)
592 env.SConscript(dirs = ['pycad/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/pycad', duplicate=0)
593 env.SConscript(dirs = ['pythonMPI/src'], variant_dir='$BUILD_DIR/$PLATFORM/pythonMPI', duplicate=0)
594 env.SConscript(dirs = ['doc'], variant_dir='$BUILD_DIR/$PLATFORM/doc', duplicate=0)
595 env.SConscript(dirs = ['paso/profiling'], variant_dir='$BUILD_DIR/$PLATFORM/paso/profiling', duplicate=0)
596
597
598 ######################## Populate the buildvars file #########################
599
600 write_buildvars(env)
601
602 write_launcher(env)
603
604 ################### Targets to build and install libraries ###################
605
606 target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
607 env.Alias('target_init', [target_init])
608 # delete buildvars upon cleanup
609 env.Clean('target_init', os.path.join(env['libinstall'], 'buildvars'))
610
611 # The headers have to be installed prior to build
612
613 env.Alias('build_paso', ['install_paso_headers', 'build_paso_lib'])
614 env.Alias('install_paso', ['build_paso', 'install_paso_lib'])
615
616 env.Alias('build_escript', ['install_escript_headers', 'build_escript_lib', 'build_escriptcpp_lib'])
617 env.Alias('install_escript', ['build_escript', 'install_escript_lib', 'install_escriptcpp_lib', 'install_escriptcore_py', 'install_escript_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_paso']
644 build_all_list += ['build_escript']
645 if 'dudley' in env['domains']: build_all_list += ['build_dudley']
646 if 'finley' in env['domains']: build_all_list += ['build_finley']
647 if 'ripley' in env['domains']: build_all_list += ['build_ripley']
648 if 'speckley' in env['domains']: build_all_list += ['build_speckley']
649 build_all_list += ['build_weipa']
650 if not IS_WINDOWS and 'finley' in env['domains']:
651 build_all_list += ['build_escriptreader']
652 if env['usempi']:
653 build_all_list += ['build_pythonMPI', 'build_overlord']
654 env.Alias('build_all', build_all_list)
655
656 install_all_list = []
657 install_all_list += ['target_init']
658 install_all_list += ['install_paso']
659 install_all_list += ['install_escript']
660 if 'dudley' in env['domains']: install_all_list += ['install_dudley']
661 if 'finley' in env['domains']: install_all_list += ['install_finley']
662 if 'ripley' in env['domains']: install_all_list += ['install_ripley']
663 if 'speckley' in env['domains']: install_all_list += ['install_speckley']
664 install_all_list += ['install_weipa']
665 if not IS_WINDOWS and 'finley' in env['domains']:
666 install_all_list += ['install_escriptreader']
667 install_all_list += ['install_downunder_py']
668 install_all_list += ['install_modellib_py']
669 install_all_list += ['install_pycad_py']
670 if env['usempi']:
671 install_all_list += ['install_pythonMPI', 'install_overlord']
672 install_all_list += ['install_weipa_py']
673 install_all_list += [env.Install(os.path.join(env['build_dir'],'scripts'), os.path.join('scripts', 'release_sanity.py'))]
674
675
676 if env['osx_dependency_fix']:
677 print("Require dependency fix")
678 install_all=env.Command('install_all',install_all_list,'scripts/moveall.sh')
679 else:
680 install_all=env.Alias('install_all', install_all_list)
681
682
683
684
685 # Default target is install
686 #env.Default('install_all')
687
688
689 sanity=env.Alias('sanity', env.Command('dummy','',os.path.join(env['prefix'], 'bin', 'run-escript')+' '+os.path.join(env['build_dir'],'scripts', 'release_sanity.py')))
690 env.Depends('dummy', install_all)
691 if env['usempi']:
692 #env.Requires('dummy', ['build_pythonMPI', 'install_pythonMPI'])
693 #env.Requires('dummy', env['prefix']+"/lib/pythonMPI")
694 env.Depends('dummy', ['build_pythonMPI', 'install_pythonMPI'])
695 env.Depends('dummy', env['prefix']+"/lib/pythonMPI")
696
697 if 'install_dudley' in install_all_list and \
698 'install_finley' in install_all_list and \
699 'install_ripley' in install_all_list and \
700 'install_speckley' in install_all_list:
701 env.AlwaysBuild('sanity')
702 env.Default('sanity')
703 else:
704 env.Default('install_all')
705
706 ################## Targets to build and run the test suite ###################
707
708 if not env['cppunit']:
709 test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
710 env.Alias('run_tests', test_msg)
711 env.Alias('build_tests', '')
712 env.Alias('run_tests', ['install_all'])
713 env.Alias('all_tests', ['install_all', 'run_tests', 'py_tests'])
714 env.Alias('build_full',['install_all','build_tests','build_py_tests'])
715 env.Alias('build_PasoTests','$BUILD_DIR/$PLATFORM/paso/profiling/PasoTests')
716 Requires('py_tests', 'install_all')
717
718 ##################### Targets to build the documentation #####################
719
720 env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
721 env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
722 env.Alias('docs', ['basedocs', 'sphinxdoc'])
723 env.Alias('release_prep', ['docs', 'install_all'])
724 env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install_all'])
725
726 # The test scripts are always generated, this target allows us to
727 # generate the testscripts without doing a full build
728 env.Alias('testscripts',[])
729
730 if not IS_WINDOWS:
731 generateTestScripts(env, TestGroups)
732
733
734 ######################## Summarize our environment ###########################
735 def print_summary():
736 print("")
737 print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
738 print("Escript/Finley revision %s"%global_revision)
739 print(" Install prefix: %s"%env['prefix'])
740 print(" Python: %s"%sysconfig.PREFIX)
741 print(" boost: %s (Version %s)"%(env['boost_prefix'],env['boost_version']))
742 if env['numpy_h']:
743 print(" numpy: YES (with headers)")
744 else:
745 print(" numpy: YES (without headers)")
746 if env['usempi']:
747 print(" MPI: YES (flavour: %s)"%env['mpi'])
748 else:
749 print(" MPI: NO")
750 if env['parmetis']:
751 print(" ParMETIS: %s (Version %s)"%(env['parmetis_prefix'],env['parmetis_version']))
752 else:
753 print(" ParMETIS: NO")
754 if env['uselapack']:
755 print(" LAPACK: YES (flavour: %s)"%env['lapack'])
756 else:
757 print(" LAPACK: NO")
758 if env['cuda']:
759 print(" CUDA: YES (nvcc: %s)"%env['nvcc_version'])
760 else:
761 print(" CUDA: NO")
762 d_list=[]
763 e_list=[]
764 for i in 'debug','openmp','boomeramg','cppunit','gdal','mkl','netcdf','papi','pyproj','scipy','silo','sympy','umfpack','visit':
765 if env[i]: e_list.append(i)
766 else: d_list.append(i)
767 for i in e_list:
768 print("%16s: YES"%i)
769 for i in d_list:
770 print("%16s: NO"%i)
771 if env['gmshpy']:
772 gmshpy=" + python module"
773 else:
774 gmshpy=""
775 if env['gmsh']=='m':
776 print(" gmsh: YES, MPI-ENABLED"+gmshpy)
777 elif env['gmsh']=='s':
778 print(" gmsh: YES"+gmshpy)
779 else:
780 if env['gmshpy']:
781 print(" gmsh: python module only")
782 else:
783 print(" gmsh: NO")
784 print( " gzip: " + ("YES" if env['compressed_files'] else "NO"))
785
786 if ((fatalwarning != '') and (env['werror'])):
787 print(" Treating warnings as errors")
788 else:
789 print(" NOT treating warnings as errors")
790 print("")
791 for w in env['warnings']:
792 print("WARNING: %s"%w)
793 if len(GetBuildFailures()):
794 print("\nERROR: build stopped due to errors\n")
795 else:
796 print("\nSUCCESS: build complete\n")
797
798 atexit.register(print_summary)
799

  ViewVC Help
Powered by ViewVC 1.1.26