summaryrefslogtreecommitdiff
path: root/Cython/Distutils/build_ext.py
diff options
context:
space:
mode:
Diffstat (limited to 'Cython/Distutils/build_ext.py')
-rw-r--r--Cython/Distutils/build_ext.py143
1 files changed, 124 insertions, 19 deletions
diff --git a/Cython/Distutils/build_ext.py b/Cython/Distutils/build_ext.py
index 598bb4a89..0ab979b83 100644
--- a/Cython/Distutils/build_ext.py
+++ b/Cython/Distutils/build_ext.py
@@ -1,25 +1,130 @@
import sys
+import os
-if 'setuptools' in sys.modules:
- try:
- from setuptools.command.build_ext import build_ext as _build_ext
- except ImportError:
- # We may be in the process of importing setuptools, which tries
- # to import this.
- from distutils.command.build_ext import build_ext as _build_ext
-else:
+try:
+ from __builtin__ import basestring
+except ImportError:
+ basestring = str
+
+# Always inherit from the "build_ext" in distutils since setuptools already imports
+# it from Cython if available, and does the proper distutils fallback otherwise.
+# https://github.com/pypa/setuptools/blob/9f1822ee910df3df930a98ab99f66d18bb70659b/setuptools/command/build_ext.py#L16
+
+# setuptools imports Cython's "build_ext", so make sure we go first.
+_build_ext_module = sys.modules.get('setuptools.command.build_ext')
+if _build_ext_module is None:
+ import distutils.command.build_ext as _build_ext_module
+
+# setuptools remembers the original distutils "build_ext" as "_du_build_ext"
+_build_ext = getattr(_build_ext_module, '_du_build_ext', None)
+if _build_ext is None:
+ _build_ext = getattr(_build_ext_module, 'build_ext', None)
+if _build_ext is None:
from distutils.command.build_ext import build_ext as _build_ext
-class new_build_ext(_build_ext, object):
+class build_ext(_build_ext, object):
+
+ user_options = _build_ext.user_options + [
+ ('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" + _build_ext.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"),
+ ]
+
+ boolean_options = _build_ext.boolean_options + [
+ 'cython-cplus', 'cython-create-listing', 'cython-line-directives',
+ 'cython-c-in-temp', 'cython-gdb',
+ ]
+
+ def initialize_options(self):
+ super(build_ext, self).initialize_options()
+ 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.cython_compile_time_env = None
+
def finalize_options(self):
- if self.distribution.ext_modules:
- nthreads = getattr(self, 'parallel', None) # -j option in Py3.5+
- nthreads = int(nthreads) if nthreads else None
- from Cython.Build.Dependencies import cythonize
- self.distribution.ext_modules[:] = cythonize(
- self.distribution.ext_modules, nthreads=nthreads, force=self.force)
- super(new_build_ext, self).finalize_options()
-
-# This will become new_build_ext in the future.
-from .old_build_ext import old_build_ext as build_ext
+ super(build_ext, self).finalize_options()
+ 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 get_extension_attr(self, extension, option_name, default=False):
+ return getattr(self, option_name) or getattr(extension, option_name, default)
+
+ def build_extension(self, ext):
+ from Cython.Build.Dependencies import cythonize
+
+ # Set up the include_path for the Cython compiler:
+ # 1. Start with the command line option.
+ # 2. Add in any (unique) paths from the extension
+ # cython_include_dirs (if Cython.Distutils.extension is used).
+ # 3. Add in any (unique) paths from the extension include_dirs
+ includes = list(self.cython_include_dirs)
+ for include_dir in getattr(ext, 'cython_include_dirs', []):
+ if include_dir not in includes:
+ includes.append(include_dir)
+
+ # In case extension.include_dirs is a generator, evaluate it and keep
+ # result
+ ext.include_dirs = list(ext.include_dirs)
+ for include_dir in ext.include_dirs + list(self.include_dirs):
+ if include_dir not in includes:
+ includes.append(include_dir)
+
+ # Set up Cython compiler directives:
+ # 1. Start with the command line option.
+ # 2. Add in any (unique) entries from the extension
+ # cython_directives (if Cython.Distutils.extension is used).
+ directives = dict(self.cython_directives)
+ if hasattr(ext, "cython_directives"):
+ directives.update(ext.cython_directives)
+
+ if self.get_extension_attr(ext, 'cython_cplus'):
+ ext.language = 'c++'
+
+ options = {
+ 'use_listing_file': self.get_extension_attr(ext, 'cython_create_listing'),
+ 'emit_linenums': self.get_extension_attr(ext, 'cython_line_directives'),
+ 'include_path': includes,
+ 'compiler_directives': directives,
+ 'build_dir': self.build_temp if self.get_extension_attr(ext, 'cython_c_in_temp') else None,
+ 'generate_pxi': self.get_extension_attr(ext, 'cython_gen_pxi'),
+ 'gdb_debug': self.get_extension_attr(ext, 'cython_gdb'),
+ 'c_line_in_traceback': not getattr(ext, 'no_c_in_traceback', 0),
+ 'compile_time_env': self.get_extension_attr(ext, 'cython_compile_time_env', default=None),
+ }
+
+ new_ext = cythonize(
+ ext,force=self.force, quiet=self.verbose == 0, **options
+ )[0]
+
+ ext.sources = new_ext.sources
+ super(build_ext, self).build_extension(ext)
+
+# backward compatibility
+new_build_ext = build_ext