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

Diff of /branches/diaplayground/SConstruct

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26