/[escript]/branches/diaplayground/SConstruct
ViewVC logotype

Diff of /branches/diaplayground/SConstruct

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

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

Legend:
Removed from v.751  
changed lines
  Added in v.4167

  ViewVC Help
Powered by ViewVC 1.1.26