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

Diff of /branches/diaplayground/SConstruct

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

revision 2132 by jfenwick, Fri Dec 5 00:18:06 2008 UTC revision 4110 by jfenwick, Fri Dec 14 01:21:33 2012 UTC
# Line 1  Line 1 
1    ##############################################################################
 ########################################################  
2  #  #
3  # Copyright (c) 2003-2008 by University of Queensland  # Copyright (c) 2003-2012 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  # finer control over library building, intel aggressive global optimisation    ('dudley_assemble_flags', 'compiler flags for some dudley optimisations', ''),
118  # works with dynamic libraries on windows.    # To enable passing function pointers through python
119    ('share_esysUtils', 'control static or dynamic esysUtils lib', False),    BoolVariable('iknowwhatimdoing', 'Allow non-standard C', False),
120    ('share_paso', 'control static or dynamic paso lib', False)    # 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  
   
 sysheaderopt = ""       # how do we indicate that a header is a system header. Use "" for no action.  
   
 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  
   sysheaderopt      = ""  
 elif env["CC"] == "gcc":  
   # GNU C on any system  
   cc_flags      = "-pedantic -Wall -fPIC -ansi -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER  -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing"  
 #The strict aliasing error occurs for some versions of boost  
 #the long long warning occurs on the Mac  
   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"  
   sysheaderopt      = "-isystem "  
 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      = ""  
   sysheaderopt      = ""  
 elif env["CC"] == "icl":  
   # intel C on Windows, see windows_intelc_options.py for a start  
   pedantic      = ""  
   fatalwarning      = ""  
   sysheaderopt      = ""  
   
   
 # 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  
   
 try: env['ENV']['XAUTHORITY'] = os.environ['XAUTHORITY']  
 except KeyError: pass  
140    
141  try: env['ENV']['HOME'] = os.environ['HOME']  # 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  # Configure for test suite  # PATH is needed so the compiler, linker and tools are found if they are not
145  env.PrependENVPath('PYTHONPATH', prefix)  # in default locations.
146  env.PrependENVPath('LD_LIBRARY_PATH', env['libinstall'])  env = Environment(tools = ['default'], options = vars,
147                      ENV = {'PATH': os.environ['PATH']})
148  env['ENV']['ESCRIPT_ROOT'] = prefix                    
149    
150  ############ Set up paths for Configure() ######################  #set the vars for clang
151    def mkclang(env):
152  # Make a copy of an environment    env['CC']='clang'
153  # Use env.Clone if available, but fall back on env.Copy for older version of scons    env['CXX']='clang++'
154  def clone_env(env):                    
155    if 'Clone' in dir(env): return env.Clone()    # scons-0.98                    
156    else:                   return env.Copy() # scons-0.96  if env['tools_names'] != 'default':
157        zz=env['tools_names']
158        if 'clang' in zz:
159            zz.remove('clang')
160            zz.insert(0, mkclang)
161        env = Environment(tools = ['default'] + env['tools_names'], options = vars,
162                          ENV = {'PATH' : os.environ['PATH']})
163    
164    if options_file:
165        opts_valid=False
166        if 'escript_opts_version' in env.Dictionary() and \
167            int(env['escript_opts_version']) >= REQUIRED_OPTS_VERSION:
168                opts_valid=True
169        if opts_valid:
170            print("Using options in %s." % options_file)
171        else:
172            print("\nOptions file %s" % options_file)
173            print("is outdated! Please update the file by examining one of the TEMPLATE")
174            print("files in the scons/ subdirectory and setting escript_opts_version to %d.\n"%REQUIRED_OPTS_VERSION)
175            Exit(1)
176    
177    # Generate help text (scons -h)
178    Help(vars.GenerateHelpText(env))
179    
180    # Check for superfluous options
181    if len(vars.UnknownVariables())>0:
182        for k in vars.UnknownVariables():
183            print("Unknown option '%s'" % k)
184        Exit(1)
185    
186    #################### Make sure install directories exist #####################
187    
188    env['BUILD_DIR']=Dir(env['build_dir']).abspath
189    prefix=Dir(env['prefix']).abspath
190    env['incinstall'] = os.path.join(prefix, 'include')
191    env['bininstall'] = os.path.join(prefix, 'bin')
192    env['libinstall'] = os.path.join(prefix, 'lib')
193    env['pyinstall']  = os.path.join(prefix, 'esys')
194    if not os.path.isdir(env['bininstall']):
195        os.makedirs(env['bininstall'])
196    if not os.path.isdir(env['libinstall']):
197        os.makedirs(env['libinstall'])
198    if not os.path.isdir(env['pyinstall']):
199        os.makedirs(env['pyinstall'])
200    
201    env.Append(CPPPATH = [env['incinstall']])
202    env.Append(LIBPATH = [env['libinstall']])
203    
204    ################# Fill in compiler options if not set above ##################
205    
206    if env['cc'] != 'default': env['CC']=env['cc']
207    if env['cxx'] != 'default': env['CXX']=env['cxx']
208    
209    # version >=9 of intel C++ compiler requires use of icpc to link in C++
210    # runtimes (icc does not)
211    if not IS_WINDOWS and os.uname()[4]=='ia64' and env['CXX']=='icpc':
212        env['LINK'] = env['CXX']
213    
214    # default compiler/linker options
215    cc_flags = ''
216    cc_optim = ''
217    cc_debug = ''
218    omp_flags = ''
219    omp_ldflags = ''
220    fatalwarning = '' # switch to turn warnings into errors
221    sysheaderopt = '' # how to indicate that a header is a system header
222    
223    # env['CC'] might be a full path
224    cc_name=os.path.basename(env['CC'])
225    
226    if cc_name == 'icc':
227        # Intel compiler
228        # #1875: offsetof applied to non-POD types is nonstandard (in boost)
229        cc_flags    = "-std=c99 -fPIC -w2 -wd1875 -Wno-unknown-pragmas -DBLOCKTIMER -DCORE_ID1"
230        cc_optim    = "-O3 -ftz -fno-alias -ipo -xHost"
231        cc_debug    = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
232        omp_flags   = "-openmp"
233        omp_ldflags = "-openmp -openmp_report=1"
234        fatalwarning = "-Werror"
235    elif cc_name[:3] == 'gcc':
236        # GNU C on any system
237        cc_flags     = "-pedantic -Wall -fPIC -ffast-math -Wno-unknown-pragmas -DBLOCKTIMER  -Wno-sign-compare -Wno-system-headers -Wno-long-long -Wno-strict-aliasing -finline-functions"
238        cc_optim     = "-O3"
239        cc_debug     = "-g -O0 -DDOASSERT -DDOPROF -DBOUNDS_CHECK"
240        omp_flags    = "-fopenmp"
241        omp_ldflags  = "-fopenmp"
242        fatalwarning = "-Werror"
243        sysheaderopt = "-isystem"
244    elif cc_name == 'cl':
245        # Microsoft Visual C on Windows
246        cc_flags     = "/EHsc /MD /GR /wd4068 /D_USE_MATH_DEFINES /DDLL_NETCDF"
247        cc_optim     = "/O2 /Op /W3"
248        cc_debug     = "/Od /RTCcsu /ZI /DBOUNDS_CHECK"
249        fatalwarning = "/WX"
250    elif cc_name == 'icl':
251        # Intel C on Windows
252        cc_flags     = '/EHsc /GR /MD'
253        cc_optim     = '/fast /Oi /W3 /Qssp /Qinline-factor- /Qinline-min-size=0 /Qunroll'
254        cc_debug     = '/Od /RTCcsu /Zi /Y- /debug:all /Qtrapuv'
255        omp_flags    = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
256        omp_ldflags  = '/Qvec-report0 /Qopenmp /Qopenmp-report0 /Qparallel'
257    
258    # set defaults if not otherwise specified
259    if env['cc_flags']    == 'default': env['cc_flags'] = cc_flags
260    if env['cc_optim']    == 'default': env['cc_optim'] = cc_optim
261    if env['cc_debug']    == 'default': env['cc_debug'] = cc_debug
262    if env['omp_flags']   == 'default': env['omp_flags'] = omp_flags
263    if env['omp_ldflags'] == 'default': env['omp_ldflags'] = omp_ldflags
264    if env['cc_extra']  != '': env.Append(CFLAGS = env['cc_extra'])
265    if env['cxx_extra'] != '': env.Append(CXXFLAGS = env['cxx_extra'])
266    if env['ld_extra']  != '': env.Append(LINKFLAGS = env['ld_extra'])
267    
268    if env['BADPYTHONMACROS']: env.Append(CXXFLAGS = ' -DBADPYTHONMACROS')
269    
270    if env['usepython3']:
271        env.Append(CPPDEFINES=['ESPYTHON3'])
272    
273    # set up the autolazy values
274    if env['forcelazy'] == 'on':
275        env.Append(CPPDEFINES=['FAUTOLAZYON'])
276    elif env['forcelazy'] == 'off':
277        env.Append(CPPDEFINES=['FAUTOLAZYOFF'])
278    
279    # set up the collective resolve values
280    if env['forcecollres'] == 'on':
281        env.Append(CPPDEFINES=['FRESCOLLECTON'])
282    elif env['forcecollres'] == 'off':
283        env.Append(CPPDEFINES=['FRESCOLLECTOFF'])
284    
285    # allow non-standard C if requested
286    if env['iknowwhatimdoing']:
287        env.Append(CPPDEFINES=['IKNOWWHATIMDOING'])
288    
289    # Disable OpenMP if no flags provided
290    if env['openmp'] and env['omp_flags'] == '':
291       print("OpenMP requested but no flags provided - disabling OpenMP!")
292       env['openmp'] = False
293    
294    if env['openmp']:
295        env.Append(CCFLAGS = env['omp_flags'])
296        if env['omp_ldflags'] != '': env.Append(LINKFLAGS = env['omp_ldflags'])
297    else:
298        env['omp_flags']=''
299        env['omp_ldflags']=''
300    
301    # add debug/non-debug compiler flags
302    if env['debug']:
303        env.Append(CCFLAGS = env['cc_debug'])
304    else:
305        env.Append(CCFLAGS = env['cc_optim'])
306    
307    # always add cc_flags
308    env.Append(CCFLAGS = env['cc_flags'])
309    
310    # add system libraries
311    env.AppendUnique(LIBS = env['sys_libs'])
312    
313    
314    global_revision=ARGUMENTS.get('SVN_VERSION', None)
315    if global_revision:
316        global_revision = re.sub(':.*', '', global_revision)
317        global_revision = re.sub('[^0-9]', '', global_revision)
318        if global_revision == '': global_revision='-2'
319    else:
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    # the following env variables are exported for the unit tests
346    
347    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    
362  # Add cc option -I<Escript>/trunk/include  try:
363  env.Append(CPPPATH      = [Dir('include')])      env.PrependENVPath(LD_LIBRARY_PATH_KEY, os.environ[LD_LIBRARY_PATH_KEY])
364    except KeyError:
365        pass
366    
367    # these shouldn't be needed
368    #for key in 'C_INCLUDE_PATH','CPLUS_INCLUDE_PATH','LIBRARY_PATH':
369    #    try:
370    #        env['ENV'][key] = os.environ[key]
371    #    except KeyError:
372    #        pass
373    
374  # Add cc option -L<Escript>/trunk/lib  try:
375  env.Append(LIBPATH      = [Dir(env['libinstall'])])      env['ENV']['PYTHONPATH'] = os.environ['PYTHONPATH']
376    except KeyError:
377        pass
378    
379  if env['cc_extra'] != '': env.Append(CCFLAGS = env['cc_extra'])  ######################## Add some custom builders ############################
 if env['ld_extra'] != '': env.Append(LINKFLAGS = env['ld_extra'])  
380    
381  if env['usepedantic']: env.Append(CCFLAGS = pedantic)  if env['pythoncmd']=='python':
382        py_builder = Builder(action = build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)
383    else:
384        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  # MS Windows  runUnitTest_builder = Builder(action = runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)
388  if IS_WINDOWS_PLATFORM:  env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});
   env.PrependENVPath('PATH',    [env['boost_lib_path']])  
   env.PrependENVPath('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']:  runPyUnitTest_builder = Builder(action = runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)
391      env.PrependENVPath('PATH',  [env['netCDF_lib_path']])  env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});
392    
393  env.Append(ARFLAGS = env['ar_flags'])  epstopdfbuilder = Builder(action = eps2pdf, suffix='.pdf', src_suffix='.eps', single_source=True)
394    env.Append(BUILDERS = {'EpsToPDF' : epstopdfbuilder});
395    
396  # Get the global Subversion revision number for getVersion() method  ############################ Dependency checks ###############################
 try:  
    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  ############ numarray (required) ###############################  # Create a Configure() environment to check for compilers and python
399    conf = Configure(env.Clone())
400    
401  try:  ######## Test that the compilers work
402    from numarray import identity  
403  except ImportError:  if 'CheckCC' in dir(conf): # exists since scons 1.1.0
404    print "Cannot import numarray, you need to set your PYTHONPATH"      if not conf.CheckCC():
405    sys.exit(1)          print("Cannot run C compiler '%s' (check config.log)" % (env['CC']))
406            Exit(1)
407  ############ C compiler (required) #############################      if not conf.CheckCXX():
408            print("Cannot run C++ compiler '%s' (check config.log)" % (env['CXX']))
409  # Create a Configure() environment for checking existence of required libraries and headers          Exit(1)
410  conf = Configure(clone_env(env))  else:
411        if not conf.CheckFunc('printf', language='c'):
412  # Test that the compiler is working          print("Cannot run C compiler '%s' (check config.log)" % (env['CC']))
413  if not conf.CheckFunc('printf'):          Exit(1)
414    print "Cannot run C compiler '%s' (or libc is missing)" % (env['CC'])      if not conf.CheckFunc('printf', language='c++'):
415    sys.exit(1)          print("Cannot run C++ compiler '%s' (check config.log)" % (env['CXX']))
416            Exit(1)
417    
418  if conf.CheckFunc('gethostname'):  if conf.CheckFunc('gethostname'):
419    conf.env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])      conf.env.Append(CPPDEFINES = ['HAVE_GETHOSTNAME'])
   
 ############ python libraries (required) #######################  
   
420    
421  if not sysheaderopt =="":  ######## Python headers & library (required)
   conf.env.Append(CCFLAGS=sysheaderopt+env['python_path'])  
 else:  
   conf.env.AppendUnique(CPPPATH     = [env['python_path']])  
   
 conf.env.AppendUnique(LIBPATH       = [env['python_lib_path']])  
 conf.env.AppendUnique(LIBS      = [env['python_libs']])  
422    
423  conf.env.PrependENVPath('LD_LIBRARY_PATH', env['python_lib_path'])  # The wrapper script needs to find these libs  #First we check to see if the config file has specified
424    ##Where to find the filae. Ideally, this should be automatic
425    #But we need to deal with the case where python is not in its INSTALL
426    #Directory
427    # Use the python scons is running
428    if env['pythoncmd']=='python':
429        python_inc_path=sysconfig.get_python_inc()
430        if IS_WINDOWS:
431            python_lib_path=os.path.join(sysconfig.get_config_var('prefix'), 'libs')
432        elif env['PLATFORM']=='darwin':
433            python_lib_path=sysconfig.get_config_var('LIBPL')
434        else:
435            python_lib_path=sysconfig.get_config_var('LIBDIR')
436    
437        #python_libs=[sysconfig.get_config_var('LDLIBRARY')] # only on linux
438        if IS_WINDOWS:
439            python_libs=['python%s%s'%(sys.version_info[0], sys.version_info[1])]
440        else:
441            python_libs=['python'+sysconfig.get_python_version()]
442    
443    #if we want to use a python other than the one scons is running
444    else:
445        initstring='from __future__ import print_function;from distutils import sysconfig;'
446        if env['pythonlibname']!='':
447            python_libs=env['pythonlibname']
448        else:   # work it out by calling python    
449            if IS_WINDOWS:
450                cmd='print("python%s%s"%(sys.version_info[0], sys.version_info[1]))'
451            else:
452                cmd='print("python"+sysconfig.get_python_version())'
453            p=Popen([env['pythoncmd'], '-c', initstring+cmd], stdout=PIPE)
454            python_libs=p.stdout.readline()
455            if env['usepython3']:       # This is to convert unicode str into py2 string
456                python_libs=python_libs.encode() # If scons runs on py3 then this must be rethought
457            p.wait()
458            python_libs=python_libs.strip()
459    
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['pythonincpath']!='':
490        python_inc_path=env['pythonincpath']
491    
492    
493    if sysheaderopt == '':
494        conf.env.AppendUnique(CPPPATH = [python_inc_path])
495    else:
496        conf.env.Append(CCFLAGS = [sysheaderopt, python_inc_path])
497    
498    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  if not conf.CheckCHeader('Python.h'):  if not conf.CheckCHeader('Python.h'):
504    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))
505    sys.exit(1)      Exit(1)
506  if not conf.CheckFunc('Py_Main'):  if not conf.CheckFunc('Py_Exit'):
507    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))
508    sys.exit(1)      Exit(1)
509    
510  ############ boost (required) ##################################  ## reuse conf to check for numpy header (optional)
511    if env['usepython3']:
512  if not sysheaderopt =="":      # FIXME: This is until we can work out how to make the checks in python 3
513    conf.env.Append(CCFLAGS=sysheaderopt+env['boost_path']+'boost')      conf.env['numpy_h']=False
514  else:  else:
515    conf.env.AppendUnique(CPPPATH     = [env['boost_path']])      if conf.CheckCXXHeader(['Python.h','numpy/ndarrayobject.h']):
516            conf.env.Append(CPPDEFINES = ['HAVE_NUMPY_H'])
517  conf.env.AppendUnique(LIBPATH       = [env['boost_lib_path']])          conf.env['numpy_h']=True
518  conf.env.AppendUnique(LIBS      = [env['boost_libs']])      else:
519            conf.env['numpy_h']=False
 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)  
520    
521  # Commit changes to environment  # Commit changes to environment
522  env = conf.Finish()  env = conf.Finish()
523    
524  ############ 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', 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'])  
 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', env['papi_lib_path'])  # The wrapper script needs to find these libs  
   
 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) ####################################  
525    
526  # Start a new configure environment that reflects what we've already found  boost_inc_path,boost_lib_path=findLibWithHeader(env, env['boost_libs'], 'boost/python.hpp', env['boost_prefix'], lang='c++')
527  conf = Configure(clone_env(env))  if sysheaderopt == '':
528        env.AppendUnique(CPPPATH = [boost_inc_path])
529    else:
530        # This is required because we can't -isystem /usr/include since it breaks
531        # std includes
532        if os.path.normpath(boost_inc_path) == '/usr/include':
533            conf.env.Append(CCFLAGS=[sysheaderopt, os.path.join(boost_inc_path,'boost')])
534        else:
535            env.Append(CCFLAGS=[sysheaderopt, boost_inc_path])
536    
537    env.AppendUnique(LIBPATH = [boost_lib_path])
538    env.AppendUnique(LIBS = env['boost_libs'])
539    env.PrependENVPath(LD_LIBRARY_PATH_KEY, boost_lib_path)
540    
541    ######## numpy (required)
542    
543    if not detectModule(env, 'numpy'):
544        print("Cannot import numpy. If it is installed try setting your PYTHONPATH and probably %s"%LD_LIBRARY_PATH_KEY)
545        Exit(1)
546    
547  if env['usemkl']:  ######## CppUnit (required for tests)
   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  
548    
549  if env['usemkl'] and not conf.CheckCHeader('mkl_solver.h'): env['usemkl'] = 0  try:
550  if env['usemkl'] and not conf.CheckFunc('pardiso_'): env['usemkl'] = 0      cppunit_inc_path,cppunit_lib_path=findLibWithHeader(env, env['cppunit_libs'], 'cppunit/TestFixture.h', env['cppunit_prefix'], lang='c++')
551        env.AppendUnique(CPPPATH = [cppunit_inc_path])
552  # Add MKL to environment env if it was found      env.AppendUnique(LIBPATH = [cppunit_lib_path])
553  if env['usemkl']:      env.PrependENVPath(LD_LIBRARY_PATH_KEY, cppunit_lib_path)
554    env = conf.Finish()      env['cppunit']=True
555    env.Append(CPPDEFINES = ['MKL'])  except:
556  else:      env['cppunit']=False
   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', 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  
   
 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()  
557    
558  ############ Add the compiler flags ############################  ######## sympy (optional)
559    
560  # Enable debug by choosing either cc_debug or cc_optim  if detectModule(env, 'sympy'):
561  if env['usedebug']:      env['sympy'] = True
   env.Append(CCFLAGS        = env['cc_debug'])  
   env.Append(CCFLAGS        = env['omp_debug'])  
562  else:  else:
563    env.Append(CCFLAGS        = env['cc_optim'])      print("Cannot import sympy. Symbolic toolbox and nonlinear PDEs will not be available.")
564    env.Append(CCFLAGS        = env['omp_optim'])      env['sympy'] = False
565    
566  # Always use cc_flags  ######## netCDF (optional)
567  env.Append(CCFLAGS      = env['cc_flags'])  
568  env.Append(LIBS         = [env['omp_libs']])  netcdf_inc_path=''
569    netcdf_lib_path=''
570  ############ MPI (optional) ####################################  if env['netcdf']:
571        netcdf_inc_path,netcdf_lib_path=findLibWithHeader(env, env['netcdf_libs'], 'netcdf.h', env['netcdf_prefix'], lang='c++')
572  # Create a modified environment for MPI programs (identical to env if usempi=no)      env.AppendUnique(CPPPATH = [netcdf_inc_path])
573  env_mpi = clone_env(env)      env.AppendUnique(LIBPATH = [netcdf_lib_path])
574        env.AppendUnique(LIBS = env['netcdf_libs'])
575  # Start a new configure environment that reflects what we've already found      env.PrependENVPath(LD_LIBRARY_PATH_KEY, netcdf_lib_path)
576  conf = Configure(clone_env(env_mpi))      env.Append(CPPDEFINES = ['USE_NETCDF'])
577    
578  if env_mpi['usempi']:  ######## PAPI (optional)
579    conf.env.AppendUnique(CPPPATH = [env_mpi['mpi_path']])  
580    conf.env.AppendUnique(LIBPATH = [env_mpi['mpi_lib_path']])  papi_inc_path=''
581    conf.env.AppendUnique(LIBS    = [env_mpi['mpi_libs']])  papi_lib_path=''
582    conf.env.PrependENVPath('LD_LIBRARY_PATH', env['mpi_lib_path'])   # The wrapper script needs to find these libs  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 env_mpi['usempi'] and not conf.CheckCHeader('mpi.h'): env_mpi['usempi'] = 0  ######## gmsh (optional, for tests)
 if env_mpi['usempi'] and not conf.CheckFunc('MPI_Init'): env_mpi['usempi'] = 0  
709    
710  # Add MPI to environment env_mpi if it was found  try:
711  if env_mpi['usempi']:      p=Popen(['gmsh', '-info'], stderr=PIPE)
712    env_mpi = conf.Finish()      _,e=p.communicate()
713    env_mpi.Append(CPPDEFINES = ['PASO_MPI', 'MPI_NO_CPPBIND', env_mpi['MPICH_IGNORE_CXX_SEEK']])      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:  else:
724    conf.Finish()      env['pdflatex']=False
   
 env['usempi'] = env_mpi['usempi']  
725    
726  ############ ParMETIS (optional) ###############################  ######################## Summarize our environment ###########################
727    
728  # Start a new configure environment that reflects what we've already found  # keep some of our install paths first in the list for the unit tests
729  conf = Configure(clone_env(env_mpi))  env.PrependENVPath(LD_LIBRARY_PATH_KEY, env['libinstall'])
730    env.PrependENVPath('PYTHONPATH', prefix)
731  if not env_mpi['usempi']: env_mpi['useparmetis'] = 0  env['ENV']['ESCRIPT_ROOT'] = prefix
   
 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', env['parmetis_lib_path'])  # The wrapper script needs to find these libs  
   
 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  
732    
733  # Add ParMETIS to environment env_mpi if it was found  if not env['verbose']:
734  if env_mpi['useparmetis']:      env['CCCOMSTR'] = "Compiling $TARGET"
735    env_mpi = conf.Finish()      env['CXXCOMSTR'] = "Compiling $TARGET"
736    env_mpi.Append(CPPDEFINES = ['USE_PARMETIS'])      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:  else:
757    conf.Finish()      print("             MPI:  DISABLED")
758    if env['uselapack']:
759  env['useparmetis'] = env_mpi['useparmetis']      print("          LAPACK:  YES (flavour: %s)"%env['lapack'])
760    else:
761  ############ Now we switch on Warnings as errors ###############      print("          LAPACK:  DISABLED")
762    d_list=[]
763  #this needs to be done after configuration because the scons test files have warnings in them  e_list=[]
764    for i in 'debug','openmp','boomeramg','mkl','netcdf','papi','parmetis','silo','sympy','umfpack','visit','vsl_random':
765  if ((fatalwarning != "") and (env['usewarnings'])):      if env[i]: e_list.append(i)
766    env.Append(CCFLAGS        = fatalwarning)      else: d_list.append(i)
767    env_mpi.Append(CCFLAGS        = fatalwarning)  for i in e_list:
768        print("%16s:  YES"%i)
769  ############ Summarize our environment #########################  for i in d_list:
770        print("%16s:  DISABLED"%i)
771  print ""  if env['cppunit']:
772  print "Summary of configuration (see ./config.log for information)"      print("         CppUnit:  FOUND")
773  print " Using python libraries"  else:
774  print " Using numarray"      print("         CppUnit:  NOT FOUND")
775  print " Using boost"  if env['gmsh']=='m':
776  if env['usenetcdf']: print "    Using NetCDF"      print("            gmsh:  FOUND, MPI-ENABLED")
777  else: print "   Not using NetCDF"  elif env['gmsh']=='s':
778  if env['usevtk']: print "   Using VTK"      print("            gmsh:  FOUND")
779  else: print "   Not using VTK"  else:
780  if env['usemkl']: print "   Using MKL"      print("            gmsh:  NOT FOUND")
781  else: print "   Not using MKL"  if env['numpy_h']:
782  if env['useumfpack']: print "   Using UMFPACK"      print("   numpy headers:  FOUND")
783  else: print "   Not using UMFPACK"  else:
784  if env['useopenmp']: print "    Using OpenMP"      print("   numpy headers:  NOT FOUND")
785  else: print "   Not using OpenMP"  print("   vsl_random:  %s"%env['vsl_random'])
786  if env['usempi']: print "   Using MPI"      
787  else: print "   Not using MPI"  if ((fatalwarning != '') and (env['werror'])):
788  if env['useparmetis']: print "  Using ParMETIS"      print("  Treating warnings as errors")
789  else: print "   Not using ParMETIS (requires MPI)"  else:
790  if env['usepapi']: print "  Using PAPI"      print("  NOT treating warnings as errors")
791  else: print "   Not using PAPI"  print("")
792  if env['usedebug']: print " Compiling for debug"  
793  else: print "   Not compiling for debug"  ####################### Configure the subdirectories #########################
794  print " Installing in", prefix  
795  if ((fatalwarning != "") and (env['usewarnings'])): print " Treating warnings as errors"  from grouptest import *
796  else: print "   Not treating warnings as errors"  
797  print ""  TestGroups=[]
798    
799  ############ Delete option-dependent files #####################  # keep an environment without warnings-as-errors
800    dodgy_env=env.Clone()
801  Execute(Delete(env['libinstall'] + "/Compiled.with.debug"))  
802  Execute(Delete(env['libinstall'] + "/Compiled.with.mpi"))  # now add warnings-as-errors flags. This needs to be done after configuration
803  Execute(Delete(env['libinstall'] + "/Compiled.with.openmp"))  # because the scons test files have warnings in them
804  if not env['usempi']: Execute(Delete(env['libinstall'] + "/pythonMPI"))  if ((fatalwarning != '') and (env['werror'])):
805        env.Append(CCFLAGS = fatalwarning)
 ############ Add some custom builders ##########################  
   
 py_builder = Builder(action = scons_extensions.build_py, suffix = '.pyc', src_suffix = '.py', single_source=True)  
 env.Append(BUILDERS = {'PyCompile' : py_builder});  
   
 runUnitTest_builder = Builder(action = scons_extensions.runUnitTest, suffix = '.passed', src_suffix=env['PROGSUFFIX'], single_source=True)  
 env.Append(BUILDERS = {'RunUnitTest' : runUnitTest_builder});  
   
 runPyUnitTest_builder = Builder(action = scons_extensions.runPyUnitTest, suffix = '.passed', src_suffic='.py', single_source=True)  
 env.Append(BUILDERS = {'RunPyUnitTest' : runPyUnitTest_builder});  
   
 ############ Build the subdirectories ##########################  
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 665  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('api_epydoc','install_all')
968    env.Alias('docs', ['examples_tarfile', 'examples_zipfile', 'sphinxdoc', 'api_doxygen', 'user_pdf', 'install_pdf', 'cookbook_pdf', 'inversion_pdf'])
969    env.Alias('release_prep', ['docs', 'install_all'])
970    
971    
972    # The test scripts are always generated, this target allows us to
973    # generate the testscripts without doing a full build
974    env.Alias('testscripts',[])
975    
976    if not IS_WINDOWS:
977        try:
978            utest=open('utest.sh','w')
979            utest.write(GroupTest.makeHeader(env['PLATFORM'], prefix, False))
980            for tests in TestGroups:
981                utest.write(tests.makeString())
982            utest.close()
983            Execute(Chmod('utest.sh', 0o755))
984            print("Generated utest.sh.")
985            # This version contains only python tests - I want this to be usable
986            # From a binary only install if you have the test files
987            utest=open('itest.sh','w')
988            utest.write(GroupTest.makeHeader(env['PLATFORM'], prefix, True))
989            for tests in TestGroups:
990              if tests.exec_cmd=='$PYTHONRUNNER ':
991                utest.write(tests.makeString())
992            utest.close()
993            Execute(Chmod('itest.sh', 0o755))
994            print("Generated itest.sh.")        
995        except IOError:
996            print("Error attempting to write unittests file.")
997            Exit(1)
998    
999        # delete utest.sh upon cleanup
1000        env.Clean('target_init', 'utest.sh')
1001        env.Clean('target_init', 'itest.sh')
1002    
1003        # Make sure that the escript wrapper is in place
1004        if not os.path.isfile(os.path.join(env['bininstall'], 'run-escript')):
1005            print("Copying escript wrapper.")
1006            Execute(Copy(os.path.join(env['bininstall'],'run-escript'), 'bin/run-escript'))
1007    

Legend:
Removed from v.2132  
changed lines
  Added in v.4110

  ViewVC Help
Powered by ViewVC 1.1.26