/[escript]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6944 - (hide annotations)
Thu Jan 30 03:39:44 2020 UTC (3 weeks, 5 days ago) by uqaeller
File size: 34000 byte(s)
Updated the install guide.

Also, added in a new option (disable_boost_numpy) which enables a user to disable the boost_numpy libraries (on by default) during the build.



1 jfenwick 3982 ##############################################################################
2 jgs 214 #
3 jfenwick 6651 # Copyright (c) 2003-2018 by The University of Queensland
4 jfenwick 3982 # http://www.uq.edu.au
5 ksteube 1811 #
6     # Primary Business: Queensland, Australia
7 jfenwick 6112 # Licensed under the Apache License, version 2.0
8     # http://www.apache.org/licenses/LICENSE-2.0
9 ksteube 1811 #
10 jfenwick 3982 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
11 jfenwick 4657 # Development 2012-2013 by School of Earth Sciences
12     # Development from 2014 by Centre for Geoscience Computing (GeoComp)
13 jfenwick 3982 #
14     ##############################################################################
15 jgs 455
16 jfenwick 3259 EnsureSConsVersion(0,98,1)
17     EnsurePythonVersion(2,5)
18 ksteube 1811
19 caltinay 4295 import atexit, sys, os, platform, re
20 jfenwick 3259 from distutils import sysconfig
21 caltinay 4295 from dependencies import *
22 jfenwick 3259 from site_init import *
23 jgs 214
24 gross 6702 print(sys.version)
25    
26 jfenwick 3259 # Version number to check for in options file. Increment when new features are
27     # added or existing options changed.
28 caltinay 6241 REQUIRED_OPTS_VERSION=203
29 ksteube 1705
30     # MS Windows support, many thanks to PH
31 jfenwick 3259 IS_WINDOWS = (os.name == 'nt')
32 gross 806
33 jfenwick 4640 IS_OSX = (os.uname()[0] == 'Darwin')
34    
35 jfenwick 3259 ########################## Determine options file ############################
36     # 1. command line
37     # 2. scons/<hostname>_options.py
38     # 3. name as part of a cluster
39 jfenwick 2391 options_file=ARGUMENTS.get('options_file', None)
40     if not options_file:
41 jfenwick 3259 ext_dir = os.path.join(os.getcwd(), 'scons')
42     hostname = platform.node().split('.')[0]
43     for name in hostname, effectiveName(hostname):
44     mangledhostname = re.sub('[^0-9a-zA-Z]', '_', hostname)
45     options_file = os.path.join(ext_dir, mangledhostname+'_options.py')
46     if os.path.isfile(options_file): break
47 jfenwick 2391
48 ksteube 1866 if not os.path.isfile(options_file):
49 jfenwick 3259 print("\nWARNING:\nOptions file %s" % options_file)
50     print("not found! Default options will be used which is most likely suboptimal.")
51 jfenwick 5601 print("We recommend that you copy the most relavent options file in the scons/template/")
52 jfenwick 3259 print("subdirectory and customize it to your needs.\n")
53     options_file = None
54 ksteube 1217
55 jfenwick 3259 ############################### Build options ################################
56 gross 1149
57 jfenwick 3259 default_prefix='/usr'
58 jfenwick 3618 mpi_flavours=('no', 'none', 'MPT', 'MPICH', 'MPICH2', 'OPENMPI', 'INTELMPI')
59 jfenwick 6509 netcdf_flavours = ('no', 'off', 'none', 'False', # Must be last of the false alternatives
60     'yes', 'on', 'True', '3', # Must be last of the version 3 alternatives
61     '4')
62 caltinay 6119 all_domains = ['dudley','finley','ripley','speckley']
63 jfenwick 2430
64 jfenwick 5589 #Note that scons construction vars the the following purposes:
65     # CPPFLAGS -> to the preprocessor
66     # CCFLAGS -> flags for _both_ C and C++
67     # CXXFLAGS -> flags for c++ _only_
68     # CFLAGS -> flags for c only
69    
70 jfenwick 3259 vars = Variables(options_file, ARGUMENTS)
71     vars.AddVariables(
72     PathVariable('options_file', 'Path to options file', options_file, PathVariable.PathIsFile),
73     PathVariable('prefix', 'Installation prefix', Dir('#.').abspath, PathVariable.PathIsDirCreate),
74 caltinay 3349 PathVariable('build_dir', 'Top-level build directory', Dir('#/build').abspath, PathVariable.PathIsDirCreate),
75 jfenwick 3259 BoolVariable('verbose', 'Output full compile/link lines', False),
76     # Compiler/Linker options
77     ('cxx', 'Path to C++ compiler', 'default'),
78 jfenwick 5589 ('cc_flags', 'Base (C and C++) compiler flags', 'default'),
79     ('cc_optim', 'Additional (C and C++) flags for a non-debug build', 'default'),
80     ('cc_debug', 'Additional (C and C++) flags for a debug build', 'default'),
81 caltinay 2967 ('cxx_extra', 'Extra C++ compiler flags', ''),
82 ksteube 1771 ('ld_extra', 'Extra linker flags', ''),
83 jfenwick 3259 BoolVariable('werror','Treat compiler warnings as errors', True),
84     BoolVariable('debug', 'Compile with debug flags', False),
85     BoolVariable('openmp', 'Compile parallel version using OpenMP', False),
86     ('omp_flags', 'OpenMP compiler flags', 'default'),
87     ('omp_ldflags', 'OpenMP linker flags', 'default'),
88     # Mandatory libraries
89     ('boost_prefix', 'Prefix/Paths of boost installation', default_prefix),
90 jfenwick 3338 ('boost_libs', 'Boost libraries to link with', ['boost_python-mt']),
91 caltinay 3597 # Mandatory for tests
92     ('cppunit_prefix', 'Prefix/Paths of CppUnit installation', default_prefix),
93     ('cppunit_libs', 'CppUnit libraries to link with', ['cppunit']),
94 jfenwick 3259 # Optional libraries and options
95     EnumVariable('mpi', 'Compile parallel version using MPI flavour', 'none', allowed_values=mpi_flavours),
96     ('mpi_prefix', 'Prefix/Paths of MPI installation', default_prefix),
97     ('mpi_libs', 'MPI shared libraries to link with', ['mpi']),
98 aellery 6824 BoolVariable('use_gmsh', 'Enable gmsh, if available', True),
99 jfenwick 6509 EnumVariable('netcdf', 'Enable netCDF file support', False, allowed_values=netcdf_flavours),
100 jfenwick 3259 ('netcdf_prefix', 'Prefix/Paths of netCDF installation', default_prefix),
101 jfenwick 6509 ('netcdf_libs', 'netCDF libraries to link with', 'DEFAULT'),
102 jfenwick 3259 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 caltinay 6247 TristateVariable('lapack', 'Enable LAPACK', 'auto'),
112 jfenwick 3259 ('lapack_prefix', 'Prefix/Paths to LAPACK installation', default_prefix),
113     ('lapack_libs', 'LAPACK libraries to link with', []),
114     BoolVariable('silo', 'Enable the Silo file format in weipa', False),
115     ('silo_prefix', 'Prefix/Paths to Silo installation', default_prefix),
116 caltinay 2184 ('silo_libs', 'Silo libraries to link with', ['siloh5', 'hdf5']),
117 caltinay 6119 BoolVariable('trilinos', 'Enable the Trilinos solvers', False),
118     ('trilinos_prefix', 'Prefix/Paths to Trilinos installation', default_prefix),
119     ('trilinos_libs', 'Trilinos libraries to link with', []),
120 jfenwick 3259 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 caltinay 6119 ListVariable('domains', 'Which domains to build', 'all', all_domains),
124     BoolVariable('paso', 'Build Paso solver library', True),
125     BoolVariable('weipa', 'Build Weipa data export library', True),
126 jfenwick 6682 ('mathjax_path', 'Path to MathJax.js file', 'default'),
127 jfenwick 3259 # Advanced settings
128 caltinay 5266 ('launcher', 'Launcher command (e.g. mpirun)', 'default'),
129     ('prelaunch', 'Command to execute before launcher (e.g. mpdboot)', 'default'),
130     ('postlaunch', 'Command to execute after launcher (e.g. mpdexit)', 'default'),
131 jfenwick 3259 #dudley_assemble_flags = -funroll-loops to actually do something
132     ('dudley_assemble_flags', 'compiler flags for some dudley optimisations', ''),
133     # To enable passing function pointers through python
134     BoolVariable('iknowwhatimdoing', 'Allow non-standard C', False),
135 caltinay 5266 # An option for specifying the compiler tools
136 jfenwick 3259 ('tools_names', 'Compiler tools to use', ['default']),
137     ('env_export', 'Environment variables to be passed to tools',[]),
138 caltinay 6297 TristateVariable('forcelazy', 'For testing use only - set the default value for autolazy', 'auto'),
139     TristateVariable('forcecollres', 'For testing use only - set the default value for force resolving collective ops', 'auto'),
140 caltinay 6241 BoolVariable('build_shared', '(deprecated option, ignored)', True),
141 jfenwick 3259 ('sys_libs', 'Extra libraries to link with', []),
142     ('escript_opts_version', 'Version of options file (do not specify on command line)'),
143 jfenwick 3618 ('SVN_VERSION', 'Do not use from options file', -2),
144 caltinay 6241 ('pythoncmd', 'which python to compile with', sys.executable),
145 jfenwick 3892 ('pythonlibname', 'Name of the python library to link. (This is found automatically for python2.X.)', ''),
146 jfenwick 3942 ('pythonlibpath', 'Path to the python library. (You should not need to set this unless your python has moved)',''),
147     ('pythonincpath','Path to python include files. (You should not need to set this unless your python has moved',''),
148 caltinay 5250 BoolVariable('longindices', 'use long indices (for very large matrices)', False),
149 sshaw 4738 BoolVariable('compressed_files','Enables reading from compressed binary files', True),
150 caltinay 5250 ('compression_libs', 'Compression libraries to link with', ['boost_iostreams']),
151 uqaeller 6944 BoolVariable('disable_boost_numpy', 'Do not build using boost_numpy, even if it is available', False),
152 jfenwick 6493 BoolVariable('osx_dependency_fix', 'Fix dependencies for libraries to have absolute paths (OSX)', False),
153 jfenwick 6573 BoolVariable('stdlocationisprefix', 'Set the prefix as escript root in the launcher', False),
154 aellery 6722 BoolVariable('mpi_no_host', 'Do not specify --host in run-escript launcher (only OPENMPI)', False),
155     BoolVariable('insane', 'Instructs scons to not run a sanity check after compilation.', False)
156 robwdcock 682 )
157 phornby 1232
158 jfenwick 3259 ##################### Create environment and help text #######################
159 jfenwick 3078
160 jfenwick 3259 # 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 jfenwick 3078
163 caltinay 3319 # 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 jfenwick 3967
168 caltinay 4295 # set the vars for clang
169 jfenwick 3967 def mkclang(env):
170 caltinay 4295 env['CXX']='clang++'
171    
172 jfenwick 6510 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 jfenwick 6509 # Covert env['netcdf'] into one of False, 3, 4
181     # Also choose default values for libraries
182     pos1=netcdf_flavours.index('False')
183     pos2=netcdf_flavours.index('3')
184     mypos=netcdf_flavours.index(env['netcdf'])
185     if 0 <= mypos <=pos1:
186 jfenwick 6510 env['netcdf']=0
187 jfenwick 6509 elif pos1 < mypos <= pos2:
188     env['netcdf']=3
189     if env['netcdf_libs']=='DEFAULT':
190     env['netcdf_libs']=['netcdf_c++', 'netcdf']
191     else: # netcdf4
192     env['netcdf']=4
193     if env['netcdf_libs']=='DEFAULT':
194     env['netcdf_libs']=['netcdf_c++4']
195 jfenwick 3078
196 jfenwick 3259 if options_file:
197     opts_valid=False
198     if 'escript_opts_version' in env.Dictionary() and \
199     int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
200     opts_valid=True
201     if opts_valid:
202     print("Using options in %s." % options_file)
203     else:
204     print("\nOptions file %s" % options_file)
205 caltinay 6241 print("is outdated! Please update the file after reading scons/templates/README_FIRST")
206     print("and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
207 jfenwick 3259 Exit(1)
208 jfenwick 3078
209 jfenwick 3259 # Generate help text (scons -h)
210     Help(vars.GenerateHelpText(env))
211 jfenwick 3078
212 jfenwick 3259 # Check for superfluous options
213 caltinay 3268 if len(vars.UnknownVariables())>0:
214     for k in vars.UnknownVariables():
215     print("Unknown option '%s'" % k)
216     Exit(1)
217 jfenwick 3078
218 sshaw 5381 if 'dudley' in env['domains']:
219     env['domains'].append('finley')
220    
221 caltinay 6119 env['domains'] = sorted(set(env['domains']))
222    
223 caltinay 4295 # create dictionary which will be populated with info for buildvars file
224 caltinay 6119 env['buildvars'] = {}
225 caltinay 4295 # create list which will be populated with warnings if there are any
226 caltinay 6119 env['warnings'] = []
227 caltinay 4295
228 jfenwick 3259 #################### Make sure install directories exist #####################
229 ksteube 1705
230 caltinay 6119 env['BUILD_DIR'] = Dir(env['build_dir']).abspath
231     prefix = Dir(env['prefix']).abspath
232     env['buildvars']['prefix'] = prefix
233 jfenwick 3259 env['incinstall'] = os.path.join(prefix, 'include')
234     env['bininstall'] = os.path.join(prefix, 'bin')
235     env['libinstall'] = os.path.join(prefix, 'lib')
236     env['pyinstall'] = os.path.join(prefix, 'esys')
237 jfenwick 2604 if not os.path.isdir(env['bininstall']):
238     os.makedirs(env['bininstall'])
239     if not os.path.isdir(env['libinstall']):
240     os.makedirs(env['libinstall'])
241     if not os.path.isdir(env['pyinstall']):
242     os.makedirs(env['pyinstall'])
243    
244 jfenwick 3259 env.Append(CPPPATH = [env['incinstall']])
245     env.Append(LIBPATH = [env['libinstall']])
246 jfenwick 2603
247 jfenwick 3259 ################# Fill in compiler options if not set above ##################
248 ksteube 1312
249 caltinay 6119 if env['cxx'] != 'default':
250     env['CXX'] = env['cxx']
251 gross 1024
252 jfenwick 3259 # default compiler/linker options
253 caltinay 6287 cc_flags = '-std=c++11'
254 jfenwick 3259 cc_optim = ''
255     cc_debug = ''
256     omp_flags = ''
257     omp_ldflags = ''
258     fatalwarning = '' # switch to turn warnings into errors
259     sysheaderopt = '' # how to indicate that a header is a system header
260 jfenwick 2130
261 jfenwick 3259 # env['CC'] might be a full path
262 caltinay 4520 cc_name=os.path.basename(env['CXX'])
263 caltinay 2882
264 caltinay 4520 if cc_name == 'icpc':
265 jfenwick 3259 # Intel compiler
266 caltinay 6010 # #1478: class "std::auto_ptr<...>" was declared deprecated
267 caltinay 4090 # #1875: offsetof applied to non-POD types is nonstandard (in boost)
268 jfenwick 4542 # removed -std=c99 because icpc doesn't like it and we aren't using c anymore
269 caltinay 6010 cc_flags = "-std=c++11 -fPIC -w2 -wd1875 -wd1478 -Wno-unknown-pragmas"
270 aellery 6723 cc_optim = "-Ofast -ftz -fno-alias -xCORE-AVX2 -ipo"
271 gross 6702 #cc_optim = "-Ofast -ftz -fno-alias -inline-level=2 -ipo -xCORE-AVX2"
272     #cc_optim = "-O2 -ftz -fno-alias -inline-level=2"
273     #cc_optim = "-O0 -ftz -fno-alias"
274     #cc_optim = "-O3 -ftz -fno-alias -inline-level=2 -ipo -xHost"
275 jfenwick 6098 cc_debug = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK"
276 jfenwick 6404 omp_flags = "-qopenmp"
277     omp_ldflags = "-qopenmp" # removing -openmp-report (which is deprecated) because the replacement outputs to a file
278 jfenwick 3259 fatalwarning = "-Werror"
279 caltinay 4520 elif cc_name[:3] == 'g++':
280 caltinay 5250 # GNU C++ on any system
281 caltinay 4173 # note that -ffast-math is not used because it breaks isnan(),
282     # see mantis #691
283 aellery 6786 cc_flags = "-std=c++11 -pedantic -Wall -fPIC -finline-functions"
284 aellery 6799 cc_flags += " -Wno-unknown-pragmas -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing "
285 aellery 6913 cc_flags += " -Wno-stringop-truncation --param=max-vartrack-size=100000000"
286 jfenwick 3259 cc_optim = "-O3"
287 caltinay 5250 #max-vartrack-size: avoid vartrack limit being exceeded with escriptcpp.cpp
288 jfenwick 6501 cc_debug = "-g3 -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK --param=max-vartrack-size=100000000"
289     #Removed because new netcdf doesn't seem to like it
290 aellery 6898 #cc_debug += ' -D_GLIBCXX_DEBUG '
291 jfenwick 3259 omp_flags = "-fopenmp"
292     omp_ldflags = "-fopenmp"
293     fatalwarning = "-Werror"
294     sysheaderopt = "-isystem"
295     elif cc_name == 'cl':
296     # Microsoft Visual C on Windows
297     cc_flags = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
298     cc_optim = "/O2 /Op /W3"
299     cc_debug = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
300     fatalwarning = "/WX"
301     elif cc_name == 'icl':
302     # Intel C on Windows
303     cc_flags = '/EHsc /GR /MD'
304     cc_optim = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
305     cc_debug = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
306     omp_flags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
307     omp_ldflags = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
308 aellery 6788 elif cc_name == 'clang++':
309     # Clang++ on any system
310 aellery 6879 cc_flags = "-std=c++11 -Wall -fPIC -fdiagnostics-color=always -Wno-uninitialized "
311 aellery 6791 cc_flags += "-Wno-unused-private-field -Wno-unknown-pragmas "
312 aellery 6799 if env['trilinos'] is True:
313     cc_flags += "-Wno-unused-variable -Wno-exceptions -Wno-deprecated-declarations"
314 aellery 6788 cc_optim = "-O3"
315     cc_debug = "-ggdb3 -O0 -fdiagnostics-fixit-info -pedantic "
316     cc_debug += "-DDOASSERT -DDOPROF -DBOUNDS_CHECK -DSLOWSHARECHECK "
317     omp_flags = "-fopenmp"
318     omp_ldflags = "-fopenmp"
319     fatalwarning = "-Werror"
320     sysheaderopt = "-isystem"
321 phornby 1243
322 caltinay 4295 env['sysheaderopt']=sysheaderopt
323    
324 jfenwick 3259 # set defaults if not otherwise specified
325     if env['cc_flags'] == 'default': env['cc_flags'] = cc_flags
326     if env['cc_optim'] == 'default': env['cc_optim'] = cc_optim
327     if env['cc_debug'] == 'default': env['cc_debug'] = cc_debug
328     if env['omp_flags'] == 'default': env['omp_flags'] = omp_flags
329     if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
330     if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
331     if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])
332 jfenwick 2130
333 caltinay 5183 if env['longindices']:
334 aellery 6844 if env['paso']:
335 caltinay 5183 env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
336 aellery 6844 else:
337     env['warnings'].append("The longindices feature requires paso!")
338 caltinay 5183
339 jfenwick 3259 # set up the autolazy values
340 caltinay 6297 if env['forcelazy'] == 1:
341 jfenwick 3259 env.Append(CPPDEFINES=['FAUTOLAZYON'])
342 caltinay 6297 elif env['forcelazy'] == 0:
343 jfenwick 3259 env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
344 ksteube 1312
345 jfenwick 3259 # set up the collective resolve values
346 caltinay 6297 if env['forcecollres'] == 1:
347 jfenwick 3259 env.Append(CPPDEFINES=['FRESCOLLECTON'])
348 caltinay 6297 elif env['forcecollres'] == 0:
349 jfenwick 3259 env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
350 jfenwick 2273
351 jfenwick 3259 # allow non-standard C if requested
352 jfenwick 2827 if env['iknowwhatimdoing']:
353 jfenwick 3259 env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
354 jfenwick 2827
355 jfenwick 3259 # Disable OpenMP if no flags provided
356     if env['openmp'] and env['omp_flags'] == '':
357 caltinay 4295 env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
358 jfenwick 3259 env['openmp'] = False
359 gross 1160
360 jfenwick 3259 if env['openmp']:
361     env.Append(CCFLAGS = env['omp_flags'])
362     if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
363     else:
364     env['omp_flags']=''
365     env['omp_ldflags']=''
366 ksteube 1312
367 caltinay 4295 env['buildvars']['openmp']=int(env['openmp'])
368    
369 jfenwick 3259 # add debug/non-debug compiler flags
370 caltinay 4295 env['buildvars']['debug']=int(env['debug'])
371 jfenwick 3259 if env['debug']:
372     env.Append(CCFLAGS = env['cc_debug'])
373 gross 2423 else:
374 jfenwick 3259 env.Append(CCFLAGS = env['cc_optim'])
375 gross 1163
376 jfenwick 3259 # always add cc_flags
377     env.Append(CCFLAGS = env['cc_flags'])
378 phornby 1243
379 jfenwick 3259 # add system libraries
380     env.AppendUnique(LIBS = env['sys_libs'])
381 gross 2363
382 caltinay 4295 # determine svn revision
383 jfenwick 3618 global_revision=ARGUMENTS.get('SVN_VERSION', None)
384     if global_revision:
385     global_revision = re.sub(':.*', '', global_revision)
386     global_revision = re.sub('[^0-9]', '', global_revision)
387     if global_revision == '': global_revision='-2'
388     else:
389     # Get the global Subversion revision number for the getVersion() method
390     try:
391 jfenwick 3259 global_revision = os.popen('svnversion -n .').read()
392     global_revision = re.sub(':.*', '', global_revision)
393     global_revision = re.sub('[^0-9]', '', global_revision)
394     if global_revision == '': global_revision='-2'
395 jfenwick 3618 except:
396 jfenwick 3259 global_revision = '-1'
397 caltinay 3271 env['svn_revision']=global_revision
398 caltinay 4295 env['buildvars']['svn_revision']=global_revision
399 jfenwick 3259 env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
400 gross 2363
401 aellery 6848 # If that failed, try to get the version number from the file svn_version
402 aellery 6843 if global_revision=='-2' or global_revision=='-1':
403 aellery 6848 try:
404     global_revision=str(os.popen('cat svn_version 2>/dev/null').read())
405     if global_revision[global_revision.__len__()-1] == '\n':
406     temp=global_revision[0:(global_revision.__len__()-1)]
407     else:
408     temp=global_revision
409     print("Using svn revision information from file. Got revision = %s" % temp)
410     except:
411     global_revision='-2'
412 aellery 6843
413 aellery 6848 if global_revision=='-2' or global_revision=='-1':
414     env['warnings'].append("Could not detect the svn revision number!")
415    
416 caltinay 4295 env['IS_WINDOWS']=IS_WINDOWS
417 jfenwick 5407 env['IS_OSX']=IS_OSX
418 caltinay 4295
419 jfenwick 3259 ###################### Copy required environment vars ########################
420 gross 2363
421 jfenwick 3259 # Windows doesn't use LD_LIBRARY_PATH but PATH instead
422     if IS_WINDOWS:
423     LD_LIBRARY_PATH_KEY='PATH'
424     env['ENV']['LD_LIBRARY_PATH']=''
425     else:
426     LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
427 robwdcock 682
428 caltinay 4295 env['LD_LIBRARY_PATH_KEY']=LD_LIBRARY_PATH_KEY
429    
430 caltinay 3319 # the following env variables are exported for the unit tests
431 phornby 1244
432 jfenwick 3259 for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
433     try:
434     env['ENV'][key] = os.environ[key]
435     except KeyError:
436 caltinay 5045 env['ENV'][key] = '1'
437 robwdcock 682
438 jfenwick 3259 env_export=env['env_export']
439 caltinay 4917 env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','KMP_MONITOR_STACKSIZE','TMPDIR','TEMP','TMP','LD_PRELOAD'])
440 robwdcock 682
441 jfenwick 3259 for key in set(env_export):
442     try:
443     env['ENV'][key] = os.environ[key]
444     except KeyError:
445     pass
446 ksteube 1312
447 caltinay 5436 for key in os.environ.keys():
448     if key.startswith("SLURM_"):
449     env['ENV'][key] = os.environ[key]
450    
451 jfenwick 3259 try:
452     env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
453     except KeyError:
454     pass
455 ksteube 1312
456 jfenwick 4640 if IS_OSX:
457     try:
458     env.PrependENVPath('DYLD_LIBRARY_PATH', os.environ['DYLD_LIBRARY_PATH'])
459     except KeyError:
460     pass
461    
462 jfenwick 3259 try:
463     env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
464     except KeyError:
465     pass
466 ksteube 1312
467 jfenwick 3259 ######################## Add some custom builders ############################
468 ksteube 1312
469 caltinay 6124 # Takes care of prefix and suffix for Python modules:
470     def build_python_module(env, target, source):
471     return env.SharedLibrary(target, source, SHLIBPREFIX='', SHLIBSUFFIX='.so')
472     env.AddMethod(build_python_module, "PythonModule")
473    
474 jfenwick 3851 if env['pythoncmd']=='python':
475     py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
476     else:
477 jfenwick 3892 py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
478 jfenwick 3259 env.Append(BUILDERS = {'PyCompile' : py_builder});
479 gross 2423
480 jfenwick 3259 runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
481     env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
482 gross 2423
483 jfenwick 3259 runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
484     env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
485 ksteube 1756
486 sshaw 5017 runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
487     env.Append(BUILDERS = {'RunPyExample' : runPyExample_builder});
488    
489 jfenwick 3259 epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
490     env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
491 ksteube 817
492 jfenwick 3259 ############################ Dependency checks ###############################
493 phornby 1246
494 caltinay 4295 ######## Compiler
495     env=checkCompiler(env)
496 phornby 1634
497 jfenwick 3259 ######## Python headers & library (required)
498 caltinay 4295 env=checkPython(env)
499 gross 806
500 caltinay 4295 ######## boost & boost-python (required)
501     env=checkBoost(env)
502 jfenwick 3892
503 caltinay 4295 ######## numpy (required) and numpy headers (optional)
504     env=checkNumpy(env)
505 jfenwick 3892
506 caltinay 3597 ######## CppUnit (required for tests)
507 caltinay 4295 env=checkCppUnit(env)
508 caltinay 3597
509 caltinay 4295 ######## optional python modules (sympy, pyproj)
510     env=checkOptionalModules(env)
511 caltinay 3597
512 aellery 6781 ######## optional dependencies (netCDF, MKL, UMFPACK, Lapack, Silo, ...)
513 caltinay 4295 env=checkOptionalLibraries(env)
514 caltinay 3975
515 caltinay 3604 ######## PDFLaTeX (for documentation)
516 caltinay 4295 env=checkPDFLatex(env)
517 caltinay 3604
518 caltinay 6249 # set defaults for launchers if not otherwise specified
519     if env['prelaunch'] == 'default':
520     if env['mpi'] == 'INTELMPI' and env['openmp']:
521     env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
522     elif env['mpi'] == 'OPENMPI':
523     # transform comma-separated list to '-x a -x b -x c ...'
524     env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
525     elif env['mpi'] == 'MPT':
526     env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
527     elif env['mpi'] == 'MPICH2':
528     env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
529     else:
530     env['prelaunch'] = ""
531    
532     if env['launcher'] == 'default':
533     if env['mpi'] == 'INTELMPI':
534     env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
535     elif env['mpi'] == 'OPENMPI':
536 jfenwick 6573 if env['mpi_no_host']:
537     hostoptionstr=''
538     else:
539     hostoptionstr='--host %h'
540 caltinay 6249 # default to OpenMPI version 1.10 or higher
541 jfenwick 6573 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} "+hostoptionstr+" --map-by node:pe=%t -bind-to core -np %N %b"
542 caltinay 6249 if 'orte_version' in env:
543     major,minor,point = [int(i) for i in env['orte_version'].split('.')]
544     if major == 1 and minor < 10:
545 jfenwick 6573 env['launcher'] = "mpirun ${AGENTOVERRIDE} --gmca mpi_warn_on_fork 0 ${EE} "+hostoptionstr+" --cpus-per-rank %t -np %N %b"
546 caltinay 6249 elif env['mpi'] == 'MPT':
547     env['launcher'] = "mpirun %h -np %p %b"
548     elif env['mpi'] == 'MPICH':
549     env['launcher'] = "mpirun -machinefile %f -np %N %b"
550     elif env['mpi'] == 'MPICH2':
551     env['launcher'] = "mpiexec -genvlist %e -np %N %b"
552     else:
553     env['launcher'] = "%b"
554    
555     if env['postlaunch'] == 'default':
556     if env['mpi'] == 'MPICH2':
557     env['postlaunch'] = "mpdallexit"
558     else:
559     env['postlaunch'] = ""
560    
561 caltinay 6119 # dependency sanity checks
562    
563     if len(env['domains']) == 0:
564     env['warnings'].append("No domains have been built, escript will not be very useful!")
565    
566 jfenwick 3259 # keep some of our install paths first in the list for the unit tests
567     env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
568     env.PrependENVPath('PYTHONPATH', prefix)
569     env['ENV']['ESCRIPT_ROOT'] = prefix
570 ksteube 1705
571 jfenwick 3259 if not env['verbose']:
572     env['CXXCOMSTR'] = "Compiling $TARGET"
573     env['SHCXXCOMSTR'] = "Compiling $TARGET"
574     env['ARCOMSTR'] = "Linking $TARGET"
575     env['LINKCOMSTR'] = "Linking $TARGET"
576     env['SHLINKCOMSTR'] = "Linking $TARGET"
577 caltinay 3271 env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
578     env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
579     env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
580     env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
581 jfenwick 3259 #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
582 ksteube 1705
583 caltinay 6119 ########################### Configure the targets ############################
584 ksteube 1247
585 caltinay 6119 from grouptest import GroupTest
586 jfenwick 2235 TestGroups=[]
587    
588 jfenwick 3259 # keep an environment without warnings-as-errors
589     dodgy_env=env.Clone()
590 jfenwick 2827
591 jfenwick 3259 # now add warnings-as-errors flags. This needs to be done after configuration
592     # because the scons test files have warnings in them
593     if ((fatalwarning != '') and (env['werror'])):
594     env.Append(CCFLAGS = fatalwarning)
595 jfenwick 2827
596 phornby 2027 Export(
597 jfenwick 3259 ['env',
598     'dodgy_env',
599     'IS_WINDOWS',
600     'TestGroups'
601     ]
602     )
603 ksteube 1705
604 caltinay 3604 target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
605 ksteube 1705 env.Alias('target_init', [target_init])
606    
607 caltinay 6119 # escript can't be turned off
608 caltinay 6174 build_all_list = ['build_escript']
609     install_all_list = ['target_init', 'install_escript']
610 caltinay 2810
611 caltinay 6119 if env['usempi']:
612     build_all_list += ['build_pythonMPI', 'build_overlord']
613     install_all_list += ['install_pythonMPI', 'install_overlord']
614 caltinay 3096
615 caltinay 6333 env['buildvars']['paso'] = int(env['paso'])
616 caltinay 6119 if env['paso']:
617 caltinay 6167 env.Append(CPPDEFINES = ['ESYS_HAVE_PASO'])
618 caltinay 6119 build_all_list += ['build_paso']
619     install_all_list += ['install_paso']
620 caltinay 2910
621 caltinay 6555 env['buildvars']['trilinos'] = int(env['trilinos'])
622 caltinay 6119 if env['trilinos']:
623     build_all_list += ['build_trilinoswrap']
624     install_all_list += ['install_trilinoswrap']
625 caltinay 3792
626 caltinay 6333 env['buildvars']['domains'] = ','.join(env['domains'])
627 caltinay 6119 for domain in env['domains']:
628 caltinay 6174 env.Append(CPPDEFINES = ['ESYS_HAVE_'+domain.upper()])
629 caltinay 6119 build_all_list += ['build_%s'%domain]
630     install_all_list += ['install_%s'%domain]
631 ksteube 1705
632 caltinay 6333 env['buildvars']['weipa'] = int(env['weipa'])
633 caltinay 6119 if env['weipa']:
634 caltinay 6174 env.Append(CPPDEFINES = ['ESYS_HAVE_WEIPA'])
635 caltinay 6119 build_all_list += ['build_weipa']
636     install_all_list += ['install_weipa']
637 caltinay 6184 if 'finley' in env['domains'] or 'dudley' in env['domains']:
638 caltinay 6119 build_all_list += ['build_escriptreader']
639     install_all_list += ['install_escriptreader']
640 ksteube 1705
641 caltinay 6174 variant='$BUILD_DIR/$PLATFORM/'
642     env.SConscript('escriptcore/SConscript', variant_dir=variant+'escriptcore', duplicate=0)
643     env.SConscript('escript/py_src/SConscript', variant_dir=variant+'escript', duplicate=0)
644     env.SConscript('pythonMPI/src/SConscript', variant_dir=variant+'pythonMPI', duplicate=0)
645     env.SConscript('tools/overlord/SConscript', variant_dir=variant+'tools/overlord', duplicate=0)
646     env.SConscript('paso/SConscript', variant_dir=variant+'paso', duplicate=0)
647     env.SConscript('trilinoswrap/SConscript', variant_dir=variant+'trilinoswrap', duplicate=0)
648     env.SConscript('cusplibrary/SConscript')
649     env.SConscript('dudley/SConscript', variant_dir=variant+'dudley', duplicate=0)
650     env.SConscript('finley/SConscript', variant_dir=variant+'finley', duplicate=0)
651     env.SConscript('ripley/SConscript', variant_dir=variant+'ripley', duplicate=0)
652     env.SConscript('speckley/SConscript', variant_dir=variant+'speckley', duplicate=0)
653     env.SConscript('weipa/SConscript', variant_dir=variant+'weipa', duplicate=0)
654     env.SConscript(dirs = ['downunder/py_src'], variant_dir=variant+'downunder', duplicate=0)
655     env.SConscript(dirs = ['modellib/py_src'], variant_dir=variant+'modellib', duplicate=0)
656     env.SConscript(dirs = ['pycad/py_src'], variant_dir=variant+'pycad', duplicate=0)
657     env.SConscript('tools/escriptconvert/SConscript', variant_dir=variant+'tools/escriptconvert', duplicate=0)
658     env.SConscript('doc/SConscript', variant_dir=variant+'doc', duplicate=0)
659 ksteube 1705
660 caltinay 6119 env.Alias('build', build_all_list)
661    
662 caltinay 3947 install_all_list += ['install_downunder_py']
663 jfenwick 3259 install_all_list += ['install_modellib_py']
664     install_all_list += ['install_pycad_py']
665 caltinay 6119 install_all_list += [env.Install(Dir('scripts',env['build_dir']), os.path.join('scripts', 'release_sanity.py'))]
666 ksteube 1705
667 jfenwick 5851 if env['osx_dependency_fix']:
668     print("Require dependency fix")
669 caltinay 6119 install_all=env.Command('install', install_all_list, 'scripts/moveall.sh')
670 jfenwick 5851 else:
671 caltinay 6119 install_all=env.Alias('install', install_all_list)
672 jfenwick 5851
673 jfenwick 5811 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')))
674 jfenwick 5802 env.Depends('dummy', install_all)
675 jfenwick 5801 if env['usempi']:
676 caltinay 6119 env.Depends('dummy', ['install_pythonMPI'])
677 jfenwick 5801
678 caltinay 6119 # if all domains are built:
679 aellery 6722 if env['domains'] == all_domains and env['insane'] == False:
680     env.AlwaysBuild('sanity')
681     env.Default('sanity')
682 jfenwick 5802 else:
683 caltinay 6119 env.Default('install')
684 jfenwick 5800
685 jfenwick 3259 ################## Targets to build and run the test suite ###################
686 ksteube 1705
687 caltinay 3597 if not env['cppunit']:
688 caltinay 4520 test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
689 caltinay 3597 env.Alias('run_tests', test_msg)
690 caltinay 4249 env.Alias('build_tests', '')
691 caltinay 6119 env.Alias('run_tests', ['install'])
692     env.Alias('all_tests', ['install', 'run_tests', 'py_tests'])
693     env.Alias('build_full',['install','build_tests','build_py_tests'])
694     Requires('py_tests', 'install')
695 ksteube 1705
696 jfenwick 3259 ##################### Targets to build the documentation #####################
697 artak 2820
698 jfenwick 4244 env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
699     env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
700 jfenwick 4167 env.Alias('docs', ['basedocs', 'sphinxdoc'])
701 caltinay 6119 env.Alias('release_prep', ['docs', 'install'])
702     env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install'])
703 ksteube 1705
704 jfenwick 4078 # The test scripts are always generated, this target allows us to
705     # generate the testscripts without doing a full build
706     env.Alias('testscripts',[])
707    
708 jfenwick 3259 if not IS_WINDOWS:
709 caltinay 4295 generateTestScripts(env, TestGroups)
710 jfenwick 2879
711 caltinay 6119 ######################## Populate the buildvars file #########################
712 caltinay 3604
713 caltinay 6119 write_buildvars(env)
714     # delete buildvars upon cleanup - target_init is default so use it
715     env.Clean('target_init', File('buildvars', env['libinstall']))
716    
717     write_launcher(env)
718    
719     # remove obsolete files
720     if not env['usempi']:
721     Execute(Delete(File(['pythonMPI','pythonMPIredirect'], env['libinstall'])))
722     Execute(Delete(File('escript-overlord', env['bininstall'])))
723    
724 caltinay 4295 ######################## Summarize our environment ###########################
725     def print_summary():
726 caltinay 6255 d_list=[]
727 caltinay 4295 print("")
728 caltinay 4299 print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
729 caltinay 6119 print("Escript revision %s"%global_revision)
730 caltinay 4295 print(" Install prefix: %s"%env['prefix'])
731 caltinay 6248 print(" Python: %s (Version %s)"%(env['pythoncmd'],env['python_version']))
732 caltinay 5696 print(" boost: %s (Version %s)"%(env['boost_prefix'],env['boost_version']))
733 aellery 6882 if env['have_boost_numpy'] is True:
734 aellery 6872 print(" boost numpy: YES")
735     else:
736     print(" boost numpy: NO")
737 aellery 6818 if env['trilinos']:
738 aellery 6898 print(" trilinos: %s (Version %s)" % (env['trilinos_prefix'],env['trilinos_version']))
739 aellery 6818 else:
740     print(" trilinos: NO")
741 caltinay 4299 if env['numpy_h']:
742     print(" numpy: YES (with headers)")
743     else:
744     print(" numpy: YES (without headers)")
745 caltinay 4295 if env['usempi']:
746 caltinay 6249 if 'orte_version' in env:
747     print(" MPI: %s (Version %s)"%(env['mpi'], env['orte_version']))
748     else:
749     print(" MPI: YES (flavour: %s)"%env['mpi'])
750 caltinay 4295 else:
751 caltinay 6255 d_list.append('mpi')
752 caltinay 5696 if env['parmetis']:
753     print(" ParMETIS: %s (Version %s)"%(env['parmetis_prefix'],env['parmetis_version']))
754     else:
755 caltinay 6255 d_list.append('parmetis')
756 caltinay 4295 if env['uselapack']:
757     print(" LAPACK: YES (flavour: %s)"%env['lapack'])
758     else:
759 caltinay 6255 d_list.append('lapack')
760 caltinay 5391 if env['gmshpy']:
761     gmshpy=" + python module"
762     else:
763     gmshpy=""
764 caltinay 4295 if env['gmsh']=='m':
765 caltinay 5391 print(" gmsh: YES, MPI-ENABLED"+gmshpy)
766 caltinay 4295 elif env['gmsh']=='s':
767 caltinay 5391 print(" gmsh: YES"+gmshpy)
768 caltinay 4295 else:
769 caltinay 5391 if env['gmshpy']:
770     print(" gmsh: python module only")
771     else:
772 caltinay 6255 d_list.append('gmsh')
773     if env['compressed_files']:
774     print(" gzip: YES")
775     else:
776     d_list.append('gzip')
777 caltinay 4299
778 caltinay 6255 solvers = []
779     direct = []
780     if env['paso']:
781     solvers.append('paso')
782     if env['mkl']:
783     direct.append('mkl')
784     if env['umfpack']:
785     direct.append('umfpack')
786     else:
787     d_list.append('paso')
788     if env['trilinos']:
789     solvers.append('trilinos')
790     direct.append('trilinos')
791     else:
792     d_list.append('trilinos')
793    
794     print(" Solver library: %s"%(", ".join(solvers)))
795     if len(direct) > 0:
796     print(" Direct solver: YES (%s)"%(", ".join(direct)))
797     else:
798     print(" Direct solver: NONE")
799     print(" domains: %s"%(", ".join(env['domains'])))
800 jfenwick 6509 if env['netcdf']==4:
801     print(" netcdf: YES (4 + 3)")
802     elif env['netcdf']==3:
803     print(" netcdf: YES (3)")
804     else:
805     print(" netcdf: NO")
806 caltinay 6255 e_list=[]
807 aellery 6739 for i in ('weipa','debug','openmp','cppunit','gdal','mkl',
808 aellery 6781 'pyproj','scipy','silo','sympy','umfpack','visit'):
809 caltinay 6255 if env[i]: e_list.append(i)
810     else: d_list.append(i)
811    
812     d_list += set(all_domains).difference(env['domains'])
813     for i in e_list:
814     print("%16s: YES"%i)
815     print("\n DISABLED features: %s"%(" ".join(sorted(d_list))))
816    
817 caltinay 4295 if ((fatalwarning != '') and (env['werror'])):
818     print(" Treating warnings as errors")
819     else:
820     print(" NOT treating warnings as errors")
821     print("")
822     for w in env['warnings']:
823     print("WARNING: %s"%w)
824 sshaw 4726 if len(GetBuildFailures()):
825     print("\nERROR: build stopped due to errors\n")
826     else:
827     print("\nSUCCESS: build complete\n")
828 caltinay 4295
829     atexit.register(print_summary)

  ViewVC Help
Powered by ViewVC 1.1.26