Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / distutils / msvccompiler.py
CommitLineData
86530b38
AT
1"""distutils.msvccompiler
2
3Contains MSVCCompiler, an implementation of the abstract CCompiler class
4for 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,v 1.64.2.4 2005/08/07 20:50:37 loewis Exp $"
14
15import sys, os, string
16from distutils.errors import \
17 DistutilsExecError, DistutilsPlatformError, \
18 CompileError, LibError, LinkError
19from distutils.ccompiler import \
20 CCompiler, gen_preprocess_options, gen_lib_options
21from distutils import log
22
23_can_read_reg = 0
24try:
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
35except 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
54if _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
60def 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
78def 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
99def 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
108class 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 self.set_macro("FrameworkDir", net, "installroot")
127 try:
128 if version > 7.0:
129 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
130 else:
131 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
132 except KeyError, exc: #
133 raise DistutilsPlatformError, \
134 ("The .NET Framework SDK needs to be installed before "
135 "building extensions for Python.")
136
137 p = r"Software\Microsoft\NET Framework Setup\Product"
138 for base in HKEYS:
139 try:
140 h = RegOpenKeyEx(base, p)
141 except RegError:
142 continue
143 key = RegEnumKey(h, 0)
144 d = read_values(base, r"%s\%s" % (p, key))
145 self.macros["$(FrameworkVersion)"] = d["version"]
146
147 def sub(self, s):
148 for k, v in self.macros.items():
149 s = string.replace(s, k, v)
150 return s
151
152def get_build_version():
153 """Return the version of MSVC that was used to build Python.
154
155 For Python 2.3 and up, the version number is included in
156 sys.version. For earlier versions, assume the compiler is MSVC 6.
157 """
158
159 prefix = "MSC v."
160 i = string.find(sys.version, prefix)
161 if i == -1:
162 return 6
163 i = i + len(prefix)
164 s, rest = sys.version[i:].split(" ", 1)
165 majorVersion = int(s[:-2]) - 6
166 minorVersion = int(s[2:3]) / 10.0
167 # I don't think paths are affected by minor version in version 6
168 if majorVersion == 6:
169 minorVersion = 0
170 if majorVersion >= 6:
171 return majorVersion + minorVersion
172 # else we don't know what version of the compiler this is
173 return None
174
175
176class MSVCCompiler (CCompiler) :
177 """Concrete class that implements an interface to Microsoft Visual C++,
178 as defined by the CCompiler abstract class."""
179
180 compiler_type = 'msvc'
181
182 # Just set this so CCompiler's constructor doesn't barf. We currently
183 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
184 # as it really isn't necessary for this sort of single-compiler class.
185 # Would be nice to have a consistent interface with UnixCCompiler,
186 # though, so it's worth thinking about.
187 executables = {}
188
189 # Private class data (need to distinguish C from C++ source for compiler)
190 _c_extensions = ['.c']
191 _cpp_extensions = ['.cc', '.cpp', '.cxx']
192 _rc_extensions = ['.rc']
193 _mc_extensions = ['.mc']
194
195 # Needed for the filename generation methods provided by the
196 # base class, CCompiler.
197 src_extensions = (_c_extensions + _cpp_extensions +
198 _rc_extensions + _mc_extensions)
199 res_extension = '.res'
200 obj_extension = '.obj'
201 static_lib_extension = '.lib'
202 shared_lib_extension = '.dll'
203 static_lib_format = shared_lib_format = '%s%s'
204 exe_extension = '.exe'
205
206 def __init__ (self, verbose=0, dry_run=0, force=0):
207 CCompiler.__init__ (self, verbose, dry_run, force)
208 self.__version = get_build_version()
209 if self.__version >= 7:
210 self.__root = r"Software\Microsoft\VisualStudio"
211 self.__macros = MacroExpander(self.__version)
212 else:
213 self.__root = r"Software\Microsoft\Devstudio"
214 self.initialized = False
215
216 def initialize(self):
217 self.__paths = self.get_msvc_paths("path")
218
219 if len (self.__paths) == 0:
220 raise DistutilsPlatformError, \
221 ("Python was built with version %s of Visual Studio, "
222 "and extensions need to be built with the same "
223 "version of the compiler, but it isn't installed." % self.__version)
224
225 self.cc = self.find_exe("cl.exe")
226 self.linker = self.find_exe("link.exe")
227 self.lib = self.find_exe("lib.exe")
228 self.rc = self.find_exe("rc.exe") # resource compiler
229 self.mc = self.find_exe("mc.exe") # message compiler
230 self.set_path_env_var('lib')
231 self.set_path_env_var('include')
232
233 # extend the MSVC path with the current path
234 try:
235 for p in string.split(os.environ['path'], ';'):
236 self.__paths.append(p)
237 except KeyError:
238 pass
239 os.environ['path'] = string.join(self.__paths, ';')
240
241 self.preprocess_options = None
242 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
243 '/DNDEBUG']
244 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
245 '/Z7', '/D_DEBUG']
246
247 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
248 if self.__version >= 7:
249 self.ldflags_shared_debug = [
250 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
251 ]
252 else:
253 self.ldflags_shared_debug = [
254 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
255 ]
256 self.ldflags_static = [ '/nologo']
257
258 self.initialized = True
259
260
261 # -- Worker methods ------------------------------------------------
262
263 def object_filenames (self,
264 source_filenames,
265 strip_dir=0,
266 output_dir=''):
267 # Copied from ccompiler.py, extended to return .res as 'object'-file
268 # for .rc input file
269 if output_dir is None: output_dir = ''
270 obj_names = []
271 for src_name in source_filenames:
272 (base, ext) = os.path.splitext (src_name)
273 base = os.path.splitdrive(base)[1] # Chop off the drive
274 base = base[os.path.isabs(base):] # If abs, chop off leading /
275 if ext not in self.src_extensions:
276 # Better to raise an exception instead of silently continuing
277 # and later complain about sources and targets having
278 # different lengths
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,
284 base + self.res_extension))
285 elif ext in self._mc_extensions:
286 obj_names.append (os.path.join (output_dir,
287 base + self.res_extension))
288 else:
289 obj_names.append (os.path.join (output_dir,
290 base + self.obj_extension))
291 return obj_names
292
293 # object_filenames ()
294
295
296 def compile(self, sources,
297 output_dir=None, macros=None, include_dirs=None, debug=0,
298 extra_preargs=None, extra_postargs=None, depends=None):
299
300 if not self.initialized: self.initialize()
301 macros, objects, extra_postargs, pp_opts, build = \
302 self._setup_compile(output_dir, macros, include_dirs, sources,
303 depends, extra_postargs)
304
305 compile_opts = extra_preargs or []
306 compile_opts.append ('/c')
307 if debug:
308 compile_opts.extend(self.compile_options_debug)
309 else:
310 compile_opts.extend(self.compile_options)
311
312 for obj in objects:
313 try:
314 src, ext = build[obj]
315 except KeyError:
316 continue
317 if debug:
318 # pass the full pathname to MSVC in debug mode,
319 # this allows the debugger to find the source file
320 # without asking the user to browse for it
321 src = os.path.abspath(src)
322
323 if ext in self._c_extensions:
324 input_opt = "/Tc" + src
325 elif ext in self._cpp_extensions:
326 input_opt = "/Tp" + src
327 elif ext in self._rc_extensions:
328 # compile .RC to .RES file
329 input_opt = src
330 output_opt = "/fo" + obj
331 try:
332 self.spawn ([self.rc] + pp_opts +
333 [output_opt] + [input_opt])
334 except DistutilsExecError, msg:
335 raise CompileError, msg
336 continue
337 elif ext in self._mc_extensions:
338
339 # Compile .MC to .RC file to .RES file.
340 # * '-h dir' specifies the directory for the
341 # generated include file
342 # * '-r dir' specifies the target directory of the
343 # generated RC file and the binary message resource
344 # it includes
345 #
346 # For now (since there are no options to change this),
347 # we use the source-directory for the include file and
348 # the build directory for the RC file and message
349 # resources. This works at least for win32all.
350
351 h_dir = os.path.dirname (src)
352 rc_dir = os.path.dirname (obj)
353 try:
354 # first compile .MC to .RC and .H file
355 self.spawn ([self.mc] +
356 ['-h', h_dir, '-r', rc_dir] + [src])
357 base, _ = os.path.splitext (os.path.basename (src))
358 rc_file = os.path.join (rc_dir, base + '.rc')
359 # then compile .RC to .RES file
360 self.spawn ([self.rc] +
361 ["/fo" + obj] + [rc_file])
362
363 except DistutilsExecError, msg:
364 raise CompileError, msg
365 continue
366 else:
367 # how to handle this file?
368 raise CompileError (
369 "Don't know how to compile %s to %s" % \
370 (src, obj))
371
372 output_opt = "/Fo" + obj
373 try:
374 self.spawn ([self.cc] + compile_opts + pp_opts +
375 [input_opt, output_opt] +
376 extra_postargs)
377 except DistutilsExecError, msg:
378 raise CompileError, msg
379
380 return objects
381
382 # compile ()
383
384
385 def create_static_lib (self,
386 objects,
387 output_libname,
388 output_dir=None,
389 debug=0,
390 target_lang=None):
391
392 if not self.initialized: self.initialize()
393 (objects, output_dir) = self._fix_object_args (objects, output_dir)
394 output_filename = \
395 self.library_filename (output_libname, output_dir=output_dir)
396
397 if self._need_link (objects, output_filename):
398 lib_args = objects + ['/OUT:' + output_filename]
399 if debug:
400 pass # XXX what goes here?
401 try:
402 self.spawn ([self.lib] + lib_args)
403 except DistutilsExecError, msg:
404 raise LibError, msg
405
406 else:
407 log.debug("skipping %s (up-to-date)", output_filename)
408
409 # create_static_lib ()
410
411 def link (self,
412 target_desc,
413 objects,
414 output_filename,
415 output_dir=None,
416 libraries=None,
417 library_dirs=None,
418 runtime_library_dirs=None,
419 export_symbols=None,
420 debug=0,
421 extra_preargs=None,
422 extra_postargs=None,
423 build_temp=None,
424 target_lang=None):
425
426 if not self.initialized: self.initialize()
427 (objects, output_dir) = self._fix_object_args (objects, output_dir)
428 (libraries, library_dirs, runtime_library_dirs) = \
429 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
430
431 if runtime_library_dirs:
432 self.warn ("I don't know what to do with 'runtime_library_dirs': "
433 + str (runtime_library_dirs))
434
435 lib_opts = gen_lib_options (self,
436 library_dirs, runtime_library_dirs,
437 libraries)
438 if output_dir is not None:
439 output_filename = os.path.join (output_dir, output_filename)
440
441 if self._need_link (objects, output_filename):
442
443 if target_desc == CCompiler.EXECUTABLE:
444 if debug:
445 ldflags = self.ldflags_shared_debug[1:]
446 else:
447 ldflags = self.ldflags_shared[1:]
448 else:
449 if debug:
450 ldflags = self.ldflags_shared_debug
451 else:
452 ldflags = self.ldflags_shared
453
454 export_opts = []
455 for sym in (export_symbols or []):
456 export_opts.append("/EXPORT:" + sym)
457
458 ld_args = (ldflags + lib_opts + export_opts +
459 objects + ['/OUT:' + output_filename])
460
461 # The MSVC linker generates .lib and .exp files, which cannot be
462 # suppressed by any linker switches. The .lib files may even be
463 # needed! Make sure they are generated in the temporary build
464 # directory. Since they have different names for debug and release
465 # builds, they can go into the same directory.
466 if export_symbols is not None:
467 (dll_name, dll_ext) = os.path.splitext(
468 os.path.basename(output_filename))
469 implib_file = os.path.join(
470 os.path.dirname(objects[0]),
471 self.library_filename(dll_name))
472 ld_args.append ('/IMPLIB:' + implib_file)
473
474 if extra_preargs:
475 ld_args[:0] = extra_preargs
476 if extra_postargs:
477 ld_args.extend(extra_postargs)
478
479 self.mkpath (os.path.dirname (output_filename))
480 try:
481 self.spawn ([self.linker] + ld_args)
482 except DistutilsExecError, msg:
483 raise LinkError, msg
484
485 else:
486 log.debug("skipping %s (up-to-date)", output_filename)
487
488 # link ()
489
490
491 # -- Miscellaneous methods -----------------------------------------
492 # These are all used by the 'gen_lib_options() function, in
493 # ccompiler.py.
494
495 def library_dir_option (self, dir):
496 return "/LIBPATH:" + dir
497
498 def runtime_library_dir_option (self, dir):
499 raise DistutilsPlatformError, \
500 "don't know how to set runtime library search path for MSVC++"
501
502 def library_option (self, lib):
503 return self.library_filename (lib)
504
505
506 def find_library_file (self, dirs, lib, debug=0):
507 # Prefer a debugging library if found (and requested), but deal
508 # with it if we don't have one.
509 if debug:
510 try_names = [lib + "_d", lib]
511 else:
512 try_names = [lib]
513 for dir in dirs:
514 for name in try_names:
515 libfile = os.path.join(dir, self.library_filename (name))
516 if os.path.exists(libfile):
517 return libfile
518 else:
519 # Oops, didn't find it in *any* of 'dirs'
520 return None
521
522 # find_library_file ()
523
524 # Helper methods for using the MSVC registry settings
525
526 def find_exe(self, exe):
527 """Return path to an MSVC executable program.
528
529 Tries to find the program in several places: first, one of the
530 MSVC program search paths from the registry; next, the directories
531 in the PATH environment variable. If any of those work, return an
532 absolute path that is known to exist. If none of them work, just
533 return the original program name, 'exe'.
534 """
535
536 for p in self.__paths:
537 fn = os.path.join(os.path.abspath(p), exe)
538 if os.path.isfile(fn):
539 return fn
540
541 # didn't find it; try existing path
542 for p in string.split(os.environ['Path'],';'):
543 fn = os.path.join(os.path.abspath(p),exe)
544 if os.path.isfile(fn):
545 return fn
546
547 return exe
548
549 def get_msvc_paths(self, path, platform='x86'):
550 """Get a list of devstudio directories (include, lib or path).
551
552 Return a list of strings. The list will be empty if unable to
553 access the registry or appropriate registry keys not found.
554 """
555
556 if not _can_read_reg:
557 return []
558
559 path = path + " dirs"
560 if self.__version >= 7:
561 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
562 % (self.__root, self.__version))
563 else:
564 key = (r"%s\6.0\Build System\Components\Platforms"
565 r"\Win32 (%s)\Directories" % (self.__root, platform))
566
567 for base in HKEYS:
568 d = read_values(base, key)
569 if d:
570 if self.__version >= 7:
571 return string.split(self.__macros.sub(d[path]), ";")
572 else:
573 return string.split(d[path], ";")
574 # MSVC 6 seems to create the registry entries we need only when
575 # the GUI is run.
576 if self.__version == 6:
577 for base in HKEYS:
578 if read_values(base, r"%s\6.0" % self.__root) is not None:
579 self.warn("It seems you have Visual Studio 6 installed, "
580 "but the expected registry settings are not present.\n"
581 "You must at least run the Visual Studio GUI once "
582 "so that these entries are created.")
583 break
584 return []
585
586 def set_path_env_var(self, name):
587 """Set environment variable 'name' to an MSVC path type value.
588
589 This is equivalent to a SET command prior to execution of spawned
590 commands.
591 """
592
593 if name == "lib":
594 p = self.get_msvc_paths("library")
595 else:
596 p = self.get_msvc_paths(name)
597 if p:
598 os.environ[name] = string.join(p, ';')