[Python-checkins] r59290 - in python/trunk: Lib/distutils/command/build_ext.py Lib/distutils/cygwinccompiler.py Lib/distutils/msvc9compiler.py Lib/distutils/msvccompiler.py Modules/xxmodule.c

christian.heimes python-checkins at python.org
Mon Dec 3 14:47:30 CET 2007


Author: christian.heimes
Date: Mon Dec  3 14:47:29 2007
New Revision: 59290

Added:
   python/trunk/Lib/distutils/msvc9compiler.py
      - copied, changed from r59283, python/trunk/Lib/distutils/msvccompiler.py
Modified:
   python/trunk/Lib/distutils/command/build_ext.py
   python/trunk/Lib/distutils/cygwinccompiler.py
   python/trunk/Lib/distutils/msvccompiler.py
   python/trunk/Modules/xxmodule.c
Log:
Applied my patch #1455 with some extra fixes for VS 2005
The new msvc9compiler module supports VS 2005 and VS 2008. I've also fixed build_ext to support PCbuild8 and PCbuild9 and backported my fix for xxmodule.c from py3k. The old code msvccompiler is still in place in case somebody likes to build an extension with VS 2003 or earlier.
I've also updated the cygwin compiler module for VS 2005 and VS 2008. It works with VS 2005 but I'm unable to test it with VS 2008. We have to wait for a new version of cygwin.

Modified: python/trunk/Lib/distutils/command/build_ext.py
==============================================================================
--- python/trunk/Lib/distutils/command/build_ext.py	(original)
+++ python/trunk/Lib/distutils/command/build_ext.py	Mon Dec  3 14:47:29 2007
@@ -17,6 +17,10 @@
 from distutils.extension import Extension
 from distutils import log
 
+if os.name == 'nt':
+    from distutils.msvccompiler import get_build_version
+    MSVC_VERSION = int(get_build_version())
+
 # An extension name is just a dot-separated list of Python NAMEs (ie.
 # the same as a fully-qualified module name).
 extension_name_re = re.compile \
@@ -176,7 +180,15 @@
             # Append the source distribution include and library directories,
             # this allows distutils on windows to work in the source tree
             self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC'))
-            self.library_dirs.append(os.path.join(sys.exec_prefix, 'PCBuild'))
+            if MSVC_VERSION == 9:
+                self.library_dirs.append(os.path.join(sys.exec_prefix,
+                                         'PCBuild9'))
+            elif MSVC_VERSION == 8:
+                self.library_dirs.append(os.path.join(sys.exec_prefix,
+                                         'PCBuild8', 'win32release'))
+            else:
+                self.library_dirs.append(os.path.join(sys.exec_prefix,
+                                         'PCBuild'))
 
         # OS/2 (EMX) doesn't support Debug vs Release builds, but has the
         # import libraries in its "Config" subdirectory

Modified: python/trunk/Lib/distutils/cygwinccompiler.py
==============================================================================
--- python/trunk/Lib/distutils/cygwinccompiler.py	(original)
+++ python/trunk/Lib/distutils/cygwinccompiler.py	Mon Dec  3 14:47:29 2007
@@ -56,6 +56,29 @@
 from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
 from distutils import log
 
+def get_msvcr():
+    """Include the appropriate MSVC runtime library if Python was built
+    with MSVC 7.0 or later.
+    """
+    msc_pos = sys.version.find('MSC v.')
+    if msc_pos != -1:
+        msc_ver = sys.version[msc_pos+6:msc_pos+10]
+        if msc_ver == '1300':
+            # MSVC 7.0
+            return ['msvcr70']
+        elif msc_ver == '1310':
+            # MSVC 7.1
+            return ['msvcr71']
+        elif msc_ver == '1400':
+            # VS2005 / MSVC 8.0
+            return ['msvcr80']
+        elif msc_ver == '1500':
+            # VS2008 / MSVC 9.0
+            return ['msvcr90']
+        else:
+            raise ValueError("Unknown MS Compiler version %i " % msc_Ver)
+
+
 class CygwinCCompiler (UnixCCompiler):
 
     compiler_type = 'cygwin'
@@ -121,18 +144,9 @@
             self.warn(
                 "Consider upgrading to a newer version of gcc")
         else:
-            self.dll_libraries=[]
             # Include the appropriate MSVC runtime library if Python was built
-            # with MSVC 7.0 or 7.1.
-            msc_pos = sys.version.find('MSC v.')
-            if msc_pos != -1:
-                msc_ver = sys.version[msc_pos+6:msc_pos+10]
-                if msc_ver == '1300':
-                    # MSVC 7.0
-                    self.dll_libraries = ['msvcr70']
-                elif msc_ver == '1310':
-                    # MSVC 7.1
-                    self.dll_libraries = ['msvcr71']
+            # with MSVC 7.0 or later.
+            self.dll_libraries = get_msvcr()
 
     # __init__ ()
 
@@ -320,16 +334,8 @@
         self.dll_libraries=[]
 
         # Include the appropriate MSVC runtime library if Python was built
-        # with MSVC 7.0 or 7.1.
-        msc_pos = sys.version.find('MSC v.')
-        if msc_pos != -1:
-            msc_ver = sys.version[msc_pos+6:msc_pos+10]
-            if msc_ver == '1300':
-                # MSVC 7.0
-                self.dll_libraries = ['msvcr70']
-            elif msc_ver == '1310':
-                # MSVC 7.1
-                self.dll_libraries = ['msvcr71']
+        # with MSVC 7.0 or later.
+        self.dll_libraries = get_msvcr()
 
     # __init__ ()
 

Copied: python/trunk/Lib/distutils/msvc9compiler.py (from r59283, python/trunk/Lib/distutils/msvccompiler.py)
==============================================================================
--- python/trunk/Lib/distutils/msvccompiler.py	(original)
+++ python/trunk/Lib/distutils/msvc9compiler.py	Mon Dec  3 14:47:29 2007
@@ -1,154 +1,157 @@
-"""distutils.msvccompiler
+"""distutils.msvc9compiler
 
 Contains MSVCCompiler, an implementation of the abstract CCompiler class
-for the Microsoft Visual Studio.
+for the Microsoft Visual Studio 2008.
+
+The module is compatible with VS 2005 and VS 2008. You can find legacy support
+for older versions of VS in distutils.msvccompiler.
 """
 
 # Written by Perry Stoll
 # hacked by Robin Becker and Thomas Heller to do a better job of
 #   finding DevStudio (through the registry)
-
-# This module should be kept compatible with Python 2.1.
+# ported to VS2005 and VS 2008 by Christian Heimes
 
 __revision__ = "$Id$"
 
-import sys, os, string
-from distutils.errors import \
-     DistutilsExecError, DistutilsPlatformError, \
-     CompileError, LibError, LinkError
-from distutils.ccompiler import \
-     CCompiler, gen_preprocess_options, gen_lib_options
+import os
+import subprocess
+import sys
+from distutils.errors import (DistutilsExecError, DistutilsPlatformError,
+    CompileError, LibError, LinkError)
+from distutils.ccompiler import (CCompiler, gen_preprocess_options,
+    gen_lib_options)
 from distutils import log
 
-_can_read_reg = 0
-try:
-    import _winreg
-
-    _can_read_reg = 1
-    hkey_mod = _winreg
-
-    RegOpenKeyEx = _winreg.OpenKeyEx
-    RegEnumKey = _winreg.EnumKey
-    RegEnumValue = _winreg.EnumValue
-    RegError = _winreg.error
+import _winreg
 
-except ImportError:
-    try:
-        import win32api
-        import win32con
-        _can_read_reg = 1
-        hkey_mod = win32con
-
-        RegOpenKeyEx = win32api.RegOpenKeyEx
-        RegEnumKey = win32api.RegEnumKey
-        RegEnumValue = win32api.RegEnumValue
-        RegError = win32api.error
-
-    except ImportError:
-        log.info("Warning: Can't read registry to find the "
-                 "necessary compiler setting\n"
-                 "Make sure that Python modules _winreg, "
-                 "win32api or win32con are installed.")
-        pass
-
-if _can_read_reg:
-    HKEYS = (hkey_mod.HKEY_USERS,
-             hkey_mod.HKEY_CURRENT_USER,
-             hkey_mod.HKEY_LOCAL_MACHINE,
-             hkey_mod.HKEY_CLASSES_ROOT)
+RegOpenKeyEx = _winreg.OpenKeyEx
+RegEnumKey = _winreg.EnumKey
+RegEnumValue = _winreg.EnumValue
+RegError = _winreg.error
+
+HKEYS = (_winreg.HKEY_USERS,
+         _winreg.HKEY_CURRENT_USER,
+         _winreg.HKEY_LOCAL_MACHINE,
+         _winreg.HKEY_CLASSES_ROOT)
+
+VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f"
+WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows"
+NET_BASE = r"Software\Microsoft\.NETFramework"
+ARCHS = {'DEFAULT' : 'x86',
+    'intel' : 'x86', 'x86' : 'x86',
+    'amd64' : 'x64', 'x64' : 'x64',
+    'itanium' : 'ia64', 'ia64' : 'ia64',
+    }
 
-def read_keys(base, key):
-    """Return list of registry keys."""
+# The globals VERSION, ARCH, MACROS and VC_ENV are defined later
 
-    try:
-        handle = RegOpenKeyEx(base, key)
-    except RegError:
-        return None
-    L = []
-    i = 0
-    while 1:
+class Reg:
+    """Helper class to read values from the registry
+    """
+
+    @classmethod
+    def get_value(cls, path, key):
+        for base in HKEYS:
+            d = cls.read_values(base, path)
+            if d and key in d:
+                return d[key]
+        raise KeyError(key)
+
+    @classmethod
+    def read_keys(cls, base, key):
+        """Return list of registry keys."""
         try:
-            k = RegEnumKey(handle, i)
+            handle = RegOpenKeyEx(base, key)
         except RegError:
-            break
-        L.append(k)
-        i = i + 1
-    return L
-
-def read_values(base, key):
-    """Return dict of registry keys and values.
+            return None
+        L = []
+        i = 0
+        while True:
+            try:
+                k = RegEnumKey(handle, i)
+            except RegError:
+                break
+            L.append(k)
+            i += 1
+        return L
+
+    @classmethod
+    def read_values(cls, base, key):
+        """Return dict of registry keys and values.
 
-    All names are converted to lowercase.
-    """
-    try:
-        handle = RegOpenKeyEx(base, key)
-    except RegError:
-        return None
-    d = {}
-    i = 0
-    while 1:
+        All names are converted to lowercase.
+        """
         try:
-            name, value, type = RegEnumValue(handle, i)
+            handle = RegOpenKeyEx(base, key)
         except RegError:
-            break
-        name = name.lower()
-        d[convert_mbcs(name)] = convert_mbcs(value)
-        i = i + 1
-    return d
-
-def convert_mbcs(s):
-    enc = getattr(s, "encode", None)
-    if enc is not None:
-        try:
-            s = enc("mbcs")
-        except UnicodeError:
-            pass
-    return s
+            return None
+        d = {}
+        i = 0
+        while True:
+            try:
+                name, value, type = RegEnumValue(handle, i)
+            except RegError:
+                break
+            name = name.lower()
+            d[cls.convert_mbcs(name)] = cls.convert_mbcs(value)
+            i += 1
+        return d
+
+    @staticmethod
+    def convert_mbcs(s):
+        dec = getattr(s, "decode", None)
+        if dec is not None:
+            try:
+                s = dec("mbcs")
+            except UnicodeError:
+                pass
+        return s
 
 class MacroExpander:
 
     def __init__(self, version):
         self.macros = {}
+        self.vsbase = VS_BASE % version
         self.load_macros(version)
 
     def set_macro(self, macro, path, key):
-        for base in HKEYS:
-            d = read_values(base, path)
-            if d:
-                self.macros["$(%s)" % macro] = d[key]
-                break
+        self.macros["$(%s)" % macro] = Reg.get_value(path, key)
 
     def load_macros(self, version):
-        vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
-        self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
-        self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
-        net = r"Software\Microsoft\.NETFramework"
-        self.set_macro("FrameworkDir", net, "installroot")
+        self.set_macro("VCInstallDir", self.vsbase + r"\Setup\VC", "productdir")
+        self.set_macro("VSInstallDir", self.vsbase + r"\Setup\VS", "productdir")
+        self.set_macro("FrameworkDir", NET_BASE, "installroot")
         try:
-            if version > 7.0:
-                self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
+            if version >= 8.0:
+                self.set_macro("FrameworkSDKDir", NET_BASE,
+                               "sdkinstallrootv2.0")
             else:
-                self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
-        except KeyError, exc: #
-            raise DistutilsPlatformError, \
-                  ("""Python was built with Visual Studio 2003;
+                raise KeyError("sdkinstallrootv2.0")
+        except KeyError as exc: #
+            raise DistutilsPlatformError(
+            """Python was built with Visual Studio 2008;
 extensions must be built with a compiler than can generate compatible binaries.
-Visual Studio 2003 was not found on this system. If you have Cygwin installed,
+Visual Studio 2008 was not found on this system. If you have Cygwin installed,
 you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
 
-        p = r"Software\Microsoft\NET Framework Setup\Product"
-        for base in HKEYS:
-            try:
-                h = RegOpenKeyEx(base, p)
-            except RegError:
-                continue
-            key = RegEnumKey(h, 0)
-            d = read_values(base, r"%s\%s" % (p, key))
-            self.macros["$(FrameworkVersion)"] = d["version"]
+        if version >= 9.0:
+            self.set_macro("FrameworkVersion", self.vsbase, "clr version")
+            self.set_macro("WindowsSdkDir", WINSDK_BASE, "currentinstallfolder")
+        else:
+            p = r"Software\Microsoft\NET Framework Setup\Product"
+            for base in HKEYS:
+                try:
+                    h = RegOpenKeyEx(base, p)
+                except RegError:
+                    continue
+                key = RegEnumKey(h, 0)
+                d = Reg.get_value(base, r"%s\%s" % (p, key))
+                self.macros["$(FrameworkVersion)"] = d["version"]
 
     def sub(self, s):
         for k, v in self.macros.items():
-            s = string.replace(s, k, v)
+            s = s.replace(k, v)
         return s
 
 def get_build_version():
@@ -157,9 +160,8 @@
     For Python 2.3 and up, the version number is included in
     sys.version.  For earlier versions, assume the compiler is MSVC 6.
     """
-
     prefix = "MSC v."
-    i = string.find(sys.version, prefix)
+    i = sys.version.find(prefix)
     if i == -1:
         return 6
     i = i + len(prefix)
@@ -177,15 +179,19 @@
 def get_build_architecture():
     """Return the processor architecture.
 
-    Possible results are "Intel", "Itanium", or "AMD64".
+    Possible results are "x86" or "amd64".
     """
-
     prefix = " bit ("
-    i = string.find(sys.version, prefix)
+    i = sys.version.find(prefix)
     if i == -1:
-        return "Intel"
-    j = string.find(sys.version, ")", i)
-    return sys.version[i+len(prefix):j]
+        return "x86"
+    j = sys.version.find(")", i)
+    sysarch = sys.version[i+len(prefix):j].lower()
+    arch = ARCHS.get(sysarch, None)
+    if arch is None:
+        return ARCHS['DEFAULT']
+    else:
+        return arch
 
 def normalize_and_reduce_paths(paths):
     """Return a list of normalized paths with duplicates removed.
@@ -201,8 +207,82 @@
             reduced_paths.append(np)
     return reduced_paths
 
+def find_vcvarsall(version):
+    """Find the vcvarsall.bat file
+
+    At first it tries to find the productdir of VS 2008 in the registry. If
+    that fails it falls back to the VS90COMNTOOLS env var.
+    """
+    vsbase = VS_BASE % version
+    try:
+        productdir = Reg.get_value(r"%s\Setup\VC" % vsbase,
+                                   "productdir")
+    except KeyError:
+        log.debug("Unable to find productdir in registry")
+        productdir = None
+
+    if not productdir or not os.path.isdir(productdir):
+        toolskey = "VS%0.f0COMNTOOLS" % version
+        toolsdir = os.environ.get(toolskey, None)
+
+        if toolsdir and os.path.isdir(toolsdir):
+            productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC")
+            productdir = os.path.abspath(productdir)
+            if not os.path.isdir(productdir):
+                log.debug("%s is not a valid directory" % productdir)
+                return None
+        else:
+            log.debug("Env var %s is not set or invalid" % toolskey)
+    if not productdir:
+        log.debug("No productdir found")
+        return None
+    vcvarsall = os.path.join(productdir, "vcvarsall.bat")
+    if os.path.isfile(vcvarsall):
+        return vcvarsall
+    log.debug("Unable to find vcvarsall.bat")
+    return None
+
+def query_vcvarsall(version, arch="x86"):
+    """Launch vcvarsall.bat and read the settings from its environment
+    """
+    vcvarsall = find_vcvarsall(version)
+    interesting = set(("include", "lib", "libpath", "path"))
+    result = {}
+
+    if vcvarsall is None:
+        raise IOError("Unable to find vcvarsall.bat")
+    popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch),
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE)
+    if popen.wait() != 0:
+        raise IOError(popen.stderr.read())
+
+    for line in popen.stdout:
+        line = Reg.convert_mbcs(line)
+        if '=' not in line:
+            continue
+        line = line.strip()
+        key, value = line.split('=')
+        key = key.lower()
+        if key in interesting:
+            if value.endswith(os.pathsep):
+                value = value[:-1]
+            result[key] = value
+
+    if len(result) != len(interesting):
+        raise ValueError(str(list(result.keys())))
+
+    return result
+
+# More globals
+VERSION = get_build_version()
+if VERSION < 8.0:
+    raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION)
+ARCH = get_build_architecture()
+# MACROS = MacroExpander(VERSION)
+VC_ENV = query_vcvarsall(VERSION, ARCH)
 
-class MSVCCompiler (CCompiler) :
+class MSVCCompiler(CCompiler) :
     """Concrete class that implements an interface to Microsoft Visual C++,
        as defined by the CCompiler abstract class."""
 
@@ -232,27 +312,17 @@
     static_lib_format = shared_lib_format = '%s%s'
     exe_extension = '.exe'
 
-    def __init__ (self, verbose=0, dry_run=0, force=0):
+    def __init__(self, verbose=0, dry_run=0, force=0):
         CCompiler.__init__ (self, verbose, dry_run, force)
-        self.__version = get_build_version()
-        self.__arch = get_build_architecture()
-        if self.__arch == "Intel":
-            # x86
-            if self.__version >= 7:
-                self.__root = r"Software\Microsoft\VisualStudio"
-                self.__macros = MacroExpander(self.__version)
-            else:
-                self.__root = r"Software\Microsoft\Devstudio"
-            self.__product = "Visual Studio version %s" % self.__version
-        else:
-            # Win64. Assume this was built with the platform SDK
-            self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
-
+        self.__version = VERSION
+        self.__arch = ARCH
+        self.__root = r"Software\Microsoft\VisualStudio"
+        # self.__macros = MACROS
+        self.__path = []
         self.initialized = False
 
     def initialize(self):
-        self.__paths = []
-        if os.environ.has_key("DISTUTILS_USE_SDK") and os.environ.has_key("MSSdk") and self.find_exe("cl.exe"):
+        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
             # Assume that the SDK set up everything alright; don't try to be
             # smarter
             self.cc = "cl.exe"
@@ -261,36 +331,38 @@
             self.rc = "rc.exe"
             self.mc = "mc.exe"
         else:
-            self.__paths = self.get_msvc_paths("path")
+            self.__paths = VC_ENV['path'].split(os.pathsep)
+            os.environ['lib'] = VC_ENV['lib']
+            os.environ['include'] = VC_ENV['include']
 
-            if len (self.__paths) == 0:
-                raise DistutilsPlatformError, \
-                      ("Python was built with %s, "
+            if len(self.__paths) == 0:
+                raise DistutilsPlatformError("Python was built with %s, "
                        "and extensions need to be built with the same "
-                       "version of the compiler, but it isn't installed." % self.__product)
+                       "version of the compiler, but it isn't installed."
+                       % self.__product)
 
             self.cc = self.find_exe("cl.exe")
             self.linker = self.find_exe("link.exe")
             self.lib = self.find_exe("lib.exe")
             self.rc = self.find_exe("rc.exe")   # resource compiler
             self.mc = self.find_exe("mc.exe")   # message compiler
-            self.set_path_env_var('lib')
-            self.set_path_env_var('include')
+            #self.set_path_env_var('lib')
+            #self.set_path_env_var('include')
 
         # extend the MSVC path with the current path
         try:
-            for p in string.split(os.environ['path'], ';'):
+            for p in os.environ['path'].split(';'):
                 self.__paths.append(p)
         except KeyError:
             pass
         self.__paths = normalize_and_reduce_paths(self.__paths)
-        os.environ['path'] = string.join(self.__paths, ';')
+        os.environ['path'] = ";".join(self.__paths)
 
         self.preprocess_options = None
-        if self.__arch == "Intel":
-            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
+        if self.__arch == "x86":
+            self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3',
                                      '/DNDEBUG']
-            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
+            self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3',
                                           '/Z7', '/D_DEBUG']
         else:
             # Win64
@@ -302,11 +374,7 @@
         self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
         if self.__version >= 7:
             self.ldflags_shared_debug = [
-                '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
-                ]
-        else:
-            self.ldflags_shared_debug = [
-                '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
+                '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None'
                 ]
         self.ldflags_static = [ '/nologo']
 
@@ -314,10 +382,10 @@
 
     # -- Worker methods ------------------------------------------------
 
-    def object_filenames (self,
-                          source_filenames,
-                          strip_dir=0,
-                          output_dir=''):
+    def object_filenames(self,
+                         source_filenames,
+                         strip_dir=0,
+                         output_dir=''):
         # Copied from ccompiler.py, extended to return .res as 'object'-file
         # for .rc input file
         if output_dir is None: output_dir = ''
@@ -344,17 +412,16 @@
                                                 base + self.obj_extension))
         return obj_names
 
-    # object_filenames ()
-
 
     def compile(self, sources,
                 output_dir=None, macros=None, include_dirs=None, debug=0,
                 extra_preargs=None, extra_postargs=None, depends=None):
 
-        if not self.initialized: self.initialize()
-        macros, objects, extra_postargs, pp_opts, build = \
-                self._setup_compile(output_dir, macros, include_dirs, sources,
-                                    depends, extra_postargs)
+        if not self.initialized:
+            self.initialize()
+        compile_info = self._setup_compile(output_dir, macros, include_dirs,
+                                           sources, depends, extra_postargs)
+        macros, objects, extra_postargs, pp_opts, build = compile_info
 
         compile_opts = extra_preargs or []
         compile_opts.append ('/c')
@@ -383,13 +450,12 @@
                 input_opt = src
                 output_opt = "/fo" + obj
                 try:
-                    self.spawn ([self.rc] + pp_opts +
-                                [output_opt] + [input_opt])
-                except DistutilsExecError, msg:
-                    raise CompileError, msg
+                    self.spawn([self.rc] + pp_opts +
+                               [output_opt] + [input_opt])
+                except DistutilsExecError as msg:
+                    raise CompileError(msg)
                 continue
             elif ext in self._mc_extensions:
-
                 # Compile .MC to .RC file to .RES file.
                 #   * '-h dir' specifies the directory for the
                 #     generated include file
@@ -401,99 +467,95 @@
                 # we use the source-directory for the include file and
                 # the build directory for the RC file and message
                 # resources. This works at least for win32all.
-
-                h_dir = os.path.dirname (src)
-                rc_dir = os.path.dirname (obj)
+                h_dir = os.path.dirname(src)
+                rc_dir = os.path.dirname(obj)
                 try:
                     # first compile .MC to .RC and .H file
-                    self.spawn ([self.mc] +
-                                ['-h', h_dir, '-r', rc_dir] + [src])
+                    self.spawn([self.mc] +
+                               ['-h', h_dir, '-r', rc_dir] + [src])
                     base, _ = os.path.splitext (os.path.basename (src))
                     rc_file = os.path.join (rc_dir, base + '.rc')
                     # then compile .RC to .RES file
-                    self.spawn ([self.rc] +
-                                ["/fo" + obj] + [rc_file])
+                    self.spawn([self.rc] +
+                               ["/fo" + obj] + [rc_file])
 
-                except DistutilsExecError, msg:
-                    raise CompileError, msg
+                except DistutilsExecError as msg:
+                    raise CompileError(msg)
                 continue
             else:
                 # how to handle this file?
-                raise CompileError (
-                    "Don't know how to compile %s to %s" % \
-                    (src, obj))
+                raise CompileError("Don't know how to compile %s to %s"
+                                   % (src, obj))
 
             output_opt = "/Fo" + obj
             try:
-                self.spawn ([self.cc] + compile_opts + pp_opts +
-                            [input_opt, output_opt] +
-                            extra_postargs)
-            except DistutilsExecError, msg:
-                raise CompileError, msg
+                self.spawn([self.cc] + compile_opts + pp_opts +
+                           [input_opt, output_opt] +
+                           extra_postargs)
+            except DistutilsExecError as msg:
+                raise CompileError(msg)
 
         return objects
 
-    # compile ()
 
+    def create_static_lib(self,
+                          objects,
+                          output_libname,
+                          output_dir=None,
+                          debug=0,
+                          target_lang=None):
+
+        if not self.initialized:
+            self.initialize()
+        (objects, output_dir) = self._fix_object_args(objects, output_dir)
+        output_filename = self.library_filename(output_libname,
+                                                output_dir=output_dir)
 
-    def create_static_lib (self,
-                           objects,
-                           output_libname,
-                           output_dir=None,
-                           debug=0,
-                           target_lang=None):
-
-        if not self.initialized: self.initialize()
-        (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):
+        if self._need_link(objects, output_filename):
             lib_args = objects + ['/OUT:' + output_filename]
             if debug:
-                pass                    # XXX what goes here?
+                pass # XXX what goes here?
             try:
-                self.spawn ([self.lib] + lib_args)
-            except DistutilsExecError, msg:
-                raise LibError, msg
-
+                self.spawn([self.lib] + lib_args)
+            except DistutilsExecError as msg:
+                raise LibError(msg)
         else:
             log.debug("skipping %s (up-to-date)", output_filename)
 
-    # create_static_lib ()
 
-    def link (self,
-              target_desc,
-              objects,
-              output_filename,
-              output_dir=None,
-              libraries=None,
-              library_dirs=None,
-              runtime_library_dirs=None,
-              export_symbols=None,
-              debug=0,
-              extra_preargs=None,
-              extra_postargs=None,
-              build_temp=None,
-              target_lang=None):
-
-        if not self.initialized: self.initialize()
-        (objects, output_dir) = self._fix_object_args (objects, output_dir)
-        (libraries, library_dirs, runtime_library_dirs) = \
-            self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
+    def link(self,
+             target_desc,
+             objects,
+             output_filename,
+             output_dir=None,
+             libraries=None,
+             library_dirs=None,
+             runtime_library_dirs=None,
+             export_symbols=None,
+             debug=0,
+             extra_preargs=None,
+             extra_postargs=None,
+             build_temp=None,
+             target_lang=None):
+
+        if not self.initialized:
+            self.initialize()
+        (objects, output_dir) = self._fix_object_args(objects, output_dir)
+        fixed_args = self._fix_lib_args(libraries, library_dirs,
+                                        runtime_library_dirs)
+        (libraries, library_dirs, runtime_library_dirs) = fixed_args
 
         if runtime_library_dirs:
             self.warn ("I don't know what to do with 'runtime_library_dirs': "
                        + str (runtime_library_dirs))
 
-        lib_opts = gen_lib_options (self,
-                                    library_dirs, runtime_library_dirs,
-                                    libraries)
+        lib_opts = gen_lib_options(self,
+                                   library_dirs, runtime_library_dirs,
+                                   libraries)
         if output_dir is not None:
-            output_filename = os.path.join (output_dir, output_filename)
-
-        if self._need_link (objects, output_filename):
+            output_filename = os.path.join(output_dir, output_filename)
 
+        if self._need_link(objects, output_filename):
             if target_desc == CCompiler.EXECUTABLE:
                 if debug:
                     ldflags = self.ldflags_shared_debug[1:]
@@ -530,34 +592,32 @@
             if extra_postargs:
                 ld_args.extend(extra_postargs)
 
-            self.mkpath (os.path.dirname (output_filename))
+            self.mkpath(os.path.dirname(output_filename))
             try:
-                self.spawn ([self.linker] + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError, msg
+                self.spawn([self.linker] + ld_args)
+            except DistutilsExecError as msg:
+                raise LinkError(msg)
 
         else:
             log.debug("skipping %s (up-to-date)", output_filename)
 
-    # link ()
-
 
     # -- Miscellaneous methods -----------------------------------------
     # These are all used by the 'gen_lib_options() function, in
     # ccompiler.py.
 
-    def library_dir_option (self, dir):
+    def library_dir_option(self, dir):
         return "/LIBPATH:" + dir
 
-    def runtime_library_dir_option (self, dir):
-        raise DistutilsPlatformError, \
-              "don't know how to set runtime library search path for MSVC++"
+    def runtime_library_dir_option(self, dir):
+        raise DistutilsPlatformError(
+              "don't know how to set runtime library search path for MSVC++")
 
-    def library_option (self, lib):
-        return self.library_filename (lib)
+    def library_option(self, lib):
+        return self.library_filename(lib)
 
 
-    def find_library_file (self, dirs, lib, debug=0):
+    def find_library_file(self, dirs, lib, debug=0):
         # Prefer a debugging library if found (and requested), but deal
         # with it if we don't have one.
         if debug:
@@ -573,8 +633,6 @@
             # Oops, didn't find it in *any* of 'dirs'
             return None
 
-    # find_library_file ()
-
     # Helper methods for using the MSVC registry settings
 
     def find_exe(self, exe):
@@ -586,67 +644,15 @@
         absolute path that is known to exist.  If none of them work, just
         return the original program name, 'exe'.
         """
-
         for p in self.__paths:
             fn = os.path.join(os.path.abspath(p), exe)
             if os.path.isfile(fn):
                 return fn
 
         # didn't find it; try existing path
-        for p in string.split(os.environ['Path'],';'):
+        for p in os.environ['Path'].split(';'):
             fn = os.path.join(os.path.abspath(p),exe)
             if os.path.isfile(fn):
                 return fn
 
         return exe
-
-    def get_msvc_paths(self, path, platform='x86'):
-        """Get a list of devstudio directories (include, lib or path).
-
-        Return a list of strings.  The list will be empty if unable to
-        access the registry or appropriate registry keys not found.
-        """
-
-        if not _can_read_reg:
-            return []
-
-        path = path + " dirs"
-        if self.__version >= 7:
-            key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
-                   % (self.__root, self.__version))
-        else:
-            key = (r"%s\6.0\Build System\Components\Platforms"
-                   r"\Win32 (%s)\Directories" % (self.__root, platform))
-
-        for base in HKEYS:
-            d = read_values(base, key)
-            if d:
-                if self.__version >= 7:
-                    return string.split(self.__macros.sub(d[path]), ";")
-                else:
-                    return string.split(d[path], ";")
-        # MSVC 6 seems to create the registry entries we need only when
-        # the GUI is run.
-        if self.__version == 6:
-            for base in HKEYS:
-                if read_values(base, r"%s\6.0" % self.__root) is not None:
-                    self.warn("It seems you have Visual Studio 6 installed, "
-                        "but the expected registry settings are not present.\n"
-                        "You must at least run the Visual Studio GUI once "
-                        "so that these entries are created.")
-                    break
-        return []
-
-    def set_path_env_var(self, name):
-        """Set environment variable 'name' to an MSVC path type value.
-
-        This is equivalent to a SET command prior to execution of spawned
-        commands.
-        """
-
-        if name == "lib":
-            p = self.get_msvc_paths("library")
-        else:
-            p = self.get_msvc_paths(name)
-        if p:
-            os.environ[name] = string.join(p, ';')

Modified: python/trunk/Lib/distutils/msvccompiler.py
==============================================================================
--- python/trunk/Lib/distutils/msvccompiler.py	(original)
+++ python/trunk/Lib/distutils/msvccompiler.py	Mon Dec  3 14:47:29 2007
@@ -650,3 +650,11 @@
             p = self.get_msvc_paths(name)
         if p:
             os.environ[name] = string.join(p, ';')
+
+
+if get_build_version() >= 8.0:
+    log.debug("Importing new compiler from distutils.msvc9compiler")
+    OldMSVCCompiler = MSVCCompiler
+    from distutils.msvc9compiler import MSVCCompiler
+    from distutils.msvc9compiler import get_build_architecture
+    from distutils.msvc9compiler import MacroExpander

Modified: python/trunk/Modules/xxmodule.c
==============================================================================
--- python/trunk/Modules/xxmodule.c	(original)
+++ python/trunk/Modules/xxmodule.c	Mon Dec  3 14:47:29 2007
@@ -246,7 +246,7 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	&PyString_Type,		/*tp_base*/
+	0,			/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
@@ -301,14 +301,14 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	&PyBaseObject_Type,	/*tp_base*/
+	0,			/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
 	0,			/*tp_dictoffset*/
 	0,			/*tp_init*/
 	0,			/*tp_alloc*/
-	PyType_GenericNew,	/*tp_new*/
+	0,			/*tp_new*/
 	0,			/*tp_free*/
 	0,			/*tp_is_gc*/
 };
@@ -341,6 +341,10 @@
 {
 	PyObject *m;
 
+	Null_Type.tp_base = &PyBaseObject_Type;
+	Null_Type.tp_new = PyType_GenericNew;
+	Str_Type.tp_base = &PyUnicode_Type;
+
 	/* Finalize the type object including setting type of the new type
 	 * object; doing it here is required for portability to Windows 
 	 * without requiring C++. */


More information about the Python-checkins mailing list