Files
cantera/interfaces/cython/SConscript

165 lines
6.7 KiB
Python
Raw Normal View History

"""Cython-based Python Module"""
import re
from pathlib import Path
from pkg_resources import parse_version
import json
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}')"''')
2021-04-18 22:22:48 -04:00
for f in multi_glob(localenv, 'cantera', 'pyx', 'pxd'):
localenv.Depends(cythonized, f)
2022-02-06 20:34:07 -05:00
# This must be the path to the real pxd file, not a file node pointing at the
# possibly non-existent file in the build directory
pxd_file = File("#interfaces/cython/cantera/_cantera.pxd").abspath
for line in Path(pxd_file).read_text().splitlines():
m = re.search(r'from "(cantera.*?)"', line)
if m:
localenv.Depends('cantera/_cantera.cpp', '#include/' + m.group(1))
2022-02-06 20:34:07 -05:00
dataFiles = localenv.RecursiveInstall("cantera/data", "#build/data")
build(dataFiles)
2022-02-06 20:34:07 -05:00
testFiles = localenv.RecursiveInstall("cantera/test/data", "#test/data")
build(testFiles)
# Get information needed to build the Python module
script = """\
from sysconfig import *
import numpy
import json
vars = get_config_vars()
vars["plat"] = get_platform()
vars["numpy_include"] = numpy.get_include()
print(json.dumps(vars))
"""
info = json.loads(get_command_output(localenv["python_cmd"], "-c", script))
module_ext = info["EXT_SUFFIX"]
inc = info["INCLUDEPY"]
pylib = info.get("LDLIBRARY")
prefix = info["prefix"]
py_version_short = parse_version(info["py_version_short"])
py_version_full = parse_version(info["py_version"])
2022-02-06 20:34:07 -05:00
py_version_nodot = info["py_version_nodot"]
numpy_include = info["numpy_include"]
localenv.Prepend(CPPPATH=[Dir('#include'), inc, numpy_include])
localenv.Prepend(LIBS=localenv['cantera_libs'])
# Fix the module extension for Windows from the sysconfig library.
# See https://github.com/python/cpython/pull/22088 and
# https://bugs.python.org/issue39825
if (
py_version_full < parse_version("3.8.7")
and localenv["OS"] == "Windows"
and module_ext == ".pyd"
):
module_ext = f".cp{py_version_nodot}-{info['plat'].replace('-', '_')}.pyd"
# 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 py_version_short == parse_version("3.8"):
localenv.Append(CXXFLAGS='-Wno-deprecated-declarations')
if "icc" in localenv["CC"]:
2022-02-06 20:34:07 -05:00
localenv.Append(CPPDEFINES={"CYTHON_FALLTHROUGH": " __attribute__((fallthrough))"})
if localenv['OS'] == 'Darwin':
localenv.Append(LINKFLAGS='-undefined dynamic_lookup')
elif localenv['OS'] == 'Windows':
2022-02-06 20:34:07 -05:00
localenv.Append(LIBPATH=prefix + '/libs')
if localenv['toolchain'] == 'mingw':
localenv.Append(LIBS=f"python{py_version_nodot}")
if localenv['OS_BITS'] == 64:
localenv.Append(CPPDEFINES='MS_WIN64')
# Fix for https://bugs.python.org/issue11566. Fixed in 3.7.3 and higher.
# See https://github.com/python/cpython/pull/11283
if py_version_full < parse_version("3.7.3"):
localenv.Append(CPPDEFINES={"_hypot": "hypot"})
elif localenv['OS'] == 'Cygwin':
# extract 'pythonX.Y' from 'libpythonX.Y.dll.a'
localenv.Append(LIBS=pylib[3:-6])
localenv["module_ext"] = module_ext
setup_cfg = localenv.SubstFile("setup.cfg", "setup.cfg.in")
readme = localenv.Command("README.rst", "#README.rst", Copy("$TARGET", "$SOURCE"))
license = localenv.Command("LICENSE.txt", "#build/ext/LICENSE.txt",
Copy("$TARGET", "$SOURCE"))
localenv.Depends(license, localenv["license_target"])
# Build the Python module
obj = localenv.SharedObject('#build/temp-py/_cantera', 'cantera/_cantera.cpp')
ext = localenv.LoadableModule(f"cantera/_cantera{module_ext}",
obj, LIBPREFIX="", SHLIBSUFFIX=module_ext,
SHLIBPREFIX="", LIBSUFFIXES=[module_ext])
build_cmd = ("$python_cmd_esc -m pip wheel -v --no-build-isolation --no-deps "
"--wheel-dir=build/python/dist build/python")
plat = info['plat'].replace('-', '_').replace('.', '_')
wheel_name = (f"Cantera-{env['cantera_version']}-cp{py_version_nodot}"
f"-cp{py_version_nodot}-{plat}.whl")
2022-02-06 20:34:07 -05:00
mod = build(localenv.Command(f"#build/python/dist/{wheel_name}", "setup.cfg",
build_cmd))
env['python_module'] = mod
env['python_extension'] = ext
localenv.Depends(mod, [ext, dataFiles, testFiles, setup_cfg, readme, license,
"setup.py", "pyproject.toml"])
localenv.Depends(ext, localenv['cantera_staticlib'])
2021-04-18 22:22:48 -04:00
for f in (multi_glob(localenv, 'cantera', 'py') +
multi_glob(localenv, 'cantera/*', 'py') +
multi_glob(localenv, 'cantera/*/*', 'py')):
localenv.Depends(mod, f)
# Determine installation path and install the Python module
install_cmd = ["$python_cmd_esc", "-m", "pip", "install"]
user_install = False
python_prefix = None
if localenv['python_prefix'] == 'USER':
# Install to the OS-dependent user site-packages directory
install_cmd.append("--user")
user_install = True
2022-02-06 20:34:07 -05:00
elif localenv["python_prefix"]:
# A specific location for the Cantera python module has been given
install_cmd.append(f"--prefix={localenv.subst('$python_prefix')}")
python_prefix = localenv.subst("$python_prefix")
elif not env["default_prefix"]:
install_cmd.append(f"--prefix={env['prefix']}")
python_prefix = env["prefix"]
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.
stage_dir = Path(env["stage_dir"])
if not stage_dir.is_absolute():
stage_dir = Path(Dir("#").abspath) / stage_dir
install_cmd.append(f"--root={stage_dir.resolve()}")
2022-02-06 20:34:07 -05:00
install_cmd.extend(("--no-build-isolation", "--no-deps", "-v", "--force-reinstall",
"build/python"))
if localenv['PYTHON_INSTALLER'] == 'direct':
mod_inst = install(localenv.Command, 'dummy', mod,
" ".join(install_cmd))
env["install_python_action"] = mod_inst
install_locs = get_pip_install_location(localenv["python_cmd"], user_install,
python_prefix)
env["python_module_loc"] = install_locs["platlib"]
env["ct_pyscriptdir"] = install_locs["scripts"]
elif localenv['PYTHON_INSTALLER'] == 'debian':
install(localenv.Command, 'dummy', mod,
'cd build/python && '
'$python_cmd_esc setup.py build --build-lib=. '
'install --install-layout=deb --no-compile --root=${python_prefix}')
env["python_module_loc"] = "<unspecified>"