~vcs-imports/escript-finley/trunk

« back to all changes in this revision

Viewing changes to SConstruct

  • Committer: jfenwick
  • Date: 2010-10-11 01:48:14 UTC
  • Revision ID: svn-v4:77569008-7704-0410-b7a0-a92fef0b09fd:trunk:3259
Merging dudley and scons updates from branches

Show diffs side-by-side

added added

removed removed

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