[Numpy-svn] r3975 - in branches/distutils-revamp: . command fcompiler

numpy-svn at scipy.org numpy-svn at scipy.org
Sun Aug 19 18:31:42 EDT 2007


Author: cookedm
Date: 2007-08-19 17:31:25 -0500 (Sun, 19 Aug 2007)
New Revision: 3975

Added:
   branches/distutils-revamp/interactive.py
Removed:
   branches/distutils-revamp/interactive.py
Modified:
   branches/distutils-revamp/
   branches/distutils-revamp/ccompiler.py
   branches/distutils-revamp/command/bdist_rpm.py
   branches/distutils-revamp/command/build_clib.py
   branches/distutils-revamp/command/build_ext.py
   branches/distutils-revamp/command/build_src.py
   branches/distutils-revamp/command/config.py
   branches/distutils-revamp/command/config_compiler.py
   branches/distutils-revamp/command/sdist.py
   branches/distutils-revamp/core.py
   branches/distutils-revamp/environment.py
   branches/distutils-revamp/exec_command.py
   branches/distutils-revamp/fcompiler/__init__.py
   branches/distutils-revamp/fcompiler/absoft.py
   branches/distutils-revamp/fcompiler/compaq.py
   branches/distutils-revamp/fcompiler/g95.py
   branches/distutils-revamp/fcompiler/gnu.py
   branches/distutils-revamp/fcompiler/hpux.py
   branches/distutils-revamp/fcompiler/ibm.py
   branches/distutils-revamp/fcompiler/intel.py
   branches/distutils-revamp/fcompiler/lahey.py
   branches/distutils-revamp/fcompiler/mips.py
   branches/distutils-revamp/fcompiler/nag.py
   branches/distutils-revamp/fcompiler/none.py
   branches/distutils-revamp/fcompiler/pg.py
   branches/distutils-revamp/fcompiler/sun.py
   branches/distutils-revamp/fcompiler/vast.py
   branches/distutils-revamp/intelccompiler.py
   branches/distutils-revamp/lib2def.py
   branches/distutils-revamp/line_endings.py
   branches/distutils-revamp/log.py
   branches/distutils-revamp/misc_util.py
   branches/distutils-revamp/system_info.py
   branches/distutils-revamp/unixccompiler.py
Log:
[distutils-revamp] Merged revisions 3795-3974 via svnmerge from 
http://svn.scipy.org/svn/numpy/trunk/numpy/distutils

........
  r3796 | rkern | 2007-05-21 19:34:44 -0400 (Mon, 21 May 2007) | 1 line
  
  Use a more robust method for finding the directory of the setup.py file calling Configuration(). easy_install spoofs __name__, thus confusing the old method.
........
  r3797 | rkern | 2007-05-21 20:54:42 -0400 (Mon, 21 May 2007) | 1 line
  
  Be robust when the shared distribution object exists does not have data_files set. This can happen when easy_install automatically builds dependencies.
........
  r3822 | pearu | 2007-05-25 04:16:26 -0400 (Fri, 25 May 2007) | 1 line
  
  fix ticket 526
........
  r3823 | cookedm | 2007-05-25 07:20:02 -0400 (Fri, 25 May 2007) | 5 lines
  
  merge from distutils-revamp branch (step 1)
  - minor cleanups
  - find_executable returns None when no file found (instead of having to
    check with os.path.isfile)
........
  r3824 | cookedm | 2007-05-25 07:41:16 -0400 (Fri, 25 May 2007) | 5 lines
  
  merge from distutils-revamp branch (step 2)
  - fcompiler changes. All flags, executables, etc., should be overridable
    by the user with config_fc (either command line or setup.cfg) or by
    environment variables
........
  r3825 | cookedm | 2007-05-25 07:41:55 -0400 (Fri, 25 May 2007) | 3 lines
  
  merge from distutils-revamp branch (step 3)
  - minor command/build_src cleanup
........
  r3826 | cookedm | 2007-05-25 10:47:42 -0400 (Fri, 25 May 2007) | 4 lines
  
  Add a numpy.distutils.log.good function, which when WARN messages would be
  logged, logs a "nice" anti-warn version. Use this for finding executables
  to report when we do actually find one.
........
  r3827 | cookedm | 2007-05-25 11:05:55 -0400 (Fri, 25 May 2007) | 2 lines
  
  Add a few more log.debug's in fcompiler
........
  r3828 | cookedm | 2007-05-25 11:17:20 -0400 (Fri, 25 May 2007) | 1 line
  
  Fix at least one bug in fcompiler introduced by me
........
  r3829 | cookedm | 2007-05-25 15:38:39 -0400 (Fri, 25 May 2007) | 1 line
  
  distutils: clean up imports (found by running pyflakes)
........
  r3834 | cookedm | 2007-05-28 13:47:47 -0400 (Mon, 28 May 2007) | 2 lines
  
  Use log.info instead of print in setup.py's
........
  r3837 | cookedm | 2007-05-28 13:49:55 -0400 (Mon, 28 May 2007) | 3 lines
  
  Better temporary file handling by using one temporary directory for
  numpy.distutils, and removing that at exit. Replaces using tempfile.mktemp.
........
  r3838 | cookedm | 2007-05-28 13:59:49 -0400 (Mon, 28 May 2007) | 1 line
  
  fix my mistake in fcompiler/absoft.py and fcompiler/intel.py
........
  r3839 | cookedm | 2007-05-28 14:00:22 -0400 (Mon, 28 May 2007) | 2 lines
  
  Remove interactive support. No one uses it.
........
  r3841 | cookedm | 2007-05-29 06:36:27 -0400 (Tue, 29 May 2007) | 4 lines
  
  Add a convert procedure to the flag-getting logic in fcompiler and environment.
  Otherwise, flags (for instance) from environment variables or setup.cfg are
  are strings, where lists are expected.
........
  r3843 | cookedm | 2007-05-30 20:05:15 -0400 (Wed, 30 May 2007) | 2 lines
  
  new_fcompiler returns None when it can't match the platform. Hopefully clears up Windows compiling problem.
........
  r3844 | cookedm | 2007-05-30 20:51:48 -0400 (Wed, 30 May 2007) | 2 lines
  
  do an appropiate behaviour in the distutils commands when new_fcompiler returns None
........
  r3846 | oliphant | 2007-05-31 00:57:01 -0400 (Thu, 31 May 2007) | 1 line
  
  Fix some problems with data-files not being added in top-level and extra version information added to the name of development distributions.
........
  r3847 | pearu | 2007-05-31 03:37:04 -0400 (Thu, 31 May 2007) | 1 line
  
  Undo change in 3845.
........
  r3848 | pearu | 2007-05-31 04:16:15 -0400 (Thu, 31 May 2007) | 1 line
  
  Resolved issues in changeset 3846.
........
  r3849 | pearu | 2007-05-31 04:45:30 -0400 (Thu, 31 May 2007) | 1 line
  
  Fix issues with undetected Fortran compilers.
........
  r3853 | pearu | 2007-06-01 06:15:17 -0400 (Fri, 01 Jun 2007) | 1 line
  
  Undo changeset 3839: interactive support is being used (this convinient on windows where one can click on setup.py and build the numpy or whatever package in 2 keystrokes).
........
  r3855 | pearu | 2007-06-01 09:36:59 -0400 (Fri, 01 Jun 2007) | 1 line
  
  Fixed detecting fortran compilers under windows.
........
  r3856 | pearu | 2007-06-01 09:57:24 -0400 (Fri, 01 Jun 2007) | 1 line
  
  Reduced find_executables messages.
........
  r3858 | cookedm | 2007-06-03 00:26:22 -0400 (Sun, 03 Jun 2007) | 4 lines
  
  Fix #534, introduced by r3856. The return when exe_cache had something in it
  meant that FCompiler.find_executables would be executed *once*, regardless
  of how many subclasses called it.
........
  r3859 | pearu | 2007-06-05 06:41:43 -0400 (Tue, 05 Jun 2007) | 1 line
  
  Updated intel compiler arch flags -- intel compiler users should recheck these options.
........
  r3866 | pearu | 2007-06-08 03:32:05 -0400 (Fri, 08 Jun 2007) | 1 line
  
  use get_flags_version to set version cmd flags.
........
  r3867 | pearu | 2007-06-08 03:36:33 -0400 (Fri, 08 Jun 2007) | 1 line
  
  Fix typo.
........
  r3869 | cookedm | 2007-06-12 16:06:18 -0400 (Tue, 12 Jun 2007) | 3 lines
  
  add fdebug as distutils key in [config_fc] for compiler flags to use when
  compiling Fortran in debug mode.
........
  r3870 | cookedm | 2007-06-15 16:55:41 -0400 (Fri, 15 Jun 2007) | 2 lines
  
  Minor refactoring of build_clib (break up build_library a bit)
........
  r3871 | cookedm | 2007-06-15 17:24:46 -0400 (Fri, 15 Jun 2007) | 21 lines
  
  Better version handling in fcompiler
   * Remove FCompiler.get_version_cmd, FCompiler.get_flags_version,
     FCompiler.get_linker_so_cmd, and FCompiler.get_linker_exe_cmd;
     subclasses should do this in FCompiler.update_executables()
   * FCompiler attributes .compiler_f77, .version_cmd, etc., are now
     properties that read from the .executables dictionary.
   * Update intel.py and absoft.py for above
   * Add extra asserts for defensive programming. Most of our problems
     here seem to come from bad values being generated, and the error not
     being caught until later.
       * must call FCompiler.customize() before FCompiler.get_version();
         command/build_ext.py and command/config.py updated
       * verify that commands make sense earlier -- must be None or
         lists of strings
  
  Also,
   * add IA-32 as another pattern to search for in 32-bit Intel
     compiler version.
   * minor formatting
   * add debugging helpers to environment.py:EnvironmentConfig class
........
  r3872 | pearu | 2007-06-16 04:44:24 -0400 (Sat, 16 Jun 2007) | 1 line
  
  Fix build breakage.
........
  r3880 | rkern | 2007-07-02 15:32:02 -0400 (Mon, 02 Jul 2007) | 1 line
  
  Import Pyrex.Compiler.Main explicitly since in 0.9.5.1, it does not appear to be imported with a plain 'import Pyrex.Compiler'
........
  r3882 | cookedm | 2007-07-06 11:05:09 -0400 (Fri, 06 Jul 2007) | 3 lines
  
  Add support for aliases for Fortran compilers.
   - 'g77' for gnu, 'gfortran' for gnu95, 'ifort' for intel
........
  r3892 | pearu | 2007-07-20 07:28:43 -0400 (Fri, 20 Jul 2007) | 1 line
  
  Fixed LAPACK_SRC build for lapack-3.1.1.
........
  r3896 | pearu | 2007-07-24 08:08:46 -0400 (Tue, 24 Jul 2007) | 1 line
........
  r3899 | pearu | 2007-07-25 07:21:35 -0400 (Wed, 25 Jul 2007) | 4 lines
  
  Don't use _nt_quote_args as exec_command should
  handle spaces in program path. This fixes building
  numpy/scipy on Windows using mingw32 g77 with full
  path=C:\Program Files\MinGW\g77.exe.
........
  r3900 | pearu | 2007-07-25 07:42:39 -0400 (Wed, 25 Jul 2007) | 1 line
  
  Give a hint when getting "Too many open files" failure.
........
  r3901 | pearu | 2007-07-25 17:47:16 -0400 (Wed, 25 Jul 2007) | 1 line
  
  More fixes for building scipy with Mingw32 compilers.
........
  r3902 | pearu | 2007-07-27 05:02:31 -0400 (Fri, 27 Jul 2007) | 1 line
  
  Using own quote_args, trying to fix build failures with MSVC compiler.
........
  r3903 | pearu | 2007-07-27 05:20:08 -0400 (Fri, 27 Jul 2007) | 1 line
  
  Trying to fix Windows XP x86_64 MSVC build.
........
  r3908 | pearu | 2007-07-27 16:48:48 -0400 (Fri, 27 Jul 2007) | 1 line
  
  Try to fix build on AMD64 with MSVC compiler.
........
  r3909 | pearu | 2007-07-27 17:12:35 -0400 (Fri, 27 Jul 2007) | 1 line
  
  Fix type error on setting os.environ item.
........
  r3910 | pearu | 2007-07-27 18:09:23 -0400 (Fri, 27 Jul 2007) | 1 line
  
  Added debug messages to see if quote_args are applied properly.
........
  r3911 | pearu | 2007-07-27 18:32:40 -0400 (Fri, 27 Jul 2007) | 1 line
  
  msvc_on_amd64 must be applied *after* importing ccompiler module, apply quote_args also to include_dirs.
........
  r3913 | pearu | 2007-07-28 06:07:47 -0400 (Sat, 28 Jul 2007) | 1 line
  
  remove debug messages.
........
  r3942 | rkern | 2007-08-03 18:19:13 -0400 (Fri, 03 Aug 2007) | 3 lines
  
  * Allow an Intel Fortran 10.0 for 64-bit version string that I've seen in the wild.
  * Use -fPIC instead of -KPIC for said wild compiler.
........
  r3955 | rkern | 2007-08-08 18:31:50 -0400 (Wed, 08 Aug 2007) | 1 line
  
  Optionally use setuptools for commands that setuptools customizes.
........
  r3956 | pearu | 2007-08-09 06:01:56 -0400 (Thu, 09 Aug 2007) | 1 line
  
  Fix an incorrect usage of log.set_verbosity(INFO) causing log always to be at DEBUG level, INFO is for set_threshold.
........
  r3968 | cookedm | 2007-08-17 14:23:46 -0400 (Fri, 17 Aug 2007) | 4 lines
  
  - fix specification of noopt, etc. in the config_fc command
  - check that Fortran compiler aliases aren't duplicated
  - don't use the superclass alias in the VAST fcompiler class
........
  r3969 | cookedm | 2007-08-17 14:29:08 -0400 (Fri, 17 Aug 2007) | 4 lines
  
  - remove .a static libs and recreate, instead of updating (ar on OS X can't
    handle updating universal .a)
  - in unixccompiler, use ccompiler.replace_method instead of new.instance_method
........
  r3970 | cookedm | 2007-08-17 14:31:24 -0400 (Fri, 17 Aug 2007) | 4 lines
  
  in ccompiler.CCompiler_customize_cmd, allow a list of command attributes to
  ignore when customising. This will be used to simplify some of the compiler
  customisation in command/
........
  r3971 | cookedm | 2007-08-17 14:32:01 -0400 (Fri, 17 Aug 2007) | 2 lines
  
  exec_command.py: remove a version check for > Python 2.1
........



Property changes on: branches/distutils-revamp
___________________________________________________________________
Name: svnmerge-integrated
   - /branches/distutils-revamp:1-2756 /trunk/numpy/distutils:1-3794
   + /branches/distutils-revamp:1-2756 /trunk/numpy/distutils:1-3974

Modified: branches/distutils-revamp/ccompiler.py
===================================================================
--- branches/distutils-revamp/ccompiler.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/ccompiler.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -10,8 +10,7 @@
 
 from numpy.distutils import log
 from numpy.distutils.exec_command import exec_command
-from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32
-from distutils.spawn import _nt_quote_args
+from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, quote_args, msvc_on_amd64
 
 # hack to set compiler optimizing options. Needs to integrated with something.
 import distutils.sysconfig
@@ -32,15 +31,17 @@
         if is_sequence(display):
             display = ' '.join(list(display))
     log.info(display)
-    if is_sequence(cmd) and os.name == 'nt':
-        cmd = _nt_quote_args(list(cmd))
     s,o = exec_command(cmd)
     if s:
         if is_sequence(cmd):
             cmd = ' '.join(list(cmd))
         print o
+        if re.search('Too many open files', o):
+            msg = '\nTry rerunning setup command until build succeeds.'
+        else:
+            msg = ''
         raise DistutilsExecError,\
-              'Command "%s" failed with exit status %d' % (cmd, s)
+              'Command "%s" failed with exit status %d%s' % (cmd, s, msg)
 
 replace_method(CCompiler, 'spawn', CCompiler_spawn)
 
@@ -120,28 +121,30 @@
 
 replace_method(CCompiler, 'compile', CCompiler_compile)
 
-def CCompiler_customize_cmd(self, cmd):
+def CCompiler_customize_cmd(self, cmd, ignore=()):
     """ Customize compiler using distutils command.
     """
     log.info('customize %s using %s' % (self.__class__.__name__,
                                         cmd.__class__.__name__))
-    if getattr(cmd,'include_dirs',None) is not None:
+    def allow(attr):
+        return getattr(cmd, attr, None) is not None and attr not in ignore
+
+    if allow('include_dirs'):
         self.set_include_dirs(cmd.include_dirs)
-    if getattr(cmd,'define',None) is not None:
+    if allow('define'):
         for (name,value) in cmd.define:
             self.define_macro(name, value)
-    if getattr(cmd,'undef',None) is not None:
+    if allow('undef'):
         for macro in cmd.undef:
             self.undefine_macro(macro)
-    if getattr(cmd,'libraries',None) is not None:
+    if allow('libraries'):
         self.set_libraries(self.libraries + cmd.libraries)
-    if getattr(cmd,'library_dirs',None) is not None:
+    if allow('library_dirs'):
         self.set_library_dirs(self.library_dirs + cmd.library_dirs)
-    if getattr(cmd,'rpath',None) is not None:
+    if allow('rpath'):
         self.set_runtime_library_dirs(cmd.rpath)
-    if getattr(cmd,'link_objects',None) is not None:
+    if allow('link_objects'):
         self.set_link_objects(cmd.link_objects)
-    return
 
 replace_method(CCompiler, 'customize_cmd', CCompiler_customize_cmd)
 
@@ -174,8 +177,10 @@
             if not attr:
                 continue
             log.info("compiler '%s' is set to %s" % (attrname,attr))
-    try: self.get_version()
-    except: pass
+    try:
+        self.get_version()
+    except:
+        pass
     if log._global_log.threshold<2:
         print '*'*80
         print self.__class__
@@ -251,17 +256,17 @@
         return m.group(0)
     return matcher
 
-def CCompiler_get_version(self, force=0, ok_status=[0]):
-    """ Compiler version. Returns None if compiler is not available. """
+def CCompiler_get_version(self, force=False, ok_status=[0]):
+    """Compiler version. Returns None if compiler is not available."""
     if not force and hasattr(self,'version'):
         return self.version
+    self.find_executables()
     try:
         version_cmd = self.version_cmd
     except AttributeError:
         return None
     if not version_cmd or not version_cmd[0]:
         return None
-    cmd = ' '.join(version_cmd)
     try:
         matcher = self.version_match
     except AttributeError:
@@ -276,7 +281,8 @@
             version = m.group('version')
             return version
 
-    status, output = exec_command(cmd,use_tee=0)
+    status, output = exec_command(version_cmd,use_tee=0)
+
     version = None
     if status in ok_status:
         version = matcher(output)
@@ -363,9 +369,10 @@
 
 ccompiler.new_compiler = new_compiler
 
-
 _distutils_gen_lib_options = gen_lib_options
 def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries):
+    library_dirs = quote_args(library_dirs)
+    runtime_library_dirs = quote_args(runtime_library_dirs)
     r = _distutils_gen_lib_options(compiler, library_dirs,
                                    runtime_library_dirs, libraries)
     lib_opts = []
@@ -377,6 +384,11 @@
     return lib_opts
 ccompiler.gen_lib_options = gen_lib_options
 
+_distutils_gen_preprocess_options = gen_preprocess_options
+def gen_preprocess_options (macros, include_dirs):
+    include_dirs = quote_args(include_dirs)
+    return _distutils_gen_preprocess_options(macros, include_dirs)
+ccompiler.gen_preprocess_options = gen_preprocess_options
 
 ##Fix distutils.util.split_quoted:
 import re,string
@@ -434,3 +446,6 @@
 
     return words
 ccompiler.split_quoted = split_quoted
+
+# define DISTUTILS_USE_SDK when necessary to workaround distutils/msvccompiler.py bug
+msvc_on_amd64()

Modified: branches/distutils-revamp/command/bdist_rpm.py
===================================================================
--- branches/distutils-revamp/command/bdist_rpm.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/bdist_rpm.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,6 +1,9 @@
 import os
 import sys
-from distutils.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+if 'setuptools' in sys.modules:
+    from setuptools.command.bdist_rpm import bdist_rpm as old_bdist_rpm
+else:
+    from distutils.command.bdist_rpm import bdist_rpm as old_bdist_rpm
 
 class bdist_rpm(old_bdist_rpm):
 

Modified: branches/distutils-revamp/command/build_clib.py
===================================================================
--- branches/distutils-revamp/command/build_clib.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/build_clib.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -2,8 +2,10 @@
 """
 
 import os
+from glob import glob
 from distutils.command.build_clib import build_clib as old_build_clib
-from distutils.errors import DistutilsSetupError, DistutilsError
+from distutils.errors import DistutilsSetupError, DistutilsError, \
+     DistutilsFileError
 
 from numpy.distutils import log
 from distutils.dep_util import newer_group
@@ -75,15 +77,17 @@
                                            verbose=self.verbose,
                                            dry_run=self.dry_run,
                                            force=self.force,
-                                           requiref90='f90' in languages)
-            self.fcompiler.customize(self.distribution)
+                                           requiref90='f90' in languages,
+                                           c_compiler=self.compiler)
+            if self.compiler is not None:
+                self.fcompiler.customize(self.distribution)
 
-            libraries = self.libraries
-            self.libraries = None
-            self.fcompiler.customize_cmd(self)
-            self.libraries = libraries
+                libraries = self.libraries
+                self.libraries = None
+                self.fcompiler.customize_cmd(self)
+                self.libraries = libraries
 
-            self.fcompiler.show_customization()
+                self.fcompiler.show_customization()
 
         self.build_libraries(self.libraries)
 
@@ -96,155 +100,160 @@
 
     def build_libraries(self, libraries):
         for (lib_name, build_info) in libraries:
-            # default compilers
-            compiler = self.compiler
-            fcompiler = self.fcompiler
+            self.build_a_library(build_info, lib_name, libraries)
 
-            sources = build_info.get('sources')
-            if sources is None or not is_sequence(sources):
-                raise DistutilsSetupError, \
-                      ("in 'libraries' option (library '%s'), " +
-                       "'sources' must be present and must be " +
-                       "a list of source filenames") % lib_name
-            sources = list(sources)
+    def build_a_library(self, build_info, lib_name, libraries):
+        # default compilers
+        compiler = self.compiler
+        fcompiler = self.fcompiler
 
-            c_sources, cxx_sources, f_sources, fmodule_sources \
-                       = filter_sources(sources)
-            requiref90 = not not fmodule_sources or \
-                         build_info.get('language','c')=='f90'
+        sources = build_info.get('sources')
+        if sources is None or not is_sequence(sources):
+            raise DistutilsSetupError, \
+                  ("in 'libraries' option (library '%s'), " +
+                   "'sources' must be present and must be " +
+                   "a list of source filenames") % lib_name
+        sources = list(sources)
 
-            # save source type information so that build_ext can use it.
-            source_languages = []
-            if c_sources: source_languages.append('c')
-            if cxx_sources: source_languages.append('c++')
-            if requiref90: source_languages.append('f90')
-            elif f_sources: source_languages.append('f77')
-            build_info['source_languages'] = source_languages
+        c_sources, cxx_sources, f_sources, fmodule_sources \
+                   = filter_sources(sources)
+        requiref90 = not not fmodule_sources or \
+                     build_info.get('language','c')=='f90'
 
-            lib_file = compiler.library_filename(lib_name,
-                                                 output_dir=self.build_clib)
-            depends = sources + build_info.get('depends',[])
-            if not (self.force or newer_group(depends, lib_file, 'newer')):
-                log.debug("skipping '%s' library (up-to-date)", lib_name)
-                continue
-            else:
-                log.info("building '%s' library", lib_name)
+        # save source type information so that build_ext can use it.
+        source_languages = []
+        if c_sources: source_languages.append('c')
+        if cxx_sources: source_languages.append('c++')
+        if requiref90: source_languages.append('f90')
+        elif f_sources: source_languages.append('f77')
+        build_info['source_languages'] = source_languages
 
-            config_fc = build_info.get('config_fc',{})
-            if fcompiler is not None and config_fc:
-                log.info('using additional config_fc from setup script '\
-                         'for fortran compiler: %s' \
-                         % (config_fc,))
-                from numpy.distutils.fcompiler import new_fcompiler
-                fcompiler = new_fcompiler(compiler=fcompiler.compiler_type,
-                                          verbose=self.verbose,
-                                          dry_run=self.dry_run,
-                                          force=self.force,
-                                          requiref90=requiref90)
+        lib_file = compiler.library_filename(lib_name,
+                                             output_dir=self.build_clib)
+        depends = sources + build_info.get('depends',[])
+        if not (self.force or newer_group(depends, lib_file, 'newer')):
+            log.debug("skipping '%s' library (up-to-date)", lib_name)
+            return
+        else:
+            log.info("building '%s' library", lib_name)
+
+        config_fc = build_info.get('config_fc',{})
+        if fcompiler is not None and config_fc:
+            log.info('using additional config_fc from setup script '\
+                     'for fortran compiler: %s' \
+                     % (config_fc,))
+            from numpy.distutils.fcompiler import new_fcompiler
+            fcompiler = new_fcompiler(compiler=fcompiler.compiler_type,
+                                      verbose=self.verbose,
+                                      dry_run=self.dry_run,
+                                      force=self.force,
+                                      requiref90=requiref90,
+                                      c_compiler=self.compiler)
+            if fcompiler is not None:
                 dist = self.distribution
                 base_config_fc = dist.get_option_dict('config_fc').copy()
                 base_config_fc.update(config_fc)
                 fcompiler.customize(base_config_fc)
 
-            # check availability of Fortran compilers
-            if (f_sources or fmodule_sources) and fcompiler is None:
-                raise DistutilsError, "library %s has Fortran sources"\
-                      " but no Fortran compiler found" % (lib_name)
+        # check availability of Fortran compilers
+        if (f_sources or fmodule_sources) and fcompiler is None:
+            raise DistutilsError, "library %s has Fortran sources"\
+                  " but no Fortran compiler found" % (lib_name)
 
-            macros = build_info.get('macros')
-            include_dirs = build_info.get('include_dirs')
-            extra_postargs = build_info.get('extra_compiler_args') or []
+        macros = build_info.get('macros')
+        include_dirs = build_info.get('include_dirs')
+        extra_postargs = build_info.get('extra_compiler_args') or []
 
-            # where compiled F90 module files are:
-            module_dirs = build_info.get('module_dirs') or []
-            module_build_dir = os.path.dirname(lib_file)
-            if requiref90: self.mkpath(module_build_dir)
+        # where compiled F90 module files are:
+        module_dirs = build_info.get('module_dirs') or []
+        module_build_dir = os.path.dirname(lib_file)
+        if requiref90: self.mkpath(module_build_dir)
 
-            if compiler.compiler_type=='msvc':
-                # this hack works around the msvc compiler attributes
-                # problem, msvc uses its own convention :(
-                c_sources += cxx_sources
-                cxx_sources = []
+        if compiler.compiler_type=='msvc':
+            # this hack works around the msvc compiler attributes
+            # problem, msvc uses its own convention :(
+            c_sources += cxx_sources
+            cxx_sources = []
 
-            objects = []
-            if c_sources:
-                log.info("compiling C sources")
-                objects = compiler.compile(c_sources,
-                                           output_dir=self.build_temp,
-                                           macros=macros,
-                                           include_dirs=include_dirs,
-                                           debug=self.debug,
-                                           extra_postargs=extra_postargs)
+        objects = []
+        if c_sources:
+            log.info("compiling C sources")
+            objects = compiler.compile(c_sources,
+                                       output_dir=self.build_temp,
+                                       macros=macros,
+                                       include_dirs=include_dirs,
+                                       debug=self.debug,
+                                       extra_postargs=extra_postargs)
 
-            if cxx_sources:
-                log.info("compiling C++ sources")
-                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)
+        if cxx_sources:
+            log.info("compiling C++ sources")
+            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)
 
-            if f_sources or fmodule_sources:
-                extra_postargs = []
-                f_objects = []
+        if f_sources or fmodule_sources:
+            extra_postargs = []
+            f_objects = []
 
-                if requiref90:
-                    if fcompiler.module_dir_switch is None:
-                        existing_modules = glob('*.mod')
-                    extra_postargs += fcompiler.module_options(\
-                        module_dirs,module_build_dir)
+            if requiref90:
+                if fcompiler.module_dir_switch is None:
+                    existing_modules = glob('*.mod')
+                extra_postargs += fcompiler.module_options(\
+                    module_dirs,module_build_dir)
 
-                if fmodule_sources:
-                    log.info("compiling Fortran 90 module sources")
-                    f_objects += fcompiler.compile(fmodule_sources,
-                                                   output_dir=self.build_temp,
-                                                   macros=macros,
-                                                   include_dirs=include_dirs,
-                                                   debug=self.debug,
-                                                   extra_postargs=extra_postargs)
+            if fmodule_sources:
+                log.info("compiling Fortran 90 module sources")
+                f_objects += fcompiler.compile(fmodule_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
 
-                if requiref90 and self.fcompiler.module_dir_switch is None:
-                    # move new compiled F90 module files to module_build_dir
-                    for f in glob('*.mod'):
-                        if f in existing_modules:
-                            continue
-                        t = os.path.join(module_build_dir, f)
-                        if os.path.abspath(f)==os.path.abspath(t):
-                            continue
-                        if os.path.isfile(t):
-                            os.remove(t)
-                        try:
-                            self.move_file(f, module_build_dir)
-                        except DistutilsFileError:
-                            log.warn('failed to move %r to %r' \
-                                     % (f, module_build_dir))
+            if requiref90 and self.fcompiler.module_dir_switch is None:
+                # move new compiled F90 module files to module_build_dir
+                for f in glob('*.mod'):
+                    if f in existing_modules:
+                        continue
+                    t = os.path.join(module_build_dir, f)
+                    if os.path.abspath(f)==os.path.abspath(t):
+                        continue
+                    if os.path.isfile(t):
+                        os.remove(t)
+                    try:
+                        self.move_file(f, module_build_dir)
+                    except DistutilsFileError:
+                        log.warn('failed to move %r to %r' \
+                                 % (f, module_build_dir))
 
-                if f_sources:
-                    log.info("compiling Fortran sources")
-                    f_objects += fcompiler.compile(f_sources,
-                                                   output_dir=self.build_temp,
-                                                   macros=macros,
-                                                   include_dirs=include_dirs,
-                                                   debug=self.debug,
-                                                   extra_postargs=extra_postargs)
-            else:
-                f_objects = []
+            if f_sources:
+                log.info("compiling Fortran sources")
+                f_objects += fcompiler.compile(f_sources,
+                                               output_dir=self.build_temp,
+                                               macros=macros,
+                                               include_dirs=include_dirs,
+                                               debug=self.debug,
+                                               extra_postargs=extra_postargs)
+        else:
+            f_objects = []
 
-            objects.extend(f_objects)
+        objects.extend(f_objects)
 
-            # assume that default linker is suitable for
-            # linking Fortran object files
-            compiler.create_static_lib(objects, lib_name,
-                                       output_dir=self.build_clib,
-                                       debug=self.debug)
+        # assume that default linker is suitable for
+        # linking Fortran object files
+        compiler.create_static_lib(objects, lib_name,
+                                   output_dir=self.build_clib,
+                                   debug=self.debug)
 
-            # fix library dependencies
-            clib_libraries = build_info.get('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
+        # fix library dependencies
+        clib_libraries = build_info.get('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

Modified: branches/distutils-revamp/command/build_ext.py
===================================================================
--- branches/distutils-revamp/command/build_ext.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/build_ext.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -84,10 +84,10 @@
         clibs = {}
         if build_clib is not None:
             for libname,build_info in build_clib.libraries or []:
-                if clibs.has_key(libname):
+                if clibs.has_key(libname) and clibs[libname]!=build_info:
                     log.warn('library %r defined more than once,'\
-                             ' overwriting build_info %r with %r.' \
-                             % (libname, clibs[libname], build_info))
+                             ' overwriting build_info\n%s... \nwith\n%s...' \
+                             % (libname, `clibs[libname]`[:300], `build_info`[:300]))
                 clibs[libname] = build_info
         # .. and distribution libraries:
         for libname,build_info in self.distribution.libraries or []:
@@ -169,38 +169,46 @@
 
         # Initialize Fortran 77 compiler:
         if need_f77_compiler:
+            ctype = self.fcompiler
             self._f77_compiler = new_fcompiler(compiler=self.fcompiler,
                                                verbose=self.verbose,
                                                dry_run=self.dry_run,
                                                force=self.force,
-                                               requiref90=False)
+                                               requiref90=False,
+                                               c_compiler=self.compiler)
             fcompiler = self._f77_compiler
-            if fcompiler.get_version():
+            if fcompiler:
+                ctype = fcompiler.compiler_type
                 fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
                 fcompiler.customize_cmd(self)
                 fcompiler.show_customization()
             else:
                 self.warn('f77_compiler=%s is not available.' %
-                          (fcompiler.compiler_type))
+                          (ctype))
                 self._f77_compiler = None
         else:
             self._f77_compiler = None
 
         # Initialize Fortran 90 compiler:
         if need_f90_compiler:
+            ctype = self.fcompiler
             self._f90_compiler = new_fcompiler(compiler=self.fcompiler,
                                                verbose=self.verbose,
                                                dry_run=self.dry_run,
                                                force=self.force,
-                                               requiref90=True)
+                                               requiref90=True,
+                                               c_compiler = self.compiler)
             fcompiler = self._f90_compiler
-            if fcompiler.get_version():
+            if fcompiler:
+                ctype = fcompiler.compiler_type
                 fcompiler.customize(self.distribution)
+            if fcompiler and fcompiler.get_version():
                 fcompiler.customize_cmd(self)
                 fcompiler.show_customization()
             else:
                 self.warn('f90_compiler=%s is not available.' %
-                          (fcompiler.compiler_type))
+                          (ctype))
                 self._f90_compiler = None
         else:
             self._f90_compiler = None

Modified: branches/distutils-revamp/command/build_src.py
===================================================================
--- branches/distutils-revamp/command/build_src.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/build_src.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -11,7 +11,7 @@
 from distutils.errors import DistutilsError, DistutilsSetupError
 
 try:
-    from Pyrex.Compiler import Main
+    import Pyrex.Compiler.Main
     have_pyrex = True
 except ImportError:
     have_pyrex = False
@@ -103,7 +103,7 @@
                 self.swig_opts = self.swigflags
             self.swigflags = None
 
-        if self.swig_opts is None: 
+        if self.swig_opts is None:
             self.swig_opts = []
         else:
             self.swig_opts = splitcmdline(self.swig_opts)
@@ -224,7 +224,8 @@
         sources, h_files = self.filter_h_files(sources)
 
         if h_files:
-            print self.package,'- nothing done with h_files=',h_files
+            log.info('%s - nothing done with h_files = %s',
+                     self.package, h_files)
 
         #for f in h_files:
         #    self.distribution.headers.append((lib_name,f))
@@ -269,7 +270,8 @@
         sources, h_files = self.filter_h_files(sources)
 
         if h_files:
-            print package,'- nothing done with h_files=',h_files
+            log.info('%s - nothing done with h_files = %s',
+                     package, h_files)
         #for f in h_files:
         #    self.distribution.headers.append((package,f))
 
@@ -384,11 +386,11 @@
                     if have_pyrex:
                         log.info("pyrexc:> %s" % (target_file))
                         self.mkpath(target_dir)
-                        from Pyrex.Compiler import Main
-                        options = Main.CompilationOptions(
-                            defaults=Main.default_options,
+                        options = Pyrex.Compiler.Main.CompilationOptions(
+                            defaults=Pyrex.Compiler.Main.default_options,
                             output_file=target_file)
-                        pyrex_result = Main.compile(source, options=options)
+                        pyrex_result = Pyrex.Compiler.Main.compile(source,
+                                            options=options)
                         if pyrex_result.num_errors != 0:
                             raise DistutilsError,"%d errors while compiling %r with Pyrex" \
                                   % (pyrex_result.num_errors, source)

Modified: branches/distutils-revamp/command/config.py
===================================================================
--- branches/distutils-revamp/command/config.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/config.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -27,10 +27,13 @@
         from numpy.distutils.fcompiler import FCompiler, new_fcompiler
         if not isinstance(self.fcompiler, FCompiler):
             self.fcompiler = new_fcompiler(compiler=self.fcompiler,
-                                           dry_run=self.dry_run, force=1)
-            self.fcompiler.customize(self.distribution)
-            self.fcompiler.customize_cmd(self)
-            self.fcompiler.show_customization()
+                                           dry_run=self.dry_run, force=1,
+                                           c_compiler=self.compiler)
+            if self.fcompiler is not None:
+                self.fcompiler.customize(self.distribution)
+                if self.fcompiler.get_version():
+                    self.fcompiler.customize_cmd(self)
+                    self.fcompiler.show_customization()
 
     def _wrap_method(self,mth,lang,args):
         from distutils.ccompiler import CompileError

Modified: branches/distutils-revamp/command/config_compiler.py
===================================================================
--- branches/distutils-revamp/command/config_compiler.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/config_compiler.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,4 +1,3 @@
-import sys
 from distutils.core import Command
 from numpy.distutils import log
 

Modified: branches/distutils-revamp/command/sdist.py
===================================================================
--- branches/distutils-revamp/command/sdist.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/command/sdist.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,4 +1,9 @@
-from distutils.command.sdist import sdist as old_sdist
+import sys
+if 'setuptools' in sys.modules:
+    from setuptools.command.sdist import sdist as old_sdist
+else:
+    from distutils.command.sdist import sdist as old_sdist
+
 from numpy.distutils.misc_util import get_data_files
 
 class sdist(old_sdist):

Modified: branches/distutils-revamp/core.py
===================================================================
--- branches/distutils-revamp/core.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/core.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -21,19 +21,9 @@
 import distutils.dist
 
 from numpy.distutils.extension import Extension
-from numpy.distutils.command import config
-from numpy.distutils.command import build
-from numpy.distutils.command import build_py
-from numpy.distutils.command import config_compiler
-from numpy.distutils.command import build_ext
-from numpy.distutils.command import build_clib
-from numpy.distutils.command import build_src
-from numpy.distutils.command import build_scripts
-from numpy.distutils.command import sdist
-from numpy.distutils.command import install_data
-from numpy.distutils.command import install_headers
-from numpy.distutils.command import install
-from numpy.distutils.command import bdist_rpm
+from numpy.distutils.command import config, config_compiler, \
+     build, build_py, build_ext, build_clib, build_src, build_scripts, \
+     sdist, install_data, install_headers, install, bdist_rpm
 from numpy.distutils.misc_util import get_data_files, is_sequence, is_string
 
 numpy_cmdclass = {'build':            build.build,
@@ -73,7 +63,7 @@
         elif is_string(dv):
             d[k] = dv + v
         else:
-            raise TypeError,`type(dv)`
+            raise TypeError, repr(type(dv))
 
 def _command_line_ok(_cache=[]):
     """ Return True if command line does not contain any
@@ -93,14 +83,6 @@
     _cache.append(ok)
     return ok
 
-def _exit_interactive_session(_cache=[]):
-    if _cache:
-        return # been here
-    _cache.append(1)
-    print '-'*72
-    raw_input('Press ENTER to close the interactive session..')
-    print '='*72
-
 def get_distribution(always=False):
     dist = distutils.core._setup_distribution
     # XXX Hack to get numpy installable with easy_install.
@@ -116,6 +98,14 @@
         dist = distutils.dist.Distribution()
     return dist
 
+def _exit_interactive_session(_cache=[]):
+    if _cache:
+        return # been here
+    _cache.append(1)
+    print '-'*72
+    raw_input('Press ENTER to close the interactive session..')
+    print '='*72
+
 def setup(**attr):
 
     if len(sys.argv)<=1 and not attr.get('script_args',[]):

Modified: branches/distutils-revamp/environment.py
===================================================================
--- branches/distutils-revamp/environment.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/environment.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -10,6 +10,25 @@
         self._conf = None
         self._hook_handler = None
 
+    def dump_variable(self, name):
+        conf_desc = self._conf_keys[name]
+        hook, envvar, confvar, convert = conf_desc
+        if not convert:
+            convert = lambda x : x
+        print '%s.%s:' % (self._distutils_section, name)
+        v = self._hook_handler(name, hook)
+        print '  hook   : %s' % (convert(v),)
+        if envvar:
+            v = os.environ.get(envvar, None)
+            print '  environ: %s' % (convert(v),)
+        if confvar and self._conf:
+            v = self._conf.get(confvar, (None, None))[1]
+            print '  config : %s' % (convert(v),)
+
+    def dump_variables(self):
+        for name in self._conf_keys:
+            self.dump_variable(name)
+
     def __getattr__(self, name):
         try:
             conf_desc = self._conf_keys[name]
@@ -28,12 +47,14 @@
         return var
 
     def _get_var(self, name, conf_desc):
-        hook, envvar, confvar = conf_desc
+        hook, envvar, confvar, convert = conf_desc
         var = self._hook_handler(name, hook)
         if envvar is not None:
             var = os.environ.get(envvar, var)
         if confvar is not None and self._conf:
             var = self._conf.get(confvar, (None, var))[1]
+        if convert is not None:
+            var = convert(var)
         return var
 
     def clone(self, hook_handler):

Modified: branches/distutils-revamp/exec_command.py
===================================================================
--- branches/distutils-revamp/exec_command.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/exec_command.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -49,16 +49,16 @@
 __all__ = ['exec_command','find_executable']
 
 import os
-import re
 import sys
-import tempfile
 
-from numpy.distutils.misc_util import is_sequence
+from numpy.distutils.misc_util import is_sequence, make_temp_file
+from numpy.distutils import log
 
-############################################################
+def temp_file_name():
+    fo, name = make_temp_file()
+    fo.close()
+    return name
 
-from log import _global_log as log
-
 ############################################################
 
 def get_pythonexe():
@@ -122,17 +122,22 @@
 
 ############################################################
 
-def find_executable(exe, path=None):
-    """Return full path of a executable.
+def find_executable(exe, path=None, _cache={}):
+    """Return full path of a executable or None.
 
     Symbolic links are not followed.
     """
+    key = exe, path
+    try:
+        return _cache[key]
+    except KeyError:
+        pass
     log.debug('find_executable(%r)' % exe)
     orig_exe = exe
 
     if path is None:
         path = os.environ.get('PATH',os.defpath)
-    if os.name=='posix' and sys.version[:3]>'2.1':
+    if os.name=='posix':
         realpath = os.path.realpath
     else:
         realpath = lambda a:a
@@ -159,7 +164,8 @@
             if not os.path.islink(f_ext):
                 f_ext = realpath(f_ext)
             if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK):
-                log.debug('Found executable %s' % f_ext)
+                log.good('Found executable %s' % f_ext)
+                _cache[key] = f_ext
                 return f_ext
 
     log.warn('Could not locate executable %s' % orig_exe)
@@ -190,7 +196,7 @@
     The following special keyword arguments can be used:
       use_shell - execute `sh -c command`
       use_tee   - pipe the output of command through tee
-      execute_in - before command `cd execute_in` and after `cd -`.
+      execute_in - before run command `cd execute_in` and after `cd -`.
 
     On NT, DOS systems the returned status is correct for external commands.
     Wild cards will not work for non-posix systems or when use_shell=0.
@@ -264,17 +270,17 @@
     else:
         command_str = command
 
-    tmpfile = tempfile.mktemp()
+    tmpfile = temp_file_name()
     stsfile = None
     if use_tee:
-        stsfile = tempfile.mktemp()
+        stsfile = temp_file_name()
         filter = ''
         if use_tee == 2:
             filter = r'| tr -cd "\n" | tr "\n" "."; echo'
         command_posix = '( %s ; echo $? > %s ) 2>&1 | tee %s %s'\
                       % (command_str,stsfile,tmpfile,filter)
     else:
-        stsfile = tempfile.mktemp()
+        stsfile = temp_file_name()
         command_posix = '( %s ; echo $? > %s ) > %s 2>&1'\
                         % (command_str,stsfile,tmpfile)
         #command_posix = '( %s ) > %s 2>&1' % (command_str,tmpfile)
@@ -311,9 +317,9 @@
     log.debug('_exec_command_python(...)')
 
     python_exe = get_pythonexe()
-    cmdfile = tempfile.mktemp()
-    stsfile = tempfile.mktemp()
-    outfile = tempfile.mktemp()
+    cmdfile = temp_file_name()
+    stsfile = temp_file_name()
+    outfile = temp_file_name()
 
     f = open(cmdfile,'w')
     f.write('import os\n')
@@ -358,7 +364,6 @@
         use_shell = os.name=='posix'
     if use_tee is None:
         use_tee = os.name=='posix'
-
     using_command = 0
     if use_shell:
         # We use shell (unless use_shell==0) so that wildcards can be
@@ -380,7 +385,7 @@
         spawn_command = os.spawnvpe
     else:
         spawn_command = os.spawnve
-        argv[0] = find_executable(argv[0])
+        argv[0] = find_executable(argv[0]) or argv[0]
         if not os.path.isfile(argv[0]):
             log.warn('Executable %s does not exist' % (argv[0]))
             if os.name in ['nt','dos']:
@@ -397,10 +402,10 @@
     so_dup = os.dup(so_fileno)
     se_dup = os.dup(se_fileno)
 
-    outfile = tempfile.mktemp()
+    outfile = temp_file_name()
     fout = open(outfile,'w')
     if using_command:
-        errfile = tempfile.mktemp()
+        errfile = temp_file_name()
         ferr = open(errfile,'w')
 
     log.debug('Running %s(%s,%r,%r,os.environ)' \
@@ -589,7 +594,7 @@
 
 def test_execute_in(**kws):
     pythonexe = get_pythonexe()
-    tmpfile = tempfile.mktemp()
+    tmpfile = temp_file_name()
     fn = os.path.basename(tmpfile)
     tmpdir = os.path.dirname(tmpfile)
     f = open(tmpfile,'w')

Modified: branches/distutils-revamp/fcompiler/__init__.py
===================================================================
--- branches/distutils-revamp/fcompiler/__init__.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/__init__.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -2,6 +2,15 @@
 
 Contains FCompiler, an abstract base class that defines the interface
 for the numpy.distutils Fortran compiler abstraction model.
+
+Terminology:
+
+To be consistent, where the term 'executable' is used, it means the single
+file, like 'gcc', that is executed, and should be a string. In contrast,
+'command' means the entire command line, like ['gcc', '-c', 'file.c'], and
+should be a list.
+
+But note that FCompiler.executables is actually a dictionary of commands.
 """
 
 __all__ = ['FCompiler','new_fcompiler','show_fcompilers',
@@ -18,39 +27,52 @@
 
 from distutils.sysconfig import get_config_var, get_python_lib
 from distutils.fancy_getopt import FancyGetopt
-from distutils.errors import DistutilsModuleError,DistutilsArgError,\
-     DistutilsExecError,CompileError,LinkError,DistutilsPlatformError
-from distutils.util import split_quoted
+from distutils.errors import DistutilsModuleError, \
+     DistutilsExecError, CompileError, LinkError, DistutilsPlatformError
+from distutils.util import split_quoted, strtobool
 
 from numpy.distutils.ccompiler import CCompiler, gen_lib_options
 from numpy.distutils import log
-from numpy.distutils.misc_util import is_string, is_sequence
+from numpy.distutils.misc_util import is_string, all_strings, is_sequence, make_temp_file
 from numpy.distutils.environment import EnvironmentConfig
 from numpy.distutils.exec_command import find_executable
-from distutils.spawn import _nt_quote_args
 
 __metaclass__ = type
 
 class CompilerNotFound(Exception):
     pass
 
+def flaglist(s):
+    if is_string(s):
+        return split_quoted(s)
+    else:
+        return s
+
+def str2bool(s):
+    if is_string(s):
+        return strtobool(s)
+    return bool(s)
+
+def is_sequence_of_strings(seq):
+    return is_sequence(seq) and all_strings(seq)
+
 class FCompiler(CCompiler):
-    """ Abstract base class to define the interface that must be implemented
+    """Abstract base class to define the interface that must be implemented
     by real Fortran compiler classes.
 
     Methods that subclasses may redefine:
 
-        find_executables(), get_version_cmd(), get_linker_so(), get_version()
+        update_executables(), find_executables(), get_version()
         get_flags(), get_flags_opt(), get_flags_arch(), get_flags_debug()
         get_flags_f77(), get_flags_opt_f77(), get_flags_arch_f77(),
         get_flags_debug_f77(), get_flags_f90(), get_flags_opt_f90(),
         get_flags_arch_f90(), get_flags_debug_f90(),
-        get_flags_fix(), get_flags_linker_so(), get_flags_version()
+        get_flags_fix(), get_flags_linker_so()
 
     DON'T call these methods (except get_version) after
     constructing a compiler instance or inside any other method.
-    All methods, except get_version_cmd() and get_flags_version(), may
-    call the get_version() method.
+    All methods, except update_executables() and find_executables(),
+    may call the get_version() method.
 
     After constructing a compiler instance, always call customize(dist=None)
     method that finalizes compiler construction and makes the following
@@ -67,51 +89,53 @@
 
     # These are the environment variables and distutils keys used.
     # Each configuration descripition is
-    # (<hook name>, <environment variable>, <key in distutils.cfg>)
+    # (<hook name>, <environment variable>, <key in distutils.cfg>, <convert>)
     # The hook names are handled by the self._environment_hook method.
     #  - names starting with 'self.' call methods in this class
     #  - names starting with 'exe.' return the key in the executables dict
-    #  - names like'flags.YYY' return self.get_flag_YYY()
+    #  - names like 'flags.YYY' return self.get_flag_YYY()
+    # convert is either None or a function to convert a string to the
+    # appropiate type used.
 
     distutils_vars = EnvironmentConfig(
-        noopt = (None, None, 'noopt'),
-        noarch = (None, None, 'noarch'),
-        debug = (None, None, 'debug'),
-        verbose = (None, None, 'verbose'),
+        distutils_section='config_fc',
+        noopt = (None, None, 'noopt', str2bool),
+        noarch = (None, None, 'noarch', str2bool),
+        debug = (None, None, 'debug', str2bool),
+        verbose = (None, None, 'verbose', str2bool),
     )
 
     command_vars = EnvironmentConfig(
         distutils_section='config_fc',
-        compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec'),
-        compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec'),
-        compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec'),
-        version_cmd = ('self.get_version_cmd', None, None),
-        linker_so = ('self.get_linker_so', 'LDSHARED', 'ldshared'),
-        linker_exe = ('self.get_linker_exe', 'LD', 'ld'),
-        archiver = (None, 'AR', 'ar'),
-        ranlib = (None, 'RANLIB', 'ranlib'),
+        compiler_f77 = ('exe.compiler_f77', 'F77', 'f77exec', None),
+        compiler_f90 = ('exe.compiler_f90', 'F90', 'f90exec', None),
+        compiler_fix = ('exe.compiler_fix', 'F90', 'f90exec', None),
+        version_cmd = ('exe.version_cmd', None, None, None),
+        linker_so = ('exe.linker_so', 'LDSHARED', 'ldshared', None),
+        linker_exe = ('exe.linker_exe', 'LD', 'ld', None),
+        archiver = (None, 'AR', 'ar', None),
+        ranlib = (None, 'RANLIB', 'ranlib', None),
     )
 
     flag_vars = EnvironmentConfig(
         distutils_section='config_fc',
-        version = ('flags.version', None, None),
-        f77 = ('flags.f77', 'F77FLAGS', 'f77flags'),
-        f90 = ('flags.f90', 'F90FLAGS', 'f90flags'),
-        free = ('flags.free', 'FREEFLAGS', 'freeflags'),
-        fix = ('flags.fix', None, None),
-        opt = ('flags.opt', 'FOPT', 'opt'),
-        opt_f77 = ('flags.opt_f77', None, None),
-        opt_f90 = ('flags.opt_f90', None, None),
-        arch = ('flags.arch', 'FARCH', 'arch'),
-        arch_f77 = ('flags.arch_f77', None, None),
-        arch_f90 = ('flags.arch_f90', None, None),
-        debug = ('flags.debug', 'FDEBUG', None, None),
-        debug_f77 = ('flags.debug_f77', None, None),
-        debug_f90 = ('flags.debug_f90', None, None),
-        flags = ('self.get_flags', 'FFLAGS', 'fflags'),
-        linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags'),
-        linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags'),
-        ar = ('flags.ar', 'ARFLAGS', 'arflags'),
+        f77 = ('flags.f77', 'F77FLAGS', 'f77flags', flaglist),
+        f90 = ('flags.f90', 'F90FLAGS', 'f90flags', flaglist),
+        free = ('flags.free', 'FREEFLAGS', 'freeflags', flaglist),
+        fix = ('flags.fix', None, None, flaglist),
+        opt = ('flags.opt', 'FOPT', 'opt', flaglist),
+        opt_f77 = ('flags.opt_f77', None, None, flaglist),
+        opt_f90 = ('flags.opt_f90', None, None, flaglist),
+        arch = ('flags.arch', 'FARCH', 'arch', flaglist),
+        arch_f77 = ('flags.arch_f77', None, None, flaglist),
+        arch_f90 = ('flags.arch_f90', None, None, flaglist),
+        debug = ('flags.debug', 'FDEBUG', 'fdebug', None, flaglist),
+        debug_f77 = ('flags.debug_f77', None, None, flaglist),
+        debug_f90 = ('flags.debug_f90', None, None, flaglist),
+        flags = ('self.get_flags', 'FFLAGS', 'fflags', flaglist),
+        linker_so = ('flags.linker_so', 'LDFLAGS', 'ldflags', flaglist),
+        linker_exe = ('flags.linker_exe', 'LDFLAGS', 'ldflags', flaglist),
+        ar = ('flags.ar', 'ARFLAGS', 'arflags', flaglist),
     )
 
     language_map = {'.f':'f77',
@@ -125,6 +149,11 @@
                     }
     language_order = ['f90','f77']
 
+
+    # These will be set by the subclass
+
+    compiler_type = None
+    compiler_aliases = ()
     version_pattern = None
 
     possible_executables = []
@@ -139,6 +168,11 @@
         'ranlib'       : None,
         }
 
+    # If compiler does not support compiling Fortran 90 then it can
+    # suggest using another compiler. For example, gnu would suggest
+    # gnu95 compiler type when there are F90 sources.
+    suggested_f90_compiler = None
+
     compile_switch = "-c"
     object_switch = "-o "   # Ending space matters! It will be stripped
                             # but if it is missing then object_switch
@@ -164,18 +198,30 @@
     shared_lib_format = "%s%s"
     exe_extension = ""
 
+    _exe_cache = {}
+
+    _executable_keys = ['version_cmd', 'compiler_f77', 'compiler_f90',
+                        'compiler_fix', 'linker_so', 'linker_exe', 'archiver',
+                        'ranlib']
+
+    # This will be set by new_fcompiler when called in
+    # command/{build_ext.py, build_clib.py, config.py} files.
+    c_compiler = None
+    
     def __init__(self, *args, **kw):
         CCompiler.__init__(self, *args, **kw)
         self.distutils_vars = self.distutils_vars.clone(self._environment_hook)
         self.command_vars = self.command_vars.clone(self._environment_hook)
         self.flag_vars = self.flag_vars.clone(self._environment_hook)
         self.executables = self.executables.copy()
-        for e in ['version_cmd', 'compiler_f77', 'compiler_f90',
-                  'compiler_fix', 'linker_so', 'linker_exe', 'archiver',
-                  'ranlib']:
+        for e in self._executable_keys:
             if e not in self.executables:
                 self.executables[e] = None
 
+        # Some methods depend on .customize() being called first, so
+        # this keeps track of whether that's happened yet.
+        self._is_customised = False
+
     def __copy__(self):
         obj = new.instance(self.__class__, self.__dict__)
         obj.distutils_vars = obj.distutils_vars.clone(obj._environment_hook)
@@ -184,11 +230,44 @@
         obj.executables = obj.executables.copy()
         return obj
 
-    # If compiler does not support compiling Fortran 90 then it can
-    # suggest using another compiler. For example, gnu would suggest
-    # gnu95 compiler type when there are F90 sources.
-    suggested_f90_compiler = None
+    def copy(self):
+        return self.__copy__()
 
+    # Use properties for the attributes used by CCompiler. Setting them
+    # as attributes from the self.executables dictionary is error-prone,
+    # so we get them from there each time.
+    def _command_property(key):
+        def fget(self):
+            assert self._is_customised
+            return self.executables[key]
+        return property(fget=fget)
+    version_cmd = _command_property('version_cmd')
+    compiler_f77 = _command_property('compiler_f77')
+    compiler_f90 = _command_property('compiler_f90')
+    compiler_fix = _command_property('compiler_fix')
+    linker_so = _command_property('linker_so')
+    linker_exe = _command_property('linker_exe')
+    archiver = _command_property('archiver')
+    ranlib = _command_property('ranlib')
+
+    # Make our terminology consistent.
+    def set_executable(self, key, value):
+        self.set_command(key, value)
+
+    def set_commands(self, **kw):
+        for k, v in kw.items():
+            self.set_command(k, v)
+
+    def set_command(self, key, value):
+        if not key in self._executable_keys:
+            raise ValueError(
+                "unknown executable '%s' for class %s" %
+                (key, self.__class__.__name__))
+        if is_string(value):
+            value = split_quoted(value)
+        assert value is None or is_sequence_of_strings(value[1:]), (key, value)
+        self.executables[key] = value
+
     ######################################################################
     ## Methods that subclasses may redefine. But don't call these methods!
     ## They are private to FCompiler class and may return unexpected
@@ -205,14 +284,22 @@
         Also, if the 0th element is "<F77>" or "<F90>", the Fortran 77
         or the Fortran 90 compiler executable is used, unless overridden
         by an environment setting.
+
+        Subclasses should call this if overriden.
         """
-        exe_cache = {}
+        assert self._is_customised
+        exe_cache = self._exe_cache
         def cached_find_executable(exe):
             if exe in exe_cache:
                 return exe_cache[exe]
             fc_exe = find_executable(exe)
-            exe_cache[exe] = fc_exe
+            exe_cache[exe] = exe_cache[fc_exe] = fc_exe
             return fc_exe
+        def verify_command_form(name, value):
+            if value is not None and not is_sequence_of_strings(value):
+                raise ValueError(
+                    "%s value %r is invalid in class %s" %
+                    (name, value, self.__class__.__name__))
         def set_exe(exe_key, f77=None, f90=None):
             cmd = self.executables.get(exe_key, None)
             if not cmd:
@@ -242,96 +329,79 @@
                 if fc_exe:
                     cmd[0] = fc_exe
                     return fc_exe
+            self.set_command(exe_key, None)
             return None
 
+        ctype = self.compiler_type
         f90 = set_exe('compiler_f90')
         if not f90:
-            raise CompilerNotFound('f90')
-        f77 = set_exe('compiler_f77', f90=f90)
-        if not f77:
-            raise CompilerNotFound('f90')
-        set_exe('compiler_fix', f90=f90)
+            f77 = set_exe('compiler_f77')
+            if f77:
+                log.warn('%s: no Fortran 90 compiler found' % ctype)
+            else:
+                raise CompilerNotFound('%s: f90 nor f77' % ctype)
+        else:
+            f77 = set_exe('compiler_f77', f90=f90)
+            if not f77:
+                log.warn('%s: no Fortran 77 compiler found' % ctype)
+            set_exe('compiler_fix', f90=f90)
 
         set_exe('linker_so', f77=f77, f90=f90)
         set_exe('linker_exe', f77=f77, f90=f90)
         set_exe('version_cmd', f77=f77, f90=f90)
-
         set_exe('archiver')
         set_exe('ranlib')
 
-    def get_version_cmd(self):
-        """Compiler command to print out version information."""
-        cmd = self.executables['version_cmd']
-        if cmd:
-            return cmd[0]
-        else:
-            return None
+    def update_executables(elf):
+        """Called at the beginning of customisation. Subclasses should
+        override this if they need to set up the executables dictionary.
 
-    def get_linker_so(self):
-        """Linker command to build shared libraries."""
-        cmd = self.executables['linker_so']
-        if cmd:
-            return cmd[0]
-        else:
-            return None
+        Note that self.find_executables() is run afterwards, so the
+        self.executables dictionary values can contain <F77> or <F90> as
+        the command, which will be replaced by the found F77 or F90
+        compiler.
+        """
+        pass
 
-    def get_linker_exe(self):
-        """Linker command to build shared libraries."""
-        cmd = self.executables['linker_exe']
-        if cmd:
-            return cmd[0]
-        else:
-            return None
-
     def get_flags(self):
-        """ List of flags common to all compiler types. """
+        """List of flags common to all compiler types."""
         return [] + self.pic_flags
-    def get_flags_version(self):
-        """ List of compiler flags to print out version information. """
-        if self.executables['version_cmd']:
-            return self.executables['version_cmd'][1:]
-        return []
+
+    def _get_command_flags(self, key):
+        cmd = self.executables.get(key, None)
+        if cmd is None:
+            return []
+        return cmd[1:]
+
     def get_flags_f77(self):
-        """ List of Fortran 77 specific flags. """
-        if self.executables['compiler_f77']:
-            return self.executables['compiler_f77'][1:]
-        return []
+        """List of Fortran 77 specific flags."""
+        return self._get_command_flags('compiler_f77')
     def get_flags_f90(self):
-        """ List of Fortran 90 specific flags. """
-        if self.executables['compiler_f90']:
-            return self.executables['compiler_f90'][1:]
-        return []
+        """List of Fortran 90 specific flags."""
+        return self._get_command_flags('compiler_f90')
     def get_flags_free(self):
-        """ List of Fortran 90 free format specific flags. """
+        """List of Fortran 90 free format specific flags."""
         return []
     def get_flags_fix(self):
-        """ List of Fortran 90 fixed format specific flags. """
-        if self.executables['compiler_fix']:
-            return self.executables['compiler_fix'][1:]
-        return []
+        """List of Fortran 90 fixed format specific flags."""
+        return self._get_command_flags('compiler_fix')
     def get_flags_linker_so(self):
-        """ List of linker flags to build a shared library. """
-        if self.executables['linker_so']:
-            return self.executables['linker_so'][1:]
-        return []
+        """List of linker flags to build a shared library."""
+        return self._get_command_flags('linker_so')
     def get_flags_linker_exe(self):
-        """ List of linker flags to build an executable. """
-        if self.executables['linker_exe']:
-            return self.executables['linker_exe'][1:]
-        return []
+        """List of linker flags to build an executable."""
+        return self._get_command_flags('linker_exe')
     def get_flags_ar(self):
-        """ List of archiver flags. """
-        if self.executables['archiver']:
-            return self.executables['archiver'][1:]
-        return []
+        """List of archiver flags. """
+        return self._get_command_flags('archiver')
     def get_flags_opt(self):
-        """ List of architecture independent compiler flags. """
+        """List of architecture independent compiler flags."""
         return []
     def get_flags_arch(self):
-        """ List of architecture dependent compiler flags. """
+        """List of architecture dependent compiler flags."""
         return []
     def get_flags_debug(self):
-        """ List of compiler flags to compile with debugging information. """
+        """List of compiler flags to compile with debugging information."""
         return []
 
     get_flags_opt_f77 = get_flags_opt_f90 = get_flags_opt
@@ -339,52 +409,52 @@
     get_flags_debug_f77 = get_flags_debug_f90 = get_flags_debug
 
     def get_libraries(self):
-        """ List of compiler libraries. """
+        """List of compiler libraries."""
         return self.libraries[:]
     def get_library_dirs(self):
-        """ List of compiler library directories. """
+        """List of compiler library directories."""
         return self.library_dirs[:]
 
+    def get_version(self, force=False, ok_status=[0]):
+        assert self._is_customised
+        return CCompiler.get_version(self, force=force, ok_status=ok_status)
+
     ############################################################
 
     ## Public methods:
 
-    def customize(self, dist):
-        """ Customize Fortran compiler.
+    def customize(self, dist = None):
+        """Customize Fortran compiler.
 
         This method gets Fortran compiler specific information from
         (i) class definition, (ii) environment, (iii) distutils config
-        files, and (iv) command line.
+        files, and (iv) command line (later overrides earlier).
 
         This method should be always called after constructing a
         compiler instance. But not in __init__ because Distribution
         instance is needed for (iii) and (iv).
         """
         log.info('customize %s' % (self.__class__.__name__))
+
+        self._is_customised = True
+
         self.distutils_vars.use_distribution(dist)
         self.command_vars.use_distribution(dist)
         self.flag_vars.use_distribution(dist)
 
+        self.update_executables()
+
+        # find_executables takes care of setting the compiler commands,
+        # version_cmd, linker_so, linker_exe, ar, and ranlib
         self.find_executables()
 
         noopt = self.distutils_vars.get('noopt', False)
-        if 0: # change to `if 1:` when making release.
-            # Don't use architecture dependent compiler flags:
-            noarch = True
-        else:
-            noarch = self.distutils_vars.get('noarch', noopt)
+        noarch = self.distutils_vars.get('noarch', noopt)
         debug = self.distutils_vars.get('debug', False)
 
         f77 = self.command_vars.compiler_f77
         f90 = self.command_vars.compiler_f90
 
-        # Must set version_cmd before others as self.get_flags*
-        # methods may call self.get_version.
-        vers_cmd = self.command_vars.version_cmd
-        if vers_cmd:
-            vflags = self.flag_vars.version
-            self.set_executables(version_cmd=[vers_cmd]+vflags)
-
         f77flags = []
         f90flags = []
         freeflags = []
@@ -401,23 +471,18 @@
             fixflags = self.flag_vars.fix + f90flags
 
         oflags, aflags, dflags = [], [], []
-        def to_list(flags):
-            if is_string(flags):
-                return [flags]
-            return flags
         # examine get_flags_<tag>_<compiler> for extra flags
         # only add them if the method is different from get_flags_<tag>
         def get_flags(tag, flags):
             # note that self.flag_vars.<tag> calls self.get_flags_<tag>()
-            flags.extend(to_list(getattr(self.flag_vars, tag)))
+            flags.extend(getattr(self.flag_vars, tag))
             this_get = getattr(self, 'get_flags_' + tag)
             for name, c, flagvar in [('f77', f77, f77flags),
                                      ('f90', f90, f90flags),
                                      ('f90', fix, fixflags)]:
                 t = '%s_%s' % (tag, name)
                 if c and this_get is not getattr(self, 'get_flags_' + t):
-                    flagvar.extend(to_list(getattr(self.flag_vars, t)))
-            return oflags
+                    flagvar.extend(getattr(self.flag_vars, t))
         if not noopt:
             get_flags('opt', oflags)
             if not noarch:
@@ -425,47 +490,42 @@
         if debug:
             get_flags('debug', dflags)
 
-        fflags = to_list(self.flag_vars.flags) + dflags + oflags + aflags
+        fflags = self.flag_vars.flags + dflags + oflags + aflags
 
         if f77:
-            self.set_executables(compiler_f77=[f77]+f77flags+fflags)
+            self.set_commands(compiler_f77=[f77]+f77flags+fflags)
         if f90:
-            self.set_executables(compiler_f90=[f90]+freeflags+f90flags+fflags)
+            self.set_commands(compiler_f90=[f90]+freeflags+f90flags+fflags)
         if fix:
-            self.set_executables(compiler_fix=[fix]+fixflags+fflags)
+            self.set_commands(compiler_fix=[fix]+fixflags+fflags)
 
+
         #XXX: Do we need LDSHARED->SOSHARED, LDFLAGS->SOFLAGS
-        linker_so = self.command_vars.linker_so
+        linker_so = self.linker_so
         if linker_so:
-            linker_so_flags = to_list(self.flag_vars.linker_so)
+            linker_so_flags = self.flag_vars.linker_so
             if sys.platform.startswith('aix'):
                 python_lib = get_python_lib(standard_lib=1)
                 ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix')
                 python_exp = os.path.join(python_lib, 'config', 'python.exp')
-                linker_so = [ld_so_aix, linker_so, '-bI:'+python_exp]
-            else:
-                linker_so = [linker_so]
-            self.set_executables(linker_so=linker_so+linker_so_flags)
+                linker_so = [ld_so_aix] + linker_so + ['-bI:'+python_exp]
+            self.set_commands(linker_so=linker_so+linker_so_flags)
 
-        linker_exe = self.command_vars.linker_exe
+        linker_exe = self.linker_exe
         if linker_exe:
-            linker_exe_flags = to_list(self.flag_vars.linker_exe)
-            self.set_executables(linker_exe=[linker_exe]+linker_exe_flags)
+            linker_exe_flags = self.flag_vars.linker_exe
+            self.set_commands(linker_exe=linker_exe+linker_exe_flags)
 
         ar = self.command_vars.archiver
         if ar:
-            arflags = to_list(self.flag_vars.ar)
-            self.set_executables(archiver=[ar]+arflags)
+            arflags = self.flag_vars.ar
+            self.set_commands(archiver=[ar]+arflags)
 
-        ranlib = self.command_vars.ranlib
-        if ranlib:
-            self.set_executables(ranlib=[ranlib])
-
         self.set_library_dirs(self.get_library_dirs())
         self.set_libraries(self.get_libraries())
 
     def dump_properties(self):
-        """ Print out the attributes of a compiler instance. """
+        """Print out the attributes of a compiler instance."""
         props = []
         for key in self.executables.keys() + \
                 ['version','libraries','library_dirs',
@@ -481,7 +541,6 @@
             if l[:4]=='  --':
                 l = '  ' + l[4:]
             print l
-        return
 
     ###################
 
@@ -517,8 +576,6 @@
             log.info('using compile options from source: %r' \
                      % ' '.join(extra_flags))
 
-        if os.name == 'nt':
-            compiler = _nt_quote_args(compiler)
         command = compiler + cc_args + extra_flags + s_args + o_args \
                   + extra_postargs
 
@@ -529,8 +586,6 @@
         except DistutilsExecError, msg:
             raise CompileError, msg
 
-        return
-
     def module_options(self, module_dirs, module_build_dir):
         options = []
         if self.module_dir_switch is not None:
@@ -592,8 +647,6 @@
                 linker = self.linker_exe[:]
             else:
                 linker = self.linker_so[:]
-            if os.name == 'nt':
-                linker = _nt_quote_args(linker)
             command = linker + ld_args
             try:
                 self.spawn(command)
@@ -601,7 +654,6 @@
                 raise LinkError, msg
         else:
             log.debug("skipping %s (up-to-date)", output_filename)
-        return
 
     def _environment_hook(self, name, hook_name):
         if hook_name is None:
@@ -628,7 +680,7 @@
     ## class FCompiler
 
 _default_compilers = (
-    # Platform mappings
+    # sys.platform mappings
     ('win32', ('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')),
     ('cygwin.*', ('gnu','intelv','absoft','compaqv','intelev','gnu95','g95')),
     ('linux.*', ('gnu','intel','lahey','pg','absoft','nag','vast','compaq',
@@ -637,24 +689,26 @@
     ('sunos.*', ('sun','gnu','gnu95','g95')),
     ('irix.*', ('mips','gnu','gnu95',)),
     ('aix.*', ('ibm','gnu','gnu95',)),
-    # OS mappings
+    # os.name mappings
     ('posix', ('gnu','gnu95',)),
     ('nt', ('gnu','gnu95',)),
     ('mac', ('gnu','gnu95',)),
     )
 
 fcompiler_class = None
+fcompiler_aliases = None
 
 def load_all_fcompiler_classes():
     """Cache all the FCompiler classes found in modules in the
     numpy.distutils.fcompiler package.
     """
     from glob import glob
-    global fcompiler_class
+    global fcompiler_class, fcompiler_aliases
     if fcompiler_class is not None:
         return
     pys = os.path.join(os.path.dirname(__file__), '*.py')
     fcompiler_class = {}
+    fcompiler_aliases = {}
     for fname in glob(pys):
         module_name, ext = os.path.splitext(os.path.basename(fname))
         module_name = 'numpy.distutils.fcompiler.' + module_name
@@ -663,18 +717,26 @@
         if hasattr(module, 'compilers'):
             for cname in module.compilers:
                 klass = getattr(module, cname)
-                fcompiler_class[klass.compiler_type] = (klass.compiler_type,
-                                                        klass,
-                                                        klass.description)
+                desc = (klass.compiler_type, klass, klass.description)
+                fcompiler_class[klass.compiler_type] = desc
+                for alias in klass.compiler_aliases:
+                    if alias in fcompiler_aliases:
+                        raise ValueError("alias %r defined for both %s and %s"
+                                         % (alias, klass.__name__,
+                                            fcompiler_aliases[alias][1].__name__))
+                    fcompiler_aliases[alias] = desc
 
-def _find_existing_fcompiler(compiler_types, osname=None, platform=None,
-                             requiref90=False):
+def _find_existing_fcompiler(compiler_types,
+                             osname=None, platform=None,
+                             requiref90=False,
+                             c_compiler=None):
     from numpy.distutils.core import get_distribution
     dist = get_distribution(always=True)
     for compiler_type in compiler_types:
         v = None
         try:
-            c = new_fcompiler(plat=platform, compiler=compiler_type)
+            c = new_fcompiler(plat=platform, compiler=compiler_type,
+                              c_compiler=c_compiler)
             c.customize(dist)
             v = c.get_version()
             if requiref90 and c.compiler_f90 is None:
@@ -682,9 +744,10 @@
                 new_compiler = c.suggested_f90_compiler
                 if new_compiler:
                     log.warn('Trying %r compiler as suggested by %r '
-                             'compiler for f90 support.' % (compiler,
+                             'compiler for f90 support.' % (compiler_type,
                                                             new_compiler))
-                    c = new_fcompiler(plat=platform, compiler=new_compiler)
+                    c = new_fcompiler(plat=platform, compiler=new_compiler,
+                                      c_compiler=c_compiler)
                     c.customize(dist)
                     v = c.get_version()
                     if v is not None:
@@ -693,9 +756,9 @@
                 raise ValueError('%s does not support compiling f90 codes, '
                                  'skipping.' % (c.__class__.__name__))
         except DistutilsModuleError:
-            pass
+            log.debug("_find_existing_fcompiler: compiler_type='%s' raised DistutilsModuleError", compiler_type)
         except CompilerNotFound:
-            pass
+            log.debug("_find_existing_fcompiler: compiler_type='%s' not found", compiler_type)
         if v is not None:
             return compiler_type
     return None
@@ -715,7 +778,8 @@
         matching_compiler_types.append('gnu')
     return matching_compiler_types
 
-def get_default_fcompiler(osname=None, platform=None, requiref90=False):
+def get_default_fcompiler(osname=None, platform=None, requiref90=False,
+                          c_compiler=None):
     """Determine the default Fortran compiler to use for the given
     platform."""
     matching_compiler_types = available_fcompilers_for_platform(osname,
@@ -723,7 +787,8 @@
     compiler_type =  _find_existing_fcompiler(matching_compiler_types,
                                               osname=osname,
                                               platform=platform,
-                                              requiref90=requiref90)
+                                              requiref90=requiref90,
+                                              c_compiler=c_compiler)
     return compiler_type
 
 def new_fcompiler(plat=None,
@@ -731,7 +796,8 @@
                   verbose=0,
                   dry_run=0,
                   force=0,
-                  requiref90=False):
+                  requiref90=False,
+                  c_compiler = None):
     """Generate an instance of some FCompiler subclass for the supplied
     platform/compiler combination.
     """
@@ -739,18 +805,23 @@
     if plat is None:
         plat = os.name
     if compiler is None:
-        compiler = get_default_fcompiler(plat, requiref90=requiref90)
-    try:
+        compiler = get_default_fcompiler(plat, requiref90=requiref90,
+                                         c_compiler=c_compiler)
+    if compiler in fcompiler_class:
         module_name, klass, long_description = fcompiler_class[compiler]
-    except KeyError:
+    elif compiler in fcompiler_aliases:
+        module_name, klass, long_description = fcompiler_aliases[compiler]
+    else:
         msg = "don't know how to compile Fortran code on platform '%s'" % plat
         if compiler is not None:
             msg = msg + " with '%s' compiler." % compiler
             msg = msg + " Supported compilers are: %s)" \
                   % (','.join(fcompiler_class.keys()))
-        raise DistutilsPlatformError, msg
+        log.warn(msg)
+        return None
 
     compiler = klass(verbose=verbose, dry_run=dry_run, force=force)
+    compiler.c_compiler = c_compiler
     return compiler
 
 def show_fcompilers(dist=None):
@@ -783,8 +854,9 @@
             c = new_fcompiler(compiler=compiler, verbose=dist.verbose)
             c.customize(dist)
             v = c.get_version()
-        except (DistutilsModuleError, CompilerNotFound):
-            pass
+        except (DistutilsModuleError, CompilerNotFound), e:
+            log.debug("show_fcompilers: %s not found" % (compiler,))
+            log.debug(repr(e))
 
         if v is None:
             compilers_na.append(("fcompiler="+compiler, None,
@@ -811,24 +883,14 @@
         pretty_printer.print_help("Compilers not available on this platform:")
     print "For compiler details, run 'config_fc --verbose' setup command."
 
+
 def dummy_fortran_file():
-    import atexit
-    import tempfile
-    dummy_name = tempfile.mktemp()+'__dummy'
-    dummy = open(dummy_name+'.f','w')
-    dummy.write("      subroutine dummy()\n      end\n")
-    dummy.close()
-    def rm_file(name=dummy_name,log_threshold=log._global_log.threshold):
-        save_th = log._global_log.threshold
-        log.set_threshold(log_threshold)
-        try: os.remove(name+'.f'); log.debug('removed '+name+'.f')
-        except OSError: pass
-        try: os.remove(name+'.o'); log.debug('removed '+name+'.o')
-        except OSError: pass
-        log.set_threshold(save_th)
-    atexit.register(rm_file)
-    return dummy_name
+    fo, name = make_temp_file(suffix='.f')
+    fo.write("      subroutine dummy()\n      end\n")
+    fo.close()
+    return name[:-2]
 
+
 is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z',re.I).match
 _has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-',re.I).search
 _has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-',re.I).search

Modified: branches/distutils-revamp/fcompiler/absoft.py
===================================================================
--- branches/distutils-revamp/fcompiler/absoft.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/absoft.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -7,7 +7,6 @@
 #   generated extension modules (works for f2py v2.45.241_1936 and up)
 
 import os
-import sys
 
 from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
@@ -31,8 +30,7 @@
     # Note that fink installs g77 as f77, so need to use f90 for detection.
 
     executables = {
-        'version_cmd'  : ["<F90>", "-V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':cyg2win32(dummy_fortran_file())}],
+        'version_cmd'  : None,          # set by update_executables
         'compiler_f77' : ["f77"],
         'compiler_fix' : ["f90"],
         'compiler_f90' : ["f90"],
@@ -47,6 +45,11 @@
     module_dir_switch = None
     module_include_switch = '-p'
 
+    def update_executables(self):
+        f = cyg2win32(dummy_fortran_file())
+        self.executables['version_cmd'] = ['<F90>', '-V', '-c',
+                                           f+'.f', '-o', f+'.o']
+
     def get_flags_linker_so(self):
         if os.name=='nt':
             opt = ['/dll']

Modified: branches/distutils-revamp/fcompiler/compaq.py
===================================================================
--- branches/distutils-revamp/fcompiler/compaq.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/compaq.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -4,8 +4,8 @@
 import os
 import sys
 
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
+from distutils.errors import DistutilsPlatformError
 
 compilers = ['CompaqFCompiler']
 if os.name != 'posix':
@@ -70,12 +70,22 @@
 
     ar_exe = 'lib.exe'
     fc_exe = 'DF'
+
     if sys.platform=='win32':
         from distutils.msvccompiler import MSVCCompiler
-        m = MSVCCompiler()
-        m.initialize()
-        ar_exe = m.lib
 
+        try:
+            m = MSVCCompiler()
+            m.initialize()
+            ar_exe = m.lib
+        except DistutilsPlatformError, msg:
+            print 'Ignoring "%s" (one should fix me in fcompiler/compaq.py)' % (msg)
+        except AttributeError, msg:
+            if '_MSVCCompiler__root' in str(msg):
+                print 'Ignoring "%s" (I think it is msvccompiler.py bug)' % (msg)
+            else:
+                raise
+
     executables = {
         'version_cmd'  : ['<F90>', "/what"],
         'compiler_f77' : [fc_exe, "/f77rtl","/fixed"],

Modified: branches/distutils-revamp/fcompiler/g95.py
===================================================================
--- branches/distutils-revamp/fcompiler/g95.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/g95.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,15 +1,10 @@
 # http://g95.sourceforge.net/
 
-import os
-import sys
-
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 
 compilers = ['G95FCompiler']
 
 class G95FCompiler(FCompiler):
-
     compiler_type = 'g95'
     description = 'G95 Fortran Compiler'
 
@@ -44,8 +39,6 @@
 if __name__ == '__main__':
     from distutils import log
     log.set_verbosity(2)
-    from numpy.distutils.fcompiler import new_fcompiler
-    #compiler = new_fcompiler(compiler='g95')
     compiler = G95FCompiler()
     compiler.customize()
     print compiler.get_version()

Modified: branches/distutils-revamp/fcompiler/gnu.py
===================================================================
--- branches/distutils-revamp/fcompiler/gnu.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/gnu.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -6,12 +6,13 @@
 from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 from numpy.distutils.exec_command import exec_command
-from numpy.distutils.misc_util import mingw32, msvc_runtime_library
+from numpy.distutils.misc_util import msvc_runtime_library
 
 compilers = ['GnuFCompiler', 'Gnu95FCompiler']
 
 class GnuFCompiler(FCompiler):
     compiler_type = 'gnu'
+    compiler_aliases = ('g77',)
     description = 'GNU Fortran 77 compiler'
 
     def gnu_version_match(self, version_string):
@@ -45,11 +46,12 @@
     #         GNU Fortran (GCC) 3.3.3 (Debian 20040401)
     #         GNU Fortran 0.5.25 20010319 (prerelease)
     # Redhat: GNU Fortran (GCC 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
+    # GNU Fortran (GCC) 3.4.2 (mingw-special)
 
     possible_executables = ['g77', 'f77']
     executables = {
         'version_cmd'  : [None, "--version"],
-        'compiler_f77' : [None, "-g", "-Wall","-fno-second-underscore"],
+        'compiler_f77' : [None, "-g", "-Wall", "-fno-second-underscore"],
         'compiler_f90' : None, # Use --fcompiler=gnu95 for f90 codes
         'compiler_fix' : None,
         'linker_so'    : [None, "-g", "-Wall"],
@@ -149,7 +151,10 @@
 
         if g2c is not None:
             opt.append(g2c)
-        if sys.platform == 'win32':
+        c_compiler = self.c_compiler
+        if sys.platform == 'win32' and c_compiler and \
+               c_compiler.compiler_type=='msvc':
+            # the following code is not needed (read: breaks) when using MinGW
             # in case want to link F77 compiled code with MSVC
             opt.append('gcc')
             runtime_lib = msvc_runtime_library()
@@ -270,6 +275,7 @@
 
 class Gnu95FCompiler(GnuFCompiler):
     compiler_type = 'gnu95'
+    compiler_aliases = ('gfortran',)
     description = 'GNU Fortran 95 compiler'
 
     def version_match(self, version_string):
@@ -297,7 +303,7 @@
         'linker_so'    : ["<F90>", "-Wall"],
         'archiver'     : ["ar", "-cr"],
         'ranlib'       : ["ranlib"],
-        'linker_exe'   : [None,"-Wall"]
+        'linker_exe'   : [None, "-Wall"]
         }
 
     # use -mno-cygwin flag for g77 when Python is not Cygwin-Python
@@ -320,11 +326,14 @@
 if __name__ == '__main__':
     from distutils import log
     log.set_verbosity(2)
-    from numpy.distutils.fcompiler import new_fcompiler
-    #compiler = new_fcompiler(compiler='gnu')
     compiler = GnuFCompiler()
     compiler.customize()
     print compiler.get_version()
-    compiler = Gnu95FCompiler()
-    compiler.customize()
-    print compiler.get_version()
+    raw_input('Press ENTER to continue...')
+    try:
+        compiler = Gnu95FCompiler()
+        compiler.customize()
+        print compiler.get_version()
+    except Exception, msg:
+        print msg
+    raw_input('Press ENTER to continue...')

Modified: branches/distutils-revamp/fcompiler/hpux.py
===================================================================
--- branches/distutils-revamp/fcompiler/hpux.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/hpux.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,7 +1,3 @@
-import os
-import sys
-
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 
 compilers = ['HPUXFCompiler']

Modified: branches/distutils-revamp/fcompiler/ibm.py
===================================================================
--- branches/distutils-revamp/fcompiler/ibm.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/ibm.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -4,17 +4,17 @@
 
 from numpy.distutils.fcompiler import FCompiler
 from numpy.distutils.exec_command import exec_command, find_executable
+from numpy.distutils.misc_util import make_temp_file
 from distutils import log
-from distutils.sysconfig import get_python_lib
 
 compilers = ['IBMFCompiler']
 
 class IBMFCompiler(FCompiler):
-
     compiler_type = 'ibm'
     description = 'IBM XL Fortran Compiler'
     version_pattern =  r'(xlf\(1\)\s*|)IBM XL Fortran ((Advanced Edition |)Version |Enterprise Edition V)(?P<version>[^\s*]*)'
     #IBM XL Fortran Enterprise Edition V10.1 for AIX \nVersion: 10.01.0000.0004
+
     executables = {
         'version_cmd'  : ["<F77>", "-qversion"],
         'compiler_f77' : ["xlf"],
@@ -66,15 +66,13 @@
             opt.append('-bshared')
         version = self.get_version(ok_status=[0,40])
         if version is not None:
-            import tempfile
             if sys.platform.startswith('aix'):
                 xlf_cfg = '/etc/xlf.cfg'
             else:
                 xlf_cfg = '/etc/opt/ibmcmp/xlf/%s/xlf.cfg' % version
-            new_cfg = tempfile.mktemp()+'_xlf.cfg'
+            fo, new_cfg = make_temp_file(suffix='_xlf.cfg')
             log.info('Creating '+new_cfg)
             fi = open(xlf_cfg,'r')
-            fo = open(new_cfg,'w')
             crt1_match = re.compile(r'\s*crt\s*[=]\s*(?P<path>.*)/crt1.o').match
             for line in fi.readlines():
                 m = crt1_match(line)
@@ -91,10 +89,7 @@
         return ['-O5']
 
 if __name__ == '__main__':
-    from distutils import log
     log.set_verbosity(2)
-    from numpy.distutils.fcompiler import new_fcompiler
-    #compiler = new_fcompiler(compiler='ibm')
-    compiler = IbmFCompiler()
+    compiler = IBMFCompiler()
     compiler.customize()
     print compiler.get_version()

Modified: branches/distutils-revamp/fcompiler/intel.py
===================================================================
--- branches/distutils-revamp/fcompiler/intel.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/intel.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -3,9 +3,6 @@
 # of intele
 # http://developer.intel.com/software/products/compilers/flin/
 
-import os
-import sys
-
 from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.ccompiler import simple_version_match
 from numpy.distutils.fcompiler import FCompiler, dummy_fortran_file
@@ -16,24 +13,29 @@
 
 def intel_version_match(type):
     # Match against the important stuff in the version string
-    return simple_version_match(start=r'Intel.*?Fortran.*?%s.*?Version' % (type,))
+    return simple_version_match(start=r'Intel.*?Fortran.*?(?:%s).*?Version' % (type,))
 
-class IntelFCompiler(FCompiler):
+class BaseIntelFCompiler(FCompiler):
+    def update_executables(self):
+        f = dummy_fortran_file()
+        self.executables['version_cmd'] = ['<F77>', '-FI', '-V', '-c',
+                                           f + '.f', '-o', f + '.o']
 
+class IntelFCompiler(BaseIntelFCompiler):
+
     compiler_type = 'intel'
+    compiler_aliases = ('ifort',)
     description = 'Intel Fortran Compiler for 32-bit apps'
-    version_match = intel_version_match('32-bit')
+    version_match = intel_version_match('32-bit|IA-32')
 
-
     possible_executables = ['ifort', 'ifc']
 
     executables = {
-        'version_cmd'  : ["<F77>", "-FI -V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':dummy_fortran_file()}],
-        'compiler_f77' : [None,"-72","-w90","-w95"],
+        'version_cmd'  : None,          # set by update_executables
+        'compiler_f77' : [None, "-72", "-w90", "-w95"],
         'compiler_f90' : [None],
-        'compiler_fix' : [None,"-FI"],
-        'linker_so'    : ["<F90>","-shared"],
+        'compiler_fix' : [None, "-FI"],
+        'linker_so'    : ["<F90>", "-shared"],
         'archiver'     : ["ar", "-cr"],
         'ranlib'       : ["ranlib"]
         }
@@ -53,6 +55,7 @@
         return ['-O3','-unroll']
 
     def get_flags_arch(self):
+        v = self.get_version()
         opt = []
         if cpu.has_fdiv_bug():
             opt.append('-fdiv_check')
@@ -66,8 +69,25 @@
             opt.append('-tpp5')
         elif cpu.is_PentiumIV() or cpu.is_Xeon():
             opt.extend(['-tpp7','-xW'])
-        if cpu.has_mmx() and not cpu.is_Xeon():
-            opt.append('-xM')
+        if v and v <= '7.1':
+            if cpu.has_mmx() and (cpu.is_PentiumII() or cpu.is_PentiumIII()):
+                opt.append('-xM')
+        elif v and v >= '8.0':
+            if cpu.is_PentiumIII():
+                opt.append('-xK')
+                if cpu.has_sse3():
+                    opt.extend(['-xP'])
+            elif cpu.is_PentiumIV():
+                opt.append('-xW')
+                if cpu.has_sse2():
+                    opt.append('-xN')
+            elif cpu.is_PentiumM():
+                opt.extend(['-xB'])
+            if (cpu.is_Xeon() or cpu.is_Core2() or cpu.is_Core2Extreme()) and cpu.getNCPUs()==2:
+                opt.extend(['-xT'])
+            if cpu.has_sse3() and (cpu.is_PentiumIV() or cpu.is_CoreDuo() or cpu.is_CoreSolo()):
+                opt.extend(['-xP'])
+
         if cpu.has_sse2():
             opt.append('-arch SSE2')
         elif cpu.has_sse():
@@ -83,22 +103,22 @@
 
 class IntelItaniumFCompiler(IntelFCompiler):
     compiler_type = 'intele'
+    compiler_aliases = ()
     description = 'Intel Fortran Compiler for Itanium apps'
 
     version_match = intel_version_match('Itanium')
 
 #Intel(R) Fortran Itanium(R) Compiler for Itanium(R)-based applications
-#Version 9.1    Build 20060928 Package ID: l_fc_c_9.1.039
-#Copyright (C) 1985-2006 Intel Corporation.  All rights reserved.
+#Version 9.1    Build 20060928 Package ID: l_fc_c_9.1.039
+#Copyright (C) 1985-2006 Intel Corporation.  All rights reserved.
 #30 DAY EVALUATION LICENSE
 
     possible_executables = ['ifort', 'efort', 'efc']
 
     executables = {
-        'version_cmd'  : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':dummy_fortran_file()}],
-        'compiler_f77' : [None,"-FI","-w90","-w95"],
-        'compiler_fix' : [None,"-FI"],
+        'version_cmd'  : None,
+        'compiler_f77' : [None, "-FI", "-w90", "-w95"],
+        'compiler_fix' : [None, "-FI"],
         'compiler_f90' : [None],
         'linker_so'    : ['<F90>', "-shared"],
         'archiver'     : ["ar", "-cr"],
@@ -107,15 +127,15 @@
 
 class IntelEM64TFCompiler(IntelFCompiler):
     compiler_type = 'intelem'
+    compiler_aliases = ()
     description = 'Intel Fortran Compiler for EM64T-based apps'
 
-    version_match = intel_version_match('EM64T-based')
+    version_match = intel_version_match('EM64T-based|Intel\\(R\\) 64')
 
     possible_executables = ['ifort', 'efort', 'efc']
 
     executables = {
-        'version_cmd'  : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':dummy_fortran_file()}],
+        'version_cmd'  : None,
         'compiler_f77' : [None, "-FI", "-w90", "-w95"],
         'compiler_fix' : [None, "-FI"],
         'compiler_f90' : [None],
@@ -124,6 +144,14 @@
         'ranlib'       : ["ranlib"]
         }
 
+    def get_flags(self):
+        v = self.get_version()
+        if v >= '10.0':
+            # Use -fPIC instead of -KPIC.
+            return ['-fPIC', '-cm']
+        else:
+            return IntelFCompiler.get_flags(self)
+
     def get_flags_arch(self):
         opt = []
         if cpu.is_PentiumIV() or cpu.is_Xeon():
@@ -133,21 +161,19 @@
 # Is there no difference in the version string between the above compilers
 # and the Visual compilers?
 
-class IntelVisualFCompiler(FCompiler):
+class IntelVisualFCompiler(BaseIntelFCompiler):
     compiler_type = 'intelv'
     description = 'Intel Visual Fortran Compiler for 32-bit apps'
+    version_match = intel_version_match('32-bit|IA-32')
 
-    version_match = intel_version_match('32-bit')
-
     ar_exe = 'lib.exe'
-    fc_exe = 'ifl'
+    possible_executables = ['ifl']
 
     executables = {
-        'version_cmd'  : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':dummy_fortran_file()}],
-        'compiler_f77' : [fc_exe,"-FI","-w90","-w95"],
-        'compiler_fix' : [fc_exe,"-FI","-4L72","-w"],
-        'compiler_f90' : [fc_exe],
+        'version_cmd'  : None,
+        'compiler_f77' : [None,"-FI","-w90","-w95"],
+        'compiler_fix' : [None,"-FI","-4L72","-w"],
+        'compiler_f90' : [None],
         'linker_so'    : ['<F90>', "-shared"],
         'archiver'     : [ar_exe, "/verbose", "/OUT:"],
         'ranlib'       : None
@@ -192,15 +218,14 @@
 
     version_match = intel_version_match('Itanium')
 
-    fc_exe = 'efl' # XXX this is a wild guess
+    possible_executables = ['efl'] # XXX this is a wild guess
     ar_exe = IntelVisualFCompiler.ar_exe
 
     executables = {
-        'version_cmd'  : ['<F77>', "-FI -V -c %(fname)s.f -o %(fname)s.o" \
-                          % {'fname':dummy_fortran_file()}],
-        'compiler_f77' : [fc_exe,"-FI","-w90","-w95"],
-        'compiler_fix' : [fc_exe,"-FI","-4L72","-w"],
-        'compiler_f90' : [fc_exe],
+        'version_cmd'  : None,
+        'compiler_f77' : [None,"-FI","-w90","-w95"],
+        'compiler_fix' : [None,"-FI","-4L72","-w"],
+        'compiler_f90' : [None],
         'linker_so'    : ['<F90>',"-shared"],
         'archiver'     : [ar_exe, "/verbose", "/OUT:"],
         'ranlib'       : None

Modified: branches/distutils-revamp/fcompiler/lahey.py
===================================================================
--- branches/distutils-revamp/fcompiler/lahey.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/lahey.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,7 +1,5 @@
 import os
-import sys
 
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 
 compilers = ['LaheyFCompiler']

Modified: branches/distutils-revamp/fcompiler/mips.py
===================================================================
--- branches/distutils-revamp/fcompiler/mips.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/mips.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,6 +1,3 @@
-import os
-import sys
-
 from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 

Modified: branches/distutils-revamp/fcompiler/nag.py
===================================================================
--- branches/distutils-revamp/fcompiler/nag.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/nag.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,7 +1,4 @@
-import os
 import sys
-
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 
 compilers = ['NAGFCompiler']

Modified: branches/distutils-revamp/fcompiler/none.py
===================================================================
--- branches/distutils-revamp/fcompiler/none.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/none.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -25,7 +25,6 @@
 if __name__ == '__main__':
     from distutils import log
     log.set_verbosity(2)
-    from numpy.distutils.fcompiler import new_fcompiler
     compiler = NoneFCompiler()
     compiler.customize()
     print compiler.get_version()

Modified: branches/distutils-revamp/fcompiler/pg.py
===================================================================
--- branches/distutils-revamp/fcompiler/pg.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/pg.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,10 +1,6 @@
 
 # http://www.pgroup.com
 
-import os
-import sys
-
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler import FCompiler
 
 compilers = ['PGroupFCompiler']

Modified: branches/distutils-revamp/fcompiler/sun.py
===================================================================
--- branches/distutils-revamp/fcompiler/sun.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/sun.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,7 +1,3 @@
-import os
-import sys
-
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.ccompiler import simple_version_match
 from numpy.distutils.fcompiler import FCompiler
 

Modified: branches/distutils-revamp/fcompiler/vast.py
===================================================================
--- branches/distutils-revamp/fcompiler/vast.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/fcompiler/vast.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,14 +1,12 @@
 import os
-import sys
 
-from numpy.distutils.cpuinfo import cpu
 from numpy.distutils.fcompiler.gnu import GnuFCompiler
 
 compilers = ['VastFCompiler']
 
 class VastFCompiler(GnuFCompiler):
-
     compiler_type = 'vast'
+    compiler_aliases = ()
     description = 'Pacific-Sierra Research Fortran 90 Compiler'
     version_pattern = r'\s*Pacific-Sierra Research vf90 '\
                       '(Personal|Professional)\s+(?P<version>[^\s]*)'
@@ -29,6 +27,9 @@
     module_dir_switch = None  #XXX Fix me
     module_include_switch = None #XXX Fix me
 
+    def find_executables(self):
+        pass
+
     def get_version_cmd(self):
         f90 = self.compiler_f90[0]
         d, b = os.path.split(f90)

Modified: branches/distutils-revamp/intelccompiler.py
===================================================================
--- branches/distutils-revamp/intelccompiler.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/intelccompiler.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,5 +1,4 @@
 
-import os
 from distutils.unixccompiler import UnixCCompiler
 from numpy.distutils.exec_command import find_executable
 

Deleted: branches/distutils-revamp/interactive.py
===================================================================
--- branches/distutils-revamp/interactive.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/interactive.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,187 +0,0 @@
-import os
-import sys
-from pprint import pformat
-
-__all__ = ['interactive_sys_argv']
-
-def show_information(*args):
-    print 'Python',sys.version
-    for a in ['platform','prefix','byteorder','path']:
-        print 'sys.%s = %s' % (a,pformat(getattr(sys,a)))
-    for a in ['name']:
-        print 'os.%s = %s' % (a,pformat(getattr(os,a)))
-    if hasattr(os,'uname'):
-        print 'system,node,release,version,machine = ',os.uname()
-
-def show_environ(*args):
-    for k,i in os.environ.items():
-        print '  %s = %s' % (k, i)
-
-def show_fortran_compilers(*args):
-    from fcompiler import show_fcompilers
-    show_fcompilers()
-
-def show_compilers(*args):
-    from distutils.ccompiler import show_compilers
-    show_compilers()
-
-def show_tasks(argv,ccompiler,fcompiler):
-    print """\
-
-Tasks:
-  i       - Show python/platform/machine information
-  ie      - Show environment information
-  c       - Show C compilers information
-  c<name> - Set C compiler (current:%s)
-  f       - Show Fortran compilers information
-  f<name> - Set Fortran compiler (current:%s)
-  e       - Edit proposed sys.argv[1:].
-
-Task aliases:
-  0         - Configure
-  1         - Build
-  2         - Install
-  2<prefix> - Install with prefix.
-  3         - Inplace build
-  4         - Source distribution
-  5         - Binary distribution
-
-Proposed sys.argv = %s
-    """ % (ccompiler, fcompiler, argv)
-
-
-from exec_command import splitcmdline
-
-def edit_argv(*args):
-    argv = args[0]
-    readline = args[1]
-    if readline is not None:
-        readline.add_history(' '.join(argv[1:]))
-    try:
-        s = raw_input('Edit argv [UpArrow to retrive %r]: ' % (' '.join(argv[1:])))
-    except EOFError:
-        return
-    if s:
-        argv[1:] = splitcmdline(s)
-    return
-
-def interactive_sys_argv(argv):
-    print '='*72
-    print 'Starting interactive session'
-    print '-'*72
-
-    readline = None
-    try:
-        try:
-            import readline
-        except ImportError:
-            pass
-        else:
-            import tempfile
-            tdir = tempfile.gettempdir()
-            username = os.environ.get('USER',os.environ.get('USERNAME','UNKNOWN'))
-            histfile = os.path.join(tdir,".pyhist_interactive_setup-" + username)
-            try:
-                try: readline.read_history_file(histfile)
-                except IOError: pass
-                import atexit
-                atexit.register(readline.write_history_file, histfile)
-            except AttributeError: pass
-    except Exception, msg:
-        print msg
-
-    task_dict = {'i':show_information,
-                 'ie':show_environ,
-                 'f':show_fortran_compilers,
-                 'c':show_compilers,
-                 'e':edit_argv,
-                 }
-    c_compiler_name = None
-    f_compiler_name = None
-
-    while 1:
-        show_tasks(argv,c_compiler_name, f_compiler_name)
-        try:
-            task = raw_input('Choose a task (^D to quit, Enter to continue with setup): ').lower()
-        except EOFError:
-            print
-            task = 'quit'
-        if task=='': break
-        if task=='quit': sys.exit()
-        task_func = task_dict.get(task,None)
-        if task_func is None:
-            if task[0]=='c':
-                c_compiler_name = task[1:]
-                if c_compiler_name=='none':
-                    c_compiler_name = None
-                continue
-            if task[0]=='f':
-                f_compiler_name = task[1:]
-                if f_compiler_name=='none':
-                    f_compiler_name = None
-                continue
-            if task[0]=='2' and len(task)>1:
-                prefix = task[1:]
-                task = task[0]
-            else:
-                prefix = None
-            if task == '4':
-                argv[1:] = ['sdist','-f']
-                continue
-            elif task in '01235':
-                cmd_opts = {'config':[],'config_fc':[],
-                            'build_ext':[],'build_src':[],
-                            'build_clib':[]}
-                if c_compiler_name is not None:
-                    c = '--compiler=%s' % (c_compiler_name)
-                    cmd_opts['config'].append(c)
-                    if task != '0':
-                        cmd_opts['build_ext'].append(c)
-                        cmd_opts['build_clib'].append(c)
-                if f_compiler_name is not None:
-                    c = '--fcompiler=%s' % (f_compiler_name)
-                    cmd_opts['config_fc'].append(c)
-                    if task != '0':
-                        cmd_opts['build_ext'].append(c)
-                        cmd_opts['build_clib'].append(c)
-                if task=='3':
-                    cmd_opts['build_ext'].append('--inplace')
-                    cmd_opts['build_src'].append('--inplace')
-                conf = []
-                sorted_keys = ['config','config_fc','build_src',
-                               'build_clib','build_ext']
-                for k in sorted_keys:
-                    opts = cmd_opts[k]
-                    if opts: conf.extend([k]+opts)
-                if task=='0':
-                    if 'config' not in conf:
-                        conf.append('config')
-                    argv[1:] = conf
-                elif task=='1':
-                    argv[1:] = conf+['build']
-                elif task=='2':
-                    if prefix is not None:
-                        argv[1:] = conf+['install','--prefix=%s' % (prefix)]
-                    else:
-                        argv[1:] = conf+['install']
-                elif task=='3':
-                    argv[1:] = conf+['build']
-                elif task=='5':
-                    if sys.platform=='win32':
-                        argv[1:] = conf+['bdist_wininst']
-                    else:
-                        argv[1:] = conf+['bdist']
-            else:
-                print 'Skipping unknown task:',`task`
-        else:
-            print '-'*68
-            try:
-                task_func(argv,readline)
-            except Exception,msg:
-                print 'Failed running task %s: %s' % (task,msg)
-                break
-            print '-'*68
-        print
-
-    print '-'*72
-    return argv

Copied: branches/distutils-revamp/interactive.py (from rev 3971, trunk/numpy/distutils/interactive.py)

Modified: branches/distutils-revamp/lib2def.py
===================================================================
--- branches/distutils-revamp/lib2def.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/lib2def.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -1,7 +1,6 @@
 import re
 import sys
 import os
-import string
 
 __doc__ = """This module generates a DEF file from the symbols in
 an MSVC-compiled DLL import library.  It correctly discriminates between
@@ -21,8 +20,6 @@
 
 __version__ = '0.1a'
 
-import sys
-
 py_ver = "%d%d" % tuple(sys.version_info[:2])
 
 DEFAULT_NM = 'nm -Cs'

Modified: branches/distutils-revamp/line_endings.py
===================================================================
--- branches/distutils-revamp/line_endings.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/line_endings.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -71,5 +71,4 @@
     return modified_files
 
 if __name__ == "__main__":
-    import sys
     dos2unix_dir(sys.argv[1])

Modified: branches/distutils-revamp/log.py
===================================================================
--- branches/distutils-revamp/log.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/log.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -4,7 +4,7 @@
 from distutils.log import *
 from distutils.log import Log as old_Log
 from distutils.log import _global_log
-from misc_util import red_text, yellow_text, cyan_text, is_sequence, is_string
+from misc_util import red_text, yellow_text, cyan_text, green_text, is_sequence, is_string
 
 
 def _fix_args(args,flag=1):
@@ -22,18 +22,43 @@
             else:
                 print _global_color_map[level](msg)
             sys.stdout.flush()
+
+    def good(self, msg, *args):
+        """If we'd log WARN messages, log this message as a 'nice' anti-warn
+        message.
+        """
+        if WARN >= self.threshold:
+            if args:
+                print green_text(msg % _fix_args(args))
+            else:
+                print green_text(msg)
+            sys.stdout.flush()
 _global_log.__class__ = Log
 
-def set_verbosity(v):
+good = _global_log.good
+
+def set_threshold(level, force=False):
     prev_level = _global_log.threshold
+    if prev_level > DEBUG or force:
+        # If we're running at DEBUG, don't change the threshold, as there's
+        # likely a good reason why we're running at this level.
+        _global_log.threshold = level
+        if level <= DEBUG:
+            info('set_threshold: setting thershold to DEBUG level, it can be changed only with force argument')
+    else:
+        info('set_threshold: not changing thershold from DEBUG level %s to %s' % (prev_level,level))
+    return prev_level
+
+def set_verbosity(v, force=False):
+    prev_level = _global_log.threshold
     if v < 0:
-        set_threshold(ERROR)
+        set_threshold(ERROR, force)
     elif v == 0:
-        set_threshold(WARN)
+        set_threshold(WARN, force)
     elif v == 1:
-        set_threshold(INFO)
+        set_threshold(INFO, force)
     elif v >= 2:
-        set_threshold(DEBUG)
+        set_threshold(DEBUG, force)
     return {FATAL:-2,ERROR:-1,WARN:0,INFO:1,DEBUG:2}.get(prev_level,1)
 
 _global_color_map = {
@@ -44,4 +69,5 @@
     FATAL:red_text
 }
 
-set_verbosity(1)
+# don't use INFO,.. flags in set_verbosity, these flags are for set_threshold.
+set_verbosity(0, force=True)

Modified: branches/distutils-revamp/misc_util.py
===================================================================
--- branches/distutils-revamp/misc_util.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/misc_util.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -4,6 +4,8 @@
 import imp
 import copy
 import glob
+import atexit
+import tempfile
 
 try:
     set
@@ -19,15 +21,26 @@
            'get_dependencies', 'is_local_src_dir', 'get_ext_source_files',
            'get_script_files', 'get_lib_source_files', 'get_data_files',
            'dot_join', 'get_frame', 'minrelpath','njoin',
-           'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language']
+           'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language',
+           'quote_args']
 
+def quote_args(args):
+    # don't used _nt_quote_args as it does not check if
+    # args items already have quotes or not.
+    args = list(args)
+    for i in range(len(args)):
+        a = args[i]
+        if ' ' in a and a[0] not in '"\'':
+            args[i] = '"%s"' % (a)
+    return args
+
 def allpath(name):
     "Convert a /-separated pathname to one using the OS's path separator."
     splitted = name.split('/')
     return os.path.join(*splitted)
 
 def rel_path(path, parent_path):
-    """ Return path relative to parent_path.
+    """Return path relative to parent_path.
     """
     pd = os.path.abspath(parent_path)
     apath = os.path.abspath(path)
@@ -40,20 +53,25 @@
         path = apath[len(pd)+1:]
     return path
 
-def get_path(mod_name, parent_path=None):
-    """ Return path of the module.
+def get_path_from_frame(frame, parent_path=None):
+    """Return path of the module given a frame object from the call stack.
 
     Returned path is relative to parent_path when given,
     otherwise it is absolute path.
     """
-    if mod_name == '__builtin__':
-        #builtin if/then added by Pearu for use in core.run_setup.
-        d = os.path.dirname(os.path.abspath(sys.argv[0]))
-    else:
-        __import__(mod_name)
-        mod = sys.modules[mod_name]
-        if hasattr(mod,'__file__'):
-            filename = mod.__file__
+
+    # First, try to find if the file name is in the frame.
+    try:
+        caller_file = eval('__file__', frame.f_globals, frame.f_locals)
+        d = os.path.dirname(os.path.abspath(caller_file))
+    except NameError:
+        # __file__ is not defined, so let's try __name__. We try this second
+        # because setuptools spoofs __name__ to be '__main__' even though
+        # sys.modules['__main__'] might be something else, like easy_install(1).
+        caller_name = eval('__name__', frame.f_globals, frame.f_locals)
+        __import__(caller_name)
+        mod = sys.modules[caller_name]
+        if hasattr(mod, '__file__'):
             d = os.path.dirname(os.path.abspath(mod.__file__))
         else:
             # we're probably running setup.py as execfile("setup.py")
@@ -63,10 +81,11 @@
 
     if parent_path is not None:
         d = rel_path(d, parent_path)
+
     return d or '.'
 
 def njoin(*path):
-    """ Join two or more pathname components +
+    """Join two or more pathname components +
     - convert a /-separated pathname to one using the OS's path separator.
     - resolve `..` and `.` from path.
 
@@ -93,7 +112,7 @@
     return minrelpath(joined)
 
 def get_mathlibs(path=None):
-    """ Return the MATHLIB line from config.h
+    """Return the MATHLIB line from config.h
     """
     if path is None:
         path = get_numpy_include_dirs()[0]
@@ -110,7 +129,7 @@
     return mathlibs
 
 def minrelpath(path):
-    """ Resolve `..` and '.' from path.
+    """Resolve `..` and '.' from path.
     """
     if not is_string(path):
         return path
@@ -176,13 +195,38 @@
     return map(minrelpath,new_paths)
 
 def gpaths(paths, local_path='', include_non_existing=True):
-    """ Apply glob to paths and prepend local_path if needed.
+    """Apply glob to paths and prepend local_path if needed.
     """
     if is_string(paths):
         paths = (paths,)
     return _fix_paths(paths,local_path, include_non_existing)
 
 
+_temporary_directory = None
+def clean_up_temporary_directory():
+    from numpy.distutils import log
+    global _temporary_directory
+    if not _temporary_directory:
+        return
+    log.debug('removing %s', _temporary_directory)
+    try:
+        os.rmdir(_temporary_directory)
+    except OSError:
+        pass
+    _temporary_directory = None
+
+def make_temp_file(suffix='', prefix='', text=True):
+    global _temporary_directory
+    if not _temporary_directory:
+        _temporary_directory = tempfile.mkdtemp()
+        atexit.register(clean_up_temporary_directory)
+    fid, name = tempfile.mkstemp(suffix=suffix,
+                                 prefix=prefix,
+                                 dir=_temporary_directory,
+                                 text=text)
+    fo = os.fdopen(fid, 'w')
+    return fo, name
+
 # Hooks for colored terminal output.
 # See also http://www.livinglogic.de/Python/ansistyle
 def terminal_has_colors():
@@ -213,18 +257,37 @@
     return 0
 
 if terminal_has_colors():
-    def red_text(s): return '\x1b[31m%s\x1b[0m'%s
-    def green_text(s): return '\x1b[32m%s\x1b[0m'%s
-    def yellow_text(s): return '\x1b[33m%s\x1b[0m'%s
-    def blue_text(s): return '\x1b[34m%s\x1b[0m'%s
-    def cyan_text(s): return '\x1b[35m%s\x1b[0m'%s
+    _colour_codes = dict(black=0, red=1, green=2, yellow=3,
+                         blue=4, magenta=5, cyan=6, white=7)
+    def colour_text(s, fg=None, bg=None, bold=False):
+        seq = []
+        if bold:
+            seq.append('1')
+        if fg:
+            fgcode = 30 + _colour_codes.get(fg.lower(), 0)
+            seq.append(str(fgcode))
+        if bg:
+            bgcode = 40 + _colour_codes.get(fg.lower(), 7)
+            seq.append(str(bgcode))
+        if seq:
+            return '\x1b[%sm%s\x1b[0m' % (';'.join(seq), s)
+        else:
+            return s
 else:
-    def red_text(s): return s
-    def green_text(s): return s
-    def yellow_text(s): return s
-    def cyan_text(s): return s
-    def blue_text(s): return s
+    def colour_text(s, fg=None, bg=None):
+        return s
 
+def red_text(s):
+    return colour_text(s, 'red')
+def green_text(s):
+    return colour_text(s, 'green')
+def yellow_text(s):
+    return colour_text(s, 'yellow')
+def cyan_text(s):
+    return colour_text(s, 'cyan')
+def blue_text(s):
+    return colour_text(s, 'blue')
+
 #########################
 
 def cyg2win32(path):
@@ -233,7 +296,7 @@
     return path
 
 def mingw32():
-    """ Return true when using mingw32 environment.
+    """Return true when using mingw32 environment.
     """
     if sys.platform=='win32':
         if os.environ.get('OSTYPE','')=='msys':
@@ -243,7 +306,7 @@
     return False
 
 def msvc_runtime_library():
-    "return name of MSVC runtime library if Python was built with MSVC >= 7"
+    "Return name of MSVC runtime library if Python was built with MSVC >= 7"
     msc_pos = sys.version.find('MSC v.')
     if msc_pos != -1:
         msc_ver = sys.version[msc_pos+6:msc_pos+10]
@@ -255,6 +318,19 @@
         lib = None
     return lib
 
+def msvc_on_amd64():
+    if not (sys.platform=='win32' or os.name=='nt'):
+        return
+    from distutils.msvccompiler import get_build_architecture
+    if get_build_architecture() != 'AMD64':
+        return
+    if os.environ.has_key('DISTUTILS_USE_SDK'):
+        return
+    # try to avoid _MSVCCompiler__root attribute error
+    print 'Forcing DISTUTILS_USE_SDK=1'
+    os.environ['DISTUTILS_USE_SDK']='1'
+    return
+
 #########################
 
 #XXX need support for .C that is also C++
@@ -263,7 +339,7 @@
 f90_ext_match = re.compile(r'.*[.](f90|f95)\Z',re.I).match
 f90_module_name_match = re.compile(r'\s*module\s*(?P<name>[\w_]+)',re.I).match
 def _get_f90_modules(source):
-    """ Return a list of Fortran f90 module names that
+    """Return a list of Fortran f90 module names that
     given source file defines.
     """
     if not f90_ext_match(source):
@@ -284,7 +360,7 @@
     return isinstance(s, str)
 
 def all_strings(lst):
-    """ Return True if all items in lst are string objects. """
+    """Return True if all items in lst are string objects. """
     for item in lst:
         if not is_string(item):
             return False
@@ -310,7 +386,7 @@
 
 def get_language(sources):
     # not used in numpy/scipy packages, use build_ext.detect_language instead
-    """ Determine language value (c,f77,f90) from sources """
+    """Determine language value (c,f77,f90) from sources """
     language = None
     for source in sources:
         if isinstance(source, str):
@@ -322,21 +398,21 @@
     return language
 
 def has_f_sources(sources):
-    """ Return True if sources contains Fortran files """
+    """Return True if sources contains Fortran files """
     for source in sources:
         if fortran_ext_match(source):
             return True
     return False
 
 def has_cxx_sources(sources):
-    """ Return True if sources contains C++ files """
+    """Return True if sources contains C++ files """
     for source in sources:
         if cxx_ext_match(source):
             return True
     return False
 
 def filter_sources(sources):
-    """ Return four lists of filenames containing
+    """Return four lists of filenames containing
     C, C++, Fortran, and Fortran 90 module sources,
     respectively.
     """
@@ -380,7 +456,7 @@
     return _get_headers(_get_directories(sources))
 
 def is_local_src_dir(directory):
-    """ Return true if directory is local directory.
+    """Return true if directory is local directory.
     """
     if not is_string(directory):
         return False
@@ -405,7 +481,7 @@
                 yield os.path.join(dirpath, f)
 
 def general_source_directories_files(top_path):
-    """ Return a directory name relative to top_path and
+    """Return a directory name relative to top_path and
     files contained.
     """
     pruned_directories = ['CVS','.svn','build']
@@ -484,7 +560,7 @@
     return '.'.join([a for a in args if a])
 
 def get_frame(level=0):
-    """ Return frame object from call stack with given level.
+    """Return frame object from call stack with given level.
     """
     try:
         return sys._getframe(level+1)
@@ -512,7 +588,7 @@
                  package_path=None,
                  caller_level=1,
                  **attrs):
-        """ Construct configuration instance of a package.
+        """Construct configuration instance of a package.
 
         package_name -- name of the package
                         Ex.: 'distutils'
@@ -529,17 +605,19 @@
         self.version = None
 
         caller_frame = get_frame(caller_level)
-        caller_name = eval('__name__',caller_frame.f_globals,caller_frame.f_locals)
-        self.local_path = get_path(caller_name, top_path)
+        self.local_path = get_path_from_frame(caller_frame, top_path)
         # local_path -- directory of a file (usually setup.py) that
         #               defines a configuration() function.
+        # local_path -- directory of a file (usually setup.py) that
+        #               defines a configuration() function.
         if top_path is None:
             top_path = self.local_path
+            self.local_path = ''
         if package_path is None:
             package_path = self.local_path
         elif os.path.isdir(njoin(self.local_path,package_path)):
             package_path = njoin(self.local_path,package_path)
-        if not os.path.isdir(package_path):
+        if not os.path.isdir(package_path or '.'):
             raise ValueError("%r is not a directory" % (package_path,))
         self.top_path = top_path
         self.package_path = package_path
@@ -598,7 +676,7 @@
                 self.set_options(**caller_instance.options)
 
     def todict(self):
-        """ Return configuration distionary suitable for passing
+        """Return configuration distionary suitable for passing
         to distutils.core.setup() function.
         """
         self._optimize_data_files()
@@ -618,7 +696,7 @@
         print>>sys.stderr, blue_text('Warning: %s' % (message,))
 
     def set_options(self, **options):
-        """ Configure Configuration instance.
+        """Configure Configuration instance.
 
         The following options are available:
         - ignore_setup_xxx_py
@@ -696,7 +774,7 @@
                        subpackage_path=None,
                        parent_name=None,
                        caller_level = 1):
-        """ Return list of subpackage configurations.
+        """Return list of subpackage configurations.
 
         '*' in subpackage_name is handled as a wildcard.
         """
@@ -746,7 +824,7 @@
     def add_subpackage(self,subpackage_name,
                        subpackage_path=None,
                        standalone = False):
-        """ Add subpackage to configuration.
+        """Add subpackage to configuration.
         """
         if standalone:
             parent_name = None
@@ -771,10 +849,9 @@
         if dist is not None:
             self.warn('distutils distribution has been initialized,'\
                       ' it may be too late to add a subpackage '+ subpackage_name)
-        return
 
     def add_data_dir(self,data_path):
-        """ Recursively add files under data_path to data_files list.
+        """Recursively add files under data_path to data_files list.
         Argument can be either
         - 2-sequence (<datadir suffix>,<path to data directory>)
         - path to data directory where python datadir suffix defaults
@@ -845,7 +922,7 @@
         assert not is_glob_pattern(d),`d`
 
         dist = self.get_distribution()
-        if dist is not None:
+        if dist is not None and dist.data_files is not None:
             data_files = dist.data_files
         else:
             data_files = self.data_files
@@ -854,7 +931,6 @@
             for d1,f in list(general_source_directories_files(path)):
                 target_path = os.path.join(self.path_in_package,d,d1)
                 data_files.append((target_path, f))
-        return
 
     def _optimize_data_files(self):
         data_dict = {}
@@ -863,10 +939,9 @@
                 data_dict[p] = set()
             map(data_dict[p].add,files)
         self.data_files[:] = [(p,list(files)) for p,files in data_dict.items()]
-        return
 
     def add_data_files(self,*files):
-        """ Add data files to configuration data_files.
+        """Add data files to configuration data_files.
         Argument(s) can be either
         - 2-sequence (<datadir prefix>,<path to data file(s)>)
         - paths to data files where python datadir prefix defaults
@@ -942,18 +1017,17 @@
         assert not is_glob_pattern(d),`d,filepat`
 
         dist = self.get_distribution()
-        if dist is not None:
+        if dist is not None and dist.data_files is not None:
             data_files = dist.data_files
         else:
             data_files = self.data_files
 
         data_files.append((os.path.join(self.path_in_package,d),paths))
-        return
 
     ### XXX Implement add_py_modules
 
     def add_include_dirs(self,*paths):
-        """ Add paths to configuration include directories.
+        """Add paths to configuration include directories.
         """
         include_dirs = self.paths(paths)
         dist = self.get_distribution()
@@ -961,14 +1035,13 @@
             dist.include_dirs.extend(include_dirs)
         else:
             self.include_dirs.extend(include_dirs)
-        return
 
     def add_numarray_include_dirs(self):
         import numpy.numarray.util as nnu
         self.add_include_dirs(*nnu.get_numarray_include_dirs())
 
     def add_headers(self,*files):
-        """ Add installable headers to configuration.
+        """Add installable headers to configuration.
         Argument(s) can be either
         - 2-sequence (<includedir suffix>,<path to header file(s)>)
         - path(s) to header file(s) where python includedir suffix will default
@@ -987,10 +1060,9 @@
             dist.headers.extend(headers)
         else:
             self.headers.extend(headers)
-        return
 
     def paths(self,*paths,**kws):
-        """ Apply glob to paths and prepend local_path if needed.
+        """Apply glob to paths and prepend local_path if needed.
         """
         include_non_existing = kws.get('include_non_existing',True)
         return gpaths(paths,
@@ -1004,10 +1076,9 @@
                      'module_dirs','extra_objects']:
                 new_v = self.paths(v)
                 kw[k] = new_v
-        return
 
     def add_extension(self,name,sources,**kw):
-        """ Add extension to configuration.
+        """Add extension to configuration.
 
         Keywords:
           include_dirs, define_macros, undef_macros,
@@ -1021,7 +1092,7 @@
         ext_args = copy.copy(kw)
         ext_args['name'] = dot_join(self.name,name)
         ext_args['sources'] = sources
-        
+
         if ext_args.has_key('extra_info'):
             extra_info = ext_args['extra_info']
             del ext_args['extra_info']
@@ -1072,7 +1143,7 @@
         return ext
 
     def add_library(self,name,sources,**build_info):
-        """ Add library to configuration.
+        """Add library to configuration.
 
         Valid keywords for build_info:
           depends
@@ -1094,10 +1165,9 @@
         if dist is not None:
             self.warn('distutils distribution has been initialized,'\
                       ' it may be too late to add a library '+ name)
-        return
 
     def add_scripts(self,*files):
-        """ Add scripts to configuration.
+        """Add scripts to configuration.
         """
         scripts = self.paths(files)
         dist = self.get_distribution()
@@ -1105,7 +1175,6 @@
             dist.scripts.extend(scripts)
         else:
             self.scripts.extend(scripts)
-        return
 
     def dict_append(self,**dict):
         for key in self.list_keys:
@@ -1131,7 +1200,6 @@
                 pass
             else:
                 raise ValueError, "Don't know about key=%r" % (key)
-        return
 
     def __str__(self):
         from pprint import pformat
@@ -1163,7 +1231,7 @@
         return cmd.build_temp
 
     def have_f77c(self):
-        """ Check for availability of Fortran 77 compiler.
+        """Check for availability of Fortran 77 compiler.
         Use it inside source generating function to ensure that
         setup distribution instance has been initialized.
         """
@@ -1176,7 +1244,7 @@
         return flag
 
     def have_f90c(self):
-        """ Check for availability of Fortran 90 compiler.
+        """Check for availability of Fortran 90 compiler.
         Use it inside source generating function to ensure that
         setup distribution instance has been initialized.
         """
@@ -1189,7 +1257,7 @@
         return flag
 
     def append_to(self, extlib):
-        """ Append libraries, include_dirs to extension or library item.
+        """Append libraries, include_dirs to extension or library item.
         """
         if is_sequence(extlib):
             lib_name, build_info = extlib
@@ -1201,10 +1269,9 @@
             assert isinstance(extlib,Extension), repr(extlib)
             extlib.libraries.extend(self.libraries)
             extlib.include_dirs.extend(self.include_dirs)
-        return
 
     def _get_svn_revision(self,path):
-        """ Return path's SVN revision number.
+        """Return path's SVN revision number.
         """
         revision = None
         m = None
@@ -1235,7 +1302,7 @@
         return revision
 
     def get_version(self, version_file=None, version_variable=None):
-        """ Try to get version string of a package.
+        """Try to get version string of a package.
         """
         version = getattr(self,'version',None)
         if version is not None:
@@ -1289,7 +1356,7 @@
         return version
 
     def make_svn_version_py(self, delete=True):
-        """ Generate package __svn_version__.py file from SVN revision number,
+        """Generate package __svn_version__.py file from SVN revision number,
         it will be removed after python exits but will be available
         when sdist, etc commands are executed.
 
@@ -1323,14 +1390,13 @@
             self.add_data_files(('', generate_svn_version_py()))
 
     def make_config_py(self,name='__config__'):
-        """ Generate package __config__.py file containing system_info
+        """Generate package __config__.py file containing system_info
         information used during building the package.
         """
         self.py_modules.append((self.name,name,generate_config_py))
-        return
 
     def get_info(self,*names):
-        """ Get resources information.
+        """Get resources information.
         """
         from system_info import get_info, dict_append
         info_dict = {}
@@ -1363,7 +1429,7 @@
 #########################
 
 def default_config_dict(name = None, parent_name = None, local_path=None):
-    """ Return a configuration dictionary for usage in
+    """Return a configuration dictionary for usage in
     configuration() function defined in file setup_<name>.py.
     """
     import warnings
@@ -1409,10 +1475,10 @@
     return os.path.normpath(njoin(drive + prefix, subpath))
 
 def generate_config_py(target):
-    """ Generate config.py file containing system_info information
+    """Generate config.py file containing system_info information
     used during building the package.
 
-    Usage:\
+    Usage:
         config['py_modules'].append((packagename, '__config__',generate_config_py))
     """
     from numpy.distutils.system_info import system_info
@@ -1424,20 +1490,23 @@
     f.write('__all__ = ["get_info","show"]\n\n')
     for k, i in system_info.saved_results.items():
         f.write('%s=%r\n' % (k, i))
-    f.write('\ndef get_info(name):\n    g=globals()\n    return g.get(name,g.get(name+"_info",{}))\n')
-    f.write('''
+    f.write(r'''
+def get_info(name):
+    g = globals()
+    return g.get(name, g.get(name + "_info", {}))
+
 def show():
     for name,info_dict in globals().items():
-        if name[0]=="_" or type(info_dict) is not type({}): continue
-        print name+":"
+        if name[0] == "_" or type(info_dict) is not type({}): continue
+        print name + ":"
         if not info_dict:
             print "  NOT AVAILABLE"
         for k,v in info_dict.items():
             v = str(v)
-            if k==\'sources\' and len(v)>200: v = v[:60]+\' ...\\n... \'+v[-60:]
-            print \'    %s = %s\'%(k,v)
+            if k == "sources" and len(v) > 200:
+                v = v[:60] + " ...\n... " + v[-60:]
+            print "    %s = %s" % (k,v)
         print
-    return
     ''')
 
     f.close()

Modified: branches/distutils-revamp/system_info.py
===================================================================
--- branches/distutils-revamp/system_info.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/system_info.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -416,7 +416,8 @@
         if self.verbosity>0 and flag:
             for k,v in res.items():
                 v = str(v)
-                if k=='sources' and len(v)>200: v = v[:60]+' ...\n... '+v[-60:]
+                if k in ['sources','libraries'] and len(v)>270:
+                    v = v[:120]+'...\n...\n...'+v[-120:]
                 log.info('    %s = %s', k, v)
             log.info('')
 
@@ -1030,9 +1031,12 @@
         if not src_dir:
             #XXX: Get sources from netlib. May be ask first.
             return
-        # The following is extracted from LAPACK-3.0/SRC/Makefile
+        # The following is extracted from LAPACK-3.0/SRC/Makefile.
+        # Added missing names from lapack-lite-3.1.1/SRC/Makefile
+        # while keeping removed names for Lapack-3.0 compatibility.
         allaux='''
         ilaenv ieeeck lsame lsamen xerbla
+        iparmq
         ''' # *.f
         laux = '''
         bdsdc bdsqr disna labad lacpy ladiv lae2 laebz laed0 laed1
@@ -1042,6 +1046,9 @@
         lasd5 lasd6 lasd7 lasd8 lasd9 lasda lasdq lasdt laset lasq1
         lasq2 lasq3 lasq4 lasq5 lasq6 lasr lasrt lassq lasv2 pttrf
         stebz stedc steqr sterf
+
+        larra larrc larrd larr larrk larrj larrr laneg laisnan isnan
+        lazq3 lazq4
         ''' # [s|d]*.f
         lasrc = '''
         gbbrd gbcon gbequ gbrfs gbsv gbsvx gbtf2 gbtrf gbtrs gebak
@@ -1065,6 +1072,8 @@
         tgexc tgsen tgsja tgsna tgsy2 tgsyl tpcon tprfs tptri tptrs
         trcon trevc trexc trrfs trsen trsna trsyl trti2 trtri trtrs
         tzrqf tzrzf
+        
+        lacn2 lahr2 stemr laqr0 laqr1 laqr2 laqr3 laqr4 laqr5
         ''' # [s|c|d|z]*.f
         sd_lasrc = '''
         laexc lag2 lagv2 laln2 lanv2 laqtr lasy2 opgtr opmtr org2l
@@ -1102,7 +1111,13 @@
                   + ['z%s.f'%f for f in (zlasrc).split()] \
                   + ['%s.f'%f for f in (allaux+oclasrc+ozlasrc).split()]
         sources = [os.path.join(src_dir,f) for f in sources]
-        #XXX: should we check here actual existence of source files?
+        # Lapack 3.1:
+        src_dir2 = os.path.join(src_dir,'..','INSTALL')
+        sources += [os.path.join(src_dir2,p+'lamch.f') for p in 'sdcz']
+        # Should we check here actual existence of source files?
+        # Yes, the file listing is different between 3.0 and 3.1
+        # versions.
+        sources = [f for f in sources if os.path.isfile(f)]
         info = {'sources':sources,'language':'f77'}
         self.set_info(**info)
 
@@ -1380,6 +1395,7 @@
         srotmg zdrot cdotu daxpy drotm idamax scopy sscal zdscal crotg
         dcabs1 drotmg isamax sdot sswap zrotg cscal dcopy dscal izamax
         snrm2 zaxpy zscal csrot ddot dswap sasum srot zcopy zswap
+        scabs1
         '''
         blas2 = '''
         cgbmv chpmv ctrsv dsymv dtrsv sspr2 strmv zhemv ztpmv cgemv
@@ -1398,6 +1414,7 @@
         sources = [os.path.join(src_dir,f+'.f') \
                    for f in (blas1+blas2+blas3).split()]
         #XXX: should we check here actual existence of source files?
+        sources = [f for f in sources if os.path.isfile(f)]
         info = {'sources':sources,'language':'f77'}
         self.set_info(**info)
 

Modified: branches/distutils-revamp/unixccompiler.py
===================================================================
--- branches/distutils-revamp/unixccompiler.py	2007-08-18 18:49:22 UTC (rev 3974)
+++ branches/distutils-revamp/unixccompiler.py	2007-08-19 22:31:25 UTC (rev 3975)
@@ -3,13 +3,11 @@
 """
 
 import os
-import sys
-import new
 
-from distutils.errors import DistutilsExecError, LinkError, CompileError
+from distutils.errors import DistutilsExecError, CompileError
 from distutils.unixccompiler import *
+from numpy.distutils.ccompiler import replace_method
 
-
 import log
 
 # Note that UnixCCompiler._compile appeared in Python 2.3
@@ -20,26 +18,33 @@
                    extra_postargs, display = display)
     except DistutilsExecError, msg:
         raise CompileError, msg
-UnixCCompiler._compile = new.instancemethod(UnixCCompiler__compile,
-                                            None,
-                                            UnixCCompiler)
 
+replace_method(UnixCCompiler, '_compile', UnixCCompiler__compile)
 
-def UnixCCompile_create_static_lib(self, objects, output_libname,
-                                   output_dir=None, debug=0, target_lang=None):
+
+def UnixCCompiler_create_static_lib(self, objects, output_libname,
+                                    output_dir=None, debug=0, target_lang=None):
     objects, output_dir = self._fix_object_args(objects, output_dir)
 
     output_filename = \
                     self.library_filename(output_libname, output_dir=output_dir)
 
     if self._need_link(objects, output_filename):
+        try:
+            # previous .a may be screwed up; best to remove it first
+            # and recreate.
+            # Also, ar on OS X doesn't handle updating universal archives
+            os.unlink(output_filename)
+        except (IOError, OSError):
+            pass
         self.mkpath(os.path.dirname(output_filename))
         tmp_objects = objects + self.objects
         while tmp_objects:
             objects = tmp_objects[:50]
             tmp_objects = tmp_objects[50:]
-            display = '%s: adding %d object files to %s' % (os.path.basename(self.archiver[0]),
-                                               len(objects),output_filename)
+            display = '%s: adding %d object files to %s' % (
+                           os.path.basename(self.archiver[0]),
+                           len(objects), output_filename)
             self.spawn(self.archiver + [output_filename] + objects,
                        display = display)
 
@@ -60,6 +65,5 @@
         log.debug("skipping %s (up-to-date)", output_filename)
     return
 
-UnixCCompiler.create_static_lib = \
-  new.instancemethod(UnixCCompile_create_static_lib,
-                     None,UnixCCompiler)
+replace_method(UnixCCompiler, 'create_static_lib',
+               UnixCCompiler_create_static_lib)




More information about the Numpy-svn mailing list