]> granicus.if.org Git - python/commitdiff
This patch fixes the following bugs:
authorGustavo Niemeyer <gustavo@niemeyer.net>
Tue, 5 Nov 2002 16:12:02 +0000 (16:12 +0000)
committerGustavo Niemeyer <gustavo@niemeyer.net>
Tue, 5 Nov 2002 16:12:02 +0000 (16:12 +0000)
[#413582] g++ must be called for c++ extensions
[#454030] distutils cannot link C++ code with GCC

topdir = "Lib/distutils"

* bcppcompiler.py
  (BCPPCompiler.create_static_lib): Fixed prototype, removing extra_preargs
  and extra_postargs parameters. Included target_lang parameter.
  (BCPPCompiler.link): Included target_lang parameter.

* msvccompiler.py
  (MSVCCompiler.create_static_lib): Fixed prototype, removing extra_preargs
  and extra_postargs parameters. Included target_lang parameter.
  (MSVCCompiler.link): Included target_lang parameter.

* ccompiler.py
  (CCompiler): New language_map and language_order attributes, used by
  CCompiler.detect_language().

  (CCompiler.detect_language): New method, will return the language of
  a given source, or list of sources. Individual source language is
  detected using the language_map dict. When mixed sources are used,
  language_order will stablish the language precedence.

  (CCompiler.create_static_lib, CCompiler.link, CCompiler.link_executable,
   CCompiler.link_shared_object, CCompiler.link_shared_lib):
  Inlcuded target_lang parameter.

* cygwinccompiler.py
  (CygwinCCompiler.link): Included target_lang parameter.

* emxccompiler.py
  (EMXCCompiler.link): Included target_lang parameter.

* mwerkscompiler.py
  (MWerksCompiler.link): Included target_lang parameter.

* extension.py
  (Extension.__init__): New 'language' parameter/attribute, initialized
  to None by default. If provided will overlap the automatic detection
  made by CCompiler.detect_language(), in build_ext command.

* sysconfig.py
  (customize_compiler): Check Makefile for CXX option, and also the
  environment variable CXX. Use the resulting value in the 'compiler_cxx'
  parameter of compiler.set_executables().

* unixccompiler.py
  (UnixCCompiler): Included 'compiler_cxx' in executables dict, defaulting
  to 'cc'.
  (UnixCCompiler.create_static_lib): Included target_lang parameter.
  (UnixCCompiler.link): Included target_lang parameter, and made
  linker command use compiler_cxx, if target_lang is 'c++'.

* command/build_ext.py
  (build_ext.build_extension): Pass new ext.language attribute
  to compiler.link_shared_object()'s target_lang parameter. If
  ext.language is not provided, detect language using
  compiler.detect_language(sources) instead.

* command/config.py
  (config._link): Pass already available lang parameter as target_lang
  parameter of compiler.link_executable().

Lib/distutils/bcppcompiler.py
Lib/distutils/ccompiler.py
Lib/distutils/command/build_ext.py
Lib/distutils/command/config.py
Lib/distutils/cygwinccompiler.py
Lib/distutils/emxccompiler.py
Lib/distutils/extension.py
Lib/distutils/msvccompiler.py
Lib/distutils/mwerkscompiler.py
Lib/distutils/sysconfig.py
Lib/distutils/unixccompiler.py

index 6e9d6c64de7e171f19d9fcd11c6ef77437f71901..abe302a80441a7342e19fcf21827dcf3664f0da9 100644 (file)
@@ -146,8 +146,7 @@ class BCPPCompiler(CCompiler) :
                            output_libname,
                            output_dir=None,
                            debug=0,
-                           extra_preargs=None,
-                           extra_postargs=None):
+                           target_lang=None):
 
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         output_filename = \
@@ -157,10 +156,6 @@ class BCPPCompiler(CCompiler) :
             lib_args = [output_filename, '/u'] + objects
             if debug:
                 pass                    # XXX what goes here?
-            if extra_preargs:
-                lib_args[:0] = extra_preargs
-            if extra_postargs:
-                lib_args.extend (extra_postargs)
             try:
                 self.spawn ([self.lib] + lib_args)
             except DistutilsExecError, msg:
@@ -183,7 +178,8 @@ class BCPPCompiler(CCompiler) :
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
 
         # XXX this ignores 'build_temp'!  should follow the lead of
         # msvccompiler.py
index 60d1caeed125b9b35ef5f7d433cdbf54ea35277c..317e21efb4a170fad6935f5944f0c2e93ba34902 100644 (file)
@@ -74,6 +74,19 @@ class CCompiler:
     shared_lib_format = None            # prob. same as static_lib_format
     exe_extension = None                # string
 
+    # Default language settings. language_map is used to detect a source
+    # file or Extension target language, checking source filenames.
+    # language_order is used to detect the language precedence, when deciding
+    # what language to use when mixing source types. For example, if some
+    # extension has two files with ".c" extension, and one with ".cpp", it
+    # is still linked as c++.
+    language_map = {".c"   : "c",
+                    ".cc"  : "c++",
+                    ".cpp" : "c++",
+                    ".cxx" : "c++",
+                    ".m"   : "objc",
+                   }
+    language_order = ["c++", "objc", "c"]
 
     def __init__ (self,
                   verbose=0,
@@ -572,6 +585,27 @@ class CCompiler:
 
     # _need_link ()
 
+    def detect_language (self, sources):
+        """Detect the language of a given file, or list of files. Uses
+        language_map, and language_order to do the job.
+        """
+       if type(sources) is not ListType:
+            sources = [sources]
+        lang = None
+        index = len(self.language_order)
+        for source in sources:
+            base, ext = os.path.splitext(source)
+            extlang = self.language_map.get(ext)
+            try:
+                extindex = self.language_order.index(extlang)
+                if extindex < index:
+                    lang = extlang
+                    index = extindex
+            except ValueError:
+                pass
+        return lang
+
+    # detect_language ()
 
     # -- Worker methods ------------------------------------------------
     # (must be implemented by subclasses)
@@ -671,7 +705,8 @@ class CCompiler:
                            objects,
                            output_libname,
                            output_dir=None,
-                           debug=0):
+                           debug=0,
+                           target_lang=None):
         """Link a bunch of stuff together to create a static library file.
         The "bunch of stuff" consists of the list of object files supplied
         as 'objects', the extra object files supplied to
@@ -688,6 +723,10 @@ class CCompiler:
         compile step where this matters: the 'debug' flag is included here
         just for consistency).
 
+        'target_lang' is the target language for which the given objects
+        are being compiled. This allows specific linkage time treatment of
+        certain languages.
+
         Raises LibError on failure.
         """
         pass
@@ -710,7 +749,8 @@ class CCompiler:
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
         """Link a bunch of stuff together to create an executable or
         shared library file.
 
@@ -748,6 +788,10 @@ class CCompiler:
         of course that they supply command-line arguments for the
         particular linker being used).
 
+        'target_lang' is the target language for which the given objects
+        are being compiled. This allows specific linkage time treatment of
+        certain languages.
+
         Raises LinkError on failure.
         """
         raise NotImplementedError
@@ -766,13 +810,14 @@ class CCompiler:
                          debug=0,
                          extra_preargs=None,
                          extra_postargs=None,
-                         build_temp=None):
+                         build_temp=None,
+                         target_lang=None):
         self.link(CCompiler.SHARED_LIBRARY, objects,
                   self.library_filename(output_libname, lib_type='shared'),
                   output_dir,
                   libraries, library_dirs, runtime_library_dirs,
                   export_symbols, debug,
-                  extra_preargs, extra_postargs, build_temp)
+                  extra_preargs, extra_postargs, build_temp, target_lang)
 
 
     def link_shared_object (self,
@@ -786,12 +831,13 @@ class CCompiler:
                             debug=0,
                             extra_preargs=None,
                             extra_postargs=None,
-                            build_temp=None):
+                            build_temp=None,
+                            target_lang=None):
         self.link(CCompiler.SHARED_OBJECT, objects,
                   output_filename, output_dir,
                   libraries, library_dirs, runtime_library_dirs,
                   export_symbols, debug,
-                  extra_preargs, extra_postargs, build_temp)
+                  extra_preargs, extra_postargs, build_temp, target_lang)
 
 
     def link_executable (self,
@@ -803,11 +849,12 @@ class CCompiler:
                          runtime_library_dirs=None,
                          debug=0,
                          extra_preargs=None,
-                         extra_postargs=None):
+                         extra_postargs=None,
+                         target_lang=None):
         self.link(CCompiler.EXECUTABLE, objects,
                   self.executable_filename(output_progname), output_dir,
                   libraries, library_dirs, runtime_library_dirs, None,
-                  debug, extra_preargs, extra_postargs, None)
+                  debug, extra_preargs, extra_postargs, None, target_lang)
 
 
     # -- Miscellaneous methods -----------------------------------------
index 934b4576e636b2ad57daf15c30da884adb44a6e2..4bfc20c9d4a863fa6c030c847024fc52c4e6cfb7 100644 (file)
@@ -477,6 +477,9 @@ class build_ext (Command):
             objects.extend(ext.extra_objects)
         extra_args = ext.extra_link_args or []
 
+        # Detect target language, if not provided
+        language = ext.language or self.compiler.detect_language(sources)
+
         self.compiler.link_shared_object(
             objects, ext_filename,
             libraries=self.get_libraries(ext),
@@ -485,7 +488,8 @@ class build_ext (Command):
             extra_postargs=extra_args,
             export_symbols=self.get_export_symbols(ext),
             debug=self.debug,
-            build_temp=self.build_temp)
+            build_temp=self.build_temp,
+            target_lang=language)
 
 
     def swig_sources (self, sources):
index 88b15866079c262cdb0b163381aa70fc210c8a69..9ebe0d919138217573bd8250bf6fff86c477a4ec 100644 (file)
@@ -148,7 +148,8 @@ class config (Command):
         prog = os.path.splitext(os.path.basename(src))[0]
         self.compiler.link_executable([obj], prog,
                                       libraries=libraries,
-                                      library_dirs=library_dirs)
+                                      library_dirs=library_dirs,
+                                      target_lang=lang)
 
         prog = prog + self.compiler.exe_extension
         self.temp_files.append(prog)
index 9aabd8a66b19d0f855d126bf4c51ec93b810961b..a046ee21c8ee961639f4ecd578bec84f1b5a7131 100644 (file)
@@ -140,7 +140,8 @@ class CygwinCCompiler (UnixCCompiler):
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
 
         # use separate copies, so we can modify the lists
         extra_preargs = copy.copy(extra_preargs or [])
@@ -218,7 +219,8 @@ class CygwinCCompiler (UnixCCompiler):
                            debug,
                            extra_preargs,
                            extra_postargs,
-                           build_temp)
+                           build_temp,
+                           target_lang)
 
     # link ()
 
index 7c3ad025bb2863ea45473d722614b50ce58154cf..624c0fecbdc6806d57121d81a386a404befaf1b2 100644 (file)
@@ -102,7 +102,8 @@ class EMXCCompiler (UnixCCompiler):
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
 
         # use separate copies, so we can modify the lists
         extra_preargs = copy.copy(extra_preargs or [])
@@ -171,7 +172,8 @@ class EMXCCompiler (UnixCCompiler):
                            debug,
                            extra_preargs,
                            extra_postargs,
-                           build_temp)
+                           build_temp,
+                           target_lang)
 
     # link ()
 
index d73bb08e00b82f179a96676c40cc33c517ccc137..7fbeb4e1f14e72fb151f02aa4217099020ac38a8 100644 (file)
@@ -75,6 +75,9 @@ class Extension:
         extension_name.
       depends : [string]
         list of files that the extension depends on
+      language : string
+        extension language (i.e. "c", "c++", "objc"). Will be detected
+        from the source extensions if not provided.
     """
 
     def __init__ (self, name, sources,
@@ -89,6 +92,7 @@ class Extension:
                   extra_link_args=None,
                   export_symbols=None,
                   depends=None,
+                  language=None,
                  ):
 
         assert type(name) is StringType, "'name' must be a string"
@@ -109,6 +113,7 @@ class Extension:
         self.extra_link_args = extra_link_args or []
         self.export_symbols = export_symbols or []
         self.depends = depends or []
+        self.language = language
 
 # class Extension
 
index 65b114353e8c2231a4a528cc138b4cc08bd64aba..a2459ad032504967a9836934922e724f951dc866 100644 (file)
@@ -367,8 +367,7 @@ class MSVCCompiler (CCompiler) :
                            output_libname,
                            output_dir=None,
                            debug=0,
-                           extra_preargs=None,
-                           extra_postargs=None):
+                           target_lang=None):
 
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         output_filename = \
@@ -378,10 +377,6 @@ class MSVCCompiler (CCompiler) :
             lib_args = objects + ['/OUT:' + output_filename]
             if debug:
                 pass                    # XXX what goes here?
-            if extra_preargs:
-                lib_args[:0] = extra_preargs
-            if extra_postargs:
-                lib_args.extend (extra_postargs)
             try:
                 self.spawn ([self.lib] + lib_args)
             except DistutilsExecError, msg:
@@ -404,7 +399,8 @@ class MSVCCompiler (CCompiler) :
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
 
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         (libraries, library_dirs, runtime_library_dirs) = \
index cd66a09913d265ab63279b1fde604028217a74ea..8f62bf7d878af2cf74b1fd7d264b24b8a239beb2 100644 (file)
@@ -84,7 +84,8 @@ class MWerksCompiler (CCompiler) :
               debug=0,
               extra_preargs=None,
               extra_postargs=None,
-              build_temp=None):
+              build_temp=None,
+              target_lang=None):
         # First fixup.
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         (libraries, library_dirs, runtime_library_dirs) = \
index e879fa149a8113febc294028692eb5940cf12410..cc571888db9f50d130d6dd299d12b9ec6dcb78c3 100644 (file)
@@ -139,11 +139,13 @@ def customize_compiler(compiler):
     varies across Unices and is stored in Python's Makefile.
     """
     if compiler.compiler_type == "unix":
-        (cc, opt, ccshared, ldshared, so_ext) = \
-            get_config_vars('CC', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')
+        (cc, cxx, opt, ccshared, ldshared, so_ext) = \
+            get_config_vars('CC', 'CXX', 'OPT', 'CCSHARED', 'LDSHARED', 'SO')
 
         if os.environ.has_key('CC'):
             cc = os.environ['CC']
+        if os.environ.has_key('CXX'):
+            cxx = os.environ['CXX']
         if os.environ.has_key('CPP'):
             cpp = os.environ['CPP']
         else:
@@ -163,6 +165,7 @@ def customize_compiler(compiler):
             preprocessor=cpp,
             compiler=cc_cmd,
             compiler_so=cc_cmd + ' ' + ccshared,
+            compiler_cxx=cxx,
             linker_so=ldshared,
             linker_exe=cc)
 
index 692e3eb477e229ae788c3c852c9d898a9aa53edd..2f4546e1a7a96b89f68d36506490a3e825aeb8f6 100644 (file)
@@ -57,6 +57,7 @@ class UnixCCompiler(CCompiler):
     executables = {'preprocessor' : None,
                    'compiler'     : ["cc"],
                    'compiler_so'  : ["cc"],
+                   'compiler_cxx' : ["cc"],
                    'linker_so'    : ["cc", "-shared"],
                    'linker_exe'   : ["cc"],
                    'archiver'     : ["ar", "-cr"],
@@ -114,7 +115,7 @@ class UnixCCompiler(CCompiler):
             raise CompileError, msg
 
     def create_static_lib(self, objects, output_libname,
-                          output_dir=None, debug=0):
+                          output_dir=None, debug=0, target_lang=None):
         objects, output_dir = self._fix_object_args(objects, output_dir)
 
         output_filename = \
@@ -143,7 +144,7 @@ class UnixCCompiler(CCompiler):
              output_filename, output_dir=None, libraries=None,
              library_dirs=None, runtime_library_dirs=None,
              export_symbols=None, debug=0, extra_preargs=None,
-             extra_postargs=None, build_temp=None):
+             extra_postargs=None, build_temp=None, target_lang=None):
         objects, output_dir = self._fix_object_args(objects, output_dir)
         libraries, library_dirs, runtime_library_dirs = \
             self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
@@ -167,9 +168,12 @@ class UnixCCompiler(CCompiler):
             self.mkpath(os.path.dirname(output_filename))
             try:
                 if target_desc == CCompiler.EXECUTABLE:
-                    self.spawn(self.linker_exe + ld_args)
+                    linker = self.linker_exe[:]
                 else:
-                    self.spawn(self.linker_so + ld_args)
+                    linker = self.linker_so[:]
+                if target_lang == "c++" and self.compiler_cxx:
+                    linker[0] = self.compiler_cxx[0]
+                self.spawn(linker + ld_args)
             except DistutilsExecError, msg:
                 raise LinkError, msg
         else: