ยปCore Development>Code coverage>Lib/distutils/msvccompiler.py

Python code coverage for Lib/distutils/msvccompiler.py

#countcontent
1n/a"""distutils.msvccompiler
2n/a
3n/aContains MSVCCompiler, an implementation of the abstract CCompiler class
4n/afor the Microsoft Visual Studio.
5n/a"""
6n/a
7n/a# Written by Perry Stoll
8n/a# hacked by Robin Becker and Thomas Heller to do a better job of
9n/a# finding DevStudio (through the registry)
10n/a
11n/aimport sys, os
12n/afrom distutils.errors import \
13n/a DistutilsExecError, DistutilsPlatformError, \
14n/a CompileError, LibError, LinkError
15n/afrom distutils.ccompiler import \
16n/a CCompiler, gen_preprocess_options, gen_lib_options
17n/afrom distutils import log
18n/a
19n/a_can_read_reg = False
20n/atry:
21n/a import winreg
22n/a
23n/a _can_read_reg = True
24n/a hkey_mod = winreg
25n/a
26n/a RegOpenKeyEx = winreg.OpenKeyEx
27n/a RegEnumKey = winreg.EnumKey
28n/a RegEnumValue = winreg.EnumValue
29n/a RegError = winreg.error
30n/a
31n/aexcept ImportError:
32n/a try:
33n/a import win32api
34n/a import win32con
35n/a _can_read_reg = True
36n/a hkey_mod = win32con
37n/a
38n/a RegOpenKeyEx = win32api.RegOpenKeyEx
39n/a RegEnumKey = win32api.RegEnumKey
40n/a RegEnumValue = win32api.RegEnumValue
41n/a RegError = win32api.error
42n/a except ImportError:
43n/a log.info("Warning: Can't read registry to find the "
44n/a "necessary compiler setting\n"
45n/a "Make sure that Python modules winreg, "
46n/a "win32api or win32con are installed.")
47n/a pass
48n/a
49n/aif _can_read_reg:
50n/a HKEYS = (hkey_mod.HKEY_USERS,
51n/a hkey_mod.HKEY_CURRENT_USER,
52n/a hkey_mod.HKEY_LOCAL_MACHINE,
53n/a hkey_mod.HKEY_CLASSES_ROOT)
54n/a
55n/adef read_keys(base, key):
56n/a """Return list of registry keys."""
57n/a try:
58n/a handle = RegOpenKeyEx(base, key)
59n/a except RegError:
60n/a return None
61n/a L = []
62n/a i = 0
63n/a while True:
64n/a try:
65n/a k = RegEnumKey(handle, i)
66n/a except RegError:
67n/a break
68n/a L.append(k)
69n/a i += 1
70n/a return L
71n/a
72n/adef read_values(base, key):
73n/a """Return dict of registry keys and values.
74n/a
75n/a All names are converted to lowercase.
76n/a """
77n/a try:
78n/a handle = RegOpenKeyEx(base, key)
79n/a except RegError:
80n/a return None
81n/a d = {}
82n/a i = 0
83n/a while True:
84n/a try:
85n/a name, value, type = RegEnumValue(handle, i)
86n/a except RegError:
87n/a break
88n/a name = name.lower()
89n/a d[convert_mbcs(name)] = convert_mbcs(value)
90n/a i += 1
91n/a return d
92n/a
93n/adef convert_mbcs(s):
94n/a dec = getattr(s, "decode", None)
95n/a if dec is not None:
96n/a try:
97n/a s = dec("mbcs")
98n/a except UnicodeError:
99n/a pass
100n/a return s
101n/a
102n/aclass MacroExpander:
103n/a def __init__(self, version):
104n/a self.macros = {}
105n/a self.load_macros(version)
106n/a
107n/a def set_macro(self, macro, path, key):
108n/a for base in HKEYS:
109n/a d = read_values(base, path)
110n/a if d:
111n/a self.macros["$(%s)" % macro] = d[key]
112n/a break
113n/a
114n/a def load_macros(self, version):
115n/a vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
116n/a self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
117n/a self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
118n/a net = r"Software\Microsoft\.NETFramework"
119n/a self.set_macro("FrameworkDir", net, "installroot")
120n/a try:
121n/a if version > 7.0:
122n/a self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
123n/a else:
124n/a self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
125n/a except KeyError as exc: #
126n/a raise DistutilsPlatformError(
127n/a """Python was built with Visual Studio 2003;
128n/aextensions must be built with a compiler than can generate compatible binaries.
129n/aVisual Studio 2003 was not found on this system. If you have Cygwin installed,
130n/ayou can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
131n/a
132n/a p = r"Software\Microsoft\NET Framework Setup\Product"
133n/a for base in HKEYS:
134n/a try:
135n/a h = RegOpenKeyEx(base, p)
136n/a except RegError:
137n/a continue
138n/a key = RegEnumKey(h, 0)
139n/a d = read_values(base, r"%s\%s" % (p, key))
140n/a self.macros["$(FrameworkVersion)"] = d["version"]
141n/a
142n/a def sub(self, s):
143n/a for k, v in self.macros.items():
144n/a s = s.replace(k, v)
145n/a return s
146n/a
147n/adef get_build_version():
148n/a """Return the version of MSVC that was used to build Python.
149n/a
150n/a For Python 2.3 and up, the version number is included in
151n/a sys.version. For earlier versions, assume the compiler is MSVC 6.
152n/a """
153n/a prefix = "MSC v."
154n/a i = sys.version.find(prefix)
155n/a if i == -1:
156n/a return 6
157n/a i = i + len(prefix)
158n/a s, rest = sys.version[i:].split(" ", 1)
159n/a majorVersion = int(s[:-2]) - 6
160n/a if majorVersion >= 13:
161n/a # v13 was skipped and should be v14
162n/a majorVersion += 1
163n/a minorVersion = int(s[2:3]) / 10.0
164n/a # I don't think paths are affected by minor version in version 6
165n/a if majorVersion == 6:
166n/a minorVersion = 0
167n/a if majorVersion >= 6:
168n/a return majorVersion + minorVersion
169n/a # else we don't know what version of the compiler this is
170n/a return None
171n/a
172n/adef get_build_architecture():
173n/a """Return the processor architecture.
174n/a
175n/a Possible results are "Intel", "Itanium", or "AMD64".
176n/a """
177n/a
178n/a prefix = " bit ("
179n/a i = sys.version.find(prefix)
180n/a if i == -1:
181n/a return "Intel"
182n/a j = sys.version.find(")", i)
183n/a return sys.version[i+len(prefix):j]
184n/a
185n/adef normalize_and_reduce_paths(paths):
186n/a """Return a list of normalized paths with duplicates removed.
187n/a
188n/a The current order of paths is maintained.
189n/a """
190n/a # Paths are normalized so things like: /a and /a/ aren't both preserved.
191n/a reduced_paths = []
192n/a for p in paths:
193n/a np = os.path.normpath(p)
194n/a # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
195n/a if np not in reduced_paths:
196n/a reduced_paths.append(np)
197n/a return reduced_paths
198n/a
199n/a
200n/aclass MSVCCompiler(CCompiler) :
201n/a """Concrete class that implements an interface to Microsoft Visual C++,
202n/a as defined by the CCompiler abstract class."""
203n/a
204n/a compiler_type = 'msvc'
205n/a
206n/a # Just set this so CCompiler's constructor doesn't barf. We currently
207n/a # don't use the 'set_executables()' bureaucracy provided by CCompiler,
208n/a # as it really isn't necessary for this sort of single-compiler class.
209n/a # Would be nice to have a consistent interface with UnixCCompiler,
210n/a # though, so it's worth thinking about.
211n/a executables = {}
212n/a
213n/a # Private class data (need to distinguish C from C++ source for compiler)
214n/a _c_extensions = ['.c']
215n/a _cpp_extensions = ['.cc', '.cpp', '.cxx']
216n/a _rc_extensions = ['.rc']
217n/a _mc_extensions = ['.mc']
218n/a
219n/a # Needed for the filename generation methods provided by the
220n/a # base class, CCompiler.
221n/a src_extensions = (_c_extensions + _cpp_extensions +
222n/a _rc_extensions + _mc_extensions)
223n/a res_extension = '.res'
224n/a obj_extension = '.obj'
225n/a static_lib_extension = '.lib'
226n/a shared_lib_extension = '.dll'
227n/a static_lib_format = shared_lib_format = '%s%s'
228n/a exe_extension = '.exe'
229n/a
230n/a def __init__(self, verbose=0, dry_run=0, force=0):
231n/a CCompiler.__init__ (self, verbose, dry_run, force)
232n/a self.__version = get_build_version()
233n/a self.__arch = get_build_architecture()
234n/a if self.__arch == "Intel":
235n/a # x86
236n/a if self.__version >= 7:
237n/a self.__root = r"Software\Microsoft\VisualStudio"
238n/a self.__macros = MacroExpander(self.__version)
239n/a else:
240n/a self.__root = r"Software\Microsoft\Devstudio"
241n/a self.__product = "Visual Studio version %s" % self.__version
242n/a else:
243n/a # Win64. Assume this was built with the platform SDK
244n/a self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
245n/a
246n/a self.initialized = False
247n/a
248n/a def initialize(self):
249n/a self.__paths = []
250n/a if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
251n/a # Assume that the SDK set up everything alright; don't try to be
252n/a # smarter
253n/a self.cc = "cl.exe"
254n/a self.linker = "link.exe"
255n/a self.lib = "lib.exe"
256n/a self.rc = "rc.exe"
257n/a self.mc = "mc.exe"
258n/a else:
259n/a self.__paths = self.get_msvc_paths("path")
260n/a
261n/a if len(self.__paths) == 0:
262n/a raise DistutilsPlatformError("Python was built with %s, "
263n/a "and extensions need to be built with the same "
264n/a "version of the compiler, but it isn't installed."
265n/a % self.__product)
266n/a
267n/a self.cc = self.find_exe("cl.exe")
268n/a self.linker = self.find_exe("link.exe")
269n/a self.lib = self.find_exe("lib.exe")
270n/a self.rc = self.find_exe("rc.exe") # resource compiler
271n/a self.mc = self.find_exe("mc.exe") # message compiler
272n/a self.set_path_env_var('lib')
273n/a self.set_path_env_var('include')
274n/a
275n/a # extend the MSVC path with the current path
276n/a try:
277n/a for p in os.environ['path'].split(';'):
278n/a self.__paths.append(p)
279n/a except KeyError:
280n/a pass
281n/a self.__paths = normalize_and_reduce_paths(self.__paths)
282n/a os.environ['path'] = ";".join(self.__paths)
283n/a
284n/a self.preprocess_options = None
285n/a if self.__arch == "Intel":
286n/a self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
287n/a '/DNDEBUG']
288n/a self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
289n/a '/Z7', '/D_DEBUG']
290n/a else:
291n/a # Win64
292n/a self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
293n/a '/DNDEBUG']
294n/a self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
295n/a '/Z7', '/D_DEBUG']
296n/a
297n/a self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
298n/a if self.__version >= 7:
299n/a self.ldflags_shared_debug = [
300n/a '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
301n/a ]
302n/a else:
303n/a self.ldflags_shared_debug = [
304n/a '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
305n/a ]
306n/a self.ldflags_static = [ '/nologo']
307n/a
308n/a self.initialized = True
309n/a
310n/a # -- Worker methods ------------------------------------------------
311n/a
312n/a def object_filenames(self,
313n/a source_filenames,
314n/a strip_dir=0,
315n/a output_dir=''):
316n/a # Copied from ccompiler.py, extended to return .res as 'object'-file
317n/a # for .rc input file
318n/a if output_dir is None: output_dir = ''
319n/a obj_names = []
320n/a for src_name in source_filenames:
321n/a (base, ext) = os.path.splitext (src_name)
322n/a base = os.path.splitdrive(base)[1] # Chop off the drive
323n/a base = base[os.path.isabs(base):] # If abs, chop off leading /
324n/a if ext not in self.src_extensions:
325n/a # Better to raise an exception instead of silently continuing
326n/a # and later complain about sources and targets having
327n/a # different lengths
328n/a raise CompileError ("Don't know how to compile %s" % src_name)
329n/a if strip_dir:
330n/a base = os.path.basename (base)
331n/a if ext in self._rc_extensions:
332n/a obj_names.append (os.path.join (output_dir,
333n/a base + self.res_extension))
334n/a elif ext in self._mc_extensions:
335n/a obj_names.append (os.path.join (output_dir,
336n/a base + self.res_extension))
337n/a else:
338n/a obj_names.append (os.path.join (output_dir,
339n/a base + self.obj_extension))
340n/a return obj_names
341n/a
342n/a
343n/a def compile(self, sources,
344n/a output_dir=None, macros=None, include_dirs=None, debug=0,
345n/a extra_preargs=None, extra_postargs=None, depends=None):
346n/a
347n/a if not self.initialized:
348n/a self.initialize()
349n/a compile_info = self._setup_compile(output_dir, macros, include_dirs,
350n/a sources, depends, extra_postargs)
351n/a macros, objects, extra_postargs, pp_opts, build = compile_info
352n/a
353n/a compile_opts = extra_preargs or []
354n/a compile_opts.append ('/c')
355n/a if debug:
356n/a compile_opts.extend(self.compile_options_debug)
357n/a else:
358n/a compile_opts.extend(self.compile_options)
359n/a
360n/a for obj in objects:
361n/a try:
362n/a src, ext = build[obj]
363n/a except KeyError:
364n/a continue
365n/a if debug:
366n/a # pass the full pathname to MSVC in debug mode,
367n/a # this allows the debugger to find the source file
368n/a # without asking the user to browse for it
369n/a src = os.path.abspath(src)
370n/a
371n/a if ext in self._c_extensions:
372n/a input_opt = "/Tc" + src
373n/a elif ext in self._cpp_extensions:
374n/a input_opt = "/Tp" + src
375n/a elif ext in self._rc_extensions:
376n/a # compile .RC to .RES file
377n/a input_opt = src
378n/a output_opt = "/fo" + obj
379n/a try:
380n/a self.spawn([self.rc] + pp_opts +
381n/a [output_opt] + [input_opt])
382n/a except DistutilsExecError as msg:
383n/a raise CompileError(msg)
384n/a continue
385n/a elif ext in self._mc_extensions:
386n/a # Compile .MC to .RC file to .RES file.
387n/a # * '-h dir' specifies the directory for the
388n/a # generated include file
389n/a # * '-r dir' specifies the target directory of the
390n/a # generated RC file and the binary message resource
391n/a # it includes
392n/a #
393n/a # For now (since there are no options to change this),
394n/a # we use the source-directory for the include file and
395n/a # the build directory for the RC file and message
396n/a # resources. This works at least for win32all.
397n/a h_dir = os.path.dirname(src)
398n/a rc_dir = os.path.dirname(obj)
399n/a try:
400n/a # first compile .MC to .RC and .H file
401n/a self.spawn([self.mc] +
402n/a ['-h', h_dir, '-r', rc_dir] + [src])
403n/a base, _ = os.path.splitext (os.path.basename (src))
404n/a rc_file = os.path.join (rc_dir, base + '.rc')
405n/a # then compile .RC to .RES file
406n/a self.spawn([self.rc] +
407n/a ["/fo" + obj] + [rc_file])
408n/a
409n/a except DistutilsExecError as msg:
410n/a raise CompileError(msg)
411n/a continue
412n/a else:
413n/a # how to handle this file?
414n/a raise CompileError("Don't know how to compile %s to %s"
415n/a % (src, obj))
416n/a
417n/a output_opt = "/Fo" + obj
418n/a try:
419n/a self.spawn([self.cc] + compile_opts + pp_opts +
420n/a [input_opt, output_opt] +
421n/a extra_postargs)
422n/a except DistutilsExecError as msg:
423n/a raise CompileError(msg)
424n/a
425n/a return objects
426n/a
427n/a
428n/a def create_static_lib(self,
429n/a objects,
430n/a output_libname,
431n/a output_dir=None,
432n/a debug=0,
433n/a target_lang=None):
434n/a
435n/a if not self.initialized:
436n/a self.initialize()
437n/a (objects, output_dir) = self._fix_object_args(objects, output_dir)
438n/a output_filename = self.library_filename(output_libname,
439n/a output_dir=output_dir)
440n/a
441n/a if self._need_link(objects, output_filename):
442n/a lib_args = objects + ['/OUT:' + output_filename]
443n/a if debug:
444n/a pass # XXX what goes here?
445n/a try:
446n/a self.spawn([self.lib] + lib_args)
447n/a except DistutilsExecError as msg:
448n/a raise LibError(msg)
449n/a else:
450n/a log.debug("skipping %s (up-to-date)", output_filename)
451n/a
452n/a
453n/a def link(self,
454n/a target_desc,
455n/a objects,
456n/a output_filename,
457n/a output_dir=None,
458n/a libraries=None,
459n/a library_dirs=None,
460n/a runtime_library_dirs=None,
461n/a export_symbols=None,
462n/a debug=0,
463n/a extra_preargs=None,
464n/a extra_postargs=None,
465n/a build_temp=None,
466n/a target_lang=None):
467n/a
468n/a if not self.initialized:
469n/a self.initialize()
470n/a (objects, output_dir) = self._fix_object_args(objects, output_dir)
471n/a fixed_args = self._fix_lib_args(libraries, library_dirs,
472n/a runtime_library_dirs)
473n/a (libraries, library_dirs, runtime_library_dirs) = fixed_args
474n/a
475n/a if runtime_library_dirs:
476n/a self.warn ("I don't know what to do with 'runtime_library_dirs': "
477n/a + str (runtime_library_dirs))
478n/a
479n/a lib_opts = gen_lib_options(self,
480n/a library_dirs, runtime_library_dirs,
481n/a libraries)
482n/a if output_dir is not None:
483n/a output_filename = os.path.join(output_dir, output_filename)
484n/a
485n/a if self._need_link(objects, output_filename):
486n/a if target_desc == CCompiler.EXECUTABLE:
487n/a if debug:
488n/a ldflags = self.ldflags_shared_debug[1:]
489n/a else:
490n/a ldflags = self.ldflags_shared[1:]
491n/a else:
492n/a if debug:
493n/a ldflags = self.ldflags_shared_debug
494n/a else:
495n/a ldflags = self.ldflags_shared
496n/a
497n/a export_opts = []
498n/a for sym in (export_symbols or []):
499n/a export_opts.append("/EXPORT:" + sym)
500n/a
501n/a ld_args = (ldflags + lib_opts + export_opts +
502n/a objects + ['/OUT:' + output_filename])
503n/a
504n/a # The MSVC linker generates .lib and .exp files, which cannot be
505n/a # suppressed by any linker switches. The .lib files may even be
506n/a # needed! Make sure they are generated in the temporary build
507n/a # directory. Since they have different names for debug and release
508n/a # builds, they can go into the same directory.
509n/a if export_symbols is not None:
510n/a (dll_name, dll_ext) = os.path.splitext(
511n/a os.path.basename(output_filename))
512n/a implib_file = os.path.join(
513n/a os.path.dirname(objects[0]),
514n/a self.library_filename(dll_name))
515n/a ld_args.append ('/IMPLIB:' + implib_file)
516n/a
517n/a if extra_preargs:
518n/a ld_args[:0] = extra_preargs
519n/a if extra_postargs:
520n/a ld_args.extend(extra_postargs)
521n/a
522n/a self.mkpath(os.path.dirname(output_filename))
523n/a try:
524n/a self.spawn([self.linker] + ld_args)
525n/a except DistutilsExecError as msg:
526n/a raise LinkError(msg)
527n/a
528n/a else:
529n/a log.debug("skipping %s (up-to-date)", output_filename)
530n/a
531n/a
532n/a # -- Miscellaneous methods -----------------------------------------
533n/a # These are all used by the 'gen_lib_options() function, in
534n/a # ccompiler.py.
535n/a
536n/a def library_dir_option(self, dir):
537n/a return "/LIBPATH:" + dir
538n/a
539n/a def runtime_library_dir_option(self, dir):
540n/a raise DistutilsPlatformError(
541n/a "don't know how to set runtime library search path for MSVC++")
542n/a
543n/a def library_option(self, lib):
544n/a return self.library_filename(lib)
545n/a
546n/a
547n/a def find_library_file(self, dirs, lib, debug=0):
548n/a # Prefer a debugging library if found (and requested), but deal
549n/a # with it if we don't have one.
550n/a if debug:
551n/a try_names = [lib + "_d", lib]
552n/a else:
553n/a try_names = [lib]
554n/a for dir in dirs:
555n/a for name in try_names:
556n/a libfile = os.path.join(dir, self.library_filename (name))
557n/a if os.path.exists(libfile):
558n/a return libfile
559n/a else:
560n/a # Oops, didn't find it in *any* of 'dirs'
561n/a return None
562n/a
563n/a # Helper methods for using the MSVC registry settings
564n/a
565n/a def find_exe(self, exe):
566n/a """Return path to an MSVC executable program.
567n/a
568n/a Tries to find the program in several places: first, one of the
569n/a MSVC program search paths from the registry; next, the directories
570n/a in the PATH environment variable. If any of those work, return an
571n/a absolute path that is known to exist. If none of them work, just
572n/a return the original program name, 'exe'.
573n/a """
574n/a for p in self.__paths:
575n/a fn = os.path.join(os.path.abspath(p), exe)
576n/a if os.path.isfile(fn):
577n/a return fn
578n/a
579n/a # didn't find it; try existing path
580n/a for p in os.environ['Path'].split(';'):
581n/a fn = os.path.join(os.path.abspath(p),exe)
582n/a if os.path.isfile(fn):
583n/a return fn
584n/a
585n/a return exe
586n/a
587n/a def get_msvc_paths(self, path, platform='x86'):
588n/a """Get a list of devstudio directories (include, lib or path).
589n/a
590n/a Return a list of strings. The list will be empty if unable to
591n/a access the registry or appropriate registry keys not found.
592n/a """
593n/a if not _can_read_reg:
594n/a return []
595n/a
596n/a path = path + " dirs"
597n/a if self.__version >= 7:
598n/a key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
599n/a % (self.__root, self.__version))
600n/a else:
601n/a key = (r"%s\6.0\Build System\Components\Platforms"
602n/a r"\Win32 (%s)\Directories" % (self.__root, platform))
603n/a
604n/a for base in HKEYS:
605n/a d = read_values(base, key)
606n/a if d:
607n/a if self.__version >= 7:
608n/a return self.__macros.sub(d[path]).split(";")
609n/a else:
610n/a return d[path].split(";")
611n/a # MSVC 6 seems to create the registry entries we need only when
612n/a # the GUI is run.
613n/a if self.__version == 6:
614n/a for base in HKEYS:
615n/a if read_values(base, r"%s\6.0" % self.__root) is not None:
616n/a self.warn("It seems you have Visual Studio 6 installed, "
617n/a "but the expected registry settings are not present.\n"
618n/a "You must at least run the Visual Studio GUI once "
619n/a "so that these entries are created.")
620n/a break
621n/a return []
622n/a
623n/a def set_path_env_var(self, name):
624n/a """Set environment variable 'name' to an MSVC path type value.
625n/a
626n/a This is equivalent to a SET command prior to execution of spawned
627n/a commands.
628n/a """
629n/a
630n/a if name == "lib":
631n/a p = self.get_msvc_paths("library")
632n/a else:
633n/a p = self.get_msvc_paths(name)
634n/a if p:
635n/a os.environ[name] = ';'.join(p)
636n/a
637n/a
638n/aif get_build_version() >= 8.0:
639n/a log.debug("Importing new compiler from distutils.msvc9compiler")
640n/a OldMSVCCompiler = MSVCCompiler
641n/a from distutils.msvc9compiler import MSVCCompiler
642n/a # get_build_architecture not really relevant now we support cross-compile
643n/a from distutils.msvc9compiler import MacroExpander