| | """Cython.Distutils.old_build_ext |
| | |
| | Implements a version of the Distutils 'build_ext' command, for |
| | building Cython extension modules. |
| | |
| | Note that this module is deprecated. Use cythonize() instead. |
| | """ |
| |
|
| | __revision__ = "$Id:$" |
| |
|
| | import inspect |
| | import sys |
| | import os |
| | from distutils.errors import DistutilsPlatformError |
| | from distutils.dep_util import newer, newer_group |
| | from distutils import log |
| | from distutils.command import build_ext as _build_ext |
| | from distutils import sysconfig |
| | import warnings |
| |
|
| |
|
| | try: |
| | from __builtin__ import basestring |
| | except ImportError: |
| | basestring = str |
| |
|
| |
|
| | def _check_stack(path): |
| | try: |
| | for frame in inspect.getouterframes(inspect.currentframe(), 0): |
| | if path in frame[1].replace(os.sep, '/'): |
| | return True |
| | except Exception: |
| | pass |
| | return False |
| |
|
| | if (not _check_stack('setuptools/extensions.py') |
| | and not _check_stack('pyximport/pyxbuild.py') |
| | and not _check_stack('Cython/Distutils/build_ext.py')): |
| | warnings.warn( |
| | "Cython.Distutils.old_build_ext does not properly handle dependencies " |
| | "and is deprecated.") |
| |
|
| |
|
| | extension_name_re = _build_ext.extension_name_re |
| |
|
| | show_compilers = _build_ext.show_compilers |
| |
|
| | class Optimization(object): |
| | def __init__(self): |
| | self.flags = ( |
| | 'OPT', |
| | 'CFLAGS', |
| | 'CPPFLAGS', |
| | 'EXTRA_CFLAGS', |
| | 'BASECFLAGS', |
| | 'PY_CFLAGS', |
| | ) |
| | self.state = sysconfig.get_config_vars(*self.flags) |
| | self.config_vars = sysconfig.get_config_vars() |
| |
|
| |
|
| | def disable_optimization(self): |
| | "disable optimization for the C or C++ compiler" |
| | badoptions = ('-O1', '-O2', '-O3') |
| |
|
| | for flag, option in zip(self.flags, self.state): |
| | if option is not None: |
| | L = [opt for opt in option.split() if opt not in badoptions] |
| | self.config_vars[flag] = ' '.join(L) |
| |
|
| | def restore_state(self): |
| | "restore the original state" |
| | for flag, option in zip(self.flags, self.state): |
| | if option is not None: |
| | self.config_vars[flag] = option |
| |
|
| |
|
| | optimization = Optimization() |
| |
|
| |
|
| | class old_build_ext(_build_ext.build_ext): |
| |
|
| | description = "build C/C++ and Cython extensions (compile/link to build directory)" |
| |
|
| | sep_by = _build_ext.build_ext.sep_by |
| | user_options = _build_ext.build_ext.user_options[:] |
| | boolean_options = _build_ext.build_ext.boolean_options[:] |
| | help_options = _build_ext.build_ext.help_options[:] |
| |
|
| | |
| | user_options.extend([ |
| | ('cython-cplus', None, |
| | "generate C++ source files"), |
| | ('cython-create-listing', None, |
| | "write errors to a listing file"), |
| | ('cython-line-directives', None, |
| | "emit source line directives"), |
| | ('cython-include-dirs=', None, |
| | "path to the Cython include files" + sep_by), |
| | ('cython-c-in-temp', None, |
| | "put generated C files in temp directory"), |
| | ('cython-gen-pxi', None, |
| | "generate .pxi file for public declarations"), |
| | ('cython-directives=', None, |
| | "compiler directive overrides"), |
| | ('cython-gdb', None, |
| | "generate debug information for cygdb"), |
| | ('cython-compile-time-env', None, |
| | "cython compile time environment"), |
| |
|
| | |
| | ('pyrex-cplus', None, |
| | "generate C++ source files"), |
| | ('pyrex-create-listing', None, |
| | "write errors to a listing file"), |
| | ('pyrex-line-directives', None, |
| | "emit source line directives"), |
| | ('pyrex-include-dirs=', None, |
| | "path to the Cython include files" + sep_by), |
| | ('pyrex-c-in-temp', None, |
| | "put generated C files in temp directory"), |
| | ('pyrex-gen-pxi', None, |
| | "generate .pxi file for public declarations"), |
| | ('pyrex-directives=', None, |
| | "compiler directive overrides"), |
| | ('pyrex-gdb', None, |
| | "generate debug information for cygdb"), |
| | ]) |
| |
|
| | boolean_options.extend([ |
| | 'cython-cplus', 'cython-create-listing', 'cython-line-directives', |
| | 'cython-c-in-temp', 'cython-gdb', |
| |
|
| | |
| | 'pyrex-cplus', 'pyrex-create-listing', 'pyrex-line-directives', |
| | 'pyrex-c-in-temp', 'pyrex-gdb', |
| | ]) |
| |
|
| | def initialize_options(self): |
| | _build_ext.build_ext.initialize_options(self) |
| | self.cython_cplus = 0 |
| | self.cython_create_listing = 0 |
| | self.cython_line_directives = 0 |
| | self.cython_include_dirs = None |
| | self.cython_directives = None |
| | self.cython_c_in_temp = 0 |
| | self.cython_gen_pxi = 0 |
| | self.cython_gdb = False |
| | self.no_c_in_traceback = 0 |
| | self.cython_compile_time_env = None |
| |
|
| | def __getattr__(self, name): |
| | if name[:6] == 'pyrex_': |
| | return getattr(self, 'cython_' + name[6:]) |
| | else: |
| | return _build_ext.build_ext.__getattr__(self, name) |
| |
|
| | def __setattr__(self, name, value): |
| | if name[:6] == 'pyrex_': |
| | return setattr(self, 'cython_' + name[6:], value) |
| | else: |
| | |
| | self.__dict__[name] = value |
| |
|
| | def finalize_options (self): |
| | _build_ext.build_ext.finalize_options(self) |
| | if self.cython_include_dirs is None: |
| | self.cython_include_dirs = [] |
| | elif isinstance(self.cython_include_dirs, basestring): |
| | self.cython_include_dirs = \ |
| | self.cython_include_dirs.split(os.pathsep) |
| | if self.cython_directives is None: |
| | self.cython_directives = {} |
| | |
| |
|
| | def run(self): |
| | |
| | |
| | |
| | |
| | if self.cython_gdb or [1 for ext in self.extensions |
| | if getattr(ext, 'cython_gdb', False)]: |
| | optimization.disable_optimization() |
| |
|
| | _build_ext.build_ext.run(self) |
| |
|
| | def build_extensions(self): |
| | |
| | self.check_extensions_list(self.extensions) |
| |
|
| | for ext in self.extensions: |
| | ext.sources = self.cython_sources(ext.sources, ext) |
| | |
| | _build_ext.build_ext.build_extensions(self) |
| |
|
| | def cython_sources(self, sources, extension): |
| | """ |
| | Walk the list of source files in 'sources', looking for Cython |
| | source files (.pyx and .py). Run Cython on all that are |
| | found, and return a modified 'sources' list with Cython source |
| | files replaced by the generated C (or C++) files. |
| | """ |
| | try: |
| | from Cython.Compiler.Main \ |
| | import CompilationOptions, \ |
| | default_options as cython_default_options, \ |
| | compile as cython_compile |
| | from Cython.Compiler.Errors import PyrexError |
| | except ImportError: |
| | e = sys.exc_info()[1] |
| | print("failed to import Cython: %s" % e) |
| | raise DistutilsPlatformError("Cython does not appear to be installed") |
| |
|
| | new_sources = [] |
| | cython_sources = [] |
| | cython_targets = {} |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | create_listing = self.cython_create_listing or \ |
| | getattr(extension, 'cython_create_listing', 0) |
| | line_directives = self.cython_line_directives or \ |
| | getattr(extension, 'cython_line_directives', 0) |
| | no_c_in_traceback = self.no_c_in_traceback or \ |
| | getattr(extension, 'no_c_in_traceback', 0) |
| | cplus = self.cython_cplus or getattr(extension, 'cython_cplus', 0) or \ |
| | (extension.language and extension.language.lower() == 'c++') |
| | cython_gen_pxi = self.cython_gen_pxi or getattr(extension, 'cython_gen_pxi', 0) |
| | cython_gdb = self.cython_gdb or getattr(extension, 'cython_gdb', False) |
| | cython_compile_time_env = self.cython_compile_time_env or \ |
| | getattr(extension, 'cython_compile_time_env', None) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | includes = self.cython_include_dirs |
| | try: |
| | for i in extension.cython_include_dirs: |
| | if not i in includes: |
| | includes.append(i) |
| | except AttributeError: |
| | pass |
| |
|
| | |
| | |
| | extension.include_dirs = list(extension.include_dirs) |
| | for i in extension.include_dirs: |
| | if not i in includes: |
| | includes.append(i) |
| |
|
| | |
| | |
| | |
| | |
| | directives = self.cython_directives |
| | if hasattr(extension, "cython_directives"): |
| | directives.update(extension.cython_directives) |
| |
|
| | |
| | |
| | if cplus: |
| | target_ext = '.cpp' |
| | else: |
| | target_ext = '.c' |
| |
|
| | |
| | |
| |
|
| | if not self.inplace and (self.cython_c_in_temp |
| | or getattr(extension, 'cython_c_in_temp', 0)): |
| | target_dir = os.path.join(self.build_temp, "pyrex") |
| | for package_name in extension.name.split('.')[:-1]: |
| | target_dir = os.path.join(target_dir, package_name) |
| | else: |
| | target_dir = None |
| |
|
| | newest_dependency = None |
| | for source in sources: |
| | (base, ext) = os.path.splitext(os.path.basename(source)) |
| | if ext == ".py": |
| | |
| | ext = '.pyx' |
| | if ext == ".pyx": |
| | output_dir = target_dir or os.path.dirname(source) |
| | new_sources.append(os.path.join(output_dir, base + target_ext)) |
| | cython_sources.append(source) |
| | cython_targets[source] = new_sources[-1] |
| | elif ext == '.pxi' or ext == '.pxd': |
| | if newest_dependency is None \ |
| | or newer(source, newest_dependency): |
| | newest_dependency = source |
| | else: |
| | new_sources.append(source) |
| |
|
| | if not cython_sources: |
| | return new_sources |
| |
|
| | module_name = extension.name |
| |
|
| | for source in cython_sources: |
| | target = cython_targets[source] |
| | depends = [source] + list(extension.depends or ()) |
| | if(source[-4:].lower()==".pyx" and os.path.isfile(source[:-3]+"pxd")): |
| | depends += [source[:-3]+"pxd"] |
| | rebuild = self.force or newer_group(depends, target, 'newer') |
| | if not rebuild and newest_dependency is not None: |
| | rebuild = newer(newest_dependency, target) |
| | if rebuild: |
| | log.info("cythoning %s to %s", source, target) |
| | self.mkpath(os.path.dirname(target)) |
| | if self.inplace: |
| | output_dir = os.curdir |
| | else: |
| | output_dir = self.build_lib |
| | options = CompilationOptions(cython_default_options, |
| | use_listing_file = create_listing, |
| | include_path = includes, |
| | compiler_directives = directives, |
| | output_file = target, |
| | cplus = cplus, |
| | emit_linenums = line_directives, |
| | c_line_in_traceback = not no_c_in_traceback, |
| | generate_pxi = cython_gen_pxi, |
| | output_dir = output_dir, |
| | gdb_debug = cython_gdb, |
| | compile_time_env = cython_compile_time_env) |
| | result = cython_compile(source, options=options, |
| | full_module_name=module_name) |
| | else: |
| | log.info("skipping '%s' Cython extension (up-to-date)", target) |
| |
|
| | return new_sources |
| |
|
| | |
| |
|
| | |
| |
|