/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

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

revision 688 by robwdcock, Tue Mar 28 01:56:24 2006 UTC revision 3975 by caltinay, Thu Sep 20 01:54:06 2012 UTC
# Line 1  Line 1 
1  #          Copyright 2006 by ACcESS MNRF                    ########################################################
 #                                                            
 #              http://www.access.edu.au                      
 #       Primary Business: Queensland, Australia              
 #  Licensed under the Open Software License version 3.0      
 #     http://www.opensource.org/licenses/osl-3.0.php        
 #                                                            
2  #  #
3    # Copyright (c) 2003-2012 by University of Queensland
4    # Earth Systems Science Computational Center (ESSCC)
5    # http://www.uq.edu.au/esscc
6  #  #
7    # Primary Business: Queensland, Australia
8    # Licensed under the Open Software License version 3.0
9    # http://www.opensource.org/licenses/osl-3.0.php
10    #
11    ########################################################
12    
13    EnsureSConsVersion(0,98,1)
14    EnsurePythonVersion(2,5)
15    
16  # top-level Scons configuration file for all esys13 modules  import sys, os, platform, re
17  # Begin initialisation Section  from distutils import sysconfig
18  # all of this section just intialises default environments and helper  from site_init import *
19  # scripts. You shouldn't need to modify this section.  from subprocess import PIPE, Popen
20  EnsureSConsVersion(0,96,91)  
21  EnsurePythonVersion(2,3)  # Version number to check for in options file. Increment when new features are
22    # added or existing options changed.
23  import sys, os  REQUIRED_OPTS_VERSION=201
24  # Add our extensions  
25  if sys.path.count('scons')==0: sys.path.append('scons')  # MS Windows support, many thanks to PH
26  import scons_extensions  IS_WINDOWS = (os.name == 'nt')
27    
28  # Default options and options help text  ########################## Determine options file ############################
29  # These are defaults and can be overridden using command line arguments or an options file.  # 1. command line
30  # if the options_file or ARGUMENTS do not exist then the ones listed as default here are used  # 2. scons/<hostname>_options.py
31  # DO NOT CHANGE THEM HERE  # 3. name as part of a cluster
32  if ARGUMENTS.get('options_file',0):  options_file=ARGUMENTS.get('options_file', None)
33     options_file = ARGUMENTS.get('options_file',0)  if not options_file:
34  else:      ext_dir = os.path.join(os.getcwd(), 'scons')
35     import socket      hostname = platform.node().split('.')[0]
36     from string import ascii_letters,digits      for name in hostname, effectiveName(hostname):
37     hostname=""          mangledhostname = re.sub('[^0-9a-zA-Z]', '_', hostname)
38     for s in socket.gethostname().split('.')[0]:          options_file = os.path.join(ext_dir, mangledhostname+'_options.py')
39        if s in ascii_letters+digits:          if os.path.isfile(options_file): break
40           hostname+=s  
41        else:  if not os.path.isfile(options_file):
42           hostname+="_"      print("\nWARNING:\nOptions file %s" % options_file)
43     options_file = "scons/"+hostname+"_options.py"      print("not found! Default options will be used which is most likely suboptimal.")
44        print("It is recommended that you copy one of the TEMPLATE files in the scons/")
45  opts = Options(options_file, ARGUMENTS)      print("subdirectory and customize it to your needs.\n")
46  opts.AddOptions(      options_file = None
47  # Where to install esys stuff  
48    ('incinstall', 'where the esys headers will be installed', Dir('#.').abspath+'/include'),  ############################### Build options ################################
49    ('libinstall', 'where the esys libraries will be installed', Dir('#.').abspath+'/lib'),  
50    ('pyinstall', 'where the esys python modules will be installed', Dir('#.').abspath),  default_prefix='/usr'
51  # Compilation options  mpi_flavours=('no', 'none', 'MPT', 'MPICH', 'MPICH2', 'OPENMPI', 'INTELMPI')
52    BoolOption('dodebug', 'Do you want a debug build?', 'yes'),  lapack_flavours=('none', 'clapack', 'mkl')
53    ('options_file', "Optional file containing preferred options. Ignored if it doesn't exist (default: scons/hostname_options.py)", options_file),  
54    ('cc_defines','C/C++ defines to use', None),  vars = Variables(options_file, ARGUMENTS)
55    ('cc_flags','C compiler flags to use (Release build)', None),  vars.AddVariables(
56    ('cc_flags_debug', 'C compiler flags to use (Debug build)', None),    PathVariable('options_file', 'Path to options file', options_file, PathVariable.PathIsFile),
57    ('cxx_flags', 'C++ compiler flags to use (Release build)', None),    PathVariable('prefix', 'Installation prefix', Dir('#.').abspath, PathVariable.PathIsDirCreate),
58    ('cxx_flags_debug', 'C++ compiler flags to use (Debug build)', None),    PathVariable('build_dir', 'Top-level build directory', Dir('#/build').abspath, PathVariable.PathIsDirCreate),
59    ('ar_flags', 'Static library archiver flags to use', None),    BoolVariable('verbose', 'Output full compile/link lines', False),
60    ('sys_libs', 'System libraries to link with', None),  # Compiler/Linker options
61  # MKL    ('cc', 'Path to C compiler', 'default'),
62    PathOption('mkl_path', 'Path to MKL includes', None),    ('cxx', 'Path to C++ compiler', 'default'),
63    PathOption('mkl_lib_path', 'Path to MKL libs', None),    ('cc_flags', 'Base C/C++ compiler flags', 'default'),
64    ('mkl_libs', 'MKL libraries to link with', None),    ('cc_optim', 'Additional C/C++ flags for a non-debug build', 'default'),
65  # SCSL    ('cc_debug', 'Additional C/C++ flags for a debug build', 'default'),
66    PathOption('scsl_path', 'Path to SCSL includes', None),    ('cc_extra', 'Extra C compiler flags', ''),
67    PathOption('scsl_lib_path', 'Path to SCSL libs', None),    ('cxx_extra', 'Extra C++ compiler flags', ''),
68    ('scsl_libs', 'SCSL libraries to link with', None),    ('ld_extra', 'Extra linker flags', ''),
69  # UMFPACK    BoolVariable('werror','Treat compiler warnings as errors', True),
70    PathOption('umf_path', 'Path to UMF includes', None),    BoolVariable('debug', 'Compile with debug flags', False),
71    PathOption('umf_lib_path', 'Path to UMF libs', None),    BoolVariable('openmp', 'Compile parallel version using OpenMP', False),
72    ('umf_libs', 'UMF libraries to link with', None),    ('omp_flags', 'OpenMP compiler flags', 'default'),
73  # Python    ('omp_ldflags', 'OpenMP linker flags', 'default'),
74  # locations of include files for python  # Mandatory libraries
75    PathOption('python_path', 'Path to Python includes', '/usr/include/python%s.%s'%(sys.version_info[0],sys.version_info[1])),    ('boost_prefix', 'Prefix/Paths of boost installation', default_prefix),
76    PathOption('python_lib_path', 'Path to Python libs', '/usr/lib'),    ('boost_libs', 'Boost libraries to link with', ['boost_python-mt']),
77    ('python_lib', 'Python libraries to link with', ["python%s.%s"%(sys.version_info[0],sys.version_info[1]),]),  # Mandatory for tests
78  # Boost    ('cppunit_prefix', 'Prefix/Paths of CppUnit installation', default_prefix),
79    PathOption('boost_path', 'Path to Boost includes', '/usr/include'),    ('cppunit_libs', 'CppUnit libraries to link with', ['cppunit']),
80    PathOption('boost_lib_path', 'Path to Boost libs', '/usr/lib'),  # Optional libraries and options
81    ('boost_lib', 'Boost libraries to link with', ['boost_python',]),    EnumVariable('mpi', 'Compile parallel version using MPI flavour', 'none', allowed_values=mpi_flavours),
82  # CppUnit    ('mpi_prefix', 'Prefix/Paths of MPI installation', default_prefix),
83    PathOption('cppunit_path', 'Path to CppUnit includes', Dir('#.').abspath+'/tools/CppUnitTest/inc'),    ('mpi_libs', 'MPI shared libraries to link with', ['mpi']),
84    PathOption('cppunit_lib_path', 'Path to CppUnit libs', Dir('#.').abspath+'/lib'),    BoolVariable('netcdf', 'Enable netCDF file support', False),
85    ('cppunit_lib', 'CppUnit libraries to link with', ['CppUnitTest',]),    ('netcdf_prefix', 'Prefix/Paths of netCDF installation', default_prefix),
86  # Doc building    ('netcdf_libs', 'netCDF libraries to link with', ['netcdf_c++', 'netcdf']),
87    PathOption('doxygen_path', 'Path to Doxygen executable', None),    BoolVariable('parmetis', 'Enable ParMETIS (requires MPI)', False),
88    PathOption('epydoc_path', 'Path to Epydoc executable', None),    ('parmetis_prefix', 'Prefix/Paths of ParMETIS installation', default_prefix),
89    PathOption('epydoc_pythonpath', 'Path to Epydoc python files', None),    ('parmetis_libs', 'ParMETIS libraries to link with', ['parmetis', 'metis']),
90  # PAPI    BoolVariable('papi', 'Enable PAPI', False),
91    PathOption('papi_path', 'Path to PAPI includes', None),    ('papi_prefix', 'Prefix/Paths to PAPI installation', default_prefix),
92    PathOption('papi_lib_path', 'Path to PAPI libs', None),    ('papi_libs', 'PAPI libraries to link with', ['papi']),
93    ('papi_libs', 'PAPI libraries to link with', None),    BoolVariable('papi_instrument_solver', 'Use PAPI to instrument each iteration of the solver', False),
94      BoolVariable('mkl', 'Enable the Math Kernel Library', False),
95      ('mkl_prefix', 'Prefix/Paths to MKL installation', default_prefix),
96      ('mkl_libs', 'MKL libraries to link with', ['mkl_solver','mkl_em64t','guide','pthread']),
97      BoolVariable('umfpack', 'Enable UMFPACK', False),
98      ('umfpack_prefix', 'Prefix/Paths to UMFPACK installation', default_prefix),
99      ('umfpack_libs', 'UMFPACK libraries to link with', ['umfpack']),
100      BoolVariable('boomeramg', 'Enable BoomerAMG', False),
101      ('boomeramg_prefix', 'Prefix/Paths to BoomerAMG installation', default_prefix),
102      ('boomeramg_libs', 'BoomerAMG libraries to link with', ['boomeramg']),
103      EnumVariable('lapack', 'Set LAPACK flavour', 'none', allowed_values=lapack_flavours),
104      ('lapack_prefix', 'Prefix/Paths to LAPACK installation', default_prefix),
105      ('lapack_libs', 'LAPACK libraries to link with', []),
106      BoolVariable('silo', 'Enable the Silo file format in weipa', False),
107      ('silo_prefix', 'Prefix/Paths to Silo installation', default_prefix),
108      ('silo_libs', 'Silo libraries to link with', ['siloh5', 'hdf5']),
109      BoolVariable('visit', 'Enable the VisIt simulation interface', False),
110      ('visit_prefix', 'Prefix/Paths to VisIt installation', default_prefix),
111      ('visit_libs', 'VisIt libraries to link with', ['simV2']),
112      BoolVariable('vsl_random', 'Use VSL from intel for random data', False),
113    # Advanced settings
114      #dudley_assemble_flags = -funroll-loops      to actually do something
115      ('dudley_assemble_flags', 'compiler flags for some dudley optimisations', ''),
116      # To enable passing function pointers through python
117      BoolVariable('iknowwhatimdoing', 'Allow non-standard C', False),
118      # An option for specifying the compiler tools (see windows branch)
119      ('tools_names', 'Compiler tools to use', ['default']),
120      ('env_export', 'Environment variables to be passed to tools',[]),
121      EnumVariable('forcelazy', 'For testing use only - set the default value for autolazy', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
122      EnumVariable('forcecollres', 'For testing use only - set the default value for force resolving collective ops', 'leave_alone', allowed_values=('leave_alone', 'on', 'off')),
123      # finer control over library building, intel aggressive global optimisation
124      # works with dynamic libraries on windows.
125      ('build_shared', 'Build dynamic libraries only', False),
126      ('sys_libs', 'Extra libraries to link with', []),
127      ('escript_opts_version', 'Version of options file (do not specify on command line)'),
128      ('SVN_VERSION', 'Do not use from options file', -2),
129      ('pythoncmd', 'which python to compile with','python'),
130      ('usepython3', 'Is this a python3 build? (experimental)', False),
131      ('pythonlibname', 'Name of the python library to link. (This is found automatically for python2.X.)', ''),
132      ('pythonlibpath', 'Path to the python library. (You should not need to set this unless your python has moved)',''),
133      ('pythonincpath','Path to python include files. (You should not need to set this unless your python has moved',''),
134      BoolVariable('BADPYTHONMACROS','Extra \#include to get around a python bug.', True),
135  )  )
136    
137  # Initialise Scons Build Environment  ##################### Create environment and help text #######################
138  # check for user environment variables we are interested in  
139  try:  # Intel's compiler uses regular expressions improperly and emits a warning
140     python_path = os.environ['PYTHONPATH']  # about failing to find the compilers. This warning can be safely ignored.
141  except KeyError:  
142     python_path = ''  # PATH is needed so the compiler, linker and tools are found if they are not
143    # in default locations.
144    env = Environment(tools = ['default'], options = vars,
145                      ENV = {'PATH': os.environ['PATH']})
146                      
147    
148    #set the vars for clang
149    def mkclang(env):
150      env['CC']='clang'
151      env['CXX']='clang++'
152                      
153                      
154    if env['tools_names'] != 'default':
155        zz=env['tools_names']
156        if 'clang' in zz:
157            zz.remove('clang')
158            zz.insert(0, mkclang)
159        env = Environment(tools = ['default'] + env['tools_names'], options = vars,
160                          ENV = {'PATH' : os.environ['PATH']})
161    
162    if options_file:
163        opts_valid=False
164        if 'escript_opts_version' in env.Dictionary() and \
165            int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
166                opts_valid=True
167        if opts_valid:
168            print("Using options in %s." % options_file)
169        else:
170            print("\nOptions file %s" % options_file)
171            print("is outdated! Please update the file by examining one of the TEMPLATE")
172            print("files in the scons/ subdirectory and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
173            Exit(1)
174    
175    # Generate help text (scons -h)
176    Help(vars.GenerateHelpText(env))
177    
178    # Check for superfluous options
179    if len(vars.UnknownVariables())>0:
180        for k in vars.UnknownVariables():
181            print("Unknown option '%s'" % k)
182        Exit(1)
183    
184    #################### Make sure install directories exist #####################
185    
186    env['BUILD_DIR']=env['build_dir']
187    prefix=Dir(env['prefix']).abspath
188    env['incinstall'] = os.path.join(prefix, 'include')
189    env['bininstall'] = os.path.join(prefix, 'bin')
190    env['libinstall'] = os.path.join(prefix, 'lib')
191    env['pyinstall']  = os.path.join(prefix, 'esys')
192    if not os.path.isdir(env['bininstall']):
193        os.makedirs(env['bininstall'])
194    if not os.path.isdir(env['libinstall']):
195        os.makedirs(env['libinstall'])
196    if not os.path.isdir(env['pyinstall']):
197        os.makedirs(env['pyinstall'])
198    
199    env.Append(CPPPATH = [env['incinstall']])
200    env.Append(LIBPATH = [env['libinstall']])
201    
202    ################# Fill in compiler options if not set above ##################
203    
204    if env['cc'] != 'default': env['CC']=env['cc']
205    if env['cxx'] != 'default': env['CXX']=env['cxx']
206    
207    # version >=9 of intel C++ compiler requires use of icpc to link in C++
208    # runtimes (icc does not)
209    if not IS_WINDOWS and os.uname()[4]=='ia64' and env['CXX']=='icpc':
210        env['LINK'] = env['CXX']
211    
212    # default compiler/linker options
213    cc_flags = ''
214    cc_optim = ''
215    cc_debug = ''
216    omp_flags = ''
217    omp_ldflags = ''
218    fatalwarning = '' # switch to turn warnings into errors
219    sysheaderopt = '' # how to indicate that a header is a system header
220    
221    # env['CC'] might be a full path
222    cc_name=os.path.basename(env['CC'])
223    
224    if cc_name == 'icc':
225        # Intel compiler
226        cc_flags    = "-std=c99 -fPIC -wd161 -w1 -vec-report0 -DBLOCKTIMER -DCORE_ID1"
227        cc_optim    = "-O3 -ftz -IPF_ftlacc- -IPF_fma -fno-alias -ip"
228        cc_debug    = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
229        omp_flags   = "-openmp -openmp_report0"
230        omp_ldflags = "-openmp -openmp_report0 -lpthread"
231        fatalwarning = "-Werror"
232    elif cc_name[:3] == 'gcc':
233        # GNU C on any system
234        cc_flags     = "-pedantic -Wall -fPIC -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER  -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing -finline-functions"
235        cc_optim     = "-O3"
236        cc_debug     = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
237        omp_flags    = "-fopenmp"
238        omp_ldflags  = "-fopenmp"
239        fatalwarning = "-Werror"
240        sysheaderopt = "-isystem"
241    elif cc_name == 'cl':
242        # Microsoft Visual C on Windows
243        cc_flags     = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
244        cc_optim     = "/O2 /Op /W3"
245        cc_debug     = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
246        fatalwarning = "/WX"
247    elif cc_name == 'icl':
248        # Intel C on Windows
249        cc_flags     = '/EHsc /GR /MD'
250        cc_optim     = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
251        cc_debug     = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
252        omp_flags    = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
253        omp_ldflags  = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
254    
255    # set defaults if not otherwise specified
256    if env['cc_flags']    == 'default': env['cc_flags'] = cc_flags
257    if env['cc_optim']    == 'default': env['cc_optim'] = cc_optim
258    if env['cc_debug']    == 'default': env['cc_debug'] = cc_debug
259    if env['omp_flags']   == 'default': env['omp_flags'] = omp_flags
260    if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
261    if env['cc_extra']  != '': env.Append(CFLAGS = env['cc_extra'])
262    if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
263    if env['ld_extra']  != '': env.Append(LINKFLAGS = env['ld_extra'])
264    
265    if env['BADPYTHONMACROS']: env.Append(CXXFLAGS = ' -DBADPYTHONMACROS')
266    
267    if env['usepython3']:
268        env.Append(CPPDEFINES=['ESPYTHON3'])
269    
270    # set up the autolazy values
271    if env['forcelazy'] == 'on':
272        env.Append(CPPDEFINES=['FAUTOLAZYON'])
273    elif env['forcelazy'] == 'off':
274        env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
275    
276    # set up the collective resolve values
277    if env['forcecollres'] == 'on':
278        env.Append(CPPDEFINES=['FRESCOLLECTON'])
279    elif env['forcecollres'] == 'off':
280        env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
281    
282    # allow non-standard C if requested
283    if env['iknowwhatimdoing']:
284        env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
285    
286    # Disable OpenMP if no flags provided
287    if env['openmp'] and env['omp_flags'] == '':
288       print("OpenMP requested but no flags provided - disabling OpenMP!")
289       env['openmp'] = False
290    
291    if env['openmp']:
292        env.Append(CCFLAGS = env['omp_flags'])
293        if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
294    else:
295        env['omp_flags']=''
296        env['omp_ldflags']=''
297    
298    # add debug/non-debug compiler flags
299    if env['debug']:
300        env.Append(CCFLAGS = env['cc_debug'])
301    else:
302        env.Append(CCFLAGS = env['cc_optim'])
303    
304    # always add cc_flags
305    env.Append(CCFLAGS = env['cc_flags'])
306    
307    # add system libraries
308    env.AppendUnique(LIBS = env['sys_libs'])
309    
310    
311    global_revision=ARGUMENTS.get('SVN_VERSION', None)
312    if global_revision:
313        global_revision = re.sub(':.*', '', global_revision)
314        global_revision = re.sub('[^0-9]', '', global_revision)
315        if global_revision == '': global_revision='-2'
316    else:
317      # Get the global Subversion revision number for the getVersion() method
318      try:
319        global_revision = os.popen('svnversion -n .').read()
320        global_revision = re.sub(':.*', '', global_revision)
321        global_revision = re.sub('[^0-9]', '', global_revision)
322        if global_revision == '': global_revision='-2'
323      except:
324        global_revision = '-1'
325    env['svn_revision']=global_revision
326    env.Append(CPPDEFINES=['SVN_VERSION='+global_revision])
327    
328    if IS_WINDOWS:
329        if not env['build_shared']:
330            env.Append(CPPDEFINES = ['ESYSUTILS_STATIC_LIB'])
331            env.Append(CPPDEFINES = ['PASO_STATIC_LIB'])
332    
333    ###################### Copy required environment vars ########################
334    
335    # Windows doesn't use LD_LIBRARY_PATH but PATH instead
336    if IS_WINDOWS:
337        LD_LIBRARY_PATH_KEY='PATH'
338        env['ENV']['LD_LIBRARY_PATH']=''
339    else:
340        LD_LIBRARY_PATH_KEY='LD_LIBRARY_PATH'
341    
342    # the following env variables are exported for the unit tests
343    
344    for key in 'OMP_NUM_THREADS', 'ESCRIPT_NUM_PROCS', 'ESCRIPT_NUM_NODES':
345        try:
346            env['ENV'][key] = os.environ[key]
347        except KeyError:
348            env['ENV'][key] = 1
349    
350    env_export=env['env_export']
351    env_export.extend(['ESCRIPT_NUM_THREADS','ESCRIPT_HOSTFILE','DISPLAY','XAUTHORITY','PATH','HOME','TMPDIR','TEMP','TMP'])
352    
353    for key in set(env_export):
354        try:
355            env['ENV'][key] = os.environ[key]
356        except KeyError:
357            pass
358    
359  try:  try:
360     path = os.environ['PATH']      env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
361  except KeyError:  except KeyError:
362     path = ''      pass
363    
364    # these shouldn't be needed
365    #for key in 'C_INCLUDE_PATH','CPLUS_INCLUDE_PATH','LIBRARY_PATH':
366    #    try:
367    #        env['ENV'][key] = os.environ[key]
368    #    except KeyError:
369    #        pass
370    
371  try:  try:
372     ld_library_path = os.environ['LD_LIBRARY_PATH']      env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
373  except KeyError:  except KeyError:
374     ld_library_path = ''      pass
375    
376  # Note: On the Altix the intel compilers are not automatically  ######################## Add some custom builders ############################
 # detected by scons intelc.py script. The Altix has a different directory  
 # path and in some locations the "modules" facility is used to support  
 # multiple compiler versions. This forces the need to import the users PATH  
 # environment which isn't the "scons way"  
 # This doesn't impact linux and windows which will use the default compiler (g++ or msvc, or the intel compiler if it is installed on both platforms)  
 # FIXME: Perhaps a modification to intelc.py will allow better support for ia64 on altix  
   
 if os.name != "nt" and os.uname()[4]=='ia64':  
    env = Environment(ENV = {'PATH':path}, tools = ['default', 'intelc'], options = opts)  
    env['ENV']['PATH'] = path  
    env['ENV']['LD_LIBRARY_PATH'] = ld_library_path  
    env['ENV']['PYTHONPATH'] = python_path  
    if env['CXX'] == 'icpc':  
       env['LINK'] = env['CXX'] # version >=9 of intel c++ compiler requires use of icpc to link in C++ runtimes (icc does not). FIXME: this behaviour could be directly incorporated into scons intelc.py  
 elif os.name == "nt":  
    # FIXME: Need to implement equivalent of ld library path for windoze  
    env = Environment(tools = ['default', 'intelc'], options = opts)  
    env['ENV']['PYTHONPATH'] = python_path  
 else:  
    env = Environment(tools = ['default'], options = opts)  
    env['ENV']['PATH'] = path  
    env['ENV']['LD_LIBRARY_PATH'] = ld_library_path  
    env['ENV']['PYTHONPATH'] = python_path  
377    
378  # Setup help for options  if env['pythoncmd']=='python':
379  Help(opts.GenerateHelpText(env))      py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
380    else:
381  # Add some customer builders      py_builder = Builder(action = env['pythoncmd']+" scripts/py_comp.py $SOURCE $TARGET", suffix = '.pyc', src_suffix = '.py', single_source=True)
 py_builder = Builder(action = scons_extensions.build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)  
382  env.Append(BUILDERS = {'PyCompile' : py_builder});  env.Append(BUILDERS = {'PyCompile' : py_builder});
383    
384  if env['PLATFORM'] == "win32":  runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
    runUnitTest_builder = Builder(action = scons_extensions.runUnitTest, suffix = '.passed', src_suffix='.exe', single_source=True)  
 else:  
    runUnitTest_builder = Builder(action = scons_extensions.runUnitTest, suffix = '.passed', single_source=True)  
385  env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});  env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
386    
387  runPyUnitTest_builder = Builder(action = scons_extensions.runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)  runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
388  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
389    
390  # Convert the options which are held in environment variable into python variables for ease of handling and configure compilation options  epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
391  try:  env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
    incinstall = env['incinstall']  
    env.Append(CPPPATH = [incinstall,])  
 except KeyError:  
    incinstall = None    
 try:  
    libinstall = env['libinstall']  
    env.Append(LIBPATH = [libinstall,])  
    env.PrependENVPath('LD_LIBRARY_PATH', libinstall)  
 except KeyError:  
    libinstall = None    
 try:  
    pyinstall = env['pyinstall']+'/esys' # all targets will install into pyinstall/esys but PYTHONPATH points at straight pyinstall so you go import esys.escript etc  
    env.PrependENVPath('PYTHONPATH', env['pyinstall'])  
 except KeyError:  
    pyinstall = None    
 try:  
    dodebug = env['dodebug']  
 except KeyError:  
    dodebug = None    
 try:  
    cc_defines = env['cc_defines']  
    env.Append(CPPDEFINES = [cc_defines,])  
 except KeyError:  
    pass  
 if dodebug:  
    try:  
       flags = env['cc_flags_debug']  
       env.Append(CCFLAGS = flags)  
    except KeyError:  
       pass  
 else:  
    try:  
       flags = env['cc_flags']  
       env.Append(CCFLAGS = flags)  
    except KeyError:  
       pass  
   
 if dodebug:  
    try:  
       flags = env['cxx_flags_debug']  
       env.Append(CXXFLAGS = flags)  
    except KeyError:  
       pass  
 else:  
    try:  
       flags = env['cxx_flags']  
       env.Append(CXXFLAGS = flags)  
    except KeyError:  
       pass  
392    
393  try:  ############################ Dependency checks ###############################
    flags = env['ar_flags']  
    env.Append(ARFLAGS = flags)  
 except KeyError:  
    ar_flags = None    
 try:  
    sys_libs = env['sys_libs']  
 except KeyError:  
    sys_libs = ''  
394    
395  try:  # Create a Configure() environment to check for compilers and python
396     includes = env['mkl_path']  conf = Configure(env.Clone())
397     env.Append(CPPPATH = [includes,])  
398  except KeyError:  ######## Test that the compilers work
399     pass  
400  try:  if 'CheckCC' in dir(conf): # exists since scons 1.1.0
401     lib_path = env['mkl_lib_path']      if not conf.CheckCC():
402     env.Append(LIBPATH = [lib_path,])          print("Cannot run C compiler '%s' (check config.log)" % (env['CC']))
403  except KeyError:          Exit(1)
404     pass      if not conf.CheckCXX():
405  try:          print("Cannot run C++ compiler '%s' (check config.log)" % (env['CXX']))
406     mkl_libs = env['mkl_libs']          Exit(1)
407  except KeyError:  else:
408     mkl_libs = ''      if not conf.CheckFunc('printf', language='c'):
409  try:          print("Cannot run C compiler '%s' (check config.log)" % (env['CC']))
410     includes = env['scsl_path']          Exit(1)
411     env.Append(CPPPATH = [includes,])      if not conf.CheckFunc('printf', language='c++'):
412  except KeyError:          print("Cannot run C++ compiler '%s' (check config.log)" % (env['CXX']))
413     pass          Exit(1)
414  try:  
415     lib_path = env['scsl_lib_path']  if conf.CheckFunc('gethostname'):
416     env.Append(LIBPATH = [lib_path,])      conf.env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])
417  except KeyError:  
418     pass  ######## Python headers & library (required)
419  try:  
420     scsl_libs = env['scsl_libs']  #First we check to see if the config file has specified
421  except KeyError:  ##Where to find the filae. Ideally, this should be automatic
422     scsl_libs = ''  #But we need to deal with the case where python is not in its INSTALL
423  try:  #Directory
424     includes = env['umf_path']  # Use the python scons is running
425     env.Append(CPPPATH = [includes,])  if env['pythoncmd']=='python':
426  except KeyError:      python_inc_path=sysconfig.get_python_inc()
427     pass      if IS_WINDOWS:
428  try:          python_lib_path=os.path.join(sysconfig.get_config_var('prefix'), 'libs')
429     lib_path = env['umf_lib_path']      elif env['PLATFORM']=='darwin':
430     env.Append(LIBPATH = [lib_path,])          python_lib_path=sysconfig.get_config_var('LIBPL')
431  except KeyError:      else:
432     pass          python_lib_path=sysconfig.get_config_var('LIBDIR')
433  try:  
434     umf_libs = env['umf_libs']      #python_libs=[sysconfig.get_config_var('LDLIBRARY')] # only on linux
435  except KeyError:      if IS_WINDOWS:
436     umf_libs = ''          python_libs=['python%s%s'%(sys.version_info[0], sys.version_info[1])]
437  try:      else:
438     includes = env['boost_path']          python_libs=['python'+sysconfig.get_python_version()]
439     env.Append(CPPPATH = [includes,])  
440  except KeyError:  #if we want to use a python other than the one scons is running
441     pass  else:
442  try:      initstring='from __future__ import print_function;from distutils import sysconfig;'
443     lib_path = env['boost_lib_path']      if env['pythonlibname']!='':
444     env.Append(LIBPATH = [lib_path,])          python_libs=env['pythonlibname']
445  except KeyError:      else:   # work it out by calling python    
446     pass          if IS_WINDOWS:
447  try:              cmd='print("python%s%s"%(sys.version_info[0], sys.version_info[1]))'
448     boost_lib = env['boost_lib']          else:
449  except KeyError:              cmd='print("python"+sysconfig.get_python_version())'
450     boost_lib = None            p=Popen([env['pythoncmd'], '-c', initstring+cmd], stdout=PIPE)
451  try:          python_libs=p.stdout.readline()
452     includes = env['cppunit_path']          if env['usepython3']:       # This is to convert unicode str into py2 string
453     env.Append(CPPPATH = [includes,])              python_libs=python_libs.encode() # If scons runs on py3 then this must be rethought
454  except KeyError:          p.wait()
455     pass          python_libs=python_libs.strip()
456  try:  
457     lib_path = env['cppunit_lib_path']    
458     env.Append(LIBPATH = [lib_path,])      # Now we know whether we are using python3 or not
459  except KeyError:      p=Popen([env['pythoncmd'], '-c',  initstring+'print(sysconfig.get_python_inc())'], stdout=PIPE)
460     pass      python_inc_path=p.stdout.readline()
461  try:      if env['usepython3']:
462     cppunit_lib = env['cppunit_lib']           python_inc_path=python_inc_path.encode()
463  except KeyError:      p.wait()  
464     boost_lib = None        python_inc_path=python_inc_path.strip()
465  try:      if IS_WINDOWS:
466     includes = env['python_path']          cmd="os.path.join(sysconfig.get_config_var('prefix'), 'libs')"
467     env.Append(CPPPATH = [includes,])      elif env['PLATFORM']=='darwin':
468  except KeyError:          cmd="sysconfig.get_config_var(\"LIBPL\")"
469     pass      else:
470  try:          cmd="sysconfig.get_config_var(\"LIBDIR\")"
471     lib_path = env['python_lib_path']  
472     env.Append(LIBPATH = [lib_path,])      p=Popen([env['pythoncmd'], '-c', initstring+'print('+cmd+')'], stdout=PIPE)
473  except KeyError:      python_lib_path=p.stdout.readline()
474     pass      if env['usepython3']:
475  try:          python_lib_path=python_lib_path.decode()
476     python_lib = env['python_lib']      p.wait()
477  except KeyError:      python_lib_path=python_lib_path.strip()
478     python_lib = None    
479  try:  #Check for an override from the config file.
480     doxygen_path = env['doxygen_path']  #Ideally, this should be automatic
481  except KeyError:  #But we need to deal with the case where python is not in its INSTALL
482     doxygen_path = None    #Directory
483  try:  if env['pythonlibpath']!='':
484     epydoc_path = env['epydoc_path']      python_lib_path=env['pythonlibpath']
485  except KeyError:  
486     epydoc_path = None    if env['pythonincpath']!='':
487  try:      python_inc_path=env['pythonincpath']
488     epydoc_pythonpath = env['epydoc_pythonpath']  
489  except KeyError:  
490     epydoc_pythonpath = None    if sysheaderopt == '':
491  try:      conf.env.AppendUnique(CPPPATH = [python_inc_path])
492     includes = env['papi_path']  else:
493     env.Append(CPPPATH = [includes,])      conf.env.Append(CCFLAGS = [sysheaderopt, python_inc_path])
494  except KeyError:  
495     pass  conf.env.AppendUnique(LIBPATH = [python_lib_path])
496  try:  conf.env.AppendUnique(LIBS = python_libs)
497     lib_path = env['papi_lib_path']  # The wrapper script needs to find the libs
498     env.Append(LIBPATH = [lib_path,])  conf.env.PrependENVPath(LD_LIBRARY_PATH_KEY, python_lib_path)
499  except KeyError:  
500     pass  if not conf.CheckCHeader('Python.h'):
501  try:      print("Cannot find python include files (tried 'Python.h' in directory %s)" % (python_inc_path))
502     papi_libs = env['papi_libs']      Exit(1)
503  except KeyError:  if not conf.CheckFunc('Py_Exit'):
504     papi_libs = None        print("Cannot find python library method Py_Main (tried %s in directory %s)" % (python_libs, python_lib_path))
505        Exit(1)
506    
507    ## reuse conf to check for numpy header (optional)
508    if env['usepython3']:
509        # FIXME: This is until we can work out how to make the checks in python 3
510        conf.env['numpy_h']=False
511    else:
512        if conf.CheckCXXHeader(['Python.h','numpy/ndarrayobject.h']):
513            conf.env.Append(CPPDEFINES = ['HAVE_NUMPY_H'])
514            conf.env['numpy_h']=True
515        else:
516            conf.env['numpy_h']=False
517    
518    # Commit changes to environment
519    env = conf.Finish()
520    
521    ######## boost (required)
522    
523    boost_inc_path,boost_lib_path=findLibWithHeader(env, env['boost_libs'], 'boost/python.hpp', env['boost_prefix'], lang='c++')
524    if sysheaderopt == '':
525        env.AppendUnique(CPPPATH = [boost_inc_path])
526    else:
527        # This is required because we can't -isystem /usr/include since it breaks
528        # std includes
529        if os.path.normpath(boost_inc_path) == '/usr/include':
530            conf.env.Append(CCFLAGS=[sysheaderopt, os.path.join(boost_inc_path,'boost')])
531        else:
532            env.Append(CCFLAGS=[sysheaderopt, boost_inc_path])
533    
534    env.AppendUnique(LIBPATH = [boost_lib_path])
535    env.AppendUnique(LIBS = env['boost_libs'])
536    env.PrependENVPath(LD_LIBRARY_PATH_KEY, boost_lib_path)
537    
538    ######## numpy (required)
539    
540    if not detectModule(env, 'numpy'):
541        print("Cannot import numpy. If it is installed try setting your PYTHONPATH and probably %s"%LD_LIBRARY_PATH_KEY)
542        Exit(1)
543    
544    ######## CppUnit (required for tests)
545    
546    try:
547        cppunit_inc_path,cppunit_lib_path=findLibWithHeader(env, env['cppunit_libs'], 'cppunit/TestFixture.h', env['cppunit_prefix'], lang='c++')
548        env.AppendUnique(CPPPATH = [cppunit_inc_path])
549        env.AppendUnique(LIBPATH = [cppunit_lib_path])
550        env.PrependENVPath(LD_LIBRARY_PATH_KEY, cppunit_lib_path)
551        env['cppunit']=True
552    except:
553        env['cppunit']=False
554    
555    ######## sympy (optional)
556    
557    if detectModule(env, 'sympy'):
558        env['sympy'] = True
559    else:
560        print("Cannot import sympy. Symbolic toolbox and nonlinear PDEs will not be available.")
561        env['sympy'] = False
562    
563    ######## netCDF (optional)
564    
565    netcdf_inc_path=''
566    netcdf_lib_path=''
567    if env['netcdf']:
568        netcdf_inc_path,netcdf_lib_path=findLibWithHeader(env, env['netcdf_libs'], 'netcdf.h', env['netcdf_prefix'], lang='c++')
569        env.AppendUnique(CPPPATH = [netcdf_inc_path])
570        env.AppendUnique(LIBPATH = [netcdf_lib_path])
571        env.AppendUnique(LIBS = env['netcdf_libs'])
572        env.PrependENVPath(LD_LIBRARY_PATH_KEY, netcdf_lib_path)
573        env.Append(CPPDEFINES = ['USE_NETCDF'])
574    
575    ######## PAPI (optional)
576    
577    papi_inc_path=''
578    papi_lib_path=''
579    if env['papi']:
580        papi_inc_path,papi_lib_path=findLibWithHeader(env, env['papi_libs'], 'papi.h', env['papi_prefix'], lang='c')
581        env.AppendUnique(CPPPATH = [papi_inc_path])
582        env.AppendUnique(LIBPATH = [papi_lib_path])
583        env.AppendUnique(LIBS = env['papi_libs'])
584        env.PrependENVPath(LD_LIBRARY_PATH_KEY, papi_lib_path)
585        env.Append(CPPDEFINES = ['BLOCKPAPI'])
586    
587    ######## MKL (optional)
588    
589    mkl_inc_path=''
590    mkl_lib_path=''
591    if env['mkl']:
592        mkl_inc_path,mkl_lib_path=findLibWithHeader(env, env['mkl_libs'], 'mkl_solver.h', env['mkl_prefix'], lang='c')
593        env.AppendUnique(CPPPATH = [mkl_inc_path])
594        env.AppendUnique(LIBPATH = [mkl_lib_path])
595        env.AppendUnique(LIBS = env['mkl_libs'])
596        env.PrependENVPath(LD_LIBRARY_PATH_KEY, mkl_lib_path)
597        env.Append(CPPDEFINES = ['MKL'])
598    
599    ######## UMFPACK (optional)
600    
601    umfpack_inc_path=''
602    umfpack_lib_path=''
603    if env['umfpack']:
604        umfpack_inc_path,umfpack_lib_path=findLibWithHeader(env, env['umfpack_libs'], 'umfpack.h', env['umfpack_prefix'], lang='c')
605        env.AppendUnique(CPPPATH = [umfpack_inc_path])
606        env.AppendUnique(LIBPATH = [umfpack_lib_path])
607        env.AppendUnique(LIBS = env['umfpack_libs'])
608        env.PrependENVPath(LD_LIBRARY_PATH_KEY, umfpack_lib_path)
609        env.Append(CPPDEFINES = ['UMFPACK'])
610    
611    ######## LAPACK (optional)
612    
613    if env['lapack']=='mkl' and not env['mkl']:
614        print("mkl_lapack requires MKL!")
615        Exit(1)
616    
617    env['uselapack'] = env['lapack']!='none'
618    lapack_inc_path=''
619    lapack_lib_path=''
620    if env['uselapack']:
621        header='clapack.h'
622        if env['lapack']=='mkl':
623            env.AppendUnique(CPPDEFINES = ['MKL_LAPACK'])
624            header='mkl_lapack.h'
625        lapack_inc_path,lapack_lib_path=findLibWithHeader(env, env['lapack_libs'], header, env['lapack_prefix'], lang='c')
626        env.AppendUnique(CPPPATH = [lapack_inc_path])
627        env.AppendUnique(LIBPATH = [lapack_lib_path])
628        env.AppendUnique(LIBS = env['lapack_libs'])
629        env.Append(CPPDEFINES = ['USE_LAPACK'])
630    
631    ######## Silo (optional)
632    
633    silo_inc_path=''
634    silo_lib_path=''
635    if env['silo']:
636        silo_inc_path,silo_lib_path=findLibWithHeader(env, env['silo_libs'], 'silo.h', env['silo_prefix'], lang='c')
637        env.AppendUnique(CPPPATH = [silo_inc_path])
638        env.AppendUnique(LIBPATH = [silo_lib_path])
639        # Note that we do not add the libs since they are only needed for the
640        # weipa library and tools.
641        #env.AppendUnique(LIBS = [env['silo_libs']])
642    
643    ######## VSL random numbers (optional)
644    if env['vsl_random']:
645        env.Append(CPPDEFINES = ['MKLRANDOM'])
646    
647    ######## VisIt (optional)
648    
649    visit_inc_path=''
650    visit_lib_path=''
651    if env['visit']:
652        visit_inc_path,visit_lib_path=findLibWithHeader(env, env['visit_libs'], 'VisItControlInterface_V2.h', env['visit_prefix'], lang='c')
653        env.AppendUnique(CPPPATH = [visit_inc_path])
654        env.AppendUnique(LIBPATH = [visit_lib_path])
655    
656    ######## MPI (optional)
657    
658    if env['mpi']=='no':
659        env['mpi']='none'
660    
661    env['usempi'] = env['mpi']!='none'
662    mpi_inc_path=''
663    mpi_lib_path=''
664    if env['usempi']:
665        mpi_inc_path,mpi_lib_path=findLibWithHeader(env, env['mpi_libs'], 'mpi.h', env['mpi_prefix'], lang='c')
666        env.AppendUnique(CPPPATH = [mpi_inc_path])
667        env.AppendUnique(LIBPATH = [mpi_lib_path])
668        env.AppendUnique(LIBS = env['mpi_libs'])
669        env.PrependENVPath(LD_LIBRARY_PATH_KEY, mpi_lib_path)
670        env.Append(CPPDEFINES = ['ESYS_MPI', 'MPI_NO_CPPBIND', 'MPICH_IGNORE_CXX_SEEK'])
671        # NetCDF 4.1 defines MPI_Comm et al. if MPI_INCLUDED is not defined!
672        # On the other hand MPT and OpenMPI don't define the latter so we have to
673        # do that here
674        if env['netcdf'] and env['mpi'] in ['MPT','OPENMPI']:
675            env.Append(CPPDEFINES = ['MPI_INCLUDED'])
676    
677    ######## BOOMERAMG (optional)
678    
679    if env['mpi'] == 'none': env['boomeramg'] = False
680    
681    boomeramg_inc_path=''
682    boomeramg_lib_path=''
683    if env['boomeramg']:
684        boomeramg_inc_path,boomeramg_lib_path=findLibWithHeader(env, env['boomeramg_libs'], 'HYPRE.h', env['boomeramg_prefix'], lang='c')
685        env.AppendUnique(CPPPATH = [boomeramg_inc_path])
686        env.AppendUnique(LIBPATH = [boomeramg_lib_path])
687        env.AppendUnique(LIBS = env['boomeramg_libs'])
688        env.PrependENVPath(LD_LIBRARY_PATH_KEY, boomeramg_lib_path)
689        env.Append(CPPDEFINES = ['BOOMERAMG'])
690    
691    ######## ParMETIS (optional)
692    
693    if not env['usempi']: env['parmetis'] = False
694    
695    parmetis_inc_path=''
696    parmetis_lib_path=''
697    if env['parmetis']:
698        parmetis_inc_path,parmetis_lib_path=findLibWithHeader(env, env['parmetis_libs'], 'parmetis.h', env['parmetis_prefix'], lang='c')
699        env.AppendUnique(CPPPATH = [parmetis_inc_path])
700        env.AppendUnique(LIBPATH = [parmetis_lib_path])
701        env.AppendUnique(LIBS = env['parmetis_libs'])
702        env.PrependENVPath(LD_LIBRARY_PATH_KEY, parmetis_lib_path)
703        env.Append(CPPDEFINES = ['USE_PARMETIS'])
704    
705    ######## gmsh (optional, for tests)
706    
707    try:
708        p=Popen(['gmsh', '-info'], stderr=PIPE)
709        _,e=p.communicate()
710        if e.split().count("MPI"):
711            env['gmsh']='m'
712        else:
713            env['gmsh']='s'
714    except OSError:
715        env['gmsh']=False
716    
717    ######## PDFLaTeX (for documentation)
718    if 'PDF' in dir(env) and '.tex' in env.PDF.builder.src_suffixes(env):
719        env['pdflatex']=True
720    else:
721        env['pdflatex']=False
722    
723    ######################## Summarize our environment ###########################
724    
725    # keep some of our install paths first in the list for the unit tests
726    env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
727    env.PrependENVPath('PYTHONPATH', prefix)
728    env['ENV']['ESCRIPT_ROOT'] = prefix
729    
730    if not env['verbose']:
731        env['CCCOMSTR'] = "Compiling $TARGET"
732        env['CXXCOMSTR'] = "Compiling $TARGET"
733        env['SHCCCOMSTR'] = "Compiling $TARGET"
734        env['SHCXXCOMSTR'] = "Compiling $TARGET"
735        env['ARCOMSTR'] = "Linking $TARGET"
736        env['LINKCOMSTR'] = "Linking $TARGET"
737        env['SHLINKCOMSTR'] = "Linking $TARGET"
738        env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
739        env['BIBTEXCOMSTR'] = "Generating bibliography $TARGET"
740        env['MAKEINDEXCOMSTR'] = "Generating index $TARGET"
741        env['PDFLATEXCOMSTR'] = "Building $TARGET from LaTeX input $SOURCES"
742        #Progress(['Checking -\r', 'Checking \\\r', 'Checking |\r', 'Checking /\r'], interval=17)
743    
744    print("")
745    print("*** Config Summary (see config.log and lib/buildvars for details) ***")
746    print("Escript/Finley revision %s"%global_revision)
747    print("  Install prefix:  %s"%env['prefix'])
748    print("          Python:  %s"%sysconfig.PREFIX)
749    print("           boost:  %s"%env['boost_prefix'])
750    print("           numpy:  YES")
751    if env['usempi']:
752        print("             MPI:  YES (flavour: %s)"%env['mpi'])
753    else:
754        print("             MPI:  DISABLED")
755    if env['uselapack']:
756        print("          LAPACK:  YES (flavour: %s)"%env['lapack'])
757    else:
758        print("          LAPACK:  DISABLED")
759    d_list=[]
760    e_list=[]
761    for i in 'debug','openmp','boomeramg','mkl','netcdf','papi','parmetis','silo','sympy','umfpack','visit','vsl_random':
762        if env[i]: e_list.append(i)
763        else: d_list.append(i)
764    for i in e_list:
765        print("%16s:  YES"%i)
766    for i in d_list:
767        print("%16s:  DISABLED"%i)
768    if env['cppunit']:
769        print("         CppUnit:  FOUND")
770    else:
771        print("         CppUnit:  NOT FOUND")
772    if env['gmsh']=='m':
773        print("            gmsh:  FOUND, MPI-ENABLED")
774    elif env['gmsh']=='s':
775        print("            gmsh:  FOUND")
776    else:
777        print("            gmsh:  NOT FOUND")
778    if env['numpy_h']:
779        print("   numpy headers:  FOUND")
780    else:
781        print("   numpy headers:  NOT FOUND")
782    print("   vsl_random:  %s"%env['vsl_random'])
783        
784    if ((fatalwarning != '') and (env['werror'])):
785        print("  Treating warnings as errors")
786    else:
787        print("  NOT treating warnings as errors")
788    print("")
789    
790    ####################### Configure the subdirectories #########################
791    
792    from grouptest import *
793    
794    TestGroups=[]
795    
796    # keep an environment without warnings-as-errors
797    dodgy_env=env.Clone()
798    
799    # now add warnings-as-errors flags. This needs to be done after configuration
800    # because the scons test files have warnings in them
801    if ((fatalwarning != '') and (env['werror'])):
802        env.Append(CCFLAGS = fatalwarning)
803    
804    Export(
805      ['env',
806       'dodgy_env',
807       'IS_WINDOWS',
808       'TestGroups'
809      ]
810    )
811    
812    env.SConscript(dirs = ['tools/escriptconvert'], variant_dir='$BUILD_DIR/$PLATFORM/tools/escriptconvert', duplicate=0)
813    env.SConscript(dirs = ['paso/src'], variant_dir='$BUILD_DIR/$PLATFORM/paso', duplicate=0)
814    env.SConscript(dirs = ['weipa/src'], variant_dir='$BUILD_DIR/$PLATFORM/weipa', duplicate=0)
815    env.SConscript(dirs = ['escript/src'], variant_dir='$BUILD_DIR/$PLATFORM/escript', duplicate=0)
816    env.SConscript(dirs = ['esysUtils/src'], variant_dir='$BUILD_DIR/$PLATFORM/esysUtils', duplicate=0)
817    env.SConscript(dirs = ['pasowrap/src'], variant_dir='$BUILD_DIR/$PLATFORM/pasowrap', duplicate=0)
818    env.SConscript(dirs = ['dudley/src'], variant_dir='$BUILD_DIR/$PLATFORM/dudley', duplicate=0)
819    env.SConscript(dirs = ['finley/src'], variant_dir='$BUILD_DIR/$PLATFORM/finley', duplicate=0)
820    env.SConscript(dirs = ['ripley/src'], variant_dir='$BUILD_DIR/$PLATFORM/ripley', duplicate=0)
821    env.SConscript(dirs = ['downunder/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/downunder', duplicate=0)
822    env.SConscript(dirs = ['modellib/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/modellib', duplicate=0)
823    env.SConscript(dirs = ['pycad/py_src'], variant_dir='$BUILD_DIR/$PLATFORM/pycad', duplicate=0)
824    env.SConscript(dirs = ['pythonMPI/src'], variant_dir='$BUILD_DIR/$PLATFORM/pythonMPI', duplicate=0)
825    env.SConscript(dirs = ['doc'], variant_dir='$BUILD_DIR/$PLATFORM/doc', duplicate=0)
826    env.SConscript(dirs = ['paso/profiling'], variant_dir='$BUILD_DIR/$PLATFORM/paso/profiling', duplicate=0)
827    
828    
829    ######################## Populate the buildvars file #########################
830    
831    # remove obsolete file
832    if not env['usempi']:
833        Execute(Delete(os.path.join(env['libinstall'], 'pythonMPI')))
834        Execute(Delete(os.path.join(env['libinstall'], 'pythonMPIredirect')))
835    
836    # Try to extract the boost version from version.hpp
837    boosthpp=open(os.path.join(boost_inc_path, 'boost', 'version.hpp'))
838    boostversion='unknown'
839    try:
840        for line in boosthpp:
841            ver=re.match(r'#define BOOST_VERSION (\d+)',line)
842            if ver:
843                boostversion=ver.group(1)
844    except StopIteration:
845        pass
846    boosthpp.close()
847    
848    
849    buildvars=open(os.path.join(env['libinstall'], 'buildvars'), 'w')
850    buildvars.write("svn_revision="+str(global_revision)+"\n")
851    buildvars.write("prefix="+prefix+"\n")
852    buildvars.write("cc="+env['CC']+"\n")
853    buildvars.write("cxx="+env['CXX']+"\n")
854    if env['pythoncmd']=='python':
855        buildvars.write("python="+sys.executable+"\n")
856        buildvars.write("python_version="+str(sys.version_info[0])+"."+str(sys.version_info[1])+"."+str(sys.version_info[2])+"\n")
857    else:
858        buildvars.write("python="+env['pythoncmd']+"\n")
859        p=Popen([env['pythoncmd'], '-c', 'from __future__ import print_function;import sys;print(str(sys.version_info[0])+"."+str(sys.version_info[1])+"."+str(sys.version_info[2]))'], stdout=PIPE)
860        verstring=p.stdout.readline().strip()
861        p.wait()
862        buildvars.write("python_version="+verstring+"\n")
863    buildvars.write("boost_inc_path="+boost_inc_path+"\n")
864    buildvars.write("boost_lib_path="+boost_lib_path+"\n")
865    buildvars.write("boost_version="+boostversion+"\n")
866    buildvars.write("debug=%d\n"%int(env['debug']))
867    buildvars.write("openmp=%d\n"%int(env['openmp']))
868    buildvars.write("mpi=%s\n"%env['mpi'])
869    buildvars.write("mpi_inc_path=%s\n"%mpi_inc_path)
870    buildvars.write("mpi_lib_path=%s\n"%mpi_lib_path)
871    buildvars.write("lapack=%s\n"%env['lapack'])
872    buildvars.write("vsl_random=%d\n"%int(env['vsl_random']))
873    for i in 'netcdf','parmetis','papi','mkl','umfpack','boomeramg','silo','visit':
874        buildvars.write("%s=%d\n"%(i, int(env[i])))
875        if env[i]:
876            buildvars.write("%s_inc_path=%s\n"%(i, eval(i+'_inc_path')))
877            buildvars.write("%s_lib_path=%s\n"%(i, eval(i+'_lib_path')))
878    buildvars.close()
879    
880    ################### Targets to build and install libraries ###################
881    
882    target_init = env.Command(os.path.join(env['pyinstall'],'__init__.py'), None, Touch('$TARGET'))
883    env.Alias('target_init', [target_init])
884    # delete buildvars upon cleanup
885    env.Clean('target_init', os.path.join(env['libinstall'], 'buildvars'))
886    
887    # The headers have to be installed prior to build in order to satisfy
888    # #include <paso/Common.h>
889    env.Alias('build_esysUtils', ['install_esysUtils_headers', 'build_esysUtils_lib'])
890    env.Alias('install_esysUtils', ['build_esysUtils', 'install_esysUtils_lib'])
891    
892    env.Alias('build_paso', ['install_paso_headers', 'build_paso_lib'])
893    env.Alias('install_paso', ['build_paso', 'install_paso_lib'])
894    
895    env.Alias('build_escript', ['install_escript_headers', 'build_escript_lib', 'build_escriptcpp_lib'])
896    env.Alias('install_escript', ['build_escript', 'install_escript_lib', 'install_escriptcpp_lib', 'install_escript_py'])
897    
898    env.Alias('build_pasowrap', ['install_pasowrap_headers', 'build_pasowrap_lib', 'build_pasowrapcpp_lib'])
899    env.Alias('install_pasowrap', ['build_pasowrap', 'install_pasowrap_lib', 'install_pasowrapcpp_lib', 'install_pasowrap_py'])
900    
901    env.Alias('build_dudley', ['install_dudley_headers', 'build_dudley_lib', 'build_dudleycpp_lib'])
902    env.Alias('install_dudley', ['build_dudley', 'install_dudley_lib', 'install_dudleycpp_lib', 'install_dudley_py'])
903    
904    env.Alias('build_finley', ['install_finley_headers', 'build_finley_lib', 'build_finleycpp_lib'])
905    env.Alias('install_finley', ['build_finley', 'install_finley_lib', 'install_finleycpp_lib', 'install_finley_py'])
906    
907    env.Alias('build_ripley', ['install_ripley_headers', 'build_ripley_lib', 'build_ripleycpp_lib'])
908    env.Alias('install_ripley', ['build_ripley', 'install_ripley_lib', 'install_ripleycpp_lib', 'install_ripley_py'])
909    
910    env.Alias('build_weipa', ['install_weipa_headers', 'build_weipa_lib', 'build_weipacpp_lib'])
911    env.Alias('install_weipa', ['build_weipa', 'install_weipa_lib', 'install_weipacpp_lib', 'install_weipa_py'])
912    
913    env.Alias('build_escriptreader', ['install_weipa_headers', 'build_escriptreader_lib'])
914    env.Alias('install_escriptreader', ['build_escriptreader', 'install_escriptreader_lib'])
915    
916    # Now gather all the above into some easy targets: build_all and install_all
917    build_all_list = []
918    build_all_list += ['build_esysUtils']
919    build_all_list += ['build_paso']
920    build_all_list += ['build_escript']
921    build_all_list += ['build_pasowrap']
922    build_all_list += ['build_dudley']
923    build_all_list += ['build_finley']
924    build_all_list += ['build_ripley']
925    build_all_list += ['build_weipa']
926    if not IS_WINDOWS: build_all_list += ['build_escriptreader']
927    if env['usempi']:   build_all_list += ['build_pythonMPI']
928    build_all_list += ['build_escriptconvert']
929    env.Alias('build_all', build_all_list)
930    
931    install_all_list = []
932    install_all_list += ['target_init']
933    install_all_list += ['install_esysUtils']
934    install_all_list += ['install_paso']
935    install_all_list += ['install_escript']
936    install_all_list += ['install_pasowrap']
937    install_all_list += ['install_dudley']
938    install_all_list += ['install_finley']
939    install_all_list += ['install_ripley']
940    install_all_list += ['install_weipa']
941    if not IS_WINDOWS: install_all_list += ['install_escriptreader']
942    install_all_list += ['install_downunder_py']
943    install_all_list += ['install_modellib_py']
944    install_all_list += ['install_pycad_py']
945    if env['usempi']:   install_all_list += ['install_pythonMPI']
946    install_all_list += ['install_escriptconvert']
947    env.Alias('install_all', install_all_list)
948    
949    # Default target is install
950    env.Default('install_all')
951    
952    ################## Targets to build and run the test suite ###################
953    
954    if not env['cppunit']:
955        test_msg = env.Command('.dummy.', None, '@echo "Cannot run C/C++ unit tests, CppUnit not found!";exit 1')
956        env.Alias('run_tests', test_msg)
957    env.Alias('run_tests', ['install_all'])
958    env.Alias('all_tests', ['install_all', 'run_tests', 'py_tests'])
959    env.Alias('build_full',['install_all','build_tests','build_py_tests'])
960    env.Alias('build_PasoTests','$BUILD_DIR/$PLATFORM/paso/profiling/PasoTests')
961    
962    ##################### Targets to build the documentation #####################
963    
964    env.Alias('api_epydoc','install_all')
965    env.Alias('docs', ['examples_tarfile', 'examples_zipfile', 'api_epydoc', 'api_doxygen', 'user_pdf', 'install_pdf', 'cookbook_pdf'])
966    env.Alias('release_prep', ['docs', 'install_all'])
967    
968    if not IS_WINDOWS:
969        try:
970            utest=open('utest.sh','w')
971            utest.write(GroupTest.makeHeader(env['PLATFORM'], prefix))
972            for tests in TestGroups:
973                utest.write(tests.makeString())
974            utest.close()
975            Execute(Chmod('utest.sh', 0o755))
976            print("Generated utest.sh.")
977        except IOError:
978            print("Error attempting to write unittests file.")
979            Exit(1)
980    
981        # delete utest.sh upon cleanup
982        env.Clean('target_init', 'utest.sh')
983    
984        # Make sure that the escript wrapper is in place
985        if not os.path.isfile(os.path.join(env['bininstall'], 'run-escript')):
986            print("Copying escript wrapper.")
987            Execute(Copy(os.path.join(env['bininstall'],'run-escript'), 'bin/run-escript'))
988    
 # Targets  
 env.Default(libinstall)  
 env.Default(incinstall)  
 env.Default(pyinstall)  
 env.Alias('build_tests')  
 env.Alias('run_tests')  
 env.Alias('py_tests')  
 env.Alias('all_tests', ['run_tests', 'py_tests'])  
   
 # Python install - esys __init__.py  
 # This is just an empty file but stills need to be touched so add a special target and Command. Note you can't use the scons Touch() function as it will not  
 # create the file if it doesn't exist  
 env.Command('esys/__init__.py', None, 'touch $TARGET')  
   
 # Allow sconscripts to see the env  
 Export(["env", "incinstall", "libinstall", "pyinstall", "dodebug", "mkl_libs", "scsl_libs", "umf_libs",  
     "boost_lib", "python_lib", "doxygen_path", "epydoc_path", "epydoc_pythonpath", "papi_libs", "cppunit_lib", "sys_libs" ])  
   
 # End initialisation section  
 # Begin configuration section  
 # Insert new components to be build here  
 # FIXME: might be nice to replace this verbosity with a list of targets and some  
 # FIXME: nifty python to create the lengthy but very similar env.Sconscript lines  
 # Third Party libraries  
 env.SConscript(dirs = ['tools/CppUnitTest/src'], build_dir='build/$PLATFORM/tools/CppUnitTest', duplicate=0)  
 # C/C++ Libraries  
 env.SConscript(dirs = ['paso/src'], build_dir='build/$PLATFORM/paso', duplicate=0)  
 env.SConscript(dirs = ['bruce/src'], build_dir='build/$PLATFORM/bruce', duplicate=0)  
 env.SConscript(dirs = ['escript/src'], build_dir='build/$PLATFORM/escript', duplicate=0)  
 env.SConscript(dirs = ['esysUtils/src'], build_dir='build/$PLATFORM/esysUtils', duplicate=0)  
 env.SConscript(dirs = ['finley/src'], build_dir='build/$PLATFORM/finley', duplicate=0)  
 env.SConscript(dirs = ['modellib/py_src'], build_dir='build/$PLATFORM/modellib', duplicate=0)  
   
 # FIXME:need to be incorporated into build system  
 # FIXME: 'pyvisi/SConstruct']  
 # FIXME: 'doc/SConstruct']  
 # FIXME: 'doc/SConstruct']  

Legend:
Removed from v.688  
changed lines
  Added in v.3975

  ViewVC Help
Powered by ViewVC 1.1.26