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

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

  ViewVC Help
Powered by ViewVC 1.1.26