cantera/SConstruct
Ray Speth 0982600bcd Better default behavior for building the Matlab toolbox with SCons
If Matlab is found on the path, build the toolbox by default,
otherwise skip it. If the toolbox is required and Matlab can't be
found, exit with an error.
2011-12-14 03:53:56 +00:00

416 lines
15 KiB
Python

from buildutils import *
import subst
import platform, sys, os
env = Environment(tools = ['default', 'textfile'])
env.AddMethod(RecursiveInstall)
subst.TOOL_SUBST(env)
# ******************************************************
# *** Set system-dependent defaults for some options ***
# ******************************************************
if os.name == 'posix':
defaultPrefix = '/usr/local'
elif os.name == 'nt':
defaultPrefix = os.environ['ProgramFiles']
# **************************************
# *** Read user-configurable options ***
# **************************************
opts = Variables('cantera.conf')
opts.AddVariables(
PathVariable('prefix', 'Where to install Cantera',
defaultPrefix, PathVariable.PathIsDirCreate),
EnumVariable('python_package', 'build python package?', 'default',
('full', 'minimal', 'none','default')),
PathVariable('python_cmd', 'Path to the python interpreter', sys.executable),
EnumVariable('python_array', 'Which Python array package to use',
'numpy', ('numpy', 'numarray', 'numeric')),
PathVariable('python_array_home',
'Location for array package (e.g. if installed with --home)',
'', PathVariable.PathAccept),
PathVariable('cantera_python_home', 'where to install the python package',
'', PathVariable.PathAccept),
EnumVariable('matlab_toolbox', '', 'default', ('y', 'n', 'default')),
PathVariable('matlab_cmd', 'Path to the matlab executable',
'matlab', PathVariable.PathAccept),
BoolVariable('f90_interface', 'Build Fortran90 interface?', False),
PathVariable('f90', 'Fortran compiler',
'gfortran', PathVariable.PathAccept),
('f90flags', '', '-O3'),
('purify', '', ''),
('user_src_dir', '', 'Cantera/user'),
BoolVariable('debug', '', False), # ok
BoolVariable('with_lattice_solid', '', True), # ok
BoolVariable('with_metal', '', True), # ok
BoolVariable('with_stoich_substance', '', True), # ok
BoolVariable('with_semiconductor', '', True), # ??
BoolVariable('with_adsorbate', '', True),
BoolVariable('with_spectra', '', True),
BoolVariable('with_pure_fluids', '', True),
BoolVariable('with_ideal_solutions', '', True), # ok
BoolVariable('with_electrolytes', '', True), # ok
BoolVariable('with_prime', '', False), # ok
BoolVariable('with_h298modify_capability', '', False), # ok
BoolVariable('enable_ck', '', True),
BoolVariable('with_kinetics', '', True),
BoolVariable('with_hetero_kinetics', '', True),
BoolVariable('with_reaction_paths', '', True),
BoolVariable('with_vcsnonideal', '', False),
BoolVariable('enable_transport', '', True),
BoolVariable('enable_equil', '', True),
BoolVariable('enable_reactors', '', True),
BoolVariable('enable_flow1d', '', True),
BoolVariable('enable_solvers', '', True),
BoolVariable('enable_rxnpath', '', True),
BoolVariable('enable_tpx', '', True),
BoolVariable('with_html_log_files', '', True),
EnumVariable('use_sundials', '', 'default', ('default', 'y', 'n')),
EnumVariable('sundials_version' ,'', '2.4', ('2.2','2.3','2.4')),
PathVariable('sundials_include' ,'', ''),
PathVariable('sundials_libdir', '', ''),
('blas_lapack_libs', '', ''), # 'lapack,blas' or 'lapack,f77blas,cblas,atlas' etc.
('blas_lapack_dir', '', ''), # '/usr/lib/lapack' etc
EnumVariable('lapack_names', '', 'lower', ('lower','upper')),
BoolVariable('lapack_ftn_trailing_underscore', '', True),
BoolVariable('lapack_ftn_string_len_at_end', '', True),
('bitcompile', '', ''), # '32' or '64'
('CXX', '', env['CXX']),
('CC', '', env['CC']),
('CXXFLAGS', '', '-O3 -Wall'),
BoolVariable('build_thread_safe', '', False),
PathVariable('boost_inc_dir', '', '/usr/include/'),
PathVariable('boost_lib_dir', '', '/usr/lib/'),
('boost_thread_lib', '', 'boost_thread'),
BoolVariable('build_with_f2c', '', True),
('F77', '', env['F77']),
('F77FLAGS', '', '-O3'),
('F90', '', env['F90']),
('F90FLAGS', '', '-O3'),
('install_bin', '', 'config/install-sh'),
('graphvisdir', '' ,''),
('ct_shared_lib', '', 'clib'),
('rpfont', '', 'Helvetica'),
('cantera_version', '', '1.8.x')
# These variables shouldn't be necessary any more...
# ('cxx_ext', '', 'cpp'),
# ('f77_ext', '', 'f'),
# ('f90_ext', '', 'f90'),
# ('exe_ext', '', ''),
# ('lcxx_end_libs', '-lm'),
# ('pic', '', '-fPIC'),
# ('shared', '', '-dynamic'),
# ('lfort_flags', '', '-L/usr/local/lib'),
# ('AR', '', env['AR']),
# ('ARFLAGS', '', env['ARFLAGS']), # ('archive', '', 'ar ruv'),
# ('ranlib', '', 'ranlib'),
)
opts.Update(env)
opts.Save('cantera.conf', env)
# ********************************************
# *** Configure system-specific properties ***
# ********************************************
env['OS'] = platform.system()
if env['F90'] == 'gfortran':
env['FORTRANMODDIRPREFIX'] = '-J'
elif env['F90'] == 'g95':
env['FORTRANMODDIRPREFIX'] = '-fmod='
elif env['F90'] == 'ifort':
env['FORTRANMODDIRPREFIX'] = '-module '
env['FORTRANMODDIR'] = '${TARGET.dir}'
conf = Configure(env)
env['HAS_SSTREAM'] = conf.CheckCXXHeader('sstream', '<>')
env = conf.Finish()
if env['cantera_python_home'] == '' and env['prefix'] != defaultPrefix:
env['cantera_python_home'] = env['prefix']
if env['python_package'] in ('full','default'):
# Test to see if we can import the specified array module
warnNoPython = False
if env['python_array_home']:
sys.path.append(env['python_array_home'])
try:
__import__(env['python_array'])
print """INFO: Building the full Python package using %s.""" % env['python_array']
env['python_package'] = 'full'
except ImportError:
if env['python_package'] == 'full':
print ("""ERROR: Unable to find the array package """
"""'%s' required by the full Python package.""" % env['python_array'])
sys.exit(1)
else:
print ("""WARNING: Not building the full Python package """
""" because the array package '%s' could not be found.""" % env['python_array'])
warnNoPython = True
env['python_package'] = 'minimal'
if env['matlab_toolbox'] == 'y' and which(env['matlab_cmd']) is None:
print """ERROR: Unable to find the Matlab executable '%s'""" % env['matlab_cmd']
sys.exit(1)
elif env['matlab_toolbox'] == 'default':
cmd = which(env['matlab_cmd'])
if cmd is not None:
env['matlab_toolbox'] = 'y'
print """INFO: Building the Matlab toolbox using '%s'""" % cmd
else:
print """INFO: Skipping compilation of the Matlab toolbox. """
# **************************************
# *** Set options needed in config.h ***
# **************************************
configh = {'CANTERA_VERSION': quoted(env['cantera_version']),
}
# Conditional defines
def cdefine(definevar, configvar, comp=True, value=1):
if env.get(configvar) == comp:
configh[definevar] = value
else:
configh[definevar] = None
cdefine('DEBUG_MODE', 'debug')
cdefine('PURIFY_MODE', 'purify')
# Need to test all of these to see what platform.system() returns
configh['SOLARIS'] = 1 if env['OS'] == 'Solaris' else None
configh['DARWIN'] = 1 if env['OS'] == 'Darwin' else None
configh['CYGWIN'] = 1 if env['OS'] == 'Cygwin' else None
configh['WINMSVC'] = 1 if env['OS'] == 'Windows' else None
cdefine('NEEDS_GENERIC_TEMPL_STATIC_DECL', 'OS', 'Solaris')
cdefine('HAS_NUMPY', 'python_array', 'numpy')
cdefine('HAS_NUMARRAY', 'python_array', 'numarray')
cdefine('HAS_NUMERIC', 'python_array', 'numeric')
cdefine('HAS_NO_PYTHON', 'python_package', 'none')
configh['PYTHON_EXE'] = quoted(env['python_cmd']) if env['python_package'] != 'none' else None
cdefine('HAS_SUNDIALS', 'use_sundials', 'y')
if env['use_sundials']:
cdefine('SUNDIALS_VERSION_22', 'sundials_version', '2.2')
cdefine('SUNDIALS_VERSION_23', 'sundials_version', '2.3')
cdefine('SUNDIALS_VERSION_24', 'sundials_version', '2.4')
cdefine('WITH_ELECTROLYTES', 'with_electrolytes')
cdefine('WITH_IDEAL_SOLUTIONS', 'with_ideal_solutions')
cdefine('WITH_LATTICE_SOLID', 'with_lattice_solid')
cdefine('WITH_METAL', 'with_metal')
cdefine('WITH_STOICH_SUBSTANCE', 'with_stoich_substance')
cdefine('WITH_SEMICONDUCTOR', 'with_semiconductor')
cdefine('WITH_PRIME', 'with_prime')
cdefine('H298MODIFY_CAPABILITY', 'with_n298modify_capability')
cdefine('WITH_PURE_FLUIDS', 'with_pure_fluids')
cdefine('INCL_PURE_FLUIDS', 'with_pure_fluids') # TODO: fix redundancy
cdefine('WITH_HTML_LOGS', 'with_html_log_files')
cdefine('WITH_VCSNONIDEAL', 'with_vcsnonideal')
cdefine('LAPACK_FTN_STRING_LEN_AT_END', 'lapack_ftn_string_len_at_end')
cdefine('LAPACK_FTN_TRAILING_UNDERSCORE', 'lapack_ftn_trailing_underscore')
cdefine('FTN_TRAILING_UNDERSCORE', 'lapack_ftn_trailing_underscore')
cdefine('LAPACK_NAMES_LOWERCASE', 'lapack_names', 'lower')
configh['RXNPATH_FONT'] = quoted(env['rpfont'])
cdefine('THREAD_SAFE_CANTERA', 'build_thread_safe')
cdefine('HAS_SSTREAM', 'HAS_SSTREAM')
configh['CANTERA_DATA'] = quoted(os.path.join(env['prefix'], 'data'))
config_h = env.Command('config.h', 'config.h.in.scons', ConfigBuilder(configh))
env.AlwaysBuild(config_h)
# **********************************************
# *** Set additional configuration variables ***
# **********************************************
if env['blas_lapack_libs'] == '':
# External BLAS/LAPACK were not given, so we need to compile them
env['BUILD_BLAS_LAPACK'] = True
env['blas_lapack_libs'] = ['ctlapack', 'ctblas']
else:
ens['blas_lapack_libs'] = ','.split(env['blas_lapack_libs'])
if env['use_sundials'] == 'y' and env['sundials_include']:
env.Append(CPPPATH=env['sundials_include'])
if env['use_sundials'] == 'y' and env['sundials_libdir']:
env.Append(LIBPATH=env['sundials_libdir'])
env['ct_libdir'] = pjoin(env['prefix'], 'lib')
env['ct_bindir'] = pjoin(env['prefix'], 'bin')
env['ct_incdir'] = pjoin(env['prefix'], 'include', 'cantera')
env['ct_incroot'] = pjoin(env['prefix'], 'include')
env['ct_datadir'] = pjoin(env['prefix'], 'data')
env['ct_demodir'] = pjoin(env['prefix'], 'demos')
env['ct_templdir'] = pjoin(env['prefix'], 'templates')
env['ct_tutdir'] = pjoin(env['prefix'], 'tutorials')
env['ct_docdir'] = pjoin(env['prefix'], 'doc')
env['ct_dir'] = env['prefix']
env['ct_mandir'] = pjoin(env['prefix'], 'man1')
env['ct_matlab_dir'] = pjoin(env['prefix'], 'matlab', 'toolbox')
# *********************
# *** Build Cantera ***
# *********************
buildDir = 'build'
buildTargets = []
installTargets = []
demoTargets = []
env.SConsignFile()
env.Append(CPPPATH=[Dir(os.getcwd()),
Dir('build/include/cantera/kernel'),
Dir('build/include/cantera'),
Dir('build/include')],
LIBPATH=[Dir('build/lib')],
CCFLAGS=['-fPIC'],
FORTRANFLAGS=['-fPIC'],
F90FLAGS=['-fPIC'])
# Put headers in place
for header in mglob(env, 'Cantera/cxx/include', 'h'):
header = env.Command('build/include/cantera/%s' % header.name, header,
Copy('$TARGET', '$SOURCE'))
buildTargets.extend(header)
inst = env.Install('$ct_incdir', header)
installTargets.extend(inst)
for header in mglob(env, 'Cantera/clib/src', 'h'):
hcopy = env.Command('build/include/cantera/clib/%s' % header.name, header,
Copy('$TARGET', '$SOURCE'))
buildTargets.append(header)
inst = env.Install(pjoin('$ct_incdir','clib'), header)
installTargets.extend(inst)
### List of libraries needed to link to Cantera ###
linkLibs = ['clib','oneD','zeroD','equil','kinetics','transport',
'thermo','ctnumerics','ctmath','tpx',
'ctspectra','converters','ctbase']
if env['use_sundials']:
linkLibs.extend(('sundials_cvodes','sundials_nvecserial'))
linkLibs.extend(env['blas_lapack_libs'])
if env['build_with_f2c']:
linkLibs.append('ctf2c')
else:
linkLibs.append('gfortran')
env['cantera_libs'] = linkLibs
configh = env.Command('build/include/cantera/config.h', 'config.h', Copy('$TARGET', '$SOURCE'))
inst = env.Install('$ct_incdir', configh)
installTargets.extend(inst)
# Add targets from the SConscript files in the various subdirectories
Export('env', 'buildDir', 'buildTargets', 'installTargets', 'demoTargets')
VariantDir('build/ext', 'ext', duplicate=0)
SConscript('build/ext/SConscript')
VariantDir('build/kernel', 'Cantera/src', duplicate=0)
SConscript('build/kernel/SConscript')
VariantDir('build/interfaces/clib', 'Cantera/clib', duplicate=0)
SConscript('build/interfaces/clib/SConscript')
VariantDir('build/interfaces/cxx', 'Cantera/cxx', duplicate=0)
SConscript('build/interfaces/cxx/SConscript')
if env['f90_interface']:
VariantDir('build/interfaces/fortran/', 'Cantera/fortran', duplicate=1)
SConscript('build/interfaces/fortran/SConscript')
if env['python_package'] in ('full','minimal'):
SConscript('Cantera/python/SConscript')
if env['matlab_toolbox'] == 'y':
SConscript('Cantera/matlab/SConscript')
VariantDir('build/tools', 'tools', duplicate=0)
SConscript('build/tools/SConscript')
# Data files
inst = env.Install('$ct_datadir', mglob(env, pjoin('data','inputs'), 'cti', 'xml'))
installTargets.extend(inst)
# Install exp3to2.sh (used by some of the tests)
inst = env.Install('$ct_bindir', pjoin('bin', 'exp3to2.sh'))
installTargets.extend(inst)
### Meta-targets ###
build_demos = Alias('demos', demoTargets)
def postBuildMessage(target, source, env):
print "**************************************************************"
print "Compiliation complete. Type '[sudo] scons install' to install."
print "**************************************************************"
finish_build = env.Command('finish_build', [], postBuildMessage)
env.Depends(finish_build, buildTargets)
build_cantera = Alias('build', finish_build)
Default('build')
def postInstallMessage(target, source, env):
v = sys.version_info
env['python_module_loc'] = pjoin(
env['prefix'], 'lib', 'python%i.%i' % v[:2], 'site-packages')
print """
Cantera has been successfully installed.
File locations:
applications %(ct_bindir)s
library files %(ct_libdir)s
C++ headers %(ct_incdir)s
demos %(ct_demodir)s
data files %(ct_datadir)s""" % env
if env['python_package'] == 'full':
print """
Python package %(python_module_loc)s""" % env
elif warnNoPython:
print """
#################################################################
WARNING: the Cantera Python package was not installed because a
suitable array package (e.g. numpy) could not be found.
#################################################################"""
if env['matlab_toolbox'] == 'y':
print """
Matlab toolbox %(ct_matlab_dir)s
Matlab demos %(ct_demodir)s/matlab
Matlab tutorials %(ct_tutdir)s/matlab
An m-file to set the correct matlab path for Cantera is at:
%(prefix)s/matlab/ctpath.m""" % env
print """
setup script %(ct_bindir)s/setup_cantera
The setup script configures the environment for Cantera. It is
recommended that you run this script by typing:
source %(ct_bindir)s/setup_cantera
before using Cantera, or else include its contents in your shell
login script.
""" % env
finish_install = env.Command('finish_install', [], postInstallMessage)
env.Depends(finish_install, installTargets)
install_cantera = Alias('install', finish_install)