[Numpy-svn] r3724 - in trunk/numpy/distutils: . command

numpy-svn@scip... numpy-svn@scip...
Sun Apr 22 16:12:59 CDT 2007


Author: cookedm
Date: 2007-04-22 16:12:57 -0500 (Sun, 22 Apr 2007)
New Revision: 3724

Modified:
   trunk/numpy/distutils/ccompiler.py
   trunk/numpy/distutils/command/build_clib.py
   trunk/numpy/distutils/command/build_ext.py
Log:
Some distutils work:

- Add better support for C++ in numpy.distutils. Instead of munging the
  C compiler command, build_clib and build_ext call the new
  Compiler.cxx_compiler() method to get a version of the compiler suitable for
  C++ (this also takes care of the special needs of AIX).
- If config_fc is specified in the Extension definition, merge that info
  instead of replacing it (otherwise, the name of the Fortran compiler is
  overwritten). This is done at the key level (ex., compiler options are
  replaced instead of appended).
- clean up compiler.py a bit
- clean up linking in build_ext



Modified: trunk/numpy/distutils/ccompiler.py
===================================================================
--- trunk/numpy/distutils/ccompiler.py	2007-04-22 20:57:58 UTC (rev 3723)
+++ trunk/numpy/distutils/ccompiler.py	2007-04-22 21:12:57 UTC (rev 3724)
@@ -21,6 +21,10 @@
     distutils.sysconfig._config_vars['OPT'] = '-Wall -g -O0'
 #distutils.sysconfig._init_posix = _new_init_posix
 
+def replace_method(klass, method_name, func):
+    m = new.instancemethod(func, None, klass)
+    setattr(klass, method_name, m)
+
 # Using customized CCompiler.spawn.
 def CCompiler_spawn(self, cmd, display=None):
     if display is None:
@@ -37,8 +41,9 @@
         print o
         raise DistutilsExecError,\
               'Command "%s" failed with exit status %d' % (cmd, s)
-CCompiler.spawn = new.instancemethod(CCompiler_spawn,None,CCompiler)
 
+replace_method(CCompiler, 'spawn', CCompiler_spawn)
+
 def CCompiler_object_filenames(self, source_filenames, strip_dir=0, output_dir=''):
     if output_dir is None:
         output_dir = ''
@@ -63,8 +68,7 @@
         obj_names.append(obj_name)
     return obj_names
 
-CCompiler.object_filenames = new.instancemethod(CCompiler_object_filenames,
-                                                None,CCompiler)
+replace_method(CCompiler, 'object_filenames', CCompiler_object_filenames)
 
 def CCompiler_compile(self, sources, output_dir=None, macros=None,
                       include_dirs=None, debug=0, extra_preargs=None,
@@ -114,7 +118,7 @@
     # Return *all* object filenames, not just the ones we just built.
     return objects
 
-CCompiler.compile = new.instancemethod(CCompiler_compile,None,CCompiler)
+replace_method(CCompiler, 'compile', CCompiler_compile)
 
 def CCompiler_customize_cmd(self, cmd):
     """ Customize compiler using distutils command.
@@ -139,8 +143,7 @@
         self.set_link_objects(cmd.link_objects)
     return
 
-CCompiler.customize_cmd = new.instancemethod(\
-    CCompiler_customize_cmd,None,CCompiler)
+replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd)
 
 def _compiler_to_string(compiler):
     props = []
@@ -179,10 +182,8 @@
         print _compiler_to_string(self)
         print '*'*80
 
-CCompiler.show_customization = new.instancemethod(\
-    CCompiler_show_customization,None,CCompiler)
+replace_method(CCompiler, 'show_customization', CCompiler_show_customization)
 
-
 def CCompiler_customize(self, dist, need_cxx=0):
     # See FCompiler.customize for suggested usage.
     log.info('customize %s' % (self.__class__.__name__))
@@ -203,7 +204,7 @@
 
         if hasattr(self,'compiler') and self.compiler[0].find('cc')>=0:
             if not self.compiler_cxx:
-                if self.compiler[0][:3] == 'gcc':
+                if self.compiler[0].startswith('gcc'):
                     a, b = 'gcc', 'g++'
                 else:
                     a, b = 'cc', 'c++'
@@ -215,10 +216,23 @@
             log.warn('Missing compiler_cxx fix for '+self.__class__.__name__)
     return
 
-CCompiler.customize = new.instancemethod(\
-    CCompiler_customize,None,CCompiler)
+replace_method(CCompiler, 'customize', CCompiler_customize)
 
-def simple_version_match(pat=r'[-.\d]+', ignore=None, start=''):
+def simple_version_match(pat=r'[-.\d]+', ignore='', start=''):
+    """
+    Simple matching of version numbers, for use in CCompiler and FCompiler
+    classes.
+
+    :Parameters:
+        pat : regex matching version numbers.
+        ignore : false or regex matching expressions to skip over.
+        start : false or regex matching the start of where to start looking
+                for version numbers.
+
+    :Returns:
+        A function that is appropiate to use as the .version_match
+        attribute of a CCompiler class.
+    """
     def matcher(self, version_string):
         pos = 0
         if start:
@@ -271,15 +285,26 @@
     self.version = version
     return version
 
-CCompiler.get_version = new.instancemethod(\
-    CCompiler_get_version,None,CCompiler)
+replace_method(CCompiler, 'get_version', CCompiler_get_version)
 
+def CCompiler_cxx_compiler(self):
+    cxx = copy(self)
+    cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:]
+    if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]:
+        # AIX needs the ld_so_aix script included with Python
+        cxx.linker_so = [cxx.linker_so[0]] + cxx.compiler_cxx[0] \
+                        + cxx.linker_so[2:]
+    else:
+        cxx.linker_so = [cxx.compiler_cxx[0]] + cxx.linker_so[1:]
+    return cxx
+
+replace_method(CCompiler, 'cxx_compiler', CCompiler_cxx_compiler)
+
 compiler_class['intel'] = ('intelccompiler','IntelCCompiler',
                            "Intel C Compiler for 32-bit applications")
 compiler_class['intele'] = ('intelccompiler','IntelItaniumCCompiler',
                            "Intel C Itanium Compiler for Itanium-based applications")
-ccompiler._default_compilers = ccompiler._default_compilers \
-                               + (('linux.*','intel'),('linux.*','intele'))
+ccompiler._default_compilers += (('linux.*','intel'),('linux.*','intele'))
 
 if sys.platform == 'win32':
     compiler_class['mingw32'] = ('mingw32ccompiler', 'Mingw32CCompiler',

Modified: trunk/numpy/distutils/command/build_clib.py
===================================================================
--- trunk/numpy/distutils/command/build_clib.py	2007-04-22 20:57:58 UTC (rev 3723)
+++ trunk/numpy/distutils/command/build_clib.py	2007-04-22 21:12:57 UTC (rev 3724)
@@ -21,13 +21,11 @@
     def initialize_options(self):
         old_build_clib.initialize_options(self)
         self.fcompiler = None
-        return
 
     def finalize_options(self):
         old_build_clib.finalize_options(self)
         self.set_undefined_options('build_ext',
                                    ('fcompiler', 'fcompiler'))
-        return
 
     def have_f_sources(self):
         for (lib_name, build_info) in self.libraries:
@@ -84,7 +82,6 @@
             self.fcompiler.show_customization()
 
         self.build_libraries(self.libraries)
-        return
 
     def get_source_files(self):
         self.check_library_list(self.libraries)
@@ -94,8 +91,6 @@
         return filenames
 
     def build_libraries(self, libraries):
-
-
         for (lib_name, build_info) in libraries:
             # default compilers
             compiler = self.compiler
@@ -109,8 +104,6 @@
                        "a list of source filenames") % lib_name
             sources = list(sources)
 
-
-
             lib_file = compiler.library_filename(lib_name,
                                                  output_dir=self.build_clib)
 
@@ -124,9 +117,9 @@
 
             config_fc = build_info.get('config_fc',{})
             if fcompiler is not None and config_fc:
-                log.info('using setup script specified config_fc '\
+                log.info('using additional config_fc from setup script '\
                          'for fortran compiler: %s' \
-                         % (config_fc))
+                         % (config_fc,))
                 from numpy.distutils.fcompiler import new_fcompiler
                 requiref90 = build_info.get('language','c')=='f90'
                 fcompiler = new_fcompiler(compiler=self.fcompiler.compiler_type,
@@ -134,7 +127,10 @@
                                           dry_run=self.dry_run,
                                           force=self.force,
                                           requiref90=requiref90)
-                fcompiler.customize(config_fc)
+                dist = self.distribution
+                base_config_fc = dist.get_option_dict('config_fc').copy()
+                base_config_fc.update(config_fc)
+                fcompiler.customize(base_config_fc)
 
             macros = build_info.get('macros')
             include_dirs = build_info.get('include_dirs')
@@ -165,19 +161,15 @@
 
             if cxx_sources:
                 log.info("compiling C++ sources")
-                old_compiler = self.compiler.compiler_so[0]
-                self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0]
-
-                cxx_objects = compiler.compile(cxx_sources,
-                                               output_dir=self.build_temp,
-                                               macros=macros,
-                                               include_dirs=include_dirs,
-                                               debug=self.debug,
-                                               extra_postargs=extra_postargs)
+                cxx_compiler = compiler.cxx_compiler()
+                cxx_objects = cxx_compiler.compile(cxx_sources,
+                                                   output_dir=self.build_temp,
+                                                   macros=macros,
+                                                   include_dirs=include_dirs,
+                                                   debug=self.debug,
+                                                   extra_postargs=extra_postargs)
                 objects.extend(cxx_objects)
 
-                self.compiler.compiler_so[0] = old_compiler
-
             if f_sources:
                 log.info("compiling Fortran sources")
                 f_objects = fcompiler.compile(f_sources,
@@ -193,10 +185,8 @@
                                             debug=self.debug)
 
             clib_libraries = build_info.get('libraries',[])
-            for lname,binfo in libraries:
+            for lname, binfo in libraries:
                 if lname in clib_libraries:
                     clib_libraries.extend(binfo[1].get('libraries',[]))
             if clib_libraries:
                 build_info['libraries'] = clib_libraries
-
-        return

Modified: trunk/numpy/distutils/command/build_ext.py
===================================================================
--- trunk/numpy/distutils/command/build_ext.py	2007-04-22 20:57:58 UTC (rev 3723)
+++ trunk/numpy/distutils/command/build_ext.py	2007-04-22 21:12:57 UTC (rev 3724)
@@ -201,17 +201,15 @@
         if cxx_sources:
             log.info("compiling C++ sources")
 
-            old_compiler = self.compiler.compiler_so[0]
-            self.compiler.compiler_so[0] = self.compiler.compiler_cxx[0]
+            cxx_compiler = self.compiler.cxx_compiler()
 
-            c_objects += self.compiler.compile(cxx_sources,
+            c_objects += cxx_compiler.compile(cxx_sources,
                                               output_dir=output_dir,
                                               macros=macros,
                                               include_dirs=include_dirs,
                                               debug=self.debug,
                                               extra_postargs=extra_args,
                                               **kws)
-            self.compiler.compiler_so[0] = old_compiler
 
         check_for_f90_modules = not not fmodule_sources
 
@@ -272,10 +270,7 @@
             objects.extend(ext.extra_objects)
         extra_args = ext.extra_link_args or []
 
-        try:
-            old_linker_so_0 = self.compiler.linker_so[0]
-        except:
-            pass
+        linker = self.compiler.link_shared_object
 
         use_fortran_linker = getattr(ext,'language','c') in ['f77','f90'] \
                              and self.fcompiler is not None
@@ -308,38 +303,31 @@
             if cxx_sources:
                 # XXX: Which linker should be used, Fortran or C++?
                 log.warn('mixing Fortran and C++ is untested')
-            link = self.fcompiler.link_shared_object
+            linker = self.fcompiler.link_shared_object
             language = ext.language or self.fcompiler.detect_language(f_sources)
         else:
-            link = self.compiler.link_shared_object
+            linker = self.compiler.link_shared_object
             if sys.version[:3]>='2.3':
                 language = ext.language or self.compiler.detect_language(sources)
             else:
                 language = ext.language
             if cxx_sources:
-                self.compiler.linker_so[0] = self.compiler.compiler_cxx[0]
+                linker = self.compiler.cxx_compiler().link_shared_object
 
         if sys.version[:3]>='2.3':
             kws = {'target_lang':language}
         else:
             kws = {}
 
-        link(objects, ext_filename,
-             libraries=self.get_libraries(ext) + c_libraries + clib_libraries,
-             library_dirs=ext.library_dirs + c_library_dirs + clib_library_dirs,
-             runtime_library_dirs=ext.runtime_library_dirs,
-             extra_postargs=extra_args,
-             export_symbols=self.get_export_symbols(ext),
-             debug=self.debug,
-             build_temp=self.build_temp,**kws)
+        linker(objects, ext_filename,
+               libraries=self.get_libraries(ext) + c_libraries + clib_libraries,
+               library_dirs=ext.library_dirs+c_library_dirs+clib_library_dirs,
+               runtime_library_dirs=ext.runtime_library_dirs,
+               extra_postargs=extra_args,
+               export_symbols=self.get_export_symbols(ext),
+               debug=self.debug,
+               build_temp=self.build_temp,**kws)
 
-        try:
-            self.compiler.linker_so[0] = old_linker_so_0
-        except:
-            pass
-
-        return
-
     def _libs_with_msvc_and_fortran(self, c_libraries, c_library_dirs):
         # Always use system linker when using MSVC compiler.
         f_lib_dirs = []



More information about the Numpy-svn mailing list