123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 |
- #!/usr/bin/env python
- # encoding: utf-8
- # Thomas Nagy, 2007-2015 (ita)
- # 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
- from waflib import Errors, Logs, Node, Options, Task, Utils
- 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
- int main(int argc, char **argv)
- {
- (void)argc; (void)argv;
- 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
- py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True)
- '''
- """
- Piece of Python code used in :py:class:`waflib.Tools.python.pyo` and :py:class:`waflib.Tools.python.pyc` for byte-compiling python files
- """
- DISTUTILS_IMP = ['from distutils.sysconfig import get_config_var, get_python_lib']
- @before_method('process_source')
- @feature('py')
- def feature_py(self):
- """
- Create tasks to byte-compile .py files and install them, if requested
- """
- 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
- ver = self.env.PYTHON_VERSION
- if not ver:
- self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version')
- if int(ver.replace('.', '')) > 31:
- self.install_32 = True
- @extension('.py')
- def process_py(self, node):
- """
- Add signature of .py file, so it will be byte-compiled when necessary
- """
- assert(hasattr(self, 'install_path')), 'add features="py"'
- # where to install the python file
- if self.install_path:
- if self.install_from:
- self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=True)
- else:
- self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=True)
- lst = []
- if self.env.PYC:
- lst.append('pyc')
- if self.env.PYO:
- lst.append('pyo')
- if self.install_path:
- if self.install_from:
- pyd = Utils.subst_vars("%s/%s" % (self.install_path, node.path_from(self.install_from)), self.env)
- else:
- pyd = Utils.subst_vars("%s/%s" % (self.install_path, node.path_from(self.path)), self.env)
- else:
- pyd = node.abspath()
- for ext in lst:
- if self.env.PYTAG and not self.env.NOPYCACHE:
- # __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:
- self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=True)
- class pyc(Task.Task):
- """
- Byte-compiling python files
- """
- color = 'PINK'
- def __str__(self):
- node = self.outputs[0]
- return node.path_from(node.ctx.launch_node())
- 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
- class pyo(Task.Task):
- """
- Byte-compiling python files
- """
- color = 'PINK'
- def __str__(self):
- node = self.outputs[0]
- return node.path_from(node.ctx.launch_node())
- def run(self):
- 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]
- ret = self.generator.bld.exec_command(cmd)
- return ret
- @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
- 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
- try:
- if not self.install_path:
- return
- except AttributeError:
- self.install_path = '${PYTHONARCHDIR}'
- @feature('pyext')
- @before_method('apply_link', 'apply_bundle')
- def set_bundle(self):
- """Mac-specific pyext extension that enables bundles from c_osx.py"""
- if Utils.unversioned_sys_platform() == 'darwin':
- 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
- def get_python_variables(self, variables, imports=None):
- """
- Spawn a new python process to dump configuration variables
- :param variables: variables to print
- :type variables: list of string
- :param imports: one import by element
- :type imports: list of string
- :return: the variable values
- :rtype: list of string
- """
- if not imports:
- try:
- imports = self.python_imports
- except AttributeError:
- imports = DISTUTILS_IMP
- program = list(imports) # copy
- program.append('')
- for v in variables:
- program.append("print(repr(%s))" % v)
- os_env = dict(os.environ)
- try:
- del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool
- except KeyError:
- pass
- try:
- out = self.cmd_and_log(self.env.PYTHON + ['-c', '\n'.join(program)], env=os_env)
- except Errors.WafError:
- self.fatal('The distutils module is unusable: install "python-devel"?')
- self.to_log(out)
- return_values = []
- for s in out.splitlines():
- s = s.strip()
- if not s:
- continue
- if s == 'None':
- return_values.append(None)
- elif (s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"'):
- return_values.append(eval(s))
- elif s[0].isdigit():
- return_values.append(int(s))
- else: break
- return return_values
- @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))
- @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:
- flags = self.environ.get('PYTHON_PYEXT_LDFLAGS', self.environ.get('PYTHON_LDFLAGS'))
- if flags is None:
- self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required')
- else:
- self.parse_flags(flags, 'PYEXT')
- self.test_pyext(xx)
- if 'pyembed' in features:
- flags = self.environ.get('PYTHON_PYEMBED_LDFLAGS', self.environ.get('PYTHON_LDFLAGS'))
- if flags is None:
- self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required')
- else:
- self.parse_flags(flags, 'PYEMBED')
- self.test_pyembed(xx)
- return True
- @conf
- def check_python_headers(conf, features='pyembed pyext'):
- """
- Check for headers and libraries necessary to extend or embed python by using the module *distutils*.
- On success the environment variables xxx_PYEXT and xxx_PYEMBED are added:
- * PYEXT: for compiling python extensions
- * PYEMBED: for embedding a python interpreter
- """
- features = Utils.to_list(features)
- assert ('pyembed' in features) or ('pyext' in features), "check_python_headers features must include 'pyembed' and/or 'pyext'"
- env = conf.env
- if not env.CC_NAME and not env.CXX_NAME:
- conf.fatal('load a compiler first (gcc, g++, ..)')
- # bypass all the code below for cross-compilation
- if conf.python_cross_compile(features):
- return
- if not env.PYTHON_VERSION:
- conf.check_python_version()
- pybin = env.PYTHON
- if not pybin:
- conf.fatal('Could not find the python executable')
- # so we actually do all this for compatibility reasons and for obtaining pyext_PATTERN below
- v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split()
- try:
- lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v])
- except RuntimeError:
- conf.fatal("Python development headers not found (-v for details).")
- vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)]
- conf.to_log("Configuration returned from %r:\n%s\n" % (pybin, '\n'.join(vals)))
- dct = dict(zip(v, lst))
- x = 'MACOSX_DEPLOYMENT_TARGET'
- if dct[x]:
- env[x] = conf.environ[x] = dct[x]
- env.pyext_PATTERN = '%s' + dct['SO'] # not a mistake
- # Try to get pythonX.Y-config
- num = '.'.join(env.PYTHON_VERSION.split('.')[:2])
- 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:
- # python2.6-config requires 3 runs
- all_flags = [['--cflags', '--libs', '--ldflags']]
- if sys.hexversion < 0x2070000:
- all_flags = [[k] for k in all_flags[0]]
- xx = env.CXX_NAME and 'cxx' or 'c'
- if 'pyembed' in features:
- for flags in all_flags:
- conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=flags)
- 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
- 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)
- 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
- conf.define('HAVE_PYTHON_H', 1)
- return
- # No python-config, do something else on windows systems
- all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS']
- conf.parse_flags(all_flags, 'PYEMBED')
- all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS']
- conf.parse_flags(all_flags, 'PYEXT')
- result = None
- if not dct["LDVERSION"]:
- dct["LDVERSION"] = env.PYTHON_VERSION
- # further simplification will be complicated
- for name in ('python' + dct['LDVERSION'], 'python' + env.PYTHON_VERSION + 'm', 'python' + env.PYTHON_VERSION.replace('.', '')):
- # LIBPATH_PYEMBED is already set; see if it works.
- if not result and env.LIBPATH_PYEMBED:
- path = env.LIBPATH_PYEMBED
- 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")]
- conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
- result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name)
- if result:
- break # do not forget to set LIBPATH_PYEMBED
- if result:
- env.LIBPATH_PYEMBED = path
- 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']:
- env.LIBPATH_PYEXT = env.LIBPATH_PYEMBED
- env.LIB_PYEXT = env.LIB_PYEMBED
- conf.to_log("Include path for Python extensions (found via distutils module): %r\n" % (dct['INCLUDEPY'],))
- env.INCLUDES_PYEXT = [dct['INCLUDEPY']]
- env.INCLUDES_PYEMBED = [dct['INCLUDEPY']]
- # Code using the Python API needs to be compiled with -fno-strict-aliasing
- if env.CC_NAME == 'gcc':
- env.append_value('CFLAGS_PYEMBED', ['-fno-strict-aliasing'])
- env.append_value('CFLAGS_PYEXT', ['-fno-strict-aliasing'])
- if env.CXX_NAME == 'gcc':
- env.append_value('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing'])
- env.append_value('CXXFLAGS_PYEXT', ['-fno-strict-aliasing'])
- if env.CC_NAME == "msvc":
- from distutils.msvccompiler import MSVCCompiler
- dist_compiler = MSVCCompiler()
- dist_compiler.initialize()
- env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options)
- env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options)
- env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared)
- # See if it compiles
- conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', uselib='PYEMBED', fragment=FRAG, errmsg='Distutils not installed? Broken python installation? Get python-config now!')
- @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.
- 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
- 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)
- pybin = conf.env.PYTHON
- 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))']
- Logs.debug('python: Running python command %r', cmd)
- lines = conf.cmd_and_log(cmd).split()
- assert len(lines) == 5, "found %r lines, expected 5: %r" % (len(lines), lines)
- pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4]))
- # Compare python version with the minimum required
- result = (minver is None) or (pyver_tuple >= minver)
- if result:
- # define useful environment variables
- pyver = '.'.join([str(x) for x in pyver_tuple[:2]])
- conf.env.PYTHON_VERSION = pyver
- if 'PYTHONDIR' in conf.env:
- # Check if --pythondir was specified
- pydir = conf.env.PYTHONDIR
- elif 'PYTHONDIR' in conf.environ:
- # Check environment for PYTHONDIR
- pydir = conf.environ['PYTHONDIR']
- else:
- # Finally, try to guess
- if Utils.is_win32:
- (python_LIBDEST, pydir) = conf.get_python_variables(
- ["get_config_var('LIBDEST') or ''",
- "get_python_lib(standard_lib=0) or ''"])
- else:
- python_LIBDEST = None
- (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX])
- if python_LIBDEST is None:
- if conf.env.LIBDIR:
- python_LIBDEST = os.path.join(conf.env.LIBDIR, 'python' + pyver)
- else:
- python_LIBDEST = os.path.join(conf.env.PREFIX, 'lib', 'python' + pyver)
- if 'PYTHONARCHDIR' in conf.env:
- # Check if --pythonarchdir was specified
- pyarchdir = conf.env.PYTHONARCHDIR
- elif 'PYTHONARCHDIR' in conf.environ:
- # Check environment for PYTHONDIR
- pyarchdir = conf.environ['PYTHONARCHDIR']
- else:
- # Finally, try to guess
- (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX])
- 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)
- conf.env.PYTHONDIR = pydir
- conf.env.PYTHONARCHDIR = pyarchdir
- # 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))
- conf.msg('Checking for python version >= %s' % (minver_str,), pyver_full, color=result and 'GREEN' or 'YELLOW')
- if not result:
- conf.fatal('The python version is too old, expecting %r' % (minver,))
- PYTHON_MODULE_TEMPLATE = '''
- import %s as current_module
- version = getattr(current_module, '__version__', None)
- if version is not None:
- print(str(version))
- else:
- print('unknown version')
- '''
- @conf
- def check_python_module(conf, module_name, condition=''):
- """
- Check if the selected python interpreter can import the given python module::
- def configure(conf):
- conf.check_python_module('pygccxml')
- conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)")
- :param module_name: module
- :type module_name: string
- """
- msg = "Checking for python module %r" % module_name
- if condition:
- msg = '%s (%s)' % (msg, condition)
- conf.start_msg(msg)
- try:
- ret = conf.cmd_and_log(conf.env.PYTHON + ['-c', PYTHON_MODULE_TEMPLATE % module_name])
- except Errors.WafError:
- conf.end_msg(False)
- conf.fatal('Could not find the python module %r' % module_name)
- ret = ret.strip()
- if condition:
- conf.end_msg(ret)
- if ret == 'unknown version':
- conf.fatal('Could not check the %s version' % module_name)
- from distutils.version import LooseVersion
- def num(*k):
- if isinstance(k[0], int):
- return LooseVersion('.'.join([str(x) for x in k]))
- else:
- return LooseVersion(k[0])
- d = {'num': num, 'ver': LooseVersion(ret)}
- 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)
- def configure(conf):
- """
- Detect the python interpreter
- """
- v = conf.env
- if getattr(Options.options, 'pythondir', None):
- v.PYTHONDIR = Options.options.pythondir
- if getattr(Options.options, 'pythonarchdir', None):
- v.PYTHONARCHDIR = Options.options.pythonarchdir
- if getattr(Options.options, 'nopycache', None):
- v.NOPYCACHE=Options.options.nopycache
- if not v.PYTHON:
- v.PYTHON = [getattr(Options.options, 'python', None) or sys.executable]
- v.PYTHON = Utils.to_list(v.PYTHON)
- conf.find_program('python', var='PYTHON')
- v.PYFLAGS = ''
- v.PYFLAGS_OPT = '-O'
- v.PYC = getattr(Options.options, 'pyc', 1)
- v.PYO = getattr(Options.options, 'pyo', 1)
- try:
- v.PYTAG = conf.cmd_and_log(conf.env.PYTHON + ['-c', "import imp;print(imp.get_tag())"]).strip()
- except Errors.WafError:
- pass
- def options(opt):
- """
- Add python-specific options
- """
- 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]')
- pyopt.add_option('--nopycache',dest='nopycache', action='store_true',
- help='Do not use __pycache__ directory to install objects [Default:auto]')
- 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)')
|