/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

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

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

Legend:
Removed from v.805  
changed lines
  Added in v.3942

  ViewVC Help
Powered by ViewVC 1.1.26