"""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) inputFiles = ['inputs/h2o2.inp', 'inputs/gri30.inp', 'transport/gri30_tran.dat', 'thermo/gri30_thermo.dat'] for f in inputFiles: 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'] != '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 = '' env['python_module_loc'] = '' 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)