/[escript]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

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

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

Legend:
Removed from v.1705  
changed lines
  Added in v.3506

  ViewVC Help
Powered by ViewVC 1.1.26