/[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 5593 by jfenwick, Fri Apr 24 01:36:26 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 relevant options file in the scons/templates/")
50        print("subdirectory and customize it to your needs.\n")
51        options_file = None
52    
53    ############################### Build options ################################
54    
55    default_prefix='/usr'
56    mpi_flavours=('no', 'none', 'MPT', 'MPICH', 'MPICH2', 'OPENMPI', 'INTELMPI')
57    lapack_flavours=('none', 'clapack', 'mkl')
58    
59    #Note that scons construction vars the the following purposes:
60    #  CPPFLAGS -> to the preprocessor
61    #  CCFLAGS  -> flags for _both_ C and C++
62    #  CXXFLAGS -> flags for c++ _only_
63    #  CFLAGS   -> flags for c only
64    
65    vars = Variables(options_file, ARGUMENTS)
66    vars.AddVariables(
67      PathVariable('options_file', 'Path to options file', options_file, PathVariable.PathIsFile),
68      PathVariable('prefix', 'Installation prefix', Dir('#.').abspath, PathVariable.PathIsDirCreate),
69      PathVariable('build_dir', 'Top-level build directory', Dir('#/build').abspath, PathVariable.PathIsDirCreate),
70      BoolVariable('verbose', 'Output full compile/link lines', False),
71    # Compiler/Linker options
72      ('cxx', 'Path to C++ compiler', 'default'),
73      ('cc_flags', 'Base (C and C++) compiler flags', 'default'),
74      ('cc_optim', 'Additional (C and C++) flags for a non-debug build', 'default'),
75      ('cc_debug', 'Additional (C and C++) flags for a debug build', 'default'),
76      ('cxx_extra', 'Extra C++ compiler flags', ''),
77      ('cpp_flags', 'C Pre-processor flags', ''),
78      ('ld_extra', 'Extra linker flags', ''),
79      ('nvcc', 'Path to CUDA compiler', 'default'),
80      ('nvccflags', 'Base CUDA compiler flags', 'default'),
81      BoolVariable('werror','Treat compiler warnings as errors', True),
82      BoolVariable('debug', 'Compile with debug flags', False),
83      BoolVariable('openmp', 'Compile parallel version using OpenMP', False),
84      ('omp_flags', 'OpenMP compiler flags', 'default'),
85      ('omp_ldflags', 'OpenMP linker flags', 'default'),
86    # Mandatory libraries
87      ('boost_prefix', 'Prefix/Paths of boost installation', default_prefix),
88      ('boost_libs', 'Boost libraries to link with', ['boost_python-mt']),
89    # Mandatory for tests
90      ('cppunit_prefix', 'Prefix/Paths of CppUnit installation', default_prefix),
91      ('cppunit_libs', 'CppUnit libraries to link with', ['cppunit']),
92    # Optional libraries and options
93      EnumVariable('mpi', 'Compile parallel version using MPI flavour', 'none', allowed_values=mpi_flavours),
94      ('mpi_prefix', 'Prefix/Paths of MPI installation', default_prefix),
95      ('mpi_libs', 'MPI shared libraries to link with', ['mpi']),
96      BoolVariable('cuda', 'Enable GPU code with CUDA (requires thrust)', False),
97      ('cuda_prefix', 'Prefix/Paths to NVidia CUDA installation', default_prefix),
98      BoolVariable('netcdf', 'Enable netCDF file support', False),
99      ('netcdf_prefix', 'Prefix/Paths of netCDF installation', default_prefix),
100      ('netcdf_libs', 'netCDF libraries to link with', ['netcdf_c++', 'netcdf']),
101      BoolVariable('parmetis', 'Enable ParMETIS (requires MPI)', False),
102      ('parmetis_prefix', 'Prefix/Paths of ParMETIS installation', default_prefix),
103      ('parmetis_libs', 'ParMETIS libraries to link with', ['parmetis', 'metis']),
104      BoolVariable('mkl', 'Enable the Math Kernel Library', False),
105      ('mkl_prefix', 'Prefix/Paths to MKL installation', default_prefix),
106      ('mkl_libs', 'MKL libraries to link with', ['mkl_solver','mkl_em64t','guide','pthread']),
107      BoolVariable('umfpack', 'Enable UMFPACK', False),
108      ('umfpack_prefix', 'Prefix/Paths to UMFPACK installation', default_prefix),
109      ('umfpack_libs', 'UMFPACK libraries to link with', ['umfpack']),
110      BoolVariable('boomeramg', 'Enable BoomerAMG', False),
111      ('boomeramg_prefix', 'Prefix/Paths to BoomerAMG installation', default_prefix),
112      ('boomeramg_libs', 'BoomerAMG libraries to link with', ['boomeramg']),
113      EnumVariable('lapack', 'Set LAPACK flavour', 'none', allowed_values=lapack_flavours),
114      ('lapack_prefix', 'Prefix/Paths to LAPACK installation', default_prefix),
115      ('lapack_libs', 'LAPACK libraries to link with', []),
116      BoolVariable('silo', 'Enable the Silo file format in weipa', False),
117      ('silo_prefix', 'Prefix/Paths to Silo installation', default_prefix),
118      ('silo_libs', 'Silo libraries to link with', ['siloh5', 'hdf5']),
119      BoolVariable('visit', 'Enable the VisIt simulation interface', False),
120      ('visit_prefix', 'Prefix/Paths to VisIt installation', default_prefix),
121      ('visit_libs', 'VisIt libraries to link with', ['simV2']),
122      ListVariable('domains', 'Which domains to build', 'all',\
123                   ['dudley','finley','ripley','speckley']),
124    # Advanced settings
125      ('launcher', 'Launcher command (e.g. mpirun)', 'default'),
126      ('prelaunch', 'Command to execute before launcher (e.g. mpdboot)', 'default'),
127      ('postlaunch', 'Command to execute after launcher (e.g. mpdexit)', 'default'),
128      #dudley_assemble_flags = -funroll-loops      to actually do something
129      ('dudley_assemble_flags', 'compiler flags for some dudley optimisations', ''),
130      # To enable passing function pointers through python
131      BoolVariable('iknowwhatimdoing', 'Allow non-standard C', False),
132      # An option for specifying the compiler tools
133      ('tools_names', 'Compiler tools to use', ['default']),
134      ('env_export', 'Environment variables to be passed to tools',[]),
135      EnumVariable('forcelazy', 'For testing use only - set the default value for autolazy', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
136      EnumVariable('forcecollres', 'For testing use only - set the default value for force resolving collective ops', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
137      ('build_shared', 'Build dynamic libraries only', False),
138      ('sys_libs', 'Extra libraries to link with', []),
139      ('escript_opts_version', 'Version of options file (do not specify on command line)'),
140      ('SVN_VERSION', 'Do not use from options file', -2),
141      ('pythoncmd', 'which python to compile with','python'),
142      ('usepython3', 'Is this a python3 build? (experimental)', False),
143      ('pythonlibname', 'Name of the python library to link. (This is found automatically for python2.X.)', ''),
144      ('pythonlibpath', 'Path to the python library. (You should not need to set this unless your python has moved)',''),
145      ('pythonincpath','Path to python include files. (You should not need to set this unless your python has moved',''),
146      BoolVariable('longindices', 'use long indices (for very large matrices)', False),
147      BoolVariable('compressed_files','Enables reading from compressed binary files', True),
148      ('compression_libs', 'Compression libraries to link with', ['boost_iostreams']),
149      BoolVariable('papi', 'Enable PAPI', False),
150      ('papi_prefix', 'Prefix/Paths to PAPI installation', default_prefix),
151      ('papi_libs', 'PAPI libraries to link with', ['papi']),
152      BoolVariable('papi_instrument_solver', 'Use PAPI to instrument each iteration of the solver', False)
153    )
154    
155    ##################### Create environment and help text #######################
156    
157    # Intel's compiler uses regular expressions improperly and emits a warning
158    # about failing to find the compilers. This warning can be safely ignored.
159    
160    # PATH is needed so the compiler, linker and tools are found if they are not
161    # in default locations.
162    env = Environment(tools = ['default'], options = vars,
163                      ENV = {'PATH': os.environ['PATH']})
164    
165    # set the vars for clang
166    def mkclang(env):
167        env['CXX']='clang++'
168    
169    if env['tools_names'] != ['default']:
170        zz=env['tools_names']
171        if 'clang' in zz:
172            zz.remove('clang')
173            zz.insert(0, mkclang)
174        env = Environment(tools = ['default'] + env['tools_names'], options = vars,
175                          ENV = {'PATH' : os.environ['PATH']})
176    
177    if options_file:
178        opts_valid=False
179        if 'escript_opts_version' in env.Dictionary() and \
180            int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
181                opts_valid=True
182        if opts_valid:
183            print("Using options in %s." % options_file)
184        else:
185            print("\nOptions file %s" % options_file)
186            print("is outdated! Please update the file by examining one of the TEMPLATE")
187            print("files in the scons/ subdirectory and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
188            Exit(1)
189    
190    # Generate help text (scons -h)
191    Help(vars.GenerateHelpText(env))
192    
193    # Check for superfluous options
194    if len(vars.UnknownVariables())>0:
195        for k in vars.UnknownVariables():
196            print("Unknown option '%s'" % k)
197        Exit(1)
198    
199    if env['cuda']:
200        if env['nvcc'] != 'default':
201            env['NVCC'] = env['nvcc']
202        env.Tool('nvcc')
203    
204    if 'dudley' in env['domains']:
205        env['domains'].append('finley')
206    
207    # create dictionary which will be populated with info for buildvars file
208    env['buildvars']={}
209    # create list which will be populated with warnings if there are any
210    env['warnings']=[]
211    
212    #################### Make sure install directories exist #####################
213    
214    env['BUILD_DIR']=Dir(env['build_dir']).abspath
215    prefix=Dir(env['prefix']).abspath
216    env['buildvars']['prefix']=prefix
217    env['incinstall'] = os.path.join(prefix, 'include')
218    env['bininstall'] = os.path.join(prefix, 'bin')
219    env['libinstall'] = os.path.join(prefix, 'lib')
220    env['pyinstall']  = os.path.join(prefix, 'esys')
221    if not os.path.isdir(env['bininstall']):
222        os.makedirs(env['bininstall'])
223    if not os.path.isdir(env['libinstall']):
224        os.makedirs(env['libinstall'])
225    if not os.path.isdir(env['pyinstall']):
226        os.makedirs(env['pyinstall'])
227    
228    env.Append(CPPPATH = [env['incinstall']])
229    env.Append(LIBPATH = [env['libinstall']])
230    
231    ################# Fill in compiler options if not set above ##################
232    
233    if env['cxx'] != 'default': env['CXX']=env['cxx']
234    
235    # version >=9 of intel C++ compiler requires use of icpc to link in C++
236    # runtimes (icc does not)
237    if not IS_WINDOWS and os.uname()[4]=='ia64' and env['CXX']=='icpc':
238        env['LINK'] = env['CXX']
239    
240    # default compiler/linker options
241    cc_flags = ''
242    cc_optim = ''
243    cc_debug = ''
244    omp_flags = ''
245    omp_ldflags = ''
246    fatalwarning = '' # switch to turn warnings into errors
247    sysheaderopt = '' # how to indicate that a header is a system header
248    
249    # env['CC'] might be a full path
250    cc_name=os.path.basename(env['CXX'])
251    
252    if cc_name == 'icpc':
253        # Intel compiler
254        # #1875: offsetof applied to non-POD types is nonstandard (in boost)
255        # removed -std=c99 because icpc doesn't like it and we aren't using c anymore
256        cc_flags    = "-fPIC -w2 -wd1875 -Wno-unknown-pragmas"
257        cc_optim    = "-O3 -ftz -fno-alias -inline-level=2 -ipo -xHost"
258        cc_debug    = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
259        omp_flags   = "-openmp"
260        omp_ldflags = "-openmp -openmp_report=1"
261        fatalwarning = "-Werror"
262    elif cc_name[:3] == 'g++':
263        # GNU C++ on any system
264        # note that -ffast-math is not used because it breaks isnan(),
265        # see mantis #691
266        cc_flags     = "-pedantic -Wall -fPIC -Wno-unknown-pragmas -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing -finline-functions"
267        cc_optim     = "-O3"
268        #max-vartrack-size: avoid vartrack limit being exceeded with escriptcpp.cpp
269        cc_debug     = "-g3 -O0 -D_GLIBCXX_DEBUG -DDOASSERT -DDOPROF -DBOUNDS_CHECK --param=max-vartrack-size=100000000"
270        omp_flags    = "-fopenmp"
271        omp_ldflags  = "-fopenmp"
272        fatalwarning = "-Werror"
273        sysheaderopt = "-isystem"
274    elif cc_name == 'cl':
275        # Microsoft Visual C on Windows
276        cc_flags     = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
277        cc_optim     = "/O2 /Op /W3"
278        cc_debug     = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
279        fatalwarning = "/WX"
280    elif cc_name == 'icl':
281        # Intel C on Windows
282        cc_flags     = '/EHsc /GR /MD'
283        cc_optim     = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
284        cc_debug     = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
285        omp_flags    = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
286        omp_ldflags  = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
287    
288    env['sysheaderopt']=sysheaderopt
289    
290    # set defaults if not otherwise specified
291    if env['cc_flags']    == 'default': env['cc_flags'] = cc_flags
292    if env['cc_optim']    == 'default': env['cc_optim'] = cc_optim
293    if env['cc_debug']    == 'default': env['cc_debug'] = cc_debug
294    if env['omp_flags']   == 'default': env['omp_flags'] = omp_flags
295    if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
296    if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
297    if env['ld_extra']  != '': env.Append(LINKFLAGS = env['ld_extra'])
298    if env['cpp_flags'] != '': env.Append(CPPFLAGS = env['cpp_flags'])
299    
300    if env['nvccflags'] != 'default':
301        env['NVCCFLAGS'] = env['nvccflags']
302        env['SHNVCCFLAGS'] = env['nvccflags'] + ' -shared'
303    
304    if env['longindices']:
305        env.Append(CPPDEFINES = ['ESYS_INDEXTYPE_LONG'])
306    
307    if env['usepython3']:
308        env.Append(CPPDEFINES=['ESPYTHON3'])
309    
310    # set up the autolazy values
311    if env['forcelazy'] == 'on':
312        env.Append(CPPDEFINES=['FAUTOLAZYON'])
313    elif env['forcelazy'] == 'off':
314        env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
315    
316    # set up the collective resolve values
317    if env['forcecollres'] == 'on':
318        env.Append(CPPDEFINES=['FRESCOLLECTON'])
319    elif env['forcecollres'] == 'off':
320        env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
321    
322    # allow non-standard C if requested
323    if env['iknowwhatimdoing']:
324        env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
325    
326    # Disable OpenMP if no flags provided
327    if env['openmp'] and env['omp_flags'] == '':
328       env['warnings'].append("OpenMP requested but no flags provided - disabling OpenMP!")
329       env['openmp'] = False
330    
331    if env['openmp']:
332        env.Append(CCFLAGS = env['omp_flags'])
333        if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
334  else:  else:
335    pyinstall = None      env['omp_flags']=''
336  Export(["pyinstall"])      env['omp_ldflags']=''
337    
338  if ARGUMENTS.get('options',0):  env['buildvars']['openmp']=int(env['openmp'])
339    options = ARGUMENTS.get('options',0)  
340    # add debug/non-debug compiler flags
341    env['buildvars']['debug']=int(env['debug'])
342    if env['debug']:
343        env.Append(CCFLAGS = env['cc_debug'])
344  else:  else:
345    options = None      env.Append(CCFLAGS = env['cc_optim'])
346  Export(["options"])  
347    # always add cc_flags
348    env.Append(CCFLAGS = env['cc_flags'])
349    
350  if ARGUMENTS.get('debug',0):  # add system libraries
351    dodebug = 1  env.AppendUnique(LIBS = env['sys_libs'])
352    
353    # set defaults for launchers if not otherwise specified
354    if env['prelaunch'] == 'default':
355        if env['mpi'] == 'INTELMPI' and env['openmp']:
356            env['prelaunch'] = "export I_MPI_PIN_DOMAIN=omp"
357        elif env['mpi'] == 'OPENMPI':
358            # transform comma-separated list to '-x a -x b -x c ...'
359            env['prelaunch'] = "EE=$(echo -x %e|sed -e 's/,/ -x /g')"
360        elif env['mpi'] == 'MPT':
361            env['prelaunch'] = "export MPI_NUM_MEMORY_REGIONS=0"
362        elif env['mpi'] == 'MPICH2':
363            env['prelaunch'] = "mpdboot -n %n -r ssh -f %f"
364        else:
365            env['prelaunch'] = ""
366    
367    if env['launcher'] == 'default':
368        if env['mpi'] == 'INTELMPI':
369            env['launcher'] = "mpirun -hostfile %f -n %N -ppn %p %b"
370        elif env['mpi'] == 'OPENMPI':
371            env['launcher'] = "mpirun --gmca mpi_warn_on_fork 0 ${EE} --host %h -bynode -bind-to-core --cpus-per-rank %t -np %N %b"
372        elif env['mpi'] == 'MPT':
373            env['launcher'] = "mpirun %h -np %p %b"
374        elif env['mpi'] == 'MPICH':
375            env['launcher'] = "mpirun -machinefile %f -np %N %b"
376        elif env['mpi'] == 'MPICH2':
377            env['launcher'] = "mpiexec -genvlist %e -np %N %b"
378        else:
379            env['launcher'] = "%b"
380    
381    if env['postlaunch'] == 'default':
382        if env['mpi'] == 'MPICH2':
383            env['postlaunch'] = "mpdallexit"
384        else:
385            env['postlaunch'] = ""
386    
387    # determine svn revision
388    global_revision=ARGUMENTS.get('SVN_VERSION', None)
389    if global_revision:
390        global_revision = re.sub(':.*', '', global_revision)
391        global_revision = re.sub('[^0-9]', '', global_revision)
392        if global_revision == '': global_revision='-2'
393    else:
394      # Get the global Subversion revision number for the getVersion() method
395      try:
396        global_revision = os.popen('svnversion -n .').read()
397        global_revision = re.sub(':.*', '', global_revision)
398        global_revision = re.sub('[^0-9]', '', global_revision)
399        if global_revision == '': global_revision='-2'
400      except:
401        global_revision = '-1'
402    env['svn_revision']=global_revision
403    env['buildvars']['svn_revision']=global_revision
404    env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
405    
406    if IS_WINDOWS:
407        if not env['build_shared']:
408            env.Append(CPPDEFINES = ['ESYSUTILS_STATIC_LIB'])
409            env.Append(CPPDEFINES = ['PASO_STATIC_LIB'])
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:  else:
421    dodebug = 0      LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
422  Export(["dodebug"])  
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('usegcc',0):  for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
428    usegcc = 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    usegcc = 0      py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
476  Export(["usegcc"])  env.Append(BUILDERS = {'PyCompile' : py_builder});
477    
478  #  runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
479  # set and export esysroot  env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
480    
481  esysroot = Dir('#.')  runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
482  Export(["esysroot"])  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
483    
484  #  runPyExample_builder = Builder(action = runPyExample, suffix = '.passed', src_suffic='.py', single_source=True)
485  # call appropriate SConscripts  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    env.SConscript(dirs = ['esysUtils/src'], variant_dir='$BUILD_DIR/$PLATFORM/esysUtils', duplicate=0)
583    env.SConscript(dirs = ['pasowrap/src'], variant_dir='$BUILD_DIR/$PLATFORM/pasowrap', duplicate=0)
584    if 'dudley' in env['domains']:
585        env.SConscript(dirs = ['dudley/src'], variant_dir='$BUILD_DIR/$PLATFORM/dudley', duplicate=0)
586    if 'finley' in env['domains']:
587        env.SConscript(dirs = ['finley/src'], variant_dir='$BUILD_DIR/$PLATFORM/finley', duplicate=0)
588    if 'ripley' in env['domains']:
589        env.SConscript(dirs = ['ripley/src'], variant_dir='$BUILD_DIR/$PLATFORM/ripley', duplicate=0)
590    if 'speckley' in env['domains']:
591        env.SConscript(dirs = ['speckley/src'], variant_dir='$BUILD_DIR/$PLATFORM/speckley', duplicate=0)
592    env.SConscript(dirs = ['downunder/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/downunder', duplicate=0)
593    env.SConscript(dirs = ['modellib/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/modellib', duplicate=0)
594    env.SConscript(dirs = ['pycad/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/pycad', duplicate=0)
595    env.SConscript(dirs = ['pythonMPI/src'], variant_dir='$BUILD_DIR/$PLATFORM/pythonMPI', duplicate=0)
596    env.SConscript(dirs = ['doc'], variant_dir='$BUILD_DIR/$PLATFORM/doc', duplicate=0)
597    env.SConscript(dirs = ['paso/profiling'], variant_dir='$BUILD_DIR/$PLATFORM/paso/profiling', duplicate=0)
598    
599    
600    ######################## Populate the buildvars file #########################
601    
602    write_buildvars(env)
603    
604    write_launcher(env)
605    
606    ################### Targets to build and install libraries ###################
607    
608    target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
609    env.Alias('target_init', [target_init])
610    # delete buildvars upon cleanup
611    env.Clean('target_init', os.path.join(env['libinstall'], 'buildvars'))
612    
613    # The headers have to be installed prior to build in order to satisfy
614    # #include <paso/Common.h>
615    env.Alias('build_esysUtils', ['install_esysUtils_headers', 'build_esysUtils_lib'])
616    env.Alias('install_esysUtils', ['build_esysUtils', 'install_esysUtils_lib'])
617    
618    env.Alias('build_paso', ['install_paso_headers', 'build_paso_lib'])
619    env.Alias('install_paso', ['build_paso', 'install_paso_lib'])
620    
621    env.Alias('build_escript', ['install_escript_headers', 'build_escript_lib', 'build_escriptcpp_lib'])
622    env.Alias('install_escript', ['build_escript', 'install_escript_lib', 'install_escriptcpp_lib', 'install_escriptcore_py', 'install_escript_py'])
623    
624    env.Alias('build_pasowrap', ['install_pasowrap_headers', 'build_pasowrap_lib', 'build_pasowrapcpp_lib'])
625    env.Alias('install_pasowrap', ['build_pasowrap', 'install_pasowrap_lib', 'install_pasowrapcpp_lib', 'install_pasowrap_py'])
626    
627    if 'dudley' in env['domains']:
628        env.Alias('build_dudley', ['install_dudley_headers', 'build_dudley_lib', 'build_dudleycpp_lib'])
629        env.Alias('install_dudley', ['build_dudley', 'install_dudley_lib', 'install_dudleycpp_lib', 'install_dudley_py'])
630    
631    if 'finley' in env['domains']:
632        env.Alias('build_finley', ['install_finley_headers', 'build_finley_lib', 'build_finleycpp_lib'])
633        env.Alias('install_finley', ['build_finley', 'install_finley_lib', 'install_finleycpp_lib', 'install_finley_py'])
634    
635    if 'ripley' in env['domains']:
636        env.Alias('build_ripley', ['install_cusp_headers', 'install_ripley_headers', 'build_ripley_lib', 'build_ripleycpp_lib'])
637        env.Alias('install_ripley', ['build_ripley', 'install_ripley_lib', 'install_ripleycpp_lib', 'install_ripley_py'])
638    
639    if 'speckley' in env['domains']:
640        env.Alias('build_speckley', ['install_speckley_headers', 'build_speckley_lib', 'build_speckleycpp_lib'])
641        env.Alias('install_speckley', ['build_speckley', 'install_speckley_lib', 'install_speckleycpp_lib', 'install_speckley_py'])
642    
643    env.Alias('build_weipa', ['install_weipa_headers', 'build_weipa_lib', 'build_weipacpp_lib'])
644    env.Alias('install_weipa', ['build_weipa', 'install_weipa_lib', 'install_weipacpp_lib', 'install_weipa_py'])
645    
646    env.Alias('build_escriptreader', ['install_weipa_headers', 'build_escriptreader_lib'])
647    env.Alias('install_escriptreader', ['build_escriptreader', 'install_escriptreader_lib'])
648    
649    # Now gather all the above into some easy targets: build_all and install_all
650    build_all_list = []
651    build_all_list += ['build_esysUtils']
652    build_all_list += ['build_paso']
653    build_all_list += ['build_escript']
654    build_all_list += ['build_pasowrap']
655    if 'dudley' in env['domains']: build_all_list += ['build_dudley']
656    if 'finley' in env['domains']: build_all_list += ['build_finley']
657    if 'ripley' in env['domains']: build_all_list += ['build_ripley']
658    if 'speckley' in env['domains']: build_all_list += ['build_speckley']
659    build_all_list += ['build_weipa']
660    if not IS_WINDOWS and 'finley' in env['domains']:
661        build_all_list += ['build_escriptreader']
662    if env['usempi']:
663        build_all_list += ['build_pythonMPI', 'build_overlord']
664    env.Alias('build_all', build_all_list)
665    
666    install_all_list = []
667    install_all_list += ['target_init']
668    install_all_list += ['install_esysUtils']
669    install_all_list += ['install_paso']
670    install_all_list += ['install_escript']
671    install_all_list += ['install_pasowrap']
672    if 'dudley' in env['domains']: install_all_list += ['install_dudley']
673    if 'finley' in env['domains']: install_all_list += ['install_finley']
674    if 'ripley' in env['domains']: install_all_list += ['install_ripley']
675    if 'speckley' in env['domains']: install_all_list += ['install_speckley']
676    install_all_list += ['install_weipa']
677    if not IS_WINDOWS and 'finley' in env['domains']:
678        install_all_list += ['install_escriptreader']
679    install_all_list += ['install_downunder_py']
680    install_all_list += ['install_modellib_py']
681    install_all_list += ['install_pycad_py']
682    if env['usempi']:
683        install_all_list += ['install_pythonMPI', 'install_overlord']
684    env.Alias('install_all', install_all_list)
685    
686    # Default target is install
687    env.Default('install_all')
688    
689    ################## Targets to build and run the test suite ###################
690    
691    if not env['cppunit']:
692        test_msg = env.Command('.dummy.', None, '@echo "Cannot run C++ unit tests, CppUnit not found!";exit 1')
693        env.Alias('run_tests', test_msg)
694        env.Alias('build_tests', '')
695    env.Alias('run_tests', ['install_all'])
696    env.Alias('all_tests', ['install_all', 'run_tests', 'py_tests'])
697    env.Alias('build_full',['install_all','build_tests','build_py_tests'])
698    env.Alias('build_PasoTests','$BUILD_DIR/$PLATFORM/paso/profiling/PasoTests')
699    Requires('py_tests', 'install_all')
700    
701    ##################### Targets to build the documentation #####################
702    
703    env.Alias('pdfdocs',['user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
704    env.Alias('basedocs', ['pdfdocs','examples_tarfile', 'examples_zipfile', 'api_doxygen'])
705    env.Alias('docs', ['basedocs', 'sphinxdoc'])
706    env.Alias('release_prep', ['docs', 'install_all'])
707    env.Alias('release_prep_old', ['basedocs', 'api_epydoc', 'install_all'])
708    
709    # The test scripts are always generated, this target allows us to
710    # generate the testscripts without doing a full build
711    env.Alias('testscripts',[])
712    
713    if not IS_WINDOWS:
714        generateTestScripts(env, TestGroups)
715    
716    
717    ######################## Summarize our environment ###########################
718    def print_summary():
719        print("")
720        print("*** Config Summary (see config.log and <prefix>/lib/buildvars for details) ***")
721        print("Escript/Finley revision %s"%global_revision)
722        print("  Install prefix:  %s"%env['prefix'])
723        print("          Python:  %s"%sysconfig.PREFIX)
724        print("           boost:  %s"%env['boost_prefix'])
725        if env['numpy_h']:
726            print("           numpy:  YES (with headers)")
727        else:
728            print("           numpy:  YES (without headers)")
729        if env['usempi']:
730            print("             MPI:  YES (flavour: %s)"%env['mpi'])
731        else:
732            print("             MPI:  NO")
733        if env['uselapack']:
734            print("          LAPACK:  YES (flavour: %s)"%env['lapack'])
735        else:
736            print("          LAPACK:  NO")
737        if env['cuda']:
738            print("            CUDA:  YES (nvcc: %s)"%env['nvcc_version'])
739        else:
740            print("            CUDA:  NO")
741        d_list=[]
742        e_list=[]
743        for i in 'debug','openmp','boomeramg','gdal','mkl','netcdf','papi','parmetis','pyproj','scipy','silo','sympy','umfpack','visit':
744            if env[i]: e_list.append(i)
745            else: d_list.append(i)
746        for i in e_list:
747            print("%16s:  YES"%i)
748        for i in d_list:
749            print("%16s:  NO"%i)
750        if env['cppunit']:
751            print("         CppUnit:  YES")
752        else:
753            print("         CppUnit:  NO")
754        if env['gmshpy']:
755            gmshpy=" + python module"
756        else:
757            gmshpy=""
758        if env['gmsh']=='m':
759            print("            gmsh:  YES, MPI-ENABLED"+gmshpy)
760        elif env['gmsh']=='s':
761            print("            gmsh:  YES"+gmshpy)
762        else:
763            if env['gmshpy']:
764                print("            gmsh:  python module only")
765            else:
766                print("            gmsh:  NO")
767        print(    "            gzip:  " + ("YES" if env['compressed_files'] else "NO"))
768    
769        if ((fatalwarning != '') and (env['werror'])):
770            print("  Treating warnings as errors")
771        else:
772            print("  NOT treating warnings as errors")
773        print("")
774        for w in env['warnings']:
775            print("WARNING: %s"%w)
776        if len(GetBuildFailures()):
777            print("\nERROR: build stopped due to errors\n")
778        else:
779            print("\nSUCCESS: build complete\n")
780    
781  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']  
782    
 SConscript(target_scripts, duplicate=0)  

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

  ViewVC Help
Powered by ViewVC 1.1.26