summaryrefslogtreecommitdiff
path: root/setuptools
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools')
-rw-r--r--setuptools/__init__.py3
-rw-r--r--setuptools/command/build_ext.py98
-rw-r--r--setuptools/dist.py4
-rw-r--r--setuptools/extension.py33
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