2017-11-08 16:19:53 -05:00
|
|
|
"""Cython-based Python Module"""
|
2012-09-06 19:58:03 +00:00
|
|
|
from buildutils import *
|
2014-01-31 23:15:17 +00:00
|
|
|
import Cython.Build
|
2012-09-06 19:58:03 +00:00
|
|
|
|
|
|
|
|
Import('env', 'build', 'install')
|
|
|
|
|
|
|
|
|
|
localenv = env.Clone()
|
|
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
|
2014-01-31 23:15:17 +00:00
|
|
|
def configure_python(env, python_command):
|
2012-12-26 23:55:48 +00:00
|
|
|
script = '\n'.join(("from distutils.sysconfig import *",
|
|
|
|
|
"import numpy",
|
2014-01-31 23:15:17 +00:00
|
|
|
"print(get_config_var('EXT_SUFFIX') or get_config_var('SO'))",
|
|
|
|
|
"print(get_config_var('INCLUDEPY'))",
|
2014-02-20 03:01:01 +00:00
|
|
|
"print(get_config_var('LDLIBRARY'))",
|
2014-01-31 23:15:17 +00:00
|
|
|
"print(get_config_var('prefix'))",
|
2012-12-26 23:55:48 +00:00
|
|
|
"print(get_python_version())",
|
|
|
|
|
"print(numpy.get_include())"))
|
|
|
|
|
info = getCommandOutput(python_command, '-c', script)
|
2014-02-20 03:01:01 +00:00
|
|
|
module_ext, inc, pylib, prefix, py_version, numpy_include = info.splitlines()[-6:]
|
2015-07-01 12:24:49 -04:00
|
|
|
env.Prepend(CPPPATH=[Dir('#include'), inc, numpy_include])
|
2014-01-31 23:15:17 +00:00
|
|
|
env.Prepend(LIBS=env['cantera_libs'])
|
|
|
|
|
if env['OS'] == 'Darwin':
|
|
|
|
|
env.Append(LINKFLAGS='-undefined dynamic_lookup')
|
|
|
|
|
elif env['OS'] == 'Windows':
|
|
|
|
|
env.Append(LIBPATH=prefix+'/libs')
|
2014-02-24 03:25:30 +00:00
|
|
|
if env['toolchain'] == 'mingw':
|
|
|
|
|
env.Append(LIBS='python%s' % py_version.replace('.',''))
|
|
|
|
|
if env['OS_BITS'] == 64:
|
|
|
|
|
env.Append(CPPDEFINES='MS_WIN64')
|
2015-09-08 18:08:27 -04:00
|
|
|
# fix for http://bugs.python.org/issue11566
|
|
|
|
|
env.Append(CPPDEFINES={'_hypot':'hypot'})
|
2014-02-20 03:01:01 +00:00
|
|
|
elif env['OS'] == 'Cygwin':
|
|
|
|
|
# extract 'pythonX.Y' from 'libpythonX.Y.dll.a'
|
|
|
|
|
env.Append(LIBS=pylib[3:-6])
|
2012-12-26 23:55:48 +00:00
|
|
|
return module_ext, py_version
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_dependencies(mod, ext):
|
|
|
|
|
localenv.Depends(mod, ext)
|
2015-08-02 14:08:55 -04:00
|
|
|
localenv.Depends(mod, dataFiles + testFiles)
|
2014-02-21 19:07:58 +00:00
|
|
|
localenv.Depends(ext, localenv['cantera_staticlib'])
|
2012-12-26 23:55:48 +00:00
|
|
|
|
2014-05-07 21:56:57 +00:00
|
|
|
for f in (mglob(localenv, 'cantera', 'py') +
|
|
|
|
|
mglob(localenv, 'cantera/test', 'py') +
|
2012-12-26 23:55:48 +00:00
|
|
|
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)
|
|
|
|
|
|
2014-01-31 23:15:17 +00:00
|
|
|
|
|
|
|
|
def cythonize(target, source, env):
|
|
|
|
|
Cython.Build.cythonize([f.abspath for f in source])
|
|
|
|
|
|
|
|
|
|
cythonized = localenv.Command('cantera/_cantera.cpp', ['cantera/_cantera.pyx'],
|
|
|
|
|
cythonize)
|
|
|
|
|
for f in mglob(localenv, 'cantera', 'pyx', 'pxd'):
|
|
|
|
|
localenv.Depends(cythonized, f)
|
|
|
|
|
|
2014-10-29 15:36:28 +00:00
|
|
|
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))
|
|
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
def install_module(prefix, python_version):
|
2015-08-02 14:08:55 -04:00
|
|
|
major = python_version[0]
|
2016-06-29 20:52:58 -04:00
|
|
|
minor = python_version.split('.')[1]
|
2015-08-02 14:08:55 -04:00
|
|
|
dummy = 'dummy' + major
|
2013-03-04 17:31:08 +00:00
|
|
|
if prefix == 'USER':
|
|
|
|
|
# Install to the OS-dependent user site-packages directory
|
|
|
|
|
extra = '--user'
|
2015-08-02 14:08:55 -04:00
|
|
|
if localenv['OS'] == 'Darwin':
|
|
|
|
|
extra += ' --prefix=""'
|
2013-03-04 17:31:08 +00:00
|
|
|
elif prefix:
|
2015-08-02 14:08:55 -04:00
|
|
|
# A specific location for the Cantera python module has been given
|
2016-07-29 15:27:38 -04:00
|
|
|
if localenv['debian'] and localenv.subst(prefix) == '/usr/local':
|
|
|
|
|
# Installation to /usr/local is the default on Debian-based distributions
|
|
|
|
|
extra = ''
|
|
|
|
|
elif localenv['OS'] == 'Darwin':
|
2017-11-08 16:19:53 -05:00
|
|
|
extra = localenv.subst(' --prefix=${python%s_prefix}' % major)
|
2016-06-29 20:52:58 -04:00
|
|
|
elif localenv['libdirname'] == 'lib64':
|
|
|
|
|
# 64-bit RHEL / Fedora
|
|
|
|
|
extra = localenv.subst(
|
2017-11-08 16:19:53 -05:00
|
|
|
' --prefix=${python%s_prefix} --install-lib=${python%s_prefix}/lib64/python%s.%s/site-packages' % (major, major, major, minor))
|
2015-11-13 17:45:21 -08:00
|
|
|
else:
|
|
|
|
|
extra = '--user'
|
|
|
|
|
localenv.AppendENVPath(
|
|
|
|
|
'PYTHONUSERBASE',
|
2017-11-08 16:19:53 -05:00
|
|
|
normpath(localenv.subst('$python%s_prefix' % major)))
|
2012-12-26 23:55:48 +00:00
|
|
|
else:
|
|
|
|
|
# Install Python module in the default location
|
|
|
|
|
extra = ''
|
|
|
|
|
|
2017-11-08 16:19:53 -05:00
|
|
|
env['python%s_module_loc' % major] = '<unspecified>'
|
2012-12-26 23:55:48 +00:00
|
|
|
if localenv['PYTHON_INSTALLER'] == 'direct':
|
2013-07-29 01:37:57 +00:00
|
|
|
mod_inst = install(localenv.Command, dummy, mod,
|
|
|
|
|
build_cmd + ' install %s' % extra +
|
2015-08-02 14:08:55 -04:00
|
|
|
' --record=../../build/python%s-installed-files.txt' % major +
|
|
|
|
|
' --single-version-externally-managed')
|
2013-07-29 01:37:57 +00:00
|
|
|
global_env = env
|
|
|
|
|
def find_module_dir(target, source, env):
|
|
|
|
|
check = pjoin('cantera','__init__.py')
|
|
|
|
|
for filename in open('build/python%s-installed-files.txt' % major).readlines():
|
|
|
|
|
filename = filename.strip()
|
|
|
|
|
if filename.endswith(check):
|
|
|
|
|
filename = filename.replace(check,'')
|
2017-11-08 16:19:53 -05:00
|
|
|
global_env['python%s_module_loc' % major] = normpath(filename)
|
2013-07-29 01:37:57 +00:00
|
|
|
break
|
|
|
|
|
localenv.AlwaysBuild(localenv.AddPostAction(mod_inst, find_module_dir))
|
2017-11-08 16:19:53 -05:00
|
|
|
env['install_python{}_action'.format(major)] = mod_inst
|
2013-07-29 01:37:57 +00:00
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
elif localenv['PYTHON_INSTALLER'] == 'debian':
|
2017-11-08 16:19:53 -05:00
|
|
|
extra = localenv.subst(' --root=${python%s_prefix}' % major)
|
2012-12-26 23:55:48 +00:00
|
|
|
install(localenv.Command, dummy, mod,
|
|
|
|
|
build_cmd + ' install --install-layout=deb --no-compile %s' % extra)
|
|
|
|
|
elif localenv['PYTHON_INSTALLER'] == 'binary':
|
|
|
|
|
install(localenv.Command, dummy, mod,
|
|
|
|
|
build_cmd + ' bdist_msi --dist-dir=../..' +
|
|
|
|
|
' --target-version=%s' % python_version)
|
|
|
|
|
|
2012-09-06 19:58:03 +00:00
|
|
|
dataFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/data',
|
2012-09-06 19:58:32 +00:00
|
|
|
'#build/data')
|
2012-09-06 19:58:03 +00:00
|
|
|
build(dataFiles)
|
|
|
|
|
|
2012-09-06 19:58:32 +00:00
|
|
|
testFiles = localenv.RecursiveInstall('#interfaces/cython/cantera/test/data',
|
|
|
|
|
'#test/data')
|
|
|
|
|
build(testFiles)
|
|
|
|
|
|
2016-11-08 17:00:37 -05:00
|
|
|
for f in ['inputs/h2o2.inp', 'inputs/gri30.inp', 'transport/gri30_tran.dat']:
|
2017-02-16 17:31:37 -05:00
|
|
|
inp = build(localenv.Install('#interfaces/cython/cantera/test/data/', '#data/' + f))
|
|
|
|
|
testFiles.append(inp)
|
2016-11-08 17:00:37 -05:00
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
# Cython module for Python 3.x
|
2017-11-08 16:19:53 -05:00
|
|
|
if localenv['python3_package'] == 'full':
|
|
|
|
|
localenv['python3_cmd_esc'] = quoted(localenv['python3_cmd'])
|
2014-01-30 00:48:03 +00:00
|
|
|
py3env = localenv.Clone()
|
2014-01-31 23:15:17 +00:00
|
|
|
module_ext, py3_version = configure_python(py3env, py3env['python3_cmd'])
|
|
|
|
|
|
|
|
|
|
obj = py3env.SharedObject('#build/temp-py/_cantera3', 'cantera/_cantera.cpp')
|
|
|
|
|
ext = py3env.LoadableModule('#build/python3/cantera/_cantera%s' % module_ext,
|
|
|
|
|
obj, LIBPREFIX='', SHLIBSUFFIX=module_ext,
|
2015-08-13 22:22:33 -04:00
|
|
|
SHLIBPREFIX='', LIBSUFFIXES=[module_ext])
|
2014-01-31 23:15:17 +00:00
|
|
|
py3env['py_extension'] = ext[0].name
|
|
|
|
|
|
|
|
|
|
py3env.SubstFile('setup3.py', 'setup.py.in')
|
|
|
|
|
build_cmd = ('cd interfaces/cython &&'
|
2017-11-08 16:19:53 -05:00
|
|
|
' $python3_cmd_esc setup3.py build --build-lib=../../build/python3')
|
2014-01-31 23:15:17 +00:00
|
|
|
mod = build(py3env.Command('#build/python3/cantera/__init__.py', 'setup3.py',
|
2014-01-30 00:48:03 +00:00
|
|
|
build_cmd))
|
2012-09-06 19:58:32 +00:00
|
|
|
env['python3_module'] = mod
|
2013-07-16 22:09:53 +00:00
|
|
|
env['python3_extension'] = ext
|
2012-09-06 19:58:03 +00:00
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
add_dependencies(mod, ext)
|
2014-01-30 00:48:03 +00:00
|
|
|
install_module(py3env['python3_prefix'], py3_version)
|
2012-09-06 19:58:26 +00:00
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
# Cython module for Python 2.x
|
2017-11-08 16:19:53 -05:00
|
|
|
if localenv['python2_package'] == 'full':
|
|
|
|
|
localenv['python2_cmd_esc'] = quoted(localenv['python2_cmd'])
|
2014-01-30 00:48:03 +00:00
|
|
|
py2env = localenv.Clone()
|
2017-11-08 16:19:53 -05:00
|
|
|
module_ext, py2_version = configure_python(py2env, py2env['python2_cmd'])
|
2014-01-31 23:15:17 +00:00
|
|
|
|
|
|
|
|
obj = py2env.SharedObject('#build/temp-py/_cantera2', 'cantera/_cantera.cpp')
|
|
|
|
|
ext = py2env.LoadableModule('#build/python2/cantera/_cantera%s' % module_ext,
|
|
|
|
|
obj, LIBPREFIX='', SHLIBSUFFIX=module_ext,
|
2015-08-13 22:22:33 -04:00
|
|
|
SHLIBPREFIX='', LIBSUFFIXES=[module_ext])
|
2014-01-31 23:15:17 +00:00
|
|
|
py2env['py_extension'] = ext[0].name
|
|
|
|
|
py2env.SubstFile('setup2.py', 'setup.py.in')
|
|
|
|
|
build_cmd = ('cd interfaces/cython &&'
|
2017-11-08 16:19:53 -05:00
|
|
|
' $python2_cmd_esc setup2.py build --build-lib=../../build/python2')
|
2014-01-30 00:48:03 +00:00
|
|
|
mod = build(py2env.Command('#build/python2/cantera/__init__.py',
|
|
|
|
|
'setup2.py',
|
|
|
|
|
build_cmd))
|
2012-09-06 19:58:32 +00:00
|
|
|
env['python2_module'] = mod
|
2013-07-16 22:09:53 +00:00
|
|
|
env['python2_extension'] = ext
|
2012-09-06 19:58:22 +00:00
|
|
|
|
2012-12-18 00:03:03 +00:00
|
|
|
# Use 3to2 to convert examples from Python 3 syntax
|
|
|
|
|
if env['python_convert_examples']:
|
2017-11-13 11:36:09 -05:00
|
|
|
a = build(py2env.Command('#build/python2/cantera/examples', 'cantera/examples',
|
|
|
|
|
Copy("$TARGET", "$SOURCE")))
|
|
|
|
|
# In these next few things, the double quotes are necessary
|
|
|
|
|
# so the command line is processed properly
|
|
|
|
|
threetotwo_options = ['--no-diff', '-n', '-w', '-x', 'str', '-x', 'print', '-x', 'open',
|
|
|
|
|
'-f', 'all', '-f', 'printfunction']
|
|
|
|
|
threetotwo_options = ', '.join(["'{}'"]*len(threetotwo_options)).format(*threetotwo_options)
|
|
|
|
|
ex_loc = "'build/python2/cantera/examples'"
|
2017-11-19 12:53:58 -05:00
|
|
|
convert_script = textwrap.dedent("""\
|
|
|
|
|
$python2_cmd_esc -c "from lib3to2.main import main; main('lib3to2.fixes', [{opts}, {loc}])"
|
2017-11-13 11:36:09 -05:00
|
|
|
""".format(opts=threetotwo_options, loc=ex_loc))
|
|
|
|
|
b = build(py2env.AddPostAction(a, convert_script))
|
|
|
|
|
py2env.Depends(mod, b)
|
2012-12-18 00:03:03 +00:00
|
|
|
|
2012-12-26 23:55:48 +00:00
|
|
|
add_dependencies(mod, ext)
|
2017-11-08 16:19:53 -05:00
|
|
|
install_module(py2env['python2_prefix'], py2_version)
|