msvccompiler.py (17164B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\msvccompiler.py 2 __revision__ = '$Id: msvccompiler.py 82110 2010-06-20 13:38:51Z kristjan.jonsson $' 3 import sys 4 import os 5 import string 6 from distutils.errors import DistutilsExecError, DistutilsPlatformError, CompileError, LibError, LinkError 7 from distutils.ccompiler import CCompiler, gen_lib_options 8 from distutils import log 9 _can_read_reg = 0 10 try: 11 import _winreg 12 _can_read_reg = 1 13 hkey_mod = _winreg 14 RegOpenKeyEx = _winreg.OpenKeyEx 15 RegEnumKey = _winreg.EnumKey 16 RegEnumValue = _winreg.EnumValue 17 RegError = _winreg.error 18 except ImportError: 19 try: 20 import win32api 21 import win32con 22 _can_read_reg = 1 23 hkey_mod = win32con 24 RegOpenKeyEx = win32api.RegOpenKeyEx 25 RegEnumKey = win32api.RegEnumKey 26 RegEnumValue = win32api.RegEnumValue 27 RegError = win32api.error 28 except ImportError: 29 log.info("Warning: Can't read registry to find the necessary compiler setting\nMake sure that Python modules _winreg, win32api or win32con are installed.") 30 31 if _can_read_reg: 32 HKEYS = (hkey_mod.HKEY_USERS, 33 hkey_mod.HKEY_CURRENT_USER, 34 hkey_mod.HKEY_LOCAL_MACHINE, 35 hkey_mod.HKEY_CLASSES_ROOT) 36 37 def read_keys(base, key): 38 try: 39 handle = RegOpenKeyEx(base, key) 40 except RegError: 41 return None 42 43 L = [] 44 i = 0 45 while 1: 46 try: 47 k = RegEnumKey(handle, i) 48 except RegError: 49 break 50 51 L.append(k) 52 i = i + 1 53 54 return L 55 56 57 def read_values(base, key): 58 try: 59 handle = RegOpenKeyEx(base, key) 60 except RegError: 61 return None 62 63 d = {} 64 i = 0 65 while 1: 66 try: 67 name, value, type = RegEnumValue(handle, i) 68 except RegError: 69 break 70 71 name = name.lower() 72 d[convert_mbcs(name)] = convert_mbcs(value) 73 i = i + 1 74 75 return d 76 77 78 def convert_mbcs(s): 79 enc = getattr(s, 'encode', None) 80 if enc is not None: 81 try: 82 s = enc('mbcs') 83 except UnicodeError: 84 pass 85 86 return s 87 88 89 class MacroExpander(): 90 91 def __init__(self, version): 92 self.macros = {} 93 self.load_macros(version) 94 95 def set_macro(self, macro, path, key): 96 for base in HKEYS: 97 d = read_values(base, path) 98 if d: 99 self.macros['$(%s)' % macro] = d[key] 100 break 101 102 def load_macros(self, version): 103 vsbase = 'Software\\Microsoft\\VisualStudio\\%0.1f' % version 104 self.set_macro('VCInstallDir', vsbase + '\\Setup\\VC', 'productdir') 105 self.set_macro('VSInstallDir', vsbase + '\\Setup\\VS', 'productdir') 106 net = 'Software\\Microsoft\\.NETFramework' 107 self.set_macro('FrameworkDir', net, 'installroot') 108 try: 109 if version > 7.0: 110 self.set_macro('FrameworkSDKDir', net, 'sdkinstallrootv1.1') 111 else: 112 self.set_macro('FrameworkSDKDir', net, 'sdkinstallroot') 113 except KeyError: 114 raise DistutilsPlatformError, 'Python was built with Visual Studio 2003;\nextensions must be built with a compiler than can generate compatible binaries.\nVisual Studio 2003 was not found on this system. If you have Cygwin installed,\nyou can try compiling with MingW32, by passing "-c mingw32" to setup.py.' 115 116 p = 'Software\\Microsoft\\NET Framework Setup\\Product' 117 for base in HKEYS: 118 try: 119 h = RegOpenKeyEx(base, p) 120 except RegError: 121 continue 122 123 key = RegEnumKey(h, 0) 124 d = read_values(base, '%s\\%s' % (p, key)) 125 self.macros['$(FrameworkVersion)'] = d['version'] 126 127 def sub(self, s): 128 for k, v in self.macros.items(): 129 s = string.replace(s, k, v) 130 131 return s 132 133 134 def get_build_version(): 135 prefix = 'MSC v.' 136 i = string.find(sys.version, prefix) 137 if i == -1: 138 return 6 139 i = i + len(prefix) 140 s, rest = sys.version[i:].split(' ', 1) 141 majorVersion = int(s[:-2]) - 6 142 minorVersion = int(s[2:3]) / 10.0 143 if majorVersion == 6: 144 minorVersion = 0 145 if majorVersion >= 6: 146 return majorVersion + minorVersion 147 148 149 def get_build_architecture(): 150 prefix = ' bit (' 151 i = string.find(sys.version, prefix) 152 if i == -1: 153 return 'Intel' 154 j = string.find(sys.version, ')', i) 155 return sys.version[i + len(prefix):j] 156 157 158 def normalize_and_reduce_paths(paths): 159 reduced_paths = [] 160 for p in paths: 161 np = os.path.normpath(p) 162 if np not in reduced_paths: 163 reduced_paths.append(np) 164 165 return reduced_paths 166 167 168 class MSVCCompiler(CCompiler): 169 compiler_type = 'msvc' 170 executables = {} 171 _c_extensions = ['.c'] 172 _cpp_extensions = ['.cc', '.cpp', '.cxx'] 173 _rc_extensions = ['.rc'] 174 _mc_extensions = ['.mc'] 175 src_extensions = _c_extensions + _cpp_extensions + _rc_extensions + _mc_extensions 176 res_extension = '.res' 177 obj_extension = '.obj' 178 static_lib_extension = '.lib' 179 shared_lib_extension = '.dll' 180 static_lib_format = shared_lib_format = '%s%s' 181 exe_extension = '.exe' 182 183 def __init__(self, verbose = 0, dry_run = 0, force = 0): 184 CCompiler.__init__(self, verbose, dry_run, force) 185 self.__version = get_build_version() 186 self.__arch = get_build_architecture() 187 if self.__arch == 'Intel': 188 if self.__version >= 7: 189 self.__root = 'Software\\Microsoft\\VisualStudio' 190 self.__macros = MacroExpander(self.__version) 191 else: 192 self.__root = 'Software\\Microsoft\\Devstudio' 193 self.__product = 'Visual Studio version %s' % self.__version 194 else: 195 self.__product = 'Microsoft SDK compiler %s' % (self.__version + 6) 196 self.initialized = False 197 198 def initialize(self): 199 self.__paths = [] 200 if 'DISTUTILS_USE_SDK' in os.environ and 'MSSdk' in os.environ and self.find_exe('cl.exe'): 201 self.cc = 'cl.exe' 202 self.linker = 'link.exe' 203 self.lib = 'lib.exe' 204 self.rc = 'rc.exe' 205 self.mc = 'mc.exe' 206 else: 207 self.__paths = self.get_msvc_paths('path') 208 if len(self.__paths) == 0: 209 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 210 self.cc = self.find_exe('cl.exe') 211 self.linker = self.find_exe('link.exe') 212 self.lib = self.find_exe('lib.exe') 213 self.rc = self.find_exe('rc.exe') 214 self.mc = self.find_exe('mc.exe') 215 self.set_path_env_var('lib') 216 self.set_path_env_var('include') 217 try: 218 for p in string.split(os.environ['path'], ';'): 219 self.__paths.append(p) 220 221 except KeyError: 222 pass 223 224 self.__paths = normalize_and_reduce_paths(self.__paths) 225 os.environ['path'] = string.join(self.__paths, ';') 226 self.preprocess_options = None 227 if self.__arch == 'Intel': 228 self.compile_options = ['/nologo', 229 '/Ox', 230 '/MD', 231 '/W3', 232 '/GX', 233 '/DNDEBUG'] 234 self.compile_options_debug = ['/nologo', 235 '/Od', 236 '/MDd', 237 '/W3', 238 '/GX', 239 '/Z7', 240 '/D_DEBUG'] 241 else: 242 self.compile_options = ['/nologo', 243 '/Ox', 244 '/MD', 245 '/W3', 246 '/GS-', 247 '/DNDEBUG'] 248 self.compile_options_debug = ['/nologo', 249 '/Od', 250 '/MDd', 251 '/W3', 252 '/GS-', 253 '/Z7', 254 '/D_DEBUG'] 255 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] 256 if self.__version >= 7: 257 self.ldflags_shared_debug = ['/DLL', 258 '/nologo', 259 '/INCREMENTAL:no', 260 '/DEBUG'] 261 else: 262 self.ldflags_shared_debug = ['/DLL', 263 '/nologo', 264 '/INCREMENTAL:no', 265 '/pdb:None', 266 '/DEBUG'] 267 self.ldflags_static = ['/nologo'] 268 self.initialized = True 269 270 def object_filenames(self, source_filenames, strip_dir = 0, output_dir = ''): 271 if output_dir is None: 272 output_dir = '' 273 obj_names = [] 274 for src_name in source_filenames: 275 base, ext = os.path.splitext(src_name) 276 base = os.path.splitdrive(base)[1] 277 base = base[os.path.isabs(base):] 278 if ext not in self.src_extensions: 279 raise CompileError("Don't know how to compile %s" % src_name) 280 if strip_dir: 281 base = os.path.basename(base) 282 if ext in self._rc_extensions: 283 obj_names.append(os.path.join(output_dir, base + self.res_extension)) 284 elif ext in self._mc_extensions: 285 obj_names.append(os.path.join(output_dir, base + self.res_extension)) 286 else: 287 obj_names.append(os.path.join(output_dir, base + self.obj_extension)) 288 289 return obj_names 290 291 def compile(self, sources, output_dir = None, macros = None, include_dirs = None, debug = 0, extra_preargs = None, extra_postargs = None, depends = None): 292 if not self.initialized: 293 self.initialize() 294 macros, objects, extra_postargs, pp_opts, build = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) 295 compile_opts = extra_preargs or [] 296 compile_opts.append('/c') 297 if debug: 298 compile_opts.extend(self.compile_options_debug) 299 else: 300 compile_opts.extend(self.compile_options) 301 for obj in objects: 302 try: 303 src, ext = build[obj] 304 except KeyError: 305 continue 306 307 if debug: 308 src = os.path.abspath(src) 309 if ext in self._c_extensions: 310 input_opt = '/Tc' + src 311 elif ext in self._cpp_extensions: 312 input_opt = '/Tp' + src 313 elif ext in self._rc_extensions: 314 input_opt = src 315 output_opt = '/fo' + obj 316 try: 317 self.spawn([self.rc] + pp_opts + [output_opt] + [input_opt]) 318 except DistutilsExecError as msg: 319 raise CompileError, msg 320 321 continue 322 elif ext in self._mc_extensions: 323 h_dir = os.path.dirname(src) 324 rc_dir = os.path.dirname(obj) 325 try: 326 self.spawn([self.mc] + ['-h', 327 h_dir, 328 '-r', 329 rc_dir] + [src]) 330 base, _ = os.path.splitext(os.path.basename(src)) 331 rc_file = os.path.join(rc_dir, base + '.rc') 332 self.spawn([self.rc] + ['/fo' + obj] + [rc_file]) 333 except DistutilsExecError as msg: 334 raise CompileError, msg 335 336 continue 337 else: 338 raise CompileError("Don't know how to compile %s to %s" % (src, obj)) 339 output_opt = '/Fo' + obj 340 try: 341 self.spawn([self.cc] + compile_opts + pp_opts + [input_opt, output_opt] + extra_postargs) 342 except DistutilsExecError as msg: 343 raise CompileError, msg 344 345 return objects 346 347 def create_static_lib(self, objects, output_libname, output_dir = None, debug = 0, target_lang = None): 348 if not self.initialized: 349 self.initialize() 350 objects, output_dir = self._fix_object_args(objects, output_dir) 351 output_filename = self.library_filename(output_libname, output_dir=output_dir) 352 if self._need_link(objects, output_filename): 353 lib_args = objects + ['/OUT:' + output_filename] 354 if debug: 355 pass 356 try: 357 self.spawn([self.lib] + lib_args) 358 except DistutilsExecError as msg: 359 raise LibError, msg 360 361 else: 362 log.debug('skipping %s (up-to-date)', output_filename) 363 364 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): 365 if not self.initialized: 366 self.initialize() 367 objects, output_dir = self._fix_object_args(objects, output_dir) 368 libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) 369 if runtime_library_dirs: 370 self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) 371 lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) 372 if output_dir is not None: 373 output_filename = os.path.join(output_dir, output_filename) 374 if self._need_link(objects, output_filename): 375 if target_desc == CCompiler.EXECUTABLE: 376 if debug: 377 ldflags = self.ldflags_shared_debug[1:] 378 else: 379 ldflags = self.ldflags_shared[1:] 380 elif debug: 381 ldflags = self.ldflags_shared_debug 382 else: 383 ldflags = self.ldflags_shared 384 export_opts = [] 385 for sym in export_symbols or []: 386 export_opts.append('/EXPORT:' + sym) 387 388 ld_args = ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename] 389 if export_symbols is not None: 390 dll_name, dll_ext = os.path.splitext(os.path.basename(output_filename)) 391 implib_file = os.path.join(os.path.dirname(objects[0]), self.library_filename(dll_name)) 392 ld_args.append('/IMPLIB:' + implib_file) 393 if extra_preargs: 394 ld_args[:0] = extra_preargs 395 if extra_postargs: 396 ld_args.extend(extra_postargs) 397 self.mkpath(os.path.dirname(output_filename)) 398 try: 399 self.spawn([self.linker] + ld_args) 400 except DistutilsExecError as msg: 401 raise LinkError, msg 402 403 else: 404 log.debug('skipping %s (up-to-date)', output_filename) 405 406 def library_dir_option(self, dir): 407 return '/LIBPATH:' + dir 408 409 def runtime_library_dir_option(self, dir): 410 raise DistutilsPlatformError, "don't know how to set runtime library search path for MSVC++" 411 412 def library_option(self, lib): 413 return self.library_filename(lib) 414 415 def find_library_file(self, dirs, lib, debug = 0): 416 if debug: 417 try_names = [lib + '_d', lib] 418 else: 419 try_names = [lib] 420 for dir in dirs: 421 for name in try_names: 422 libfile = os.path.join(dir, self.library_filename(name)) 423 if os.path.exists(libfile): 424 return libfile 425 426 else: 427 return None 428 429 def find_exe(self, exe): 430 for p in self.__paths: 431 fn = os.path.join(os.path.abspath(p), exe) 432 if os.path.isfile(fn): 433 return fn 434 435 for p in string.split(os.environ['Path'], ';'): 436 fn = os.path.join(os.path.abspath(p), exe) 437 if os.path.isfile(fn): 438 return fn 439 440 return exe 441 442 def get_msvc_paths(self, path, platform = 'x86'): 443 if not _can_read_reg: 444 return [] 445 path = path + ' dirs' 446 if self.__version >= 7: 447 key = '%s\\%0.1f\\VC\\VC_OBJECTS_PLATFORM_INFO\\Win32\\Directories' % (self.__root, self.__version) 448 else: 449 key = '%s\\6.0\\Build System\\Components\\Platforms\\Win32 (%s)\\Directories' % (self.__root, platform) 450 for base in HKEYS: 451 d = read_values(base, key) 452 if d: 453 if self.__version >= 7: 454 return string.split(self.__macros.sub(d[path]), ';') 455 else: 456 return string.split(d[path], ';') 457 458 if self.__version == 6: 459 for base in HKEYS: 460 if read_values(base, '%s\\6.0' % self.__root) is not None: 461 self.warn('It seems you have Visual Studio 6 installed, but the expected registry settings are not present.\nYou must at least run the Visual Studio GUI once so that these entries are created.') 462 break 463 464 return [] 465 466 def set_path_env_var(self, name): 467 if name == 'lib': 468 p = self.get_msvc_paths('library') 469 else: 470 p = self.get_msvc_paths(name) 471 if p: 472 os.environ[name] = string.join(p, ';') 473 474 475 if get_build_version() >= 8.0: 476 log.debug('Importing new compiler from distutils.msvc9compiler') 477 OldMSVCCompiler = MSVCCompiler 478 from distutils.msvc9compiler import MSVCCompiler 479 from distutils.msvc9compiler import MacroExpander