/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

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

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

Legend:
Removed from v.2455  
changed lines
  Added in v.3892

  ViewVC Help
Powered by ViewVC 1.1.26