14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""distutils.command.build_ext
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoImplements the Distutils 'build_ext' command, for building extension
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaomodules (currently limited to C extensions, should accommodate C++
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoextensions ASAP)."""
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# This module should be kept compatible with Python 2.1.
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__revision__ = "$Id$"
104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys, os, string, re
124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom types import *
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom site import USER_BASE, USER_SITE
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.core import Command
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.errors import *
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.sysconfig import customize_compiler, get_python_version
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.dep_util import newer_group
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.extension import Extension
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils.util import get_platform
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom distutils import log
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# GCC(mingw): os.name is "nt" but build system is posix
234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif os.name == 'nt' and sys.version.find('GCC') < 0:
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from distutils.msvccompiler import get_build_version
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    MSVC_VERSION = int(get_build_version())
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# An extension name is just a dot-separated list of Python NAMEs (ie.
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# the same as a fully-qualified module name).
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoextension_name_re = re.compile \
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef show_compilers ():
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from distutils.ccompiler import show_compilers
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    show_compilers()
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass build_ext (Command):
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    description = "build C/C++ extensions (compile/link to build directory)"
414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # XXX thoughts on how to deal with complex command-line options like
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # these, i.e. how to make it so fancy_getopt can suck them off the
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # command line and make it look like setup.py defined the appropriate
454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # lists of tuples of what-have-you.
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #   - each command needs a callback to process its command-line options
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #   - Command.__init__() needs access to its share of the whole
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     command line (must ultimately come from
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     Distribution.parse_command_line())
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #   - it then calls the current command class' option-parsing
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     callback to deal with weird options like -D, which have to
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     parse the option text and churn out some custom data
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     structure
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #   - that data structure (in this case, a list of 2-tuples)
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     will then be present in the command object by the time
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     we get to finalize_options() (i.e. the constructor
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     takes care of both command-line and client options
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    #     in between initialize_options() and finalize_options())
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    sep_by = " (separated by '%s')" % os.pathsep
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    user_options = [
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('build-lib=', 'b',
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "directory for compiled extension modules"),
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('build-temp=', 't',
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "directory for temporary files (build by-products)"),
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('plat-name=', 'p',
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "platform name to cross-compile for, if supported "
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "(default: %s)" % get_platform()),
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('inplace', 'i',
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "ignore build-lib and put compiled extensions into the source " +
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "directory alongside your pure Python modules"),
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('include-dirs=', 'I',
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "list of directories to search for header files" + sep_by),
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('define=', 'D',
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "C preprocessor macros to define"),
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('undef=', 'U',
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "C preprocessor macros to undefine"),
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('libraries=', 'l',
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "external C libraries to link with"),
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('library-dirs=', 'L',
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "directories to search for external C libraries" + sep_by),
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('rpath=', 'R',
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "directories to search for shared C libraries at runtime"),
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('link-objects=', 'O',
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "extra explicit link objects to include in the link"),
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('debug', 'g',
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "compile/link with debugging information"),
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('force', 'f',
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "forcibly build everything (ignore file timestamps)"),
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('compiler=', 'c',
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "specify the compiler type"),
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('swig-cpp', None,
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "make SWIG create C++ files (default is C)"),
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('swig-opts=', None,
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "list of SWIG command line options"),
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('swig=', None,
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "path to the SWIG executable"),
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('user', None,
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "add user include, library and rpath"),
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ]
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user']
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    help_options = [
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ('help-compiler', None,
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         "list available compilers", show_compilers),
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ]
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def initialize_options (self):
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.extensions = None
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.build_lib = None
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.plat_name = None
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.build_temp = None
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.inplace = 0
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.package = None
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.include_dirs = None
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.define = None
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.undef = None
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.libraries = None
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.library_dirs = None
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.rpath = None
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.link_objects = None
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.debug = None
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.force = None
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.compiler = None
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.swig = None
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.swig_cpp = None
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.swig_opts = None
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.user = None
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def finalize_options(self):
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from distutils import sysconfig
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.set_undefined_options('build',
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('build_lib', 'build_lib'),
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('build_temp', 'build_temp'),
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('compiler', 'compiler'),
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('debug', 'debug'),
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('force', 'force'),
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   ('plat_name', 'plat_name'),
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                   )
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.package is None:
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.package = self.distribution.ext_package
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.extensions = self.distribution.ext_modules
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Make sure Python's include directories (for Python.h, pyconfig.h,
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # etc.) are in the include search path.
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        py_include = sysconfig.get_python_inc()
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        plat_py_include = sysconfig.get_python_inc(plat_specific=1)
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.include_dirs is None:
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.include_dirs = self.distribution.include_dirs or []
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if isinstance(self.include_dirs, str):
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.include_dirs = self.include_dirs.split(os.pathsep)
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Put the Python "system" include dir at the end, so that
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # any local include dirs take precedence.
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.include_dirs.append(py_include)
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if plat_py_include != py_include:
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.include_dirs.append(plat_py_include)
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.ensure_string_list('libraries')
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Life is easier if we're not forever checking for None, so
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # simplify these options to empty lists if unset
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.libraries is None:
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.libraries = []
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.library_dirs is None:
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.library_dirs = []
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif type(self.library_dirs) is StringType:
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.library_dirs = string.split(self.library_dirs, os.pathsep)
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.rpath is None:
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.rpath = []
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif type(self.rpath) is StringType:
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.rpath = string.split(self.rpath, os.pathsep)
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # for extensions under windows use different directories
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # for Release and Debug builds.
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # also Python's library directory must be appended to library_dirs
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # GCC(mingw): os.name is "nt" but build system is posix
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == 'nt' and sys.version.find('GCC') < 0:
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # the 'libs' directory is for binary installs - we assume that
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # must be the *native* platform.  But we don't really support
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # cross-compiling via a binary install anyway, so we let it go.
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if self.debug:
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.build_temp = os.path.join(self.build_temp, "Debug")
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.build_temp = os.path.join(self.build_temp, "Release")
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Append the source distribution include and library directories,
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # this allows distutils on windows to work in the source tree
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if MSVC_VERSION == 9:
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # Use the .lib files for the correct architecture
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if self.plat_name == 'win32':
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    suffix = ''
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                else:
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    # win-amd64 or win-ia64
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    suffix = self.plat_name[4:]
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                new_lib = os.path.join(sys.exec_prefix, 'PCbuild')
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if suffix:
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    new_lib = os.path.join(new_lib, suffix)
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(new_lib)
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            elif MSVC_VERSION == 8:
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(os.path.join(sys.exec_prefix,
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         'PC', 'VS8.0'))
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            elif MSVC_VERSION == 7:
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(os.path.join(sys.exec_prefix,
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         'PC', 'VS7.1'))
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(os.path.join(sys.exec_prefix,
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         'PC', 'VC6'))
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # import libraries in its "Config" subdirectory
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == 'os2':
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config'))
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # for extensions under Cygwin and AtheOS Python's library directory must be
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # appended to library_dirs
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if (sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos'
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            or (sys.platform == 'win32' and sys.version.find('GCC') >= 0)):
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # building third party extensions
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(os.path.join(sys.prefix, "lib",
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                                      "python" + get_python_version(),
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                                      "config"))
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # building python standard extensions
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append('.')
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # for extensions under Linux or Solaris with a shared Python library,
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Python's library directory must be appended to library_dirs
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        sysconfig.get_config_var('Py_ENABLE_SHARED')
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao             or sys.platform.startswith('sunos'))
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            and sysconfig.get_config_var('Py_ENABLE_SHARED')):
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # building third party extensions
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(sysconfig.get_config_var('LIBDIR'))
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # building python standard extensions
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append('.')
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The argument parsing will result in self.define being a string, but
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # it has to be a list of 2-tuples.  All the preprocessor symbols
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # specified by the 'define' option will be set to '1'.  Multiple
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # symbols can be separated with commas.
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.define:
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            defines = self.define.split(',')
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.define = map(lambda symbol: (symbol, '1'), defines)
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The option for macros to undefine is also a string from the
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # option parsing, but has to be a list.  Multiple symbols can also
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # be separated with commas here.
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.undef:
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.undef = self.undef.split(',')
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.swig_opts is None:
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.swig_opts = []
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.swig_opts = self.swig_opts.split(' ')
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Finally add the user include and library directories if requested
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.user:
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            user_include = os.path.join(USER_BASE, "include")
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            user_lib = os.path.join(USER_BASE, "lib")
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if os.path.isdir(user_include):
2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.include_dirs.append(user_include)
2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if os.path.isdir(user_lib):
2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.library_dirs.append(user_lib)
2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.rpath.append(user_lib)
2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def run(self):
2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from distutils.ccompiler import new_compiler
2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # 'self.extensions', as supplied by setup.py, is a list of
2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Extension instances.  See the documentation for Extension (in
2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # distutils.extension) for details.
2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #
2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # For backwards compatibility with Distutils 0.8.2 and earlier, we
2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # also allow the 'extensions' list to be a list of tuples:
2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #    (ext_name, build_info)
2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # where build_info is a dictionary containing everything that
2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Extension instances do except the name, with a few things being
2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # differently named.  We convert these 2-tuples to Extension
2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # instances as needed.
2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not self.extensions:
2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return
2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # If we were asked to build any C/C++ libraries, make sure that the
2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # directory where we put them is in the library search path for
3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # linking extensions.
3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.distribution.has_c_libraries():
3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            build_clib = self.get_finalized_command('build_clib')
3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.libraries.extend(build_clib.get_library_names() or [])
3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.library_dirs.append(build_clib.build_clib)
3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Setup the CCompiler object that we'll use to do all the
3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # compiling and linking
3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.compiler = new_compiler(compiler=self.compiler,
3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                     verbose=self.verbose,
3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                     dry_run=self.dry_run,
3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                     force=self.force)
3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        customize_compiler(self.compiler)
3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # If we are cross-compiling, init the compiler now (if we are not
3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # cross-compiling, init would not hurt, but people may rely on
3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # late initialization of compiler even if they shouldn't...)
3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == 'nt' and self.plat_name != get_platform():
3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.initialize(self.plat_name)
3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # And make sure that any compile/link-related options (which might
3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # come from the command-line or from the setup script) are set in
3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # that CCompiler object -- that way, they automatically apply to
3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # all compiling and linking done here.
3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.include_dirs is not None:
3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.set_include_dirs(self.include_dirs)
3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.define is not None:
3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # 'define' option is a list of (name,value) tuples
3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for (name, value) in self.define:
3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.compiler.define_macro(name, value)
3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.undef is not None:
3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for macro in self.undef:
3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                self.compiler.undefine_macro(macro)
3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.libraries is not None:
3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.set_libraries(self.libraries)
3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.library_dirs is not None:
3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.set_library_dirs(self.library_dirs)
3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.rpath is not None:
3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.set_runtime_library_dirs(self.rpath)
3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.link_objects is not None:
3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.compiler.set_link_objects(self.link_objects)
3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Now actually compile and link everything.
3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.build_extensions()
3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def check_extensions_list(self, extensions):
3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Ensure that the list of extensions (presumably provided as a
3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        command option 'extensions') is valid, i.e. it is a list of
3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        Extension objects.  We also support the old-style list of 2-tuples,
3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        where the tuples are (ext_name, build_info), which are converted to
3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        Extension instances here.
3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        Raise DistutilsSetupError if the structure is invalid anywhere;
3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        just returns otherwise.
3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not isinstance(extensions, list):
3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            raise DistutilsSetupError, \
3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                  "'ext_modules' option must be a list of Extension instances"
3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for i, ext in enumerate(extensions):
3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if isinstance(ext, Extension):
3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                continue                # OK! (assume type-checking done
3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                        # by Extension constructor)
3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if not isinstance(ext, tuple) or len(ext) != 2:
3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                raise DistutilsSetupError, \
3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                      ("each element of 'ext_modules' option must be an "
3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       "Extension instance or 2-tuple")
3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ext_name, build_info = ext
3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            log.warn(("old-style (ext_name, build_info) tuple found in "
3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                      "ext_modules for extension '%s'"
3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                      "-- please convert to Extension instance" % ext_name))
3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if not (isinstance(ext_name, str) and
3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extension_name_re.match(ext_name)):
3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                raise DistutilsSetupError, \
3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                      ("first element of each tuple in 'ext_modules' "
3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       "must be the extension name (a string)")
3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if not isinstance(build_info, dict):
3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                raise DistutilsSetupError, \
3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                      ("second element of each tuple in 'ext_modules' "
3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       "must be a dictionary (build info)")
3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # OK, the (ext_name, build_info) dict is type-safe: convert it
3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # to an Extension instance.
3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ext = Extension(ext_name, build_info['sources'])
3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Easy stuff: one-to-one mapping from dict elements to
3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # instance attributes.
3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for key in ('include_dirs', 'library_dirs', 'libraries',
3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        'extra_objects', 'extra_compile_args',
3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        'extra_link_args'):
3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                val = build_info.get(key)
3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if val is not None:
3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    setattr(ext, key, val)
3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Medium-easy stuff: same syntax/semantics, different names.
3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ext.runtime_library_dirs = build_info.get('rpath')
4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if 'def_file' in build_info:
4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                log.warn("'def_file' element of build info dict "
4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                         "no longer supported")
4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Non-trivial stuff: 'macros' split into 'define_macros'
4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # and 'undef_macros'.
4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            macros = build_info.get('macros')
4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if macros:
4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                ext.define_macros = []
4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                ext.undef_macros = []
4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                for macro in macros:
4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    if not (isinstance(macro, tuple) and len(macro) in (1, 2)):
4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        raise DistutilsSetupError, \
4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                              ("'macros' element of build info dict "
4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                               "must be 1- or 2-tuple")
4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    if len(macro) == 1:
4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ext.undef_macros.append(macro[0])
4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    elif len(macro) == 2:
4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        ext.define_macros.append(macro)
4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            extensions[i] = ext
4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_source_files(self):
4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_extensions_list(self.extensions)
4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filenames = []
4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Wouldn't it be neat if we knew the names of header files too...
4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for ext in self.extensions:
4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            filenames.extend(ext.sources)
4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return filenames
4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_outputs(self):
4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Sanity check the 'extensions' list -- can't assume this is being
4344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # done in the same run as a 'build_extensions()' call (in fact, we
4354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # can probably assume that it *isn't*!).
4364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_extensions_list(self.extensions)
4374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # And build the list of output (built) filenames.  Note that this
4394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # ignores the 'inplace' flag, and assumes everything goes in the
4404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # "build" tree.
4414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        outputs = []
4424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for ext in self.extensions:
4434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            outputs.append(self.get_ext_fullpath(ext.name))
4444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return outputs
4454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def build_extensions(self):
4474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # First, sanity-check the 'extensions' list
4484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.check_extensions_list(self.extensions)
4494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for ext in self.extensions:
4514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.build_extension(ext)
4524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def build_extension(self, ext):
4544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        sources = ext.sources
4554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if sources is None or type(sources) not in (ListType, TupleType):
4564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            raise DistutilsSetupError, \
4574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                  ("in 'ext_modules' option (extension '%s'), " +
4584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   "'sources' must be present and must be " +
4594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   "a list of source filenames") % ext.name
4604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        sources = list(sources)
4614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ext_path = self.get_ext_fullpath(ext.name)
4634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        depends = sources + ext.depends
4644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not (self.force or newer_group(depends, ext_path, 'newer')):
4654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            log.debug("skipping '%s' extension (up-to-date)", ext.name)
4664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return
4674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
4684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            log.info("building '%s' extension", ext.name)
4694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # First, scan the sources for SWIG definition files (.i), run
4714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # SWIG on 'em to create .c files, and modify the sources list
4724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # accordingly.
4734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        sources = self.swig_sources(sources, ext)
4744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Next, compile the source code to object files.
4764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # XXX not honouring 'define_macros' or 'undef_macros' -- the
4784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # CCompiler API needs to change to accommodate this, and I
4794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # want to do one thing at a time!
4804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Two possible sources for extra compiler arguments:
4824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #   - 'extra_compile_args' in Extension object
4834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #   - CFLAGS environment variable (not particularly
4844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #     elegant, but people seem to expect it and I
4854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #     guess it's useful)
4864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The environment variable should take precedence, and
4874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # any sensible compiler will give precedence to later
4884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # command line args.  Hence we combine them in order:
4894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        extra_args = ext.extra_compile_args or []
4904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        macros = ext.define_macros[:]
4924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for undef in ext.undef_macros:
4934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            macros.append((undef,))
4944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        objects = self.compiler.compile(sources,
4964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         output_dir=self.build_temp,
4974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         macros=macros,
4984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         include_dirs=ext.include_dirs,
4994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         debug=self.debug,
5004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         extra_postargs=extra_args,
5014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                         depends=ext.depends)
5024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # XXX -- this is a Vile HACK!
5044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #
5054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The setup.py script for Python on Unix needs to be able to
5064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # get this list so it can perform all the clean up needed to
5074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # avoid keeping object files around when cleaning out a failed
5084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # build of an extension module.  Since Distutils does not
5094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # track dependencies, we have to get rid of intermediates to
5104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # ensure all the intermediates will be properly re-built.
5114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #
5124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self._built_objects = objects[:]
5134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Now link the object files together into a "shared object" --
5154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # of course, first we have to figure out all the other things
5164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # that go into the mix.
5174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if ext.extra_objects:
5184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            objects.extend(ext.extra_objects)
5194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        extra_args = ext.extra_link_args or []
5204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Detect target language, if not provided
5224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        language = ext.language or self.compiler.detect_language(sources)
5234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        self.compiler.link_shared_object(
5254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            objects, ext_path,
5264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            libraries=self.get_libraries(ext),
5274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            library_dirs=ext.library_dirs,
5284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            runtime_library_dirs=ext.runtime_library_dirs,
5294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            extra_postargs=extra_args,
5304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            export_symbols=self.get_export_symbols(ext),
5314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            debug=self.debug,
5324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            build_temp=self.build_temp,
5334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            target_lang=language)
5344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def swig_sources (self, sources, extension):
5374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Walk the list of source files in 'sources', looking for SWIG
5394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        interface (.i) files.  Run SWIG on all that are found, and
5404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return a modified 'sources' list with SWIG source files replaced
5414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        by the generated C (or C++) files.
5424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
5434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        new_sources = []
5454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        swig_sources = []
5464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        swig_targets = {}
5474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # XXX this drops generated C/C++ files into the source tree, which
5494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # is fine for developers who want to distribute the generated
5504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # source -- but there should be an option to put SWIG output in
5514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the temp dir.
5524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.swig_cpp:
5544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
5554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.swig_cpp or ('-c++' in self.swig_opts) or \
5574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao           ('-c++' in extension.swig_opts):
5584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            target_ext = '.cpp'
5594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
5604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            target_ext = '.c'
5614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for source in sources:
5634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            (base, ext) = os.path.splitext(source)
5644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if ext == ".i":             # SWIG interface file
5654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                new_sources.append(base + '_wrap' + target_ext)
5664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                swig_sources.append(source)
5674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                swig_targets[source] = new_sources[-1]
5684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
5694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                new_sources.append(source)
5704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not swig_sources:
5724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return new_sources
5734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        swig = self.swig or self.find_swig()
5754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        swig_cmd = [swig, "-python"]
5764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        swig_cmd.extend(self.swig_opts)
5774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.swig_cpp:
5784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            swig_cmd.append("-c++")
5794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Do not override commandline arguments
5814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not self.swig_opts:
5824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for o in extension.swig_opts:
5834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                swig_cmd.append(o)
5844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for source in swig_sources:
5864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            target = swig_targets[source]
5874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            log.info("swigging %s to %s", source, target)
5884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.spawn(swig_cmd + ["-o", target, source])
5894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return new_sources
5914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # swig_sources ()
5934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
5944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def find_swig (self):
5954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Return the name of the SWIG executable.  On Unix, this is
5964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        just "swig" -- it should be in the PATH.  Tries a bit harder on
5974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        Windows.
5984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
5994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == "posix":
6014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return "swig"
6024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif os.name == "nt":
6034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Look for SWIG in its standard installation directory on
6054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Windows (or so I presume!).  If we find it there, great;
6064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # if not, act like Unix and assume it's in the PATH.
6074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for vers in ("1.3", "1.2", "1.1"):
6084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                fn = os.path.join("c:\\swig%s" % vers, "swig.exe")
6094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if os.path.isfile(fn):
6104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    return fn
6114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
6124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return "swig.exe"
6134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif os.name == "os2":
6154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # assume swig available in the PATH.
6164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return "swig.exe"
6174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
6194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            raise DistutilsPlatformError, \
6204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                  ("I don't know how to find (much less run) SWIG "
6214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   "on platform '%s'") % os.name
6224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # find_swig ()
6244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # -- Name generators -----------------------------------------------
6264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    # (extension names, filenames, whatever)
6274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_ext_fullpath(self, ext_name):
6284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Returns the path of the filename for a given extension.
6294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        The file is located in `build_lib` or directly in the package
6314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        (inplace option).
6324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
6334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # makes sure the extension name is only using dots
6344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        all_dots = string.maketrans('/'+os.sep, '..')
6354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ext_name = ext_name.translate(all_dots)
6364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        fullname = self.get_ext_fullname(ext_name)
6384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        modpath = fullname.split('.')
6394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filename = self.get_ext_filename(ext_name)
6404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        filename = os.path.split(filename)[-1]
6414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if not self.inplace:
6434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # no further work needed
6444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # returning :
6454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            #   build_dir/package/path/filename
6464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            filename = os.path.join(*modpath[:-1]+[filename])
6474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return os.path.join(self.build_lib, filename)
6484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # the inplace option requires to find the package directory
6504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # using the build_py command for that
6514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        package = '.'.join(modpath[0:-1])
6524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        build_py = self.get_finalized_command('build_py')
6534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        package_dir = os.path.abspath(build_py.get_package_dir(package))
6544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # returning
6564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        #   package_dir/filename
6574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return os.path.join(package_dir, filename)
6584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_ext_fullname(self, ext_name):
6604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Returns the fullname of a given extension name.
6614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        Adds the `package.` prefix"""
6634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.package is None:
6644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext_name
6654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
6664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return self.package + '.' + ext_name
6674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_ext_filename(self, ext_name):
6694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        r"""Convert the name of an extension (eg. "foo.bar") into the name
6704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        of the file from which it will be loaded (eg. "foo/bar.so", or
6714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        "foo\bar.pyd").
6724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
6734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        from distutils.sysconfig import get_config_var
6744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        ext_path = string.split(ext_name, '.')
6754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # OS/2 has an 8 character module (extension) limit :-(
6764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == "os2":
6774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
6784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # extensions in debug_mode are named 'module_d.pyd' under windows
6794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        so_ext = get_config_var('SO')
6804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if os.name == 'nt' and self.debug:
6814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return os.path.join(*ext_path) + '_d' + so_ext
6824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return os.path.join(*ext_path) + so_ext
6834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_export_symbols (self, ext):
6854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Return the list of symbols that a shared extension has to
6864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        export.  This either uses 'ext.export_symbols' or, if it's not
6874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        provided, "init" + module_name.  Only relevant on Windows, where
6884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        the .pyd file (DLL) must export the module "init" function.
6894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
6904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        initfunc_name = "init" + ext.name.split('.')[-1]
6914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if initfunc_name not in ext.export_symbols:
6924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            ext.export_symbols.append(initfunc_name)
6934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return ext.export_symbols
6944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
6954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    def get_libraries (self, ext):
6964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """Return the list of libraries to link against when building a
6974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        shared extension.  On most platforms, this is just 'ext.libraries';
6984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        on Windows and OS/2, we add the Python library (eg. python20.dll).
6994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        """
7004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The python library is always needed on Windows.  For MSVC, this
7014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # is redundant, since the library is mentioned in a pragma in
7024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # pyconfig.h that MSVC groks.  The other Windows compilers all seem
7034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # to need it mentioned explicitly, though, so that's what we do.
7044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # Append '_d' to the python import library on debug builds.
7054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
7064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # FIXME: What is purpose of code below ?
7074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The posix build system khow requred libraries to build a module.
7084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The libraries are stored in config(Makefile) variables BLDLIBRARY,
7094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # MODLIBS and SHLIBS. Note that some variables may contain linker
7104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # flags.
7114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # NOTE: For now we will check only GCC(mingw) compiler as is clear
7124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # that we build for windows platfrom.
7134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # The code for GCC(mingw) is not correct but this is distutils
7144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # limitation - we has to pass variables to the linker as is
7154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # instead only library names.
7164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if self.compiler.compiler_type == 'mingw32':
7174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from distutils import sysconfig
7184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            template = "python%s"
7194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if self.debug:
7204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                template = template + '_d'
7214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            extra = [(template % (sysconfig.get_config_var('VERSION')))]
7224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for lib in sysconfig.get_config_var('BLDLIBRARY').split():
7234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if lib.startswith('-l'):
7244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extra.append(lib[2:])
7254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for lib in sysconfig.get_config_var('MODLIBS').split():
7264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if lib.startswith('-l'):
7274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extra.append(lib[2:])
7284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for lib in sysconfig.get_config_var('SHLIBS').split():
7294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if lib.startswith('-l'):
7304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extra.append(lib[2:])
7314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries + extra
7324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
7334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if sys.platform == "win32":
7344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from distutils.msvccompiler import MSVCCompiler
7354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if not isinstance(self.compiler, MSVCCompiler):
7364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                template = "python%d%d"
7374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if self.debug:
7384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    template = template + '_d'
7394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pythonlib = (template %
7404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                       (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
7414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # don't extend ext.libraries, it may be shared with other
7424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                # extensions, it is a reference to the original list
7434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return ext.libraries + [pythonlib]
7444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
7454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return ext.libraries
7464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif sys.platform == "os2emx":
7474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # EMX/GCC requires the python library explicitly, and I
7484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # believe VACPP does as well (though not confirmed) - AIM Apr01
7494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            template = "python%d%d"
7504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # debug versions of the main DLL aren't supported, at least
7514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # not at this time - AIM Apr01
7524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            #if self.debug:
7534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            #    template = template + '_d'
7544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            pythonlib = (template %
7554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
7564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # don't extend ext.libraries, it may be shared with other
7574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # extensions, it is a reference to the original list
7584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries + [pythonlib]
7594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif sys.platform[:6] == "cygwin":
7604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            template = "python%d.%d"
7614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            pythonlib = (template %
7624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
7634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # don't extend ext.libraries, it may be shared with other
7644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # extensions, it is a reference to the original list
7654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries + [pythonlib]
7664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif sys.platform[:6] == "atheos":
7674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from distutils import sysconfig
7684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
7694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            template = "python%d.%d"
7704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            pythonlib = (template %
7714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                   (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
7724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Get SHLIBS from Makefile
7734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            extra = []
7744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for lib in sysconfig.get_config_var('SHLIBS').split():
7754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if lib.startswith('-l'):
7764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extra.append(lib[2:])
7774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                else:
7784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    extra.append(lib)
7794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # don't extend ext.libraries, it may be shared with other
7804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # extensions, it is a reference to the original list
7814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries + [pythonlib, "m"] + extra
7824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
7834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif sys.platform == 'darwin':
7844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Don't use the default code below
7854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries
7864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        elif sys.platform[:3] == 'aix':
7874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            # Don't use the default code below
7884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return ext.libraries
7894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
7904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            from distutils import sysconfig
7914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if sysconfig.get_config_var('Py_ENABLE_SHARED'):
7924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                template = "python%d.%d"
7934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                pythonlib = (template %
7944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                             (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
7954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return ext.libraries + [pythonlib]
7964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
7974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                return ext.libraries
7984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
7994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# class build_ext
800