/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26