mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
The sysconfig module is available since Python 3.2. Distutils is deprecated and slated for removal from Python in the next few years. Likewise, the "SO" config variable has been deprecated for some time and was slated for removal in Python 3.8, although that seems not to have happened.
159 lines
6.8 KiB
Python
159 lines
6.8 KiB
Python
"""Cython-based Python Module"""
|
|
import re
|
|
from os.path import join as pjoin
|
|
from os.path import normpath
|
|
from pathlib import Path
|
|
from pkg_resources import parse_version
|
|
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 multi_glob(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)
|
|
|
|
# Get information needed to build the Python module
|
|
script = '\n'.join(("from sysconfig import *",
|
|
"import numpy",
|
|
"print(get_config_var('EXT_SUFFIX'))",
|
|
"print(get_config_var('INCLUDEPY'))",
|
|
"print(get_config_var('LDLIBRARY'))",
|
|
"print(get_config_var('prefix'))",
|
|
"print(get_python_version())",
|
|
"print(numpy.get_include())"))
|
|
info = get_command_output(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'])
|
|
|
|
# Don't print deprecation warnings for internal Python changes.
|
|
# Only applies to Python 3.8. The field that is deprecated in Python 3.8
|
|
# and causes the warnings to appear will be removed in Python 3.9 so no
|
|
# further warnings should be issued.
|
|
if localenv['HAS_CLANG'] and parse_version(py_version) == parse_version('3.8'):
|
|
localenv.Append(CXXFLAGS='-Wno-deprecated-declarations')
|
|
|
|
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 (multi_glob(localenv, 'cantera', 'py') +
|
|
multi_glob(localenv, 'cantera/test', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/kinetics', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/multiphase', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/onedim', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/reactors', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/surface_chemistry', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/thermo', 'py') +
|
|
multi_glob(localenv, 'cantera/examples/transport', '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'] != 'lib':
|
|
# 64-bit RHEL / Fedora etc. or e.g. x32 Gentoo profile
|
|
extra = localenv.subst(
|
|
' --prefix=${{python_prefix}}'
|
|
' --install-lib=${{python_prefix}}/${{libdirname}}/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 = ''
|
|
|
|
if env["stage_dir"]:
|
|
# Get the absolute path to the stage directory. If the stage directory is a relative
|
|
# path, consider it to be relative to the root of the Cantera source directory,
|
|
# which is two directories up from the current working directory of this SConscript
|
|
# file.
|
|
stage_absolute = Path.cwd().parents[1].joinpath(env['stage_dir']).resolve()
|
|
extra += f" --root={stage_absolute}"
|
|
|
|
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):
|
|
global_env["python_module_loc"] = normpath(filename.replace(check, ""))
|
|
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)
|