Use the Cython module from the Python installation specified by 'python_cmd', rather than the Python installation that is running SCons. This allows complilation of Cantera for Python versions that aren't supported by SCons (e.g. Python 3.4).
142 lines
6.1 KiB
Python
142 lines
6.1 KiB
Python
"""Cython-based Python Module"""
|
|
from buildutils import *
|
|
|
|
Import('env', 'build', 'install')
|
|
|
|
localenv = env.Clone()
|
|
|
|
cythonized = localenv.Command(
|
|
'cantera/_cantera.cpp',
|
|
'cantera/_cantera.pyx',
|
|
'''${python_cmd} -c "import Cython.Build; Cython.Build.cythonize('${SOURCE}')"''')
|
|
|
|
for f in mglob(localenv, 'cantera', 'pyx', 'pxd'):
|
|
localenv.Depends(cythonized, f)
|
|
|
|
for line in open('cantera/_cantera.pxd'):
|
|
m = re.search(r'from "(cantera.*?)"', line)
|
|
if m:
|
|
localenv.Depends('cantera/_cantera.cpp', '#include/' + m.group(1))
|
|
|
|
dataFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/data',
|
|
'#build/data')
|
|
build(dataFiles)
|
|
|
|
testFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/test/data',
|
|
'#test/data')
|
|
build(testFiles)
|
|
|
|
for f in ['inputs/h2o2.inp', 'inputs/gri30.inp', 'transport/gri30_tran.dat']:
|
|
inp = build(localenv.Install('#interfaces/cython/cantera/test/data/', '#data/' + f))
|
|
testFiles.append(inp)
|
|
|
|
# Get information needed to build the Python module
|
|
script = '\n'.join(("from distutils.sysconfig import *",
|
|
"import numpy",
|
|
"print(get_config_var('EXT_SUFFIX') or get_config_var('SO'))",
|
|
"print(get_config_var('INCLUDEPY'))",
|
|
"print(get_config_var('LDLIBRARY'))",
|
|
"print(get_config_var('prefix'))",
|
|
"print(get_python_version())",
|
|
"print(numpy.get_include())"))
|
|
info = getCommandOutput(localenv['python_cmd'], '-c', script)
|
|
module_ext, inc, pylib, prefix, py_version, numpy_include = info.splitlines()[-6:]
|
|
localenv.Prepend(CPPPATH=[Dir('#include'), inc, numpy_include])
|
|
localenv.Prepend(LIBS=localenv['cantera_libs'])
|
|
if localenv['OS'] == 'Darwin':
|
|
localenv.Append(LINKFLAGS='-undefined dynamic_lookup')
|
|
elif localenv['OS'] == 'Windows':
|
|
localenv.Append(LIBPATH=prefix+'/libs')
|
|
if localenv['toolchain'] == 'mingw':
|
|
localenv.Append(LIBS='python{}'.format(py_version.replace('.','')))
|
|
if localenv['OS_BITS'] == 64:
|
|
localenv.Append(CPPDEFINES='MS_WIN64')
|
|
# fix for http://bugs.python.org/issue11566
|
|
localenv.Append(CPPDEFINES={'_hypot':'hypot'})
|
|
elif localenv['OS'] == 'Cygwin':
|
|
# extract 'pythonX.Y' from 'libpythonX.Y.dll.a'
|
|
localenv.Append(LIBS=pylib[3:-6])
|
|
|
|
# Build the Python module
|
|
obj = localenv.SharedObject('#build/temp-py/_cantera', 'cantera/_cantera.cpp')
|
|
ext = localenv.LoadableModule('#build/python/cantera/_cantera{}'.format(module_ext),
|
|
obj, LIBPREFIX='', SHLIBSUFFIX=module_ext,
|
|
SHLIBPREFIX='', LIBSUFFIXES=[module_ext])
|
|
localenv['py_extension'] = ext[0].name
|
|
|
|
localenv.SubstFile('setup.py', 'setup.py.in')
|
|
build_cmd = ('cd interfaces/cython &&'
|
|
' $python_cmd_esc setup.py build --build-lib=../../build/python')
|
|
mod = build(localenv.Command('#build/python/cantera/__init__.py', 'setup.py',
|
|
build_cmd))
|
|
env['python_module'] = mod
|
|
env['python_extension'] = ext
|
|
|
|
localenv.Depends(mod, ext)
|
|
localenv.Depends(mod, dataFiles + testFiles)
|
|
localenv.Depends(ext, localenv['cantera_staticlib'])
|
|
|
|
for f in (mglob(localenv, 'cantera', 'py') +
|
|
mglob(localenv, 'cantera/test', 'py') +
|
|
mglob(localenv, 'cantera/examples/tutorial', 'py') +
|
|
mglob(localenv, 'cantera/examples/equilibrium', 'py') +
|
|
mglob(localenv, 'cantera/examples/kinetics', 'py') +
|
|
mglob(localenv, 'cantera/examples/transport', 'py') +
|
|
mglob(localenv, 'cantera/examples/reactors', 'py') +
|
|
mglob(localenv, 'cantera/examples/onedim', 'py') +
|
|
mglob(localenv, 'cantera/examples/surface_chemistry', 'py') +
|
|
mglob(localenv, 'cantera/examples/misc', 'py')):
|
|
localenv.Depends(mod, f)
|
|
|
|
# Determine installation path and install the Python module
|
|
if localenv['python_prefix'] == 'USER':
|
|
# Install to the OS-dependent user site-packages directory
|
|
extra = '--user'
|
|
if localenv['OS'] == 'Darwin':
|
|
extra += ' --prefix=""'
|
|
elif localenv['python_prefix']:
|
|
# A specific location for the Cantera python module has been given
|
|
if localenv['debian'] and localenv.subst('${python_prefix}') == '/usr/local':
|
|
# Installation to /usr/local is the default on Debian-based distributions
|
|
extra = ''
|
|
elif localenv['OS'] == 'Darwin':
|
|
extra = localenv.subst(' --prefix=${python_prefix}')
|
|
elif localenv['libdirname'] == 'lib64':
|
|
# 64-bit RHEL / Fedora
|
|
extra = localenv.subst(
|
|
' --prefix=${python_prefix}'
|
|
' --install-lib=${python_prefix}/lib64/python{}/site-packages'.format(py_version))
|
|
else:
|
|
extra = '--user'
|
|
localenv.AppendENVPath(
|
|
'PYTHONUSERBASE',
|
|
normpath(localenv.subst('$python_prefix')))
|
|
else:
|
|
# Install Python module in the default location
|
|
extra = ''
|
|
|
|
env['python_module_loc'] = '<unspecified>'
|
|
if localenv['PYTHON_INSTALLER'] == 'direct':
|
|
mod_inst = install(localenv.Command, 'dummy', mod,
|
|
build_cmd + ' install ' + extra +
|
|
' --record=../../build/python-installed-files.txt' +
|
|
' --single-version-externally-managed')
|
|
global_env = env
|
|
def find_module_dir(target, source, env):
|
|
check = pjoin('cantera', '__init__.py')
|
|
for filename in open('build/python-installed-files.txt').readlines():
|
|
filename = filename.strip()
|
|
if filename.endswith(check):
|
|
filename = filename.replace(check, '')
|
|
global_env['python_module_loc'] = normpath(filename)
|
|
break
|
|
localenv.AlwaysBuild(localenv.AddPostAction(mod_inst, find_module_dir))
|
|
env['install_python_action'] = mod_inst
|
|
elif localenv['PYTHON_INSTALLER'] == 'debian':
|
|
extra = localenv.subst(' --root=${python_prefix}')
|
|
install(localenv.Command, 'dummy', mod,
|
|
build_cmd + ' install --install-layout=deb --no-compile ' + extra)
|
|
elif localenv['PYTHON_INSTALLER'] == 'binary':
|
|
install(localenv.Command, 'dummy', mod,
|
|
build_cmd + ' bdist_msi --dist-dir=../..' +
|
|
' --target-version=' + py_version)
|