diff options
Diffstat (limited to 'setuptools')
| -rw-r--r-- | setuptools/__init__.py | 3 | ||||
| -rw-r--r-- | setuptools/command/build_ext.py | 98 | ||||
| -rw-r--r-- | setuptools/dist.py | 4 | ||||
| -rw-r--r-- | setuptools/extension.py | 33 |
4 files changed, 109 insertions, 29 deletions
diff --git a/setuptools/__init__.py b/setuptools/__init__.py index d545f2a5..4c14fe3a 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -1,8 +1,7 @@ - """Extensions to the 'distutils' for large or complex distributions""" +from setuptools.extension import Extension, SharedLibrary from setuptools.dist import Distribution, Feature, _get_unpatched import distutils.core, setuptools.command -from setuptools.extension import Extension from setuptools.depends import Require from distutils.core import Command as _Command from distutils.util import convert_path diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index 3678ac3e..b2095796 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -7,9 +7,11 @@ except ImportError: import os, sys from distutils.file_util import copy_file +from setuptools.extension import SharedLibrary +from distutils.ccompiler import new_compiler +from distutils.sysconfig import customize_compiler -class build_ext(_build_ext): - +class build_ext(_build_ext): def run(self): """Build extensions in build directory, then copy if --inplace""" old_inplace, self.inplace = self.inplace, 0 @@ -21,15 +23,13 @@ class build_ext(_build_ext): def copy_extensions_to_source(self): build_py = self.get_finalized_command('build_py') for ext in self.extensions or (): - fullname = ext.name + fullname = self.get_ext_fullname(ext.name) + filename = self.get_ext_filename(fullname) modpath = fullname.split('.') package = '.'.join(modpath[:-1]) - base = modpath[-1] package_dir = build_py.get_package_dir(package) - dest_filename = os.path.join(package_dir, - self.get_ext_filename(base)) - src_filename = os.path.join(self.build_lib, - self.get_ext_filename(fullname)) + dest_filename = os.path.join(package_dir,os.path.basename(filename)) + src_filename = os.path.join(self.build_lib,filename) # Always copy, even if source is older than destination, to ensure # that the right extensions for the current Python/platform are @@ -47,6 +47,88 @@ class build_ext(_build_ext): # Then do any actual SWIG stuff on the remainder return _du_build_ext.swig_sources(self, sources, *otherargs) + def get_ext_filename(self, fullname): + filename = _build_ext.get_ext_filename(self,fullname) + for ext in self.shlibs: + if self.get_ext_fullname(ext.name)==fullname: + fn, ext = os.path.splitext(filename) + fn = self.shlib_compiler.library_filename(fn,'shared') + print "shlib",fn + return fn + return filename + + def initialize_options(self): + _build_ext.initialize_options(self) + self.shlib_compiler = None + self.shlibs = [] + + def finalize_options(self): + _build_ext.finalize_options(self) + self.shlibs = [ext for ext in self.extensions or () + if isinstance(ext,SharedLibrary)] + if self.shlibs: + self.setup_shlib_compiler() + self.library_dirs.append(self.build_lib) + + def build_extension(self, ext): + _compiler = self.compiler + try: + if isinstance(ext,SharedLibrary): + self.compiler = self.shlib_compiler + _build_ext.build_extension(self,ext) + finally: + self.compiler = _compiler + + + def setup_shlib_compiler(self): + compiler = self.shlib_compiler = new_compiler( + compiler=self.compiler, dry_run=self.dry_run, force=self.force + ) + customize_compiler(compiler) + if sys.platform == "darwin": + # XXX need to fix up compiler_so:ccshared + linker_so:ldshared too + compiler.shared_lib_extension = ".dylib" + + if self.include_dirs is not None: + compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name,value) in self.define: + compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + compiler.undefine_macro(macro) + if self.libraries is not None: + compiler.set_libraries(self.libraries) + if self.library_dirs is not None: + compiler.set_library_dirs(self.library_dirs) + if self.rpath is not None: + compiler.set_runtime_library_dirs(self.rpath) + if self.link_objects is not None: + compiler.set_link_objects(self.link_objects) + + # hack so distutils' build_extension() builds a shared lib instead + # + def link_shared_object(self, objects, output_libname, output_dir=None, + libraries=None, library_dirs=None, runtime_library_dirs=None, + export_symbols=None, debug=0, extra_preargs=None, + extra_postargs=None, build_temp=None, target_lang=None + ): self.link( + self.SHARED_LIBRARY, objects, output_libname, + output_dir, libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, extra_preargs, extra_postargs, + build_temp, target_lang + ) + compiler.link_shared_object = link_shared_object.__get__(compiler) + + def get_export_symbols(self, ext): + if isinstance(ext,SharedLibrary): + return ext.export_symbols + return _build_ext.get_export_symbols(self,ext) + + + + diff --git a/setuptools/dist.py b/setuptools/dist.py index fb7df8ce..4a0ae146 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -1,9 +1,7 @@ __all__ = ['Distribution', 'Feature'] from distutils.core import Distribution as _Distribution -from distutils.core import Extension from setuptools.depends import Require -from setuptools.command.build_ext import build_ext from setuptools.command.install import install from setuptools.command.sdist import sdist from setuptools.command.install_lib import install_lib @@ -39,6 +37,8 @@ sequence = tuple, list + + def assert_string_list(dist, attr, value): """Verify that value is a string list or None""" try: diff --git a/setuptools/extension.py b/setuptools/extension.py index 37b62576..33b870f0 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -1,19 +1,20 @@ from distutils.core import Extension as _Extension +from dist import _get_unpatched +_Extension = _get_unpatched(_Extension) try: from Pyrex.Distutils.build_ext import build_ext - except ImportError: + have_pyrex = False +else: + have_pyrex = True - # Pyrex isn't around, so fix up the sources - - from dist import _get_unpatched - _Extension = _get_unpatched(_Extension) - - class Extension(_Extension): - """Extension that uses '.c' files in place of '.pyx' files""" +class Extension(_Extension): + """Extension that uses '.c' files in place of '.pyx' files""" + if not have_pyrex: + # convert .pyx extensions to .c def __init__(self,*args,**kw): _Extension.__init__(self,*args,**kw) sources = [] @@ -24,14 +25,12 @@ except ImportError: sources.append(s) self.sources = sources - import sys, distutils.core, distutils.extension - distutils.core.Extension = Extension - distutils.extension.Extension = Extension - if 'distutils.command.build_ext' in sys.modules: - sys.modules['distutils.command.build_ext'].Extension = Extension - -else: +class SharedLibrary(Extension): + """Just like a regular Extension, but built as a shared library instead""" - # Pyrex is here, just use regular extension type - Extension = _Extension +import sys, distutils.core, distutils.extension +distutils.core.Extension = Extension +distutils.extension.Extension = Extension +if 'distutils.command.build_ext' in sys.modules: + sys.modules['distutils.command.build_ext'].Extension = Extension |
