/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 370 by cochrane, Fri Dec 16 00:52:34 2005 UTC revision 6098 by jfenwick, Tue Mar 29 02:21:44 2016 UTC
# Line 1  Line 1 
1  # top-level Scons configuration file for all esys13 modules  ##############################################################################
   
 import os  
   
2  #  #
3  # ensure correct versions of python and scons  # Copyright (c) 2003-2016 by The University of Queensland
4    # http://www.uq.edu.au
 EnsurePythonVersion(2,3)  
 EnsureSConsVersion(0,96)  
   
5  #  #
6  # retreive command-line arguments if any  # Primary Business: Queensland, Australia
7  # these are passed through to SConscripts  # 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  if ARGUMENTS.get('libinstall',0):  import atexit, sys, os, platform, re
20    libinstall = ARGUMENTS.get('libinstall',0)  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 -DSLOWSHARECHECK"
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 -DSLOWSHARECHECK --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:  else:
340    libinstall = None      env['omp_flags']=''
341  Export(["libinstall"])      env['omp_ldflags']=''
342    
343  if ARGUMENTS.get('pyinstall',0):  env['buildvars']['openmp']=int(env['openmp'])
344    pyinstall = ARGUMENTS.get('pyinstall',0)  
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:  else:
350    pyinstall = None      env.Append(CCFLAGS = env['cc_optim'])
351  Export(["pyinstall"])  
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  if ARGUMENTS.get('options',0):  # set defaults for launchers if not otherwise specified
359    options = ARGUMENTS.get('options',0)  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 -bynode -bind-to-core --cpus-per-rank %t -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:  else:
399    options = None    # Get the global Subversion revision number for the getVersion() method
400  Export(["options"])    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  if ARGUMENTS.get('debug',0):  for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
428    dodebug = 1      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:  else:
475    dodebug = 0      py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
476  Export(["dodebug"])  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  if ARGUMENTS.get('usegcc',0):  runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
485    usegcc = 1  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:  else:
680    usegcc = 0      install_all=env.Alias('install_all', install_all_list)
 Export(["usegcc"])  
681    
 #  
 # set and export esysroot  
682    
 esysroot = Dir('#.')  
 Export(["esysroot"])  
683    
 #  
 # call appropriate SConscripts  
684    
685  target_scripts = ['tools/CppUnitTest/SConstruct',  # Default target is install
686                    'tools/mmio/SConstruct',  #env.Default('install_all')
687                    'esysUtils/SConstruct',  
688                    'escript/SConstruct',  
689                    'bruce/SConstruct',  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                    'paso/SConstruct',  env.Depends('dummy', install_all)
691                    'finley/SConstruct',  if env['usempi']:
692                    'modellib/SConstruct',     #env.Requires('dummy', ['build_pythonMPI', 'install_pythonMPI'])
693                    'doc/SConstruct']     #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    
 SConscript(target_scripts, duplicate=0)  

Legend:
Removed from v.370  
changed lines
  Added in v.6098

  ViewVC Help
Powered by ViewVC 1.1.26