diff options
Diffstat (limited to 'Lib/distutils/command/build_ext.py')
| -rw-r--r-- | Lib/distutils/command/build_ext.py | 200 |
1 files changed, 77 insertions, 123 deletions
diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 420d7f1..8248089 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -4,27 +4,21 @@ Implements the Distutils 'build_ext' command, for building extension modules (currently limited to C extensions, should accommodate C++ extensions ASAP).""" -__revision__ = "$Id$" +# This module should be kept compatible with Python 2.1. -import sys, os, re -from warnings import warn +__revision__ = "$Id$" -from distutils.util import get_platform +import sys, os, string, re +from types import * +from site import USER_BASE, USER_SITE from distutils.core import Command from distutils.errors import * -from distutils.ccompiler import customize_compiler +from distutils.sysconfig import customize_compiler, get_python_version from distutils.dep_util import newer_group from distutils.extension import Extension +from distutils.util import get_platform from distutils import log -# this keeps compatibility from 2.3 to 2.5 -if sys.version < "2.6": - USER_BASE = None - HAS_USER_SITE = False -else: - from site import USER_BASE - HAS_USER_SITE = True - if os.name == 'nt': from distutils.msvccompiler import get_build_version MSVC_VERSION = int(get_build_version()) @@ -40,7 +34,7 @@ def show_compilers (): show_compilers() -class build_ext(Command): +class build_ext (Command): description = "build C/C++ extensions (compile/link to build directory)" @@ -100,55 +94,18 @@ class build_ext(Command): "list of SWIG command line options"), ('swig=', None, "path to the SWIG executable"), + ('user', None, + "add user include, library and rpath"), ] - boolean_options = ['inplace', 'debug', 'force', 'swig-cpp'] - - if HAS_USER_SITE: - user_options.append(('user', None, - "add user include, library and rpath")) - boolean_options.append('user') + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] help_options = [ ('help-compiler', None, "list available compilers", show_compilers), ] - - # making 'compiler' a property to deprecate - # its usage as something else than a compiler type - # e.g. like a compiler instance - def __init__(self, dist): - self._compiler = None - Command.__init__(self, dist) - - def __setattr__(self, name, value): - # need this to make sure setattr() (used in distutils) - # doesn't kill our property - if name == 'compiler': - self._set_compiler(value) - else: - self.__dict__[name] = value - - def _set_compiler(self, compiler): - if not isinstance(compiler, str) and compiler is not None: - # we don't want to allow that anymore in the future - warn("'compiler' specifies the compiler type in build_ext. " - "If you want to get the compiler object itself, " - "use 'compiler_obj'", DeprecationWarning) - self._compiler = compiler - - def _get_compiler(self): - if not isinstance(self._compiler, str) and self._compiler is not None: - # we don't want to allow that anymore in the future - warn("'compiler' specifies the compiler type in build_ext. " - "If you want to get the compiler object itself, " - "use 'compiler_obj'", DeprecationWarning) - return self._compiler - - compiler = property(_get_compiler, _set_compiler) - - def initialize_options(self): + def initialize_options (self): self.extensions = None self.build_lib = None self.plat_name = None @@ -172,7 +129,8 @@ class build_ext(Command): self.user = None def finalize_options(self): - _sysconfig = __import__('sysconfig') + from distutils import sysconfig + self.set_undefined_options('build', ('build_lib', 'build_lib'), ('build_temp', 'build_temp'), @@ -189,8 +147,8 @@ class build_ext(Command): # Make sure Python's include directories (for Python.h, pyconfig.h, # etc.) are in the include search path. - py_include = _sysconfig.get_path('include') - plat_py_include = _sysconfig.get_path('platinclude') + py_include = sysconfig.get_python_inc() + plat_py_include = sysconfig.get_python_inc(plat_specific=1) if self.include_dirs is None: self.include_dirs = self.distribution.include_dirs or [] if isinstance(self.include_dirs, str): @@ -211,13 +169,13 @@ class build_ext(Command): self.libraries = [] if self.library_dirs is None: self.library_dirs = [] - elif isinstance(self.library_dirs, str): - self.library_dirs = self.library_dirs.split(os.pathsep) + elif type(self.library_dirs) is StringType: + self.library_dirs = string.split(self.library_dirs, os.pathsep) if self.rpath is None: self.rpath = [] - elif isinstance(self.rpath, str): - self.rpath = self.rpath.split(os.pathsep) + elif type(self.rpath) is StringType: + self.rpath = string.split(self.rpath, os.pathsep) # for extensions under windows use different directories # for Release and Debug builds. @@ -268,7 +226,7 @@ class build_ext(Command): if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): # building third party extensions self.library_dirs.append(os.path.join(sys.prefix, "lib", - "python" + _sysconfig.get_python_version(), + "python" + get_python_version(), "config")) else: # building python standard extensions @@ -276,13 +234,13 @@ class build_ext(Command): # for extensions under Linux or Solaris with a shared Python library, # Python's library directory must be appended to library_dirs - _sysconfig.get_config_var('Py_ENABLE_SHARED') + sysconfig.get_config_var('Py_ENABLE_SHARED') if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu') or sys.platform.startswith('sunos')) - and _sysconfig.get_config_var('Py_ENABLE_SHARED')): + and sysconfig.get_config_var('Py_ENABLE_SHARED')): if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): # building third party extensions - self.library_dirs.append(_sysconfig.get_config_var('LIBDIR')) + self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) else: # building python standard extensions self.library_dirs.append('.') @@ -294,7 +252,7 @@ class build_ext(Command): if self.define: defines = self.define.split(',') - self.define = [(symbol, '1') for symbol in defines] + self.define = map(lambda symbol: (symbol, '1'), defines) # The option for macros to undefine is also a string from the # option parsing, but has to be a list. Multiple symbols can also @@ -345,50 +303,38 @@ class build_ext(Command): # Setup the CCompiler object that we'll use to do all the # compiling and linking - - # used to prevent the usage of an existing compiler for the - # compiler option when calling new_compiler() - # this will be removed in 3.3 and 2.8 - if not isinstance(self._compiler, str): - self._compiler = None - - self.compiler_obj = new_compiler(compiler=self._compiler, - verbose=self.verbose, - dry_run=self.dry_run, - force=self.force) - - # used to keep the compiler object reachable with - # "self.compiler". this will be removed in 3.3 and 2.8 - self._compiler = self.compiler_obj - - customize_compiler(self.compiler_obj) + self.compiler = new_compiler(compiler=self.compiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + customize_compiler(self.compiler) # If we are cross-compiling, init the compiler now (if we are not # cross-compiling, init would not hurt, but people may rely on # late initialization of compiler even if they shouldn't...) if os.name == 'nt' and self.plat_name != get_platform(): - self.compiler_obj.initialize(self.plat_name) + self.compiler.initialize(self.plat_name) # And make sure that any compile/link-related options (which might # come from the command-line or from the setup script) are set in # that CCompiler object -- that way, they automatically apply to # all compiling and linking done here. if self.include_dirs is not None: - self.compiler_obj.set_include_dirs(self.include_dirs) + self.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: - self.compiler_obj.define_macro(name, value) + self.compiler.define_macro(name, value) if self.undef is not None: for macro in self.undef: - self.compiler_obj.undefine_macro(macro) + self.compiler.undefine_macro(macro) if self.libraries is not None: - self.compiler_obj.set_libraries(self.libraries) + self.compiler.set_libraries(self.libraries) if self.library_dirs is not None: - self.compiler_obj.set_library_dirs(self.library_dirs) + self.compiler.set_library_dirs(self.library_dirs) if self.rpath is not None: - self.compiler_obj.set_runtime_library_dirs(self.rpath) + self.compiler.set_runtime_library_dirs(self.rpath) if self.link_objects is not None: - self.compiler_obj.set_link_objects(self.link_objects) + self.compiler.set_link_objects(self.link_objects) # Now actually compile and link everything. self.build_extensions() @@ -500,17 +446,11 @@ class build_ext(Command): self.check_extensions_list(self.extensions) for ext in self.extensions: - try: - self.build_extension(ext) - except (CCompilerError, DistutilsError, CompileError), e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) + self.build_extension(ext) def build_extension(self, ext): sources = ext.sources - if sources is None or not isinstance(sources, (list, tuple)): + if sources is None or type(sources) not in (ListType, TupleType): raise DistutilsSetupError, \ ("in 'ext_modules' option (extension '%s'), " + "'sources' must be present and must be " + @@ -550,13 +490,13 @@ class build_ext(Command): for undef in ext.undef_macros: macros.append((undef,)) - objects = self.compiler_obj.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=ext.include_dirs, - debug=self.debug, - extra_postargs=extra_args, - depends=ext.depends) + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=ext.include_dirs, + debug=self.debug, + extra_postargs=extra_args, + depends=ext.depends) # XXX -- this is a Vile HACK! # @@ -577,9 +517,9 @@ class build_ext(Command): extra_args = ext.extra_link_args or [] # Detect target language, if not provided - language = ext.language or self.compiler_obj.detect_language(sources) + language = ext.language or self.compiler.detect_language(sources) - self.compiler_obj.link_shared_object( + self.compiler.link_shared_object( objects, ext_path, libraries=self.get_libraries(ext), library_dirs=ext.library_dirs, @@ -591,12 +531,14 @@ class build_ext(Command): target_lang=language) - def swig_sources(self, sources, extension): + def swig_sources (self, sources, extension): + """Walk the list of source files in 'sources', looking for SWIG interface (.i) files. Run SWIG on all that are found, and return a modified 'sources' list with SWIG source files replaced by the generated C (or C++) files. """ + new_sources = [] swig_sources = [] swig_targets = {} @@ -645,7 +587,9 @@ class build_ext(Command): return new_sources - def find_swig(self): + # swig_sources () + + def find_swig (self): """Return the name of the SWIG executable. On Unix, this is just "swig" -- it should be in the PATH. Tries a bit harder on Windows. @@ -674,6 +618,8 @@ class build_ext(Command): ("I don't know how to find (much less run) SWIG " "on platform '%s'") % os.name + # find_swig () + # -- Name generators ----------------------------------------------- # (extension names, filenames, whatever) def get_ext_fullpath(self, ext_name): @@ -682,9 +628,14 @@ class build_ext(Command): The file is located in `build_lib` or directly in the package (inplace option). """ + # makes sure the extension name is only using dots + all_dots = string.maketrans('/'+os.sep, '..') + ext_name = ext_name.translate(all_dots) + fullname = self.get_ext_fullname(ext_name) modpath = fullname.split('.') - filename = self.get_ext_filename(modpath[-1]) + filename = self.get_ext_filename(ext_name) + filename = os.path.split(filename)[-1] if not self.inplace: # no further work needed @@ -717,18 +668,18 @@ class build_ext(Command): of the file from which it will be loaded (eg. "foo/bar.so", or "foo\bar.pyd"). """ - _sysconfig = __import__('sysconfig') - ext_path = ext_name.split('.') + from distutils.sysconfig import get_config_var + ext_path = string.split(ext_name, '.') # OS/2 has an 8 character module (extension) limit :-( if os.name == "os2": ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8] # extensions in debug_mode are named 'module_d.pyd' under windows - so_ext = _sysconfig.get_config_var('SO') + so_ext = get_config_var('SO') if os.name == 'nt' and self.debug: - return os.path.join(*ext_path) + '_d' + so_ext + return apply(os.path.join, ext_path) + '_d' + so_ext return os.path.join(*ext_path) + so_ext - def get_export_symbols(self, ext): + def get_export_symbols (self, ext): """Return the list of symbols that a shared extension has to export. This either uses 'ext.export_symbols' or, if it's not provided, "init" + module_name. Only relevant on Windows, where @@ -739,7 +690,7 @@ class build_ext(Command): ext.export_symbols.append(initfunc_name) return ext.export_symbols - def get_libraries(self, ext): + def get_libraries (self, ext): """Return the list of libraries to link against when building a shared extension. On most platforms, this is just 'ext.libraries'; on Windows and OS/2, we add the Python library (eg. python20.dll). @@ -751,7 +702,7 @@ class build_ext(Command): # Append '_d' to the python import library on debug builds. if sys.platform == "win32": from distutils.msvccompiler import MSVCCompiler - if not isinstance(self.compiler_obj, MSVCCompiler): + if not isinstance(self.compiler, MSVCCompiler): template = "python%d%d" if self.debug: template = template + '_d' @@ -783,13 +734,14 @@ class build_ext(Command): # extensions, it is a reference to the original list return ext.libraries + [pythonlib] elif sys.platform[:6] == "atheos": - _sysconfig = __import__('sysconfig') + from distutils import sysconfig + template = "python%d.%d" pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) # Get SHLIBS from Makefile extra = [] - for lib in _sysconfig.get_config_var('SHLIBS').split(): + for lib in sysconfig.get_config_var('SHLIBS').split(): if lib.startswith('-l'): extra.append(lib[2:]) else: @@ -803,11 +755,13 @@ class build_ext(Command): return ext.libraries else: - _sysconfig = __import__('sysconfig') - if _sysconfig.get_config_var('Py_ENABLE_SHARED'): + from distutils import sysconfig + if sysconfig.get_config_var('Py_ENABLE_SHARED'): template = "python%d.%d" pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) return ext.libraries + [pythonlib] else: return ext.libraries + +# class build_ext |
