2011-09-10 11:13:51 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# encoding: utf-8
|
2015-01-01 16:24:54 +01:00
|
|
|
# Thomas Nagy, 2007-2015 (ita)
|
2011-09-10 11:13:51 +02:00
|
|
|
# Gustavo Carneiro (gjc), 2007
|
|
|
|
|
|
|
|
"""
|
|
|
|
Support for Python, detect the headers and libraries and provide
|
|
|
|
*use* variables to link C/C++ programs against them::
|
|
|
|
|
|
|
|
def options(opt):
|
|
|
|
opt.load('compiler_c python')
|
|
|
|
def configure(conf):
|
|
|
|
conf.load('compiler_c python')
|
|
|
|
conf.check_python_version((2,4,2))
|
|
|
|
conf.check_python_headers()
|
|
|
|
def build(bld):
|
|
|
|
bld.program(features='pyembed', source='a.c', target='myprog')
|
|
|
|
bld.shlib(features='pyext', source='b.c', target='mylib')
|
|
|
|
"""
|
|
|
|
|
|
|
|
import os, sys
|
2017-06-20 11:20:53 +02:00
|
|
|
from waflib import Errors, Logs, Node, Options, Task, Utils
|
2011-09-10 11:13:51 +02:00
|
|
|
from waflib.TaskGen import extension, before_method, after_method, feature
|
|
|
|
from waflib.Configure import conf
|
|
|
|
|
|
|
|
FRAG = '''
|
|
|
|
#include <Python.h>
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
void Py_Initialize(void);
|
|
|
|
void Py_Finalize(void);
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2012-08-24 22:53:07 +02:00
|
|
|
int main(int argc, char **argv)
|
2011-09-10 11:13:51 +02:00
|
|
|
{
|
2012-11-04 10:29:36 +01:00
|
|
|
(void)argc; (void)argv;
|
2011-09-10 11:13:51 +02:00
|
|
|
Py_Initialize();
|
|
|
|
Py_Finalize();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
'''
|
|
|
|
"""
|
|
|
|
Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers`
|
|
|
|
"""
|
|
|
|
|
|
|
|
INST = '''
|
|
|
|
import sys, py_compile
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
|
2011-09-10 11:13:51 +02:00
|
|
|
'''
|
|
|
|
"""
|
2017-11-27 19:35:59 +01:00
|
|
|
Piece of Python code used in :py:class:`waflib.Tools.python.pyo` and :py:class:`waflib.Tools.python.pyc` for byte-compiling python files
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
@before_method('process_source')
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
@feature('py')
|
|
|
|
def feature_py(self):
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
Create tasks to byte-compile .py files and install them, if requested
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
2014-07-25 18:15:23 +02:00
|
|
|
self.install_path = getattr(self, 'install_path', '${PYTHONDIR}')
|
|
|
|
install_from = getattr(self, 'install_from', None)
|
|
|
|
if install_from and not isinstance(install_from, Node.Node):
|
|
|
|
install_from = self.path.find_dir(install_from)
|
|
|
|
self.install_from = install_from
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
ver = self.env.PYTHON_VERSION
|
|
|
|
if not ver:
|
|
|
|
self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
if int(ver.replace('.', '')) > 31:
|
|
|
|
self.install_32 = True
|
2011-09-10 11:13:51 +02:00
|
|
|
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
@extension('.py')
|
|
|
|
def process_py(self, node):
|
|
|
|
"""
|
|
|
|
Add signature of .py file, so it will be byte-compiled when necessary
|
|
|
|
"""
|
2020-07-15 17:35:22 +02:00
|
|
|
assert(hasattr(self, 'install_path')), 'add features="py" for target "%s" in "%s/wscript".' % (self.target, self.path.abspath())
|
2018-10-29 10:02:31 +01:00
|
|
|
self.install_from = getattr(self, 'install_from', None)
|
|
|
|
relative_trick = getattr(self, 'relative_trick', True)
|
|
|
|
if self.install_from:
|
|
|
|
assert isinstance(self.install_from, Node.Node), \
|
2020-07-15 17:35:22 +02:00
|
|
|
'add features="py" for target "%s" in "%s/wscript" (%s).' % (self.target, self.path.abspath(), type(self.install_from))
|
2014-07-25 18:15:23 +02:00
|
|
|
|
|
|
|
# where to install the python file
|
|
|
|
if self.install_path:
|
|
|
|
if self.install_from:
|
2018-10-29 10:02:31 +01:00
|
|
|
self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=relative_trick)
|
2014-07-25 18:15:23 +02:00
|
|
|
else:
|
2018-10-29 10:02:31 +01:00
|
|
|
self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=relative_trick)
|
2014-07-25 18:15:23 +02:00
|
|
|
|
|
|
|
lst = []
|
|
|
|
if self.env.PYC:
|
|
|
|
lst.append('pyc')
|
|
|
|
if self.env.PYO:
|
|
|
|
lst.append('pyo')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
if self.install_path:
|
|
|
|
if self.install_from:
|
2018-10-29 10:02:31 +01:00
|
|
|
target_dir = node.path_from(self.install_from) if relative_trick else node.name
|
|
|
|
pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env)
|
2014-07-25 18:15:23 +02:00
|
|
|
else:
|
2018-10-29 10:02:31 +01:00
|
|
|
target_dir = node.path_from(self.path) if relative_trick else node.name
|
|
|
|
pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env)
|
2014-07-25 18:15:23 +02:00
|
|
|
else:
|
|
|
|
pyd = node.abspath()
|
|
|
|
|
|
|
|
for ext in lst:
|
2016-12-15 19:03:29 +01:00
|
|
|
if self.env.PYTAG and not self.env.NOPYCACHE:
|
2014-07-25 18:15:23 +02:00
|
|
|
# __pycache__ installation for python 3.2 - PEP 3147
|
|
|
|
name = node.name[:-3]
|
|
|
|
pyobj = node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s" % (name, self.env.PYTAG, ext))
|
|
|
|
pyobj.parent.mkdir()
|
|
|
|
else:
|
|
|
|
pyobj = node.change_ext(".%s" % ext)
|
|
|
|
|
|
|
|
tsk = self.create_task(ext, node, pyobj)
|
|
|
|
tsk.pyd = pyd
|
|
|
|
|
|
|
|
if self.install_path:
|
2018-10-29 10:02:31 +01:00
|
|
|
self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=relative_trick)
|
2014-07-25 18:15:23 +02:00
|
|
|
|
|
|
|
class pyc(Task.Task):
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
"""
|
|
|
|
Byte-compiling python files
|
|
|
|
"""
|
|
|
|
color = 'PINK'
|
2016-10-03 15:30:04 +02:00
|
|
|
def __str__(self):
|
|
|
|
node = self.outputs[0]
|
|
|
|
return node.path_from(node.ctx.launch_node())
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
def run(self):
|
|
|
|
cmd = [Utils.subst_vars('${PYTHON}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd]
|
|
|
|
ret = self.generator.bld.exec_command(cmd)
|
|
|
|
return ret
|
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
class pyo(Task.Task):
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
Byte-compiling python files
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
color = 'PINK'
|
2016-10-03 15:30:04 +02:00
|
|
|
def __str__(self):
|
|
|
|
node = self.outputs[0]
|
|
|
|
return node.path_from(node.ctx.launch_node())
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
def run(self):
|
2014-07-25 18:15:23 +02:00
|
|
|
cmd = [Utils.subst_vars('${PYTHON}', self.env), Utils.subst_vars('${PYFLAGS_OPT}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd]
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
ret = self.generator.bld.exec_command(cmd)
|
|
|
|
return ret
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
@feature('pyext')
|
|
|
|
@before_method('propagate_uselib_vars', 'apply_link')
|
|
|
|
@after_method('apply_bundle')
|
|
|
|
def init_pyext(self):
|
|
|
|
"""
|
|
|
|
Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the
|
|
|
|
*lib* prefix from library names.
|
|
|
|
"""
|
|
|
|
self.uselib = self.to_list(getattr(self, 'uselib', []))
|
|
|
|
if not 'PYEXT' in self.uselib:
|
|
|
|
self.uselib.append('PYEXT')
|
|
|
|
# override shlib_PATTERN set by the osx module
|
2012-10-21 11:29:40 +02:00
|
|
|
self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN = self.env.pyext_PATTERN
|
|
|
|
self.env.fcshlib_PATTERN = self.env.dshlib_PATTERN = self.env.pyext_PATTERN
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2012-03-18 19:05:54 +01:00
|
|
|
try:
|
|
|
|
if not self.install_path:
|
|
|
|
return
|
|
|
|
except AttributeError:
|
|
|
|
self.install_path = '${PYTHONARCHDIR}'
|
|
|
|
|
2011-09-10 11:13:51 +02:00
|
|
|
@feature('pyext')
|
|
|
|
@before_method('apply_link', 'apply_bundle')
|
|
|
|
def set_bundle(self):
|
2015-04-26 21:00:15 +02:00
|
|
|
"""Mac-specific pyext extension that enables bundles from c_osx.py"""
|
2012-01-05 21:01:11 +01:00
|
|
|
if Utils.unversioned_sys_platform() == 'darwin':
|
2011-09-10 11:13:51 +02:00
|
|
|
self.mac_bundle = True
|
|
|
|
|
|
|
|
@before_method('propagate_uselib_vars')
|
|
|
|
@feature('pyembed')
|
|
|
|
def init_pyembed(self):
|
|
|
|
"""
|
|
|
|
Add the PYEMBED variable.
|
|
|
|
"""
|
|
|
|
self.uselib = self.to_list(getattr(self, 'uselib', []))
|
|
|
|
if not 'PYEMBED' in self.uselib:
|
|
|
|
self.uselib.append('PYEMBED')
|
|
|
|
|
|
|
|
@conf
|
2021-09-30 21:30:49 +02:00
|
|
|
def get_sysconfig_variable(self, variable):
|
|
|
|
"""
|
|
|
|
Spawn a new python process to dump configuration variables
|
|
|
|
|
|
|
|
:param variable: variable to print
|
|
|
|
:type variable: string
|
|
|
|
:return: the variable value
|
|
|
|
:rtype: string
|
|
|
|
"""
|
|
|
|
|
|
|
|
env = dict(os.environ)
|
|
|
|
try:
|
|
|
|
del env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
cmd = self.env.PYTHON + ["-c", "import sysconfig; print(sysconfig.get_config_var('{}'))".format(variable)]
|
|
|
|
out = self.cmd_and_log(cmd, env=env).strip()
|
|
|
|
|
|
|
|
if out == "None":
|
|
|
|
return ""
|
|
|
|
else:
|
|
|
|
return out
|
|
|
|
|
|
|
|
@conf
|
|
|
|
def get_sysconfig_variables(self, variables):
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
2011-12-17 23:07:25 +01:00
|
|
|
Spawn a new python process to dump configuration variables
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
:param variables: variables to print
|
|
|
|
:type variables: list of string
|
|
|
|
:return: the variable values
|
|
|
|
:rtype: list of string
|
|
|
|
"""
|
2021-09-30 21:30:49 +02:00
|
|
|
return [self.get_sysconfig_variable(variable=v) for v in variables]
|
|
|
|
|
|
|
|
@conf
|
|
|
|
def get_sysconfig_path(self, name):
|
|
|
|
"""
|
|
|
|
Spawn a new python process to dump configuration paths
|
|
|
|
|
|
|
|
:param name: path to print
|
|
|
|
:type variable: string
|
|
|
|
:return: the path value
|
|
|
|
:rtype: string
|
|
|
|
"""
|
|
|
|
|
|
|
|
env = dict(os.environ)
|
2011-09-10 11:13:51 +02:00
|
|
|
try:
|
2021-09-30 21:30:49 +02:00
|
|
|
del env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
|
2011-09-10 11:13:51 +02:00
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
2021-09-30 21:30:49 +02:00
|
|
|
cmd = self.env.PYTHON + ["-c", "import sysconfig; print(sysconfig.get_path('{}'))".format(name)]
|
|
|
|
out = self.cmd_and_log(cmd, env=env).strip()
|
|
|
|
|
|
|
|
if out == "None":
|
|
|
|
return ""
|
|
|
|
else:
|
|
|
|
return out
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2015-10-09 19:19:59 +02:00
|
|
|
@conf
|
|
|
|
def test_pyembed(self, mode, msg='Testing pyembed configuration'):
|
|
|
|
self.check(header_name='Python.h', define_name='HAVE_PYEMBED', msg=msg,
|
|
|
|
fragment=FRAG, errmsg='Could not build a python embedded interpreter',
|
|
|
|
features='%s %sprogram pyembed' % (mode, mode))
|
|
|
|
|
|
|
|
@conf
|
|
|
|
def test_pyext(self, mode, msg='Testing pyext configuration'):
|
|
|
|
self.check(header_name='Python.h', define_name='HAVE_PYEXT', msg=msg,
|
|
|
|
fragment=FRAG, errmsg='Could not build python extensions',
|
|
|
|
features='%s %sshlib pyext' % (mode, mode))
|
|
|
|
|
2015-03-01 11:59:16 +01:00
|
|
|
@conf
|
|
|
|
def python_cross_compile(self, features='pyembed pyext'):
|
|
|
|
"""
|
|
|
|
For cross-compilation purposes, it is possible to bypass the normal detection and set the flags that you want:
|
|
|
|
PYTHON_VERSION='3.4' PYTAG='cpython34' pyext_PATTERN="%s.so" PYTHON_LDFLAGS='-lpthread -ldl' waf configure
|
|
|
|
|
|
|
|
The following variables are used:
|
|
|
|
PYTHON_VERSION required
|
|
|
|
PYTAG required
|
|
|
|
PYTHON_LDFLAGS required
|
|
|
|
pyext_PATTERN required
|
|
|
|
PYTHON_PYEXT_LDFLAGS
|
|
|
|
PYTHON_PYEMBED_LDFLAGS
|
|
|
|
"""
|
|
|
|
features = Utils.to_list(features)
|
|
|
|
if not ('PYTHON_LDFLAGS' in self.environ or 'PYTHON_PYEXT_LDFLAGS' in self.environ or 'PYTHON_PYEMBED_LDFLAGS' in self.environ):
|
|
|
|
return False
|
|
|
|
|
|
|
|
for x in 'PYTHON_VERSION PYTAG pyext_PATTERN'.split():
|
|
|
|
if not x in self.environ:
|
|
|
|
self.fatal('Please set %s in the os environment' % x)
|
|
|
|
else:
|
|
|
|
self.env[x] = self.environ[x]
|
|
|
|
|
|
|
|
xx = self.env.CXX_NAME and 'cxx' or 'c'
|
|
|
|
if 'pyext' in features:
|
2016-04-19 22:00:21 +02:00
|
|
|
flags = self.environ.get('PYTHON_PYEXT_LDFLAGS', self.environ.get('PYTHON_LDFLAGS'))
|
2015-03-01 11:59:16 +01:00
|
|
|
if flags is None:
|
|
|
|
self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
|
|
|
|
else:
|
|
|
|
self.parse_flags(flags, 'PYEXT')
|
2015-10-09 19:19:59 +02:00
|
|
|
self.test_pyext(xx)
|
2015-03-01 11:59:16 +01:00
|
|
|
if 'pyembed' in features:
|
2016-04-19 22:00:21 +02:00
|
|
|
flags = self.environ.get('PYTHON_PYEMBED_LDFLAGS', self.environ.get('PYTHON_LDFLAGS'))
|
2015-03-01 11:59:16 +01:00
|
|
|
if flags is None:
|
|
|
|
self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
|
|
|
|
else:
|
|
|
|
self.parse_flags(flags, 'PYEMBED')
|
2015-10-09 19:19:59 +02:00
|
|
|
self.test_pyembed(xx)
|
2015-03-01 11:59:16 +01:00
|
|
|
return True
|
|
|
|
|
2011-09-10 11:13:51 +02:00
|
|
|
@conf
|
2015-02-27 12:03:53 +01:00
|
|
|
def check_python_headers(conf, features='pyembed pyext'):
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
2021-09-30 21:30:49 +02:00
|
|
|
Check for headers and libraries necessary to extend or embed python by using the module *sysconfig*.
|
2011-09-10 11:13:51 +02:00
|
|
|
On success the environment variables xxx_PYEXT and xxx_PYEMBED are added:
|
|
|
|
|
|
|
|
* PYEXT: for compiling python extensions
|
|
|
|
* PYEMBED: for embedding a python interpreter
|
|
|
|
"""
|
2015-03-01 11:59:16 +01:00
|
|
|
features = Utils.to_list(features)
|
2015-02-27 12:03:53 +01:00
|
|
|
assert ('pyembed' in features) or ('pyext' in features), "check_python_headers features must include 'pyembed' and/or 'pyext'"
|
2012-07-03 15:42:17 +02:00
|
|
|
env = conf.env
|
2016-06-25 23:54:12 +02:00
|
|
|
if not env.CC_NAME and not env.CXX_NAME:
|
2011-09-10 11:13:51 +02:00
|
|
|
conf.fatal('load a compiler first (gcc, g++, ..)')
|
|
|
|
|
2015-03-01 11:59:16 +01:00
|
|
|
# bypass all the code below for cross-compilation
|
|
|
|
if conf.python_cross_compile(features):
|
|
|
|
return
|
|
|
|
|
2016-06-25 23:54:12 +02:00
|
|
|
if not env.PYTHON_VERSION:
|
2011-09-10 11:13:51 +02:00
|
|
|
conf.check_python_version()
|
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
pybin = env.PYTHON
|
2011-09-10 11:13:51 +02:00
|
|
|
if not pybin:
|
2012-07-03 15:42:17 +02:00
|
|
|
conf.fatal('Could not find the python executable')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2015-03-01 11:59:16 +01:00
|
|
|
# so we actually do all this for compatibility reasons and for obtaining pyext_PATTERN below
|
2022-05-17 17:09:21 +02:00
|
|
|
v = 'prefix SO EXT_SUFFIX LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
|
2011-09-10 11:13:51 +02:00
|
|
|
try:
|
2021-09-30 21:30:49 +02:00
|
|
|
lst = conf.get_sysconfig_variables(variables=v)
|
2011-09-10 11:13:51 +02:00
|
|
|
except RuntimeError:
|
|
|
|
conf.fatal("Python development headers not found (-v for details).")
|
|
|
|
|
|
|
|
vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)]
|
2015-03-01 11:59:16 +01:00
|
|
|
conf.to_log("Configuration returned from %r:\n%s\n" % (pybin, '\n'.join(vals)))
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
dct = dict(zip(v, lst))
|
|
|
|
x = 'MACOSX_DEPLOYMENT_TARGET'
|
|
|
|
if dct[x]:
|
2020-12-17 14:17:35 +01:00
|
|
|
env[x] = conf.environ[x] = str(dct[x])
|
2022-05-17 17:09:21 +02:00
|
|
|
env.pyext_PATTERN = '%s' + (dct['EXT_SUFFIX'] or dct['SO']) # SO is deprecated in 3.5 and removed in 3.11
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
# Try to get pythonX.Y-config
|
2016-06-25 23:54:12 +02:00
|
|
|
num = '.'.join(env.PYTHON_VERSION.split('.')[:2])
|
2014-10-27 04:02:39 +01:00
|
|
|
conf.find_program([''.join(pybin) + '-config', 'python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', msg="python-config", mandatory=False)
|
|
|
|
|
|
|
|
if env.PYTHON_CONFIG:
|
2018-10-23 12:38:41 +02:00
|
|
|
# check python-config output only once
|
|
|
|
if conf.env.HAVE_PYTHON_H:
|
|
|
|
return
|
|
|
|
|
2015-02-27 12:03:53 +01:00
|
|
|
# python2.6-config requires 3 runs
|
2014-10-27 04:02:39 +01:00
|
|
|
all_flags = [['--cflags', '--libs', '--ldflags']]
|
2015-02-27 12:03:53 +01:00
|
|
|
if sys.hexversion < 0x2070000:
|
2014-10-27 04:02:39 +01:00
|
|
|
all_flags = [[k] for k in all_flags[0]]
|
|
|
|
|
|
|
|
xx = env.CXX_NAME and 'cxx' or 'c'
|
|
|
|
|
2015-02-27 12:03:53 +01:00
|
|
|
if 'pyembed' in features:
|
|
|
|
for flags in all_flags:
|
2019-05-24 11:49:58 +02:00
|
|
|
# Python 3.8 has different flags for pyembed, needs --embed
|
|
|
|
embedflags = flags + ['--embed']
|
|
|
|
try:
|
|
|
|
conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(embedflags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=embedflags)
|
|
|
|
except conf.errors.ConfigurationError:
|
|
|
|
# However Python < 3.8 doesn't accept --embed, so we need a fallback
|
|
|
|
conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=flags)
|
2014-10-27 04:02:39 +01:00
|
|
|
|
2015-10-09 19:19:59 +02:00
|
|
|
try:
|
|
|
|
conf.test_pyembed(xx)
|
|
|
|
except conf.errors.ConfigurationError:
|
|
|
|
# python bug 7352
|
|
|
|
if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']:
|
|
|
|
env.append_unique('LIBPATH_PYEMBED', [dct['LIBDIR']])
|
|
|
|
conf.test_pyembed(xx)
|
|
|
|
else:
|
|
|
|
raise
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2015-02-27 12:03:53 +01:00
|
|
|
if 'pyext' in features:
|
|
|
|
for flags in all_flags:
|
|
|
|
conf.check_cfg(msg='Asking python-config for pyext %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEXT', args=flags)
|
2014-09-28 23:07:02 +02:00
|
|
|
|
2015-10-09 19:19:59 +02:00
|
|
|
try:
|
|
|
|
conf.test_pyext(xx)
|
|
|
|
except conf.errors.ConfigurationError:
|
|
|
|
# python bug 7352
|
|
|
|
if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']:
|
|
|
|
env.append_unique('LIBPATH_PYEXT', [dct['LIBDIR']])
|
|
|
|
conf.test_pyext(xx)
|
|
|
|
else:
|
|
|
|
raise
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
conf.define('HAVE_PYTHON_H', 1)
|
|
|
|
return
|
2014-09-28 23:07:02 +02:00
|
|
|
|
2015-03-01 11:59:16 +01:00
|
|
|
# No python-config, do something else on windows systems
|
2014-10-27 04:02:39 +01:00
|
|
|
all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS']
|
|
|
|
conf.parse_flags(all_flags, 'PYEMBED')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS']
|
|
|
|
conf.parse_flags(all_flags, 'PYEXT')
|
2014-09-28 23:07:02 +02:00
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
result = None
|
|
|
|
if not dct["LDVERSION"]:
|
2016-06-25 23:54:12 +02:00
|
|
|
dct["LDVERSION"] = env.PYTHON_VERSION
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
# further simplification will be complicated
|
2016-06-25 23:54:12 +02:00
|
|
|
for name in ('python' + dct['LDVERSION'], 'python' + env.PYTHON_VERSION + 'm', 'python' + env.PYTHON_VERSION.replace('.', '')):
|
2014-10-27 04:02:39 +01:00
|
|
|
|
|
|
|
# LIBPATH_PYEMBED is already set; see if it works.
|
2016-06-25 23:54:12 +02:00
|
|
|
if not result and env.LIBPATH_PYEMBED:
|
|
|
|
path = env.LIBPATH_PYEMBED
|
2014-10-27 04:02:39 +01:00
|
|
|
conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path)
|
|
|
|
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name)
|
|
|
|
|
|
|
|
if not result and dct['LIBDIR']:
|
|
|
|
path = [dct['LIBDIR']]
|
|
|
|
conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path)
|
|
|
|
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name)
|
|
|
|
|
|
|
|
if not result and dct['LIBPL']:
|
|
|
|
path = [dct['LIBPL']]
|
|
|
|
conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
|
|
|
|
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name)
|
|
|
|
|
|
|
|
if not result:
|
|
|
|
path = [os.path.join(dct['prefix'], "libs")]
|
2021-04-30 18:38:01 +02:00
|
|
|
conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY rather than pythonX.Y (win32)\n")
|
2014-10-27 04:02:39 +01:00
|
|
|
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name)
|
|
|
|
|
2021-04-30 18:38:01 +02:00
|
|
|
if not result:
|
|
|
|
path = [os.path.normpath(os.path.join(dct['INCLUDEPY'], '..', 'libs'))]
|
|
|
|
conf.to_log("\n\n# try again with -L$INCLUDEPY/../libs, and pythonXY rather than pythonX.Y (win32)\n")
|
|
|
|
result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $INCLUDEPY/../libs' % name)
|
|
|
|
|
2014-10-27 04:02:39 +01:00
|
|
|
if result:
|
|
|
|
break # do not forget to set LIBPATH_PYEMBED
|
|
|
|
|
|
|
|
if result:
|
2016-06-25 23:54:12 +02:00
|
|
|
env.LIBPATH_PYEMBED = path
|
2014-10-27 04:02:39 +01:00
|
|
|
env.append_value('LIB_PYEMBED', [name])
|
|
|
|
else:
|
|
|
|
conf.to_log("\n\n### LIB NOT FOUND\n")
|
|
|
|
|
|
|
|
# under certain conditions, python extensions must link to
|
|
|
|
# python libraries, not just python embedding programs.
|
|
|
|
if Utils.is_win32 or dct['Py_ENABLE_SHARED']:
|
2016-06-25 23:54:12 +02:00
|
|
|
env.LIBPATH_PYEXT = env.LIBPATH_PYEMBED
|
|
|
|
env.LIB_PYEXT = env.LIB_PYEMBED
|
2014-10-27 04:02:39 +01:00
|
|
|
|
2021-09-30 21:30:49 +02:00
|
|
|
conf.to_log("Include path for Python extensions (found via sysconfig module): %r\n" % (dct['INCLUDEPY'],))
|
2016-06-25 23:54:12 +02:00
|
|
|
env.INCLUDES_PYEXT = [dct['INCLUDEPY']]
|
|
|
|
env.INCLUDES_PYEMBED = [dct['INCLUDEPY']]
|
2014-10-27 04:02:39 +01:00
|
|
|
|
|
|
|
# Code using the Python API needs to be compiled with -fno-strict-aliasing
|
2016-06-25 23:54:12 +02:00
|
|
|
if env.CC_NAME == 'gcc':
|
2019-06-20 23:14:51 +02:00
|
|
|
env.append_unique('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
|
|
|
|
env.append_unique('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
|
2016-06-25 23:54:12 +02:00
|
|
|
if env.CXX_NAME == 'gcc':
|
2019-06-20 23:14:51 +02:00
|
|
|
env.append_unique('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
|
|
|
|
env.append_unique('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
|
2014-10-27 04:02:39 +01:00
|
|
|
|
|
|
|
if env.CC_NAME == "msvc":
|
2021-09-30 21:30:49 +02:00
|
|
|
# From https://github.com/python/cpython/blob/main/Lib/distutils/msvccompiler.py
|
|
|
|
env.append_value('CFLAGS_PYEXT', [ '/nologo', '/Ox', '/MD', '/W3', '/GX', '/DNDEBUG'])
|
|
|
|
env.append_value('CXXFLAGS_PYEXT', [ '/nologo', '/Ox', '/MD', '/W3', '/GX', '/DNDEBUG'])
|
|
|
|
env.append_value('LINKFLAGS_PYEXT', ['/DLL', '/nologo', '/INCREMENTAL:NO'])
|
2014-10-27 04:02:39 +01:00
|
|
|
|
|
|
|
# See if it compiles
|
2021-09-30 21:30:49 +02:00
|
|
|
conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', uselib='PYEMBED', fragment=FRAG, errmsg='Broken python installation? Get python-config now!')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
@conf
|
|
|
|
def check_python_version(conf, minver=None):
|
|
|
|
"""
|
|
|
|
Check if the python interpreter is found matching a given minimum version.
|
|
|
|
minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver.
|
|
|
|
|
2018-05-24 15:54:19 +02:00
|
|
|
If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR' (eg. '2.4')
|
|
|
|
of the actual python version found, and PYTHONDIR and PYTHONARCHDIR
|
|
|
|
are defined, pointing to the site-packages directories appropriate for
|
2011-09-10 11:13:51 +02:00
|
|
|
this python version, where modules/packages/extensions should be
|
|
|
|
installed.
|
|
|
|
|
|
|
|
:param minver: minimum version
|
|
|
|
:type minver: tuple of int
|
|
|
|
"""
|
|
|
|
assert minver is None or isinstance(minver, tuple)
|
2016-06-25 23:54:12 +02:00
|
|
|
pybin = conf.env.PYTHON
|
2011-09-10 11:13:51 +02:00
|
|
|
if not pybin:
|
|
|
|
conf.fatal('could not find the python executable')
|
|
|
|
|
|
|
|
# Get python version string
|
|
|
|
cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))']
|
2016-03-19 14:46:22 +01:00
|
|
|
Logs.debug('python: Running python command %r', cmd)
|
2011-09-10 11:13:51 +02:00
|
|
|
lines = conf.cmd_and_log(cmd).split()
|
2016-04-27 18:42:38 +02:00
|
|
|
assert len(lines) == 5, "found %r lines, expected 5: %r" % (len(lines), lines)
|
2011-09-10 11:13:51 +02:00
|
|
|
pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4]))
|
|
|
|
|
2016-06-20 21:33:26 +02:00
|
|
|
# Compare python version with the minimum required
|
2011-09-10 11:13:51 +02:00
|
|
|
result = (minver is None) or (pyver_tuple >= minver)
|
|
|
|
|
|
|
|
if result:
|
|
|
|
# define useful environment variables
|
|
|
|
pyver = '.'.join([str(x) for x in pyver_tuple[:2]])
|
2016-06-25 23:54:12 +02:00
|
|
|
conf.env.PYTHON_VERSION = pyver
|
2011-09-10 11:13:51 +02:00
|
|
|
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
if 'PYTHONDIR' in conf.env:
|
|
|
|
# Check if --pythondir was specified
|
2016-06-25 23:54:12 +02:00
|
|
|
pydir = conf.env.PYTHONDIR
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
elif 'PYTHONDIR' in conf.environ:
|
|
|
|
# Check environment for PYTHONDIR
|
2011-09-10 11:13:51 +02:00
|
|
|
pydir = conf.environ['PYTHONDIR']
|
|
|
|
else:
|
2022-12-31 10:19:18 +01:00
|
|
|
pydir = conf.get_sysconfig_path('purelib')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
if 'PYTHONARCHDIR' in conf.env:
|
|
|
|
# Check if --pythonarchdir was specified
|
2016-06-25 23:54:12 +02:00
|
|
|
pyarchdir = conf.env.PYTHONARCHDIR
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
elif 'PYTHONARCHDIR' in conf.environ:
|
|
|
|
# Check environment for PYTHONDIR
|
2011-09-10 11:13:51 +02:00
|
|
|
pyarchdir = conf.environ['PYTHONARCHDIR']
|
|
|
|
else:
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
# Finally, try to guess
|
2022-12-31 10:19:18 +01:00
|
|
|
pyarchdir = conf.get_sysconfig_path('platlib')
|
2021-09-30 21:30:49 +02:00
|
|
|
|
2011-09-10 11:13:51 +02:00
|
|
|
if not pyarchdir:
|
|
|
|
pyarchdir = pydir
|
|
|
|
|
|
|
|
if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist
|
|
|
|
conf.define('PYTHONDIR', pydir)
|
|
|
|
conf.define('PYTHONARCHDIR', pyarchdir)
|
|
|
|
|
2016-06-25 23:54:12 +02:00
|
|
|
conf.env.PYTHONDIR = pydir
|
|
|
|
conf.env.PYTHONARCHDIR = pyarchdir
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
# Feedback
|
|
|
|
pyver_full = '.'.join(map(str, pyver_tuple[:3]))
|
|
|
|
if minver is None:
|
|
|
|
conf.msg('Checking for python version', pyver_full)
|
|
|
|
else:
|
|
|
|
minver_str = '.'.join(map(str, minver))
|
2016-06-21 20:21:43 +02:00
|
|
|
conf.msg('Checking for python version >= %s' % (minver_str,), pyver_full, color=result and 'GREEN' or 'YELLOW')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
if not result:
|
|
|
|
conf.fatal('The python version is too old, expecting %r' % (minver,))
|
|
|
|
|
|
|
|
PYTHON_MODULE_TEMPLATE = '''
|
2012-01-14 16:35:33 +01:00
|
|
|
import %s as current_module
|
|
|
|
version = getattr(current_module, '__version__', None)
|
|
|
|
if version is not None:
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
print(str(version))
|
2012-01-14 16:35:33 +01:00
|
|
|
else:
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
print('unknown version')
|
2011-09-10 11:13:51 +02:00
|
|
|
'''
|
|
|
|
|
|
|
|
@conf
|
2012-01-14 16:35:33 +01:00
|
|
|
def check_python_module(conf, module_name, condition=''):
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
|
|
|
Check if the selected python interpreter can import the given python module::
|
|
|
|
|
|
|
|
def configure(conf):
|
|
|
|
conf.check_python_module('pygccxml')
|
2012-01-14 16:35:33 +01:00
|
|
|
conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)")
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
:param module_name: module
|
|
|
|
:type module_name: string
|
|
|
|
"""
|
2016-04-26 19:35:46 +02:00
|
|
|
msg = "Checking for python module %r" % module_name
|
2012-01-14 16:35:33 +01:00
|
|
|
if condition:
|
|
|
|
msg = '%s (%s)' % (msg, condition)
|
|
|
|
conf.start_msg(msg)
|
2011-09-10 11:13:51 +02:00
|
|
|
try:
|
2016-06-25 23:54:12 +02:00
|
|
|
ret = conf.cmd_and_log(conf.env.PYTHON + ['-c', PYTHON_MODULE_TEMPLATE % module_name])
|
2017-06-20 11:20:53 +02:00
|
|
|
except Errors.WafError:
|
2011-09-10 11:13:51 +02:00
|
|
|
conf.end_msg(False)
|
|
|
|
conf.fatal('Could not find the python module %r' % module_name)
|
2012-01-14 16:35:33 +01:00
|
|
|
|
|
|
|
ret = ret.strip()
|
|
|
|
if condition:
|
|
|
|
conf.end_msg(ret)
|
|
|
|
if ret == 'unknown version':
|
|
|
|
conf.fatal('Could not check the %s version' % module_name)
|
|
|
|
|
|
|
|
def num(*k):
|
|
|
|
if isinstance(k[0], int):
|
2022-12-22 18:31:36 +01:00
|
|
|
return Utils.loose_version('.'.join([str(x) for x in k]))
|
2012-01-14 16:35:33 +01:00
|
|
|
else:
|
2022-12-22 18:31:36 +01:00
|
|
|
return Utils.loose_version(k[0])
|
|
|
|
d = {'num': num, 'ver': Utils.loose_version(ret)}
|
2012-01-14 16:35:33 +01:00
|
|
|
ev = eval(condition, {}, d)
|
|
|
|
if not ev:
|
|
|
|
conf.fatal('The %s version does not satisfy the requirements' % module_name)
|
|
|
|
else:
|
|
|
|
if ret == 'unknown version':
|
|
|
|
conf.end_msg(True)
|
|
|
|
else:
|
|
|
|
conf.end_msg(ret)
|
2011-09-10 11:13:51 +02:00
|
|
|
|
|
|
|
def configure(conf):
|
|
|
|
"""
|
|
|
|
Detect the python interpreter
|
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
v = conf.env
|
2017-04-13 12:11:36 +02:00
|
|
|
if getattr(Options.options, 'pythondir', None):
|
2016-06-25 23:54:12 +02:00
|
|
|
v.PYTHONDIR = Options.options.pythondir
|
2017-04-13 12:11:36 +02:00
|
|
|
if getattr(Options.options, 'pythonarchdir', None):
|
2016-06-25 23:54:12 +02:00
|
|
|
v.PYTHONARCHDIR = Options.options.pythonarchdir
|
2017-04-13 12:11:36 +02:00
|
|
|
if getattr(Options.options, 'nopycache', None):
|
2016-12-15 19:03:29 +01:00
|
|
|
v.NOPYCACHE=Options.options.nopycache
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2017-04-14 01:54:19 +02:00
|
|
|
if not v.PYTHON:
|
2017-05-28 20:13:55 +02:00
|
|
|
v.PYTHON = [getattr(Options.options, 'python', None) or sys.executable]
|
2017-04-14 01:54:19 +02:00
|
|
|
v.PYTHON = Utils.to_list(v.PYTHON)
|
|
|
|
conf.find_program('python', var='PYTHON')
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2016-06-25 23:54:12 +02:00
|
|
|
v.PYFLAGS = ''
|
|
|
|
v.PYFLAGS_OPT = '-O'
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2016-06-25 23:54:12 +02:00
|
|
|
v.PYC = getattr(Options.options, 'pyc', 1)
|
|
|
|
v.PYO = getattr(Options.options, 'pyo', 1)
|
2011-09-10 11:13:51 +02:00
|
|
|
|
2014-07-25 18:15:23 +02:00
|
|
|
try:
|
2019-08-14 22:05:45 +02:00
|
|
|
v.PYTAG = conf.cmd_and_log(conf.env.PYTHON + ['-c', "import sys\ntry:\n print(sys.implementation.cache_tag)\nexcept AttributeError:\n import imp\n print(imp.get_tag())\n"]).strip()
|
2014-07-25 18:15:23 +02:00
|
|
|
except Errors.WafError:
|
|
|
|
pass
|
|
|
|
|
2011-09-10 11:13:51 +02:00
|
|
|
def options(opt):
|
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
Add python-specific options
|
2011-09-10 11:13:51 +02:00
|
|
|
"""
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
pyopt=opt.add_option_group("Python Options")
|
|
|
|
pyopt.add_option('--nopyc', dest = 'pyc', action='store_false', default=1,
|
|
|
|
help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]')
|
|
|
|
pyopt.add_option('--nopyo', dest='pyo', action='store_false', default=1,
|
|
|
|
help='Do not install optimised compiled .pyo files (configuration) [Default:install]')
|
2016-12-15 19:03:29 +01:00
|
|
|
pyopt.add_option('--nopycache',dest='nopycache', action='store_true',
|
|
|
|
help='Do not use __pycache__ directory to install objects [Default:auto]')
|
Tools/python: Extending python tool
add: show more command-line arguments to control which
python is used and where py/pyext files should be installed.
The new options are in addition to the existing PYTHON, PYTHONDIR,
and PYTHONARCHDIR environment variable, providing the help messages
to the user, so it can easily change parameters without second-guessing
of what are they.
Environmental parameters override command line arguments (is it right?)
updated: An extension to Configure.find_command to allow specification
of the name for the searched command (using `msg` option). This is
helpful when the search command is a huge list, as in the case of
python's python-config case.
updated: Do not specify prefix for `get_python_lib`, since this way it
can result in a wrong PYTHONDIR and PYTHONARCHDIR on certain platforms
(e.g., OSX)
updated: Changing logic with byte-compilation of python files. Mow, files are
compiled during the build stage, not install stage. During the
install stage files are simply copied to the requested
location.
updated: If there is an error in python source code, byte-compilation
phase will raise an exception and abort building process.
Signed-off-by: Thomas Nagy <tnagy2pow10@gmail.com>
2013-07-12 08:15:35 +02:00
|
|
|
pyopt.add_option('--python', dest="python",
|
|
|
|
help='python binary to be used [Default: %s]' % sys.executable)
|
|
|
|
pyopt.add_option('--pythondir', dest='pythondir',
|
|
|
|
help='Installation path for python modules (py, platform-independent .py and .pyc files)')
|
|
|
|
pyopt.add_option('--pythonarchdir', dest='pythonarchdir',
|
|
|
|
help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)')
|
2014-07-25 18:15:23 +02:00
|
|
|
|