mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
The 'install' and 'test' targets had some undeclared dependencies on the 'build' target, such that running 'scons install' or 'scons test' without having first run 'scons build' would result in incomplete installation or test failures, respectively. Fixes #432.
208 lines
9.2 KiB
Python
208 lines
9.2 KiB
Python
""" Cython-based Python Module for Python 3 """
|
|
from buildutils import *
|
|
import Cython.Build
|
|
|
|
Import('env', 'build', 'install')
|
|
|
|
localenv = env.Clone()
|
|
|
|
|
|
def configure_python(env, python_command):
|
|
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(python_command, '-c', script)
|
|
module_ext, inc, pylib, prefix, py_version, numpy_include = info.splitlines()[-6:]
|
|
env.Prepend(CPPPATH=[Dir('#include'), inc, numpy_include])
|
|
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')
|
|
if env['toolchain'] == 'mingw':
|
|
env.Append(LIBS='python%s' % py_version.replace('.',''))
|
|
if env['OS_BITS'] == 64:
|
|
env.Append(CPPDEFINES='MS_WIN64')
|
|
# fix for http://bugs.python.org/issue11566
|
|
env.Append(CPPDEFINES={'_hypot':'hypot'})
|
|
elif env['OS'] == 'Cygwin':
|
|
# extract 'pythonX.Y' from 'libpythonX.Y.dll.a'
|
|
env.Append(LIBS=pylib[3:-6])
|
|
return module_ext, py_version
|
|
|
|
|
|
def add_dependencies(mod, 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)
|
|
|
|
|
|
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)
|
|
|
|
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))
|
|
|
|
def install_module(prefix, python_version):
|
|
major = python_version[0]
|
|
minor = python_version.split('.')[1]
|
|
ver = '3' if major == '3' else ''
|
|
dummy = 'dummy' + major
|
|
if prefix == 'USER':
|
|
# Install to the OS-dependent user site-packages directory
|
|
extra = '--user'
|
|
if localenv['OS'] == 'Darwin':
|
|
extra += ' --prefix=""'
|
|
elif prefix:
|
|
# A specific location for the Cantera python module has been given
|
|
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':
|
|
extra = localenv.subst(' --prefix=${python%s_prefix}' % ver)
|
|
elif localenv['libdirname'] == 'lib64':
|
|
# 64-bit RHEL / Fedora
|
|
extra = localenv.subst(
|
|
' --prefix=${python%s_prefix} --install-lib=${python%s_prefix}/lib64/python%s.%s/site-packages' % (ver, ver, major, minor))
|
|
else:
|
|
extra = '--user'
|
|
localenv.AppendENVPath(
|
|
'PYTHONUSERBASE',
|
|
normpath(localenv.subst('$python%s_prefix' % ver)))
|
|
else:
|
|
# Install Python module in the default location
|
|
extra = ''
|
|
|
|
env['python%s_module_loc' % ver] = '<unspecified>'
|
|
if localenv['PYTHON_INSTALLER'] == 'direct':
|
|
mod_inst = install(localenv.Command, dummy, mod,
|
|
build_cmd + ' install %s' % extra +
|
|
' --record=../../build/python%s-installed-files.txt' % major +
|
|
' --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%s-installed-files.txt' % major).readlines():
|
|
filename = filename.strip()
|
|
if filename.endswith(check):
|
|
filename = filename.replace(check,'')
|
|
global_env['python%s_module_loc' % ver] = normpath(filename)
|
|
break
|
|
localenv.AlwaysBuild(localenv.AddPostAction(mod_inst, find_module_dir))
|
|
if not ver:
|
|
env['install_python2_action'] = mod_inst
|
|
|
|
elif localenv['PYTHON_INSTALLER'] == 'debian':
|
|
extra = localenv.subst(' --root=${python%s_prefix}' % ver)
|
|
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)
|
|
|
|
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)
|
|
|
|
# Cython module for Python 3.x
|
|
if localenv['python3_package'] == 'y':
|
|
py3env = localenv.Clone()
|
|
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,
|
|
SHLIBPREFIX='', LIBSUFFIXES=[module_ext])
|
|
py3env['py_extension'] = ext[0].name
|
|
|
|
py3env.SubstFile('setup3.py', 'setup.py.in')
|
|
build_cmd = ('cd interfaces/cython &&'
|
|
' $python3_cmd setup3.py build --build-lib=../../build/python3')
|
|
mod = build(py3env.Command('#build/python3/cantera/__init__.py', 'setup3.py',
|
|
build_cmd))
|
|
env['python3_module'] = mod
|
|
env['python3_extension'] = ext
|
|
|
|
add_dependencies(mod, ext)
|
|
install_module(py3env['python3_prefix'], py3_version)
|
|
|
|
|
|
# Cython module for Python 2.x
|
|
if localenv['python_package'] == 'full':
|
|
py2env = localenv.Clone()
|
|
module_ext, py2_version = configure_python(py2env, py2env['python_cmd'])
|
|
|
|
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,
|
|
SHLIBPREFIX='', LIBSUFFIXES=[module_ext])
|
|
py2env['py_extension'] = ext[0].name
|
|
py2env.SubstFile('setup2.py', 'setup.py.in')
|
|
build_cmd = ('cd interfaces/cython &&'
|
|
' $python_cmd_esc setup2.py build --build-lib=../../build/python2')
|
|
mod = build(py2env.Command('#build/python2/cantera/__init__.py',
|
|
'setup2.py',
|
|
build_cmd))
|
|
env['python2_module'] = mod
|
|
env['python2_extension'] = ext
|
|
|
|
# Use 3to2 to convert examples from Python 3 syntax
|
|
if env['python_convert_examples']:
|
|
def convert_example(target, source, env):
|
|
shutil.copyfile(source[0].abspath, target[0].abspath)
|
|
if env['OS'] == 'Windows':
|
|
subprocess.call(env['threetotwo_cmd'] + ['--no-diff', '-n', '-w','-x', 'str',
|
|
'-f', 'all', '-f', 'printfunction', '-x', 'print',
|
|
'-x', 'open', target[0].abspath])
|
|
else:
|
|
subprocess.call(['3to2', '--no-diff', '-n', '-w','-x', 'str',
|
|
'-f', 'all', '-f', 'printfunction', '-x', 'print',
|
|
'-x', 'open', target[0].abspath])
|
|
|
|
for subdir in subdirs('cantera/examples'):
|
|
dirpath = pjoin('cantera', 'examples', subdir)
|
|
for filename in os.listdir(dirpath):
|
|
if not filename.endswith('.py'):
|
|
continue
|
|
targetdir = '../../build/python2/cantera/examples'
|
|
a = build(py2env.Command(pjoin(targetdir, subdir, filename),
|
|
pjoin(dirpath, filename),
|
|
convert_example))
|
|
py2env.Depends(mod, a)
|
|
|
|
add_dependencies(mod, ext)
|
|
install_module(py2env['python_prefix'], py2_version)
|