Attachment 'msvccompiler.py'

Download

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

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2008-04-29 18:54:24, 25.5 KB) [[attachment:msvccompiler.py]]
  • [get | view] (2008-04-29 19:23:03, 0.3 KB) [[attachment:setup.bat]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.