home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Freeware 31 / FreelogHS31.iso / Texte / scribus / scribus-1.3.3.9-win32-install.exe / lib / distutils / command / build_ext.py < prev    next >
Text File  |  2004-11-18  |  29KB  |  694 lines

  1. """distutils.command.build_ext
  2.  
  3. Implements the Distutils 'build_ext' command, for building extension
  4. modules (currently limited to C extensions, should accommodate C++
  5. extensions ASAP)."""
  6.  
  7. # This module should be kept compatible with Python 2.1.
  8.  
  9. __revision__ = "$Id: build_ext.py,v 1.98 2004/11/10 22:23:15 loewis Exp $"
  10.  
  11. import sys, os, string, re
  12. from types import *
  13. from distutils.core import Command
  14. from distutils.errors import *
  15. from distutils.sysconfig import customize_compiler, get_python_version
  16. from distutils.dep_util import newer_group
  17. from distutils.extension import Extension
  18. from distutils import log
  19.  
  20. # An extension name is just a dot-separated list of Python NAMEs (ie.
  21. # the same as a fully-qualified module name).
  22. extension_name_re = re.compile \
  23.     (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$')
  24.  
  25.  
  26. def show_compilers ():
  27.     from distutils.ccompiler import show_compilers
  28.     show_compilers()
  29.  
  30.  
  31. class build_ext (Command):
  32.  
  33.     description = "build C/C++ extensions (compile/link to build directory)"
  34.  
  35.     # XXX thoughts on how to deal with complex command-line options like
  36.     # these, i.e. how to make it so fancy_getopt can suck them off the
  37.     # command line and make it look like setup.py defined the appropriate
  38.     # lists of tuples of what-have-you.
  39.     #   - each command needs a callback to process its command-line options
  40.     #   - Command.__init__() needs access to its share of the whole
  41.     #     command line (must ultimately come from
  42.     #     Distribution.parse_command_line())
  43.     #   - it then calls the current command class' option-parsing
  44.     #     callback to deal with weird options like -D, which have to
  45.     #     parse the option text and churn out some custom data
  46.     #     structure
  47.     #   - that data structure (in this case, a list of 2-tuples)
  48.     #     will then be present in the command object by the time
  49.     #     we get to finalize_options() (i.e. the constructor
  50.     #     takes care of both command-line and client options
  51.     #     in between initialize_options() and finalize_options())
  52.  
  53.     sep_by = " (separated by '%s')" % os.pathsep
  54.     user_options = [
  55.         ('build-lib=', 'b',
  56.          "directory for compiled extension modules"),
  57.         ('build-temp=', 't',
  58.          "directory for temporary files (build by-products)"),
  59.         ('inplace', 'i',
  60.          "ignore build-lib and put compiled extensions into the source " +
  61.          "directory alongside your pure Python modules"),
  62.         ('include-dirs=', 'I',
  63.          "list of directories to search for header files" + sep_by),
  64.         ('define=', 'D',
  65.          "C preprocessor macros to define"),
  66.         ('undef=', 'U',
  67.          "C preprocessor macros to undefine"),
  68.         ('libraries=', 'l',
  69.          "external C libraries to link with"),
  70.         ('library-dirs=', 'L',
  71.          "directories to search for external C libraries" + sep_by),
  72.         ('rpath=', 'R',
  73.          "directories to search for shared C libraries at runtime"),
  74.         ('link-objects=', 'O',
  75.          "extra explicit link objects to include in the link"),
  76.         ('debug', 'g',
  77.          "compile/link with debugging information"),
  78.         ('force', 'f',
  79.          "forcibly build everything (ignore file timestamps)"),
  80.         ('compiler=', 'c',
  81.          "specify the compiler type"),
  82.         ('swig-cpp', None,
  83.          "make SWIG create C++ files (default is C)"),
  84.         ('swig-opts=', None,
  85.          "list of SWIG command line options"),
  86.         ('swig=', None,
  87.          "path to the SWIG executable"),
  88.         ]
  89.  
  90.     boolean_options = ['inplace', 'debug', 'force', 'swig-cpp']
  91.  
  92.     help_options = [
  93.         ('help-compiler', None,
  94.          "list available compilers", show_compilers),
  95.         ]
  96.  
  97.     def initialize_options (self):
  98.         self.extensions = None
  99.         self.build_lib = None
  100.         self.build_temp = None
  101.         self.inplace = 0
  102.         self.package = None
  103.  
  104.         self.include_dirs = None
  105.         self.define = None
  106.         self.undef = None
  107.         self.libraries = None
  108.         self.library_dirs = None
  109.         self.rpath = None
  110.         self.link_objects = None
  111.         self.debug = None
  112.         self.force = None
  113.         self.compiler = None
  114.         self.swig = None
  115.         self.swig_cpp = None
  116.         self.swig_opts = None
  117.  
  118.     def finalize_options (self):
  119.         from distutils import sysconfig
  120.  
  121.         self.set_undefined_options('build',
  122.                                    ('build_lib', 'build_lib'),
  123.                                    ('build_temp', 'build_temp'),
  124.                                    ('compiler', 'compiler'),
  125.                                    ('debug', 'debug'),
  126.                                    ('force', 'force'))
  127.  
  128.         if self.package is None:
  129.             self.package = self.distribution.ext_package
  130.  
  131.         self.extensions = self.distribution.ext_modules
  132.  
  133.  
  134.         # Make sure Python's include directories (for Python.h, pyconfig.h,
  135.         # etc.) are in the include search path.
  136.         py_include = sysconfig.get_python_inc()
  137.         plat_py_include = sysconfig.get_python_inc(plat_specific=1)
  138.         if self.include_dirs is None:
  139.             self.include_dirs = self.distribution.include_dirs or []
  140.         if type(self.include_dirs) is StringType:
  141.             self.include_dirs = string.split(self.include_dirs, os.pathsep)
  142.  
  143.         # Put the Python "system" include dir at the end, so that
  144.         # any local include dirs take precedence.
  145.         self.include_dirs.append(py_include)
  146.         if plat_py_include != py_include:
  147.             self.include_dirs.append(plat_py_include)
  148.  
  149.         if type(self.libraries) is StringType:
  150.             self.libraries = [self.libraries]
  151.  
  152.         # Life is easier if we're not forever checking for None, so
  153.         # simplify these options to empty lists if unset
  154.         if self.libraries is None:
  155.             self.libraries = []
  156.         if self.library_dirs is None:
  157.             self.library_dirs = []
  158.         elif type(self.library_dirs) is StringType:
  159.             self.library_dirs = string.split(self.library_dirs, os.pathsep)
  160.  
  161.         if self.rpath is None:
  162.             self.rpath = []
  163.         elif type(self.rpath) is StringType:
  164.             self.rpath = string.split(self.rpath, os.pathsep)
  165.  
  166.         # for extensions under windows use different directories
  167.         # for Release and Debug builds.
  168.         # also Python's library directory must be appended to library_dirs
  169.         if os.name == 'nt':
  170.             self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs'))
  171.             if self.debug:
  172.                 self.build_temp = os.path.join(self.build_temp, "Debug")
  173.             else:
  174.                 self.build_temp = os.path.join(self.build_temp, "Release")
  175.  
  176.             # Append the source distribution include and library directories,
  177.             # this allows distutils on windows to work in the source tree
  178.             self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
  179.             self.library_dirs.append(os.path.join(sys.exec_prefix, 'PCBuild'))
  180.  
  181.         # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
  182.         # import libraries in its "Config" subdirectory
  183.         if os.name == 'os2':
  184.             self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config'))
  185.  
  186.         # for extensions under Cygwin and AtheOS Python's library directory must be
  187.         # appended to library_dirs
  188.         if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos':
  189.             if string.find(sys.executable, sys.exec_prefix) != -1:
  190.                 # building third party extensions
  191.                 self.library_dirs.append(os.path.join(sys.prefix, "lib",
  192.                                                       "python" + get_python_version(),
  193.                                                       "config"))
  194.             else:
  195.                 # building python standard extensions
  196.                 self.library_dirs.append('.')
  197.  
  198.         # The argument parsing will result in self.define being a string, but
  199.         # it has to be a list of 2-tuples.  All the preprocessor symbols
  200.         # specified by the 'define' option will be set to '1'.  Multiple
  201.         # symbols can be separated with commas.
  202.  
  203.         if self.define:
  204.             defines = string.split(self.define, ',')
  205.             self.define = map(lambda symbol: (symbol, '1'), defines)
  206.  
  207.         # The option for macros to undefine is also a string from the
  208.         # option parsing, but has to be a list.  Multiple symbols can also
  209.         # be separated with commas here.
  210.         if self.undef:
  211.             self.undef = string.split(self.undef, ',')
  212.  
  213.         if self.swig_opts is None:
  214.             self.swig_opts = []
  215.         else:
  216.             self.swig_opts = self.swig_opts.split(' ')
  217.  
  218.     # finalize_options ()
  219.  
  220.  
  221.     def run (self):
  222.  
  223.         from distutils.ccompiler import new_compiler
  224.  
  225.         # 'self.extensions', as supplied by setup.py, is a list of
  226.         # Extension instances.  See the documentation for Extension (in
  227.         # distutils.extension) for details.
  228.         #
  229.         # For backwards compatibility with Distutils 0.8.2 and earlier, we
  230.         # also allow the 'extensions' list to be a list of tuples:
  231.         #    (ext_name, build_info)
  232.         # where build_info is a dictionary containing everything that
  233.         # Extension instances do except the name, with a few things being
  234.         # differently named.  We convert these 2-tuples to Extension
  235.         # instances as needed.
  236.  
  237.         if not self.extensions:
  238.             return
  239.  
  240.         # If we were asked to build any C/C++ libraries, make sure that the
  241.         # directory where we put them is in the library search path for
  242.         # linking extensions.
  243.         if self.distribution.has_c_libraries():
  244.             build_clib = self.get_finalized_command('build_clib')
  245.             self.libraries.extend(build_clib.get_library_names() or [])
  246.             self.library_dirs.append(build_clib.build_clib)
  247.  
  248.         # Setup the CCompiler object that we'll use to do all the
  249.         # compiling and linking
  250.         self.compiler = new_compiler(compiler=self.compiler,
  251.                                      verbose=self.verbose,
  252.                                      dry_run=self.dry_run,
  253.                                      force=self.force)
  254.         customize_compiler(self.compiler)
  255.  
  256.         # And make sure that any compile/link-related options (which might
  257.         # come from the command-line or from the setup script) are set in
  258.         # that CCompiler object -- that way, they automatically apply to
  259.         # all compiling and linking done here.
  260.         if self.include_dirs is not None:
  261.             self.compiler.set_include_dirs(self.include_dirs)
  262.         if self.define is not None:
  263.             # 'define' option is a list of (name,value) tuples
  264.             for (name,value) in self.define:
  265.                 self.compiler.define_macro(name, value)
  266.         if self.undef is not None:
  267.             for macro in self.undef:
  268.                 self.compiler.undefine_macro(macro)
  269.         if self.libraries is not None:
  270.             self.compiler.set_libraries(self.libraries)
  271.         if self.library_dirs is not None:
  272.             self.compiler.set_library_dirs(self.library_dirs)
  273.         if self.rpath is not None:
  274.             self.compiler.set_runtime_library_dirs(self.rpath)
  275.         if self.link_objects is not None:
  276.             self.compiler.set_link_objects(self.link_objects)
  277.  
  278.         # Now actually compile and link everything.
  279.         self.build_extensions()
  280.  
  281.     # run ()
  282.  
  283.  
  284.     def check_extensions_list (self, extensions):
  285.         """Ensure that the list of extensions (presumably provided as a
  286.         command option 'extensions') is valid, i.e. it is a list of
  287.         Extension objects.  We also support the old-style list of 2-tuples,
  288.         where the tuples are (ext_name, build_info), which are converted to
  289.         Extension instances here.
  290.  
  291.         Raise DistutilsSetupError if the structure is invalid anywhere;
  292.         just returns otherwise.
  293.         """
  294.         if type(extensions) is not ListType:
  295.             raise DistutilsSetupError, \
  296.                   "'ext_modules' option must be a list of Extension instances"
  297.  
  298.         for i in range(len(extensions)):
  299.             ext = extensions[i]
  300.             if isinstance(ext, Extension):
  301.                 continue                # OK! (assume type-checking done
  302.                                         # by Extension constructor)
  303.  
  304.             (ext_name, build_info) = ext
  305.             log.warn(("old-style (ext_name, build_info) tuple found in "
  306.                       "ext_modules for extension '%s'"
  307.                       "-- please convert to Extension instance" % ext_name))
  308.             if type(ext) is not TupleType and len(ext) != 2:
  309.                 raise DistutilsSetupError, \
  310.                       ("each element of 'ext_modules' option must be an "
  311.                        "Extension instance or 2-tuple")
  312.  
  313.             if not (type(ext_name) is StringType and
  314.                     extension_name_re.match(ext_name)):
  315.                 raise DistutilsSetupError, \
  316.                       ("first element of each tuple in 'ext_modules' "
  317.                        "must be the extension name (a string)")
  318.  
  319.             if type(build_info) is not DictionaryType:
  320.                 raise DistutilsSetupError, \
  321.                       ("second element of each tuple in 'ext_modules' "
  322.                        "must be a dictionary (build info)")
  323.  
  324.             # OK, the (ext_name, build_info) dict is type-safe: convert it
  325.             # to an Extension instance.
  326.             ext = Extension(ext_name, build_info['sources'])
  327.  
  328.             # Easy stuff: one-to-one mapping from dict elements to
  329.             # instance attributes.
  330.             for key in ('include_dirs',
  331.                         'library_dirs',
  332.                         'libraries',
  333.                         'extra_objects',
  334.                         'extra_compile_args',
  335.                         'extra_link_args'):
  336.                 val = build_info.get(key)
  337.                 if val is not None:
  338.                     setattr(ext, key, val)
  339.  
  340.             # Medium-easy stuff: same syntax/semantics, different names.
  341.             ext.runtime_library_dirs = build_info.get('rpath')
  342.             if build_info.has_key('def_file'):
  343.                 log.warn("'def_file' element of build info dict "
  344.                          "no longer supported")
  345.  
  346.             # Non-trivial stuff: 'macros' split into 'define_macros'
  347.             # and 'undef_macros'.
  348.             macros = build_info.get('macros')
  349.             if macros:
  350.                 ext.define_macros = []
  351.                 ext.undef_macros = []
  352.                 for macro in macros:
  353.                     if not (type(macro) is TupleType and
  354.                             1 <= len(macro) <= 2):
  355.                         raise DistutilsSetupError, \
  356.                               ("'macros' element of build info dict "
  357.                                "must be 1- or 2-tuple")
  358.                     if len(macro) == 1:
  359.                         ext.undef_macros.append(macro[0])
  360.                     elif len(macro) == 2:
  361.                         ext.define_macros.append(macro)
  362.  
  363.             extensions[i] = ext
  364.  
  365.         # for extensions
  366.  
  367.     # check_extensions_list ()
  368.  
  369.  
  370.     def get_source_files (self):
  371.         self.check_extensions_list(self.extensions)
  372.         filenames = []
  373.  
  374.         # Wouldn't it be neat if we knew the names of header files too...
  375.         for ext in self.extensions:
  376.             filenames.extend(ext.sources)
  377.  
  378.         return filenames
  379.  
  380.  
  381.     def get_outputs (self):
  382.  
  383.         # Sanity check the 'extensions' list -- can't assume this is being
  384.         # done in the same run as a 'build_extensions()' call (in fact, we
  385.         # can probably assume that it *isn't*!).
  386.         self.check_extensions_list(self.extensions)
  387.  
  388.         # And build the list of output (built) filenames.  Note that this
  389.         # ignores the 'inplace' flag, and assumes everything goes in the
  390.         # "build" tree.
  391.         outputs = []
  392.         for ext in self.extensions:
  393.             fullname = self.get_ext_fullname(ext.name)
  394.             outputs.append(os.path.join(self.build_lib,
  395.                                         self.get_ext_filename(fullname)))
  396.         return outputs
  397.  
  398.     # get_outputs ()
  399.  
  400.     def build_extensions(self):
  401.         # First, sanity-check the 'extensions' list
  402.         self.check_extensions_list(self.extensions)
  403.  
  404.         for ext in self.extensions:
  405.             self.build_extension(ext)
  406.  
  407.     def build_extension(self, ext):
  408.         sources = ext.sources
  409.         if sources is None or type(sources) not in (ListType, TupleType):
  410.             raise DistutilsSetupError, \
  411.                   ("in 'ext_modules' option (extension '%s'), " +
  412.                    "'sources' must be present and must be " +
  413.                    "a list of source filenames") % ext.name
  414.         sources = list(sources)
  415.  
  416.         fullname = self.get_ext_fullname(ext.name)
  417.         if self.inplace:
  418.             # ignore build-lib -- put the compiled extension into
  419.             # the source tree along with pure Python modules
  420.  
  421.             modpath = string.split(fullname, '.')
  422.             package = string.join(modpath[0:-1], '.')
  423.             base = modpath[-1]
  424.  
  425.             build_py = self.get_finalized_command('build_py')
  426.             package_dir = build_py.get_package_dir(package)
  427.             ext_filename = os.path.join(package_dir,
  428.                                         self.get_ext_filename(base))
  429.         else:
  430.             ext_filename = os.path.join(self.build_lib,
  431.                                         self.get_ext_filename(fullname))
  432.         depends = sources + ext.depends
  433.         if not (self.force or newer_group(depends, ext_filename, 'newer')):
  434.             log.debug("skipping '%s' extension (up-to-date)", ext.name)
  435.             return
  436.         else:
  437.             log.info("building '%s' extension", ext.name)
  438.  
  439.         # First, scan the sources for SWIG definition files (.i), run
  440.         # SWIG on 'em to create .c files, and modify the sources list
  441.         # accordingly.
  442.         sources = self.swig_sources(sources, ext)
  443.  
  444.         # Next, compile the source code to object files.
  445.  
  446.         # XXX not honouring 'define_macros' or 'undef_macros' -- the
  447.         # CCompiler API needs to change to accommodate this, and I
  448.         # want to do one thing at a time!
  449.  
  450.         # Two possible sources for extra compiler arguments:
  451.         #   - 'extra_compile_args' in Extension object
  452.         #   - CFLAGS environment variable (not particularly
  453.         #     elegant, but people seem to expect it and I
  454.         #     guess it's useful)
  455.         # The environment variable should take precedence, and
  456.         # any sensible compiler will give precedence to later
  457.         # command line args.  Hence we combine them in order:
  458.         extra_args = ext.extra_compile_args or []
  459.  
  460.         macros = ext.define_macros[:]
  461.         for undef in ext.undef_macros:
  462.             macros.append((undef,))
  463.  
  464.         objects = self.compiler.compile(sources,
  465.                                         output_dir=self.build_temp,
  466.                                         macros=macros,
  467.                                         include_dirs=ext.include_dirs,
  468.                                         debug=self.debug,
  469.                                         extra_postargs=extra_args,
  470.                                         depends=ext.depends)
  471.  
  472.         # XXX -- this is a Vile HACK!
  473.         #
  474.         # The setup.py script for Python on Unix needs to be able to
  475.         # get this list so it can perform all the clean up needed to
  476.         # avoid keeping object files around when cleaning out a failed
  477.         # build of an extension module.  Since Distutils does not
  478.         # track dependencies, we have to get rid of intermediates to
  479.         # ensure all the intermediates will be properly re-built.
  480.         #
  481.         self._built_objects = objects[:]
  482.  
  483.         # Now link the object files together into a "shared object" --
  484.         # of course, first we have to figure out all the other things
  485.         # that go into the mix.
  486.         if ext.extra_objects:
  487.             objects.extend(ext.extra_objects)
  488.         extra_args = ext.extra_link_args or []
  489.  
  490.         # Detect target language, if not provided
  491.         language = ext.language or self.compiler.detect_language(sources)
  492.  
  493.         self.compiler.link_shared_object(
  494.             objects, ext_filename,
  495.             libraries=self.get_libraries(ext),
  496.             library_dirs=ext.library_dirs,
  497.             runtime_library_dirs=ext.runtime_library_dirs,
  498.             extra_postargs=extra_args,
  499.             export_symbols=self.get_export_symbols(ext),
  500.             debug=self.debug,
  501.             build_temp=self.build_temp,
  502.             target_lang=language)
  503.  
  504.  
  505.     def swig_sources (self, sources, extension):
  506.  
  507.         """Walk the list of source files in 'sources', looking for SWIG
  508.         interface (.i) files.  Run SWIG on all that are found, and
  509.         return a modified 'sources' list with SWIG source files replaced
  510.         by the generated C (or C++) files.
  511.         """
  512.  
  513.         new_sources = []
  514.         swig_sources = []
  515.         swig_targets = {}
  516.  
  517.         # XXX this drops generated C/C++ files into the source tree, which
  518.         # is fine for developers who want to distribute the generated
  519.         # source -- but there should be an option to put SWIG output in
  520.         # the temp dir.
  521.  
  522.         if self.swig_cpp:
  523.             log.warn("--swig-cpp is deprecated - use --swig-opts=-c++")
  524.  
  525.         if self.swig_cpp or ('-c++' in self.swig_opts):
  526.             target_ext = '.cpp'
  527.         else:
  528.             target_ext = '.c'
  529.  
  530.         for source in sources:
  531.             (base, ext) = os.path.splitext(source)
  532.             if ext == ".i":             # SWIG interface file
  533.                 new_sources.append(base + '_wrap' + target_ext)
  534.                 swig_sources.append(source)
  535.                 swig_targets[source] = new_sources[-1]
  536.             else:
  537.                 new_sources.append(source)
  538.  
  539.         if not swig_sources:
  540.             return new_sources
  541.  
  542.         swig = self.swig or self.find_swig()
  543.         swig_cmd = [swig, "-python"]
  544.         swig_cmd.extend(self.swig_opts)
  545.         if self.swig_cpp:
  546.             swig_cmd.append("-c++")
  547.  
  548.         # Do not override commandline arguments
  549.         if not self.swig_opts:
  550.             for o in extension.swig_opts:
  551.                 swig_cmd.append(o)
  552.  
  553.         for source in swig_sources:
  554.             target = swig_targets[source]
  555.             log.info("swigging %s to %s", source, target)
  556.             self.spawn(swig_cmd + ["-o", target, source])
  557.  
  558.         return new_sources
  559.  
  560.     # swig_sources ()
  561.  
  562.     def find_swig (self):
  563.         """Return the name of the SWIG executable.  On Unix, this is
  564.         just "swig" -- it should be in the PATH.  Tries a bit harder on
  565.         Windows.
  566.         """
  567.  
  568.         if os.name == "posix":
  569.             return "swig"
  570.         elif os.name == "nt":
  571.  
  572.             # Look for SWIG in its standard installation directory on
  573.             # Windows (or so I presume!).  If we find it there, great;
  574.             # if not, act like Unix and assume it's in the PATH.
  575.             for vers in ("1.3", "1.2", "1.1"):
  576.                 fn = os.path.join("c:\\swig%s" % vers, "swig.exe")
  577.                 if os.path.isfile(fn):
  578.                     return fn
  579.             else:
  580.                 return "swig.exe"
  581.  
  582.         elif os.name == "os2":
  583.             # assume swig available in the PATH.
  584.             return "swig.exe"
  585.  
  586.         else:
  587.             raise DistutilsPlatformError, \
  588.                   ("I don't know how to find (much less run) SWIG "
  589.                    "on platform '%s'") % os.name
  590.  
  591.     # find_swig ()
  592.  
  593.     # -- Name generators -----------------------------------------------
  594.     # (extension names, filenames, whatever)
  595.  
  596.     def get_ext_fullname (self, ext_name):
  597.         if self.package is None:
  598.             return ext_name
  599.         else:
  600.             return self.package + '.' + ext_name
  601.  
  602.     def get_ext_filename (self, ext_name):
  603.         r"""Convert the name of an extension (eg. "foo.bar") into the name
  604.         of the file from which it will be loaded (eg. "foo/bar.so", or
  605.         "foo\bar.pyd").
  606.         """
  607.  
  608.         from distutils.sysconfig import get_config_var
  609.         ext_path = string.split(ext_name, '.')
  610.         # OS/2 has an 8 character module (extension) limit :-(
  611.         if os.name == "os2":
  612.             ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
  613.         # extensions in debug_mode are named 'module_d.pyd' under windows
  614.         so_ext = get_config_var('SO')
  615.         if os.name == 'nt' and self.debug:
  616.             return apply(os.path.join, ext_path) + '_d' + so_ext
  617.         return apply(os.path.join, ext_path) + so_ext
  618.  
  619.     def get_export_symbols (self, ext):
  620.         """Return the list of symbols that a shared extension has to
  621.         export.  This either uses 'ext.export_symbols' or, if it's not
  622.         provided, "init" + module_name.  Only relevant on Windows, where
  623.         the .pyd file (DLL) must export the module "init" function.
  624.         """
  625.  
  626.         initfunc_name = "init" + string.split(ext.name,'.')[-1]
  627.         if initfunc_name not in ext.export_symbols:
  628.             ext.export_symbols.append(initfunc_name)
  629.         return ext.export_symbols
  630.  
  631.     def get_libraries (self, ext):
  632.         """Return the list of libraries to link against when building a
  633.         shared extension.  On most platforms, this is just 'ext.libraries';
  634.         on Windows and OS/2, we add the Python library (eg. python20.dll).
  635.         """
  636.         # The python library is always needed on Windows.  For MSVC, this
  637.         # is redundant, since the library is mentioned in a pragma in
  638.         # pyconfig.h that MSVC groks.  The other Windows compilers all seem
  639.         # to need it mentioned explicitly, though, so that's what we do.
  640.         # Append '_d' to the python import library on debug builds.
  641.         if sys.platform == "win32":
  642.             from distutils.msvccompiler import MSVCCompiler
  643.             if not isinstance(self.compiler, MSVCCompiler):
  644.                 template = "python%d%d"
  645.                 if self.debug:
  646.                     template = template + '_d'
  647.                 pythonlib = (template %
  648.                        (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
  649.                 # don't extend ext.libraries, it may be shared with other
  650.                 # extensions, it is a reference to the original list
  651.                 return ext.libraries + [pythonlib]
  652.             else:
  653.                 return ext.libraries
  654.         elif sys.platform == "os2emx":
  655.             # EMX/GCC requires the python library explicitly, and I
  656.             # believe VACPP does as well (though not confirmed) - AIM Apr01
  657.             template = "python%d%d"
  658.             # debug versions of the main DLL aren't supported, at least
  659.             # not at this time - AIM Apr01
  660.             #if self.debug:
  661.             #    template = template + '_d'
  662.             pythonlib = (template %
  663.                    (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
  664.             # don't extend ext.libraries, it may be shared with other
  665.             # extensions, it is a reference to the original list
  666.             return ext.libraries + [pythonlib]
  667.         elif sys.platform[:6] == "cygwin":
  668.             template = "python%d.%d"
  669.             pythonlib = (template %
  670.                    (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
  671.             # don't extend ext.libraries, it may be shared with other
  672.             # extensions, it is a reference to the original list
  673.             return ext.libraries + [pythonlib]
  674.         elif sys.platform[:6] == "atheos":
  675.             from distutils import sysconfig
  676.  
  677.             template = "python%d.%d"
  678.             pythonlib = (template %
  679.                    (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff))
  680.             # Get SHLIBS from Makefile
  681.             extra = []
  682.             for lib in sysconfig.get_config_var('SHLIBS').split():
  683.                 if lib.startswith('-l'):
  684.                     extra.append(lib[2:])
  685.                 else:
  686.                     extra.append(lib)
  687.             # don't extend ext.libraries, it may be shared with other
  688.             # extensions, it is a reference to the original list
  689.             return ext.libraries + [pythonlib, "m"] + extra
  690.         else:
  691.             return ext.libraries
  692.  
  693. # class build_ext
  694.