blob: f3acb53477e5a0035e4ff564d182dbbf2b018fd5 [file] [log] [blame]
Greg Wardbfc79d62000-06-28 01:29:09 +00001"""distutils.msvccompiler
Greg Warddbd12761999-08-29 18:15:07 +00002
3Contains MSVCCompiler, an implementation of the abstract CCompiler class
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +00004for the Microsoft Visual Studio.
5"""
Greg Warddbd12761999-08-29 18:15:07 +00006
Andrew M. Kuchlinga6483d22002-11-14 02:25:42 +00007# Written by Perry Stoll
Greg Ward32c4a8a2000-03-06 03:40:29 +00008# hacked by Robin Becker and Thomas Heller to do a better job of
9# finding DevStudio (through the registry)
10
Martin v. Löwis5a6601c2004-11-10 22:23:15 +000011# This module should be kept compatible with Python 2.1.
Andrew M. Kuchlingd448f662002-11-19 13:12:28 +000012
Greg Ward3ce77fd2000-03-02 01:49:45 +000013__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000014
Greg Ward32c4a8a2000-03-06 03:40:29 +000015import sys, os, string
Greg Ward3add77f2000-05-30 02:02:49 +000016from distutils.errors import \
17 DistutilsExecError, DistutilsPlatformError, \
Greg Wardd1517112000-05-30 01:56:44 +000018 CompileError, LibError, LinkError
Greg Ward3add77f2000-05-30 02:02:49 +000019from distutils.ccompiler import \
20 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000021from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000022
Greg Ward7642f5c2000-03-31 16:47:40 +000023_can_read_reg = 0
24try:
Greg Ward1b5ec762000-06-30 19:37:59 +000025 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000026
Greg Ward7642f5c2000-03-31 16:47:40 +000027 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000028 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000029
Greg Wardcd079c42000-06-29 22:59:10 +000030 RegOpenKeyEx = _winreg.OpenKeyEx
31 RegEnumKey = _winreg.EnumKey
32 RegEnumValue = _winreg.EnumValue
33 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000034
Greg Ward7642f5c2000-03-31 16:47:40 +000035except ImportError:
36 try:
37 import win32api
38 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000039 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000040 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000041
42 RegOpenKeyEx = win32api.RegOpenKeyEx
43 RegEnumKey = win32api.RegEnumKey
44 RegEnumValue = win32api.RegEnumValue
45 RegError = win32api.error
46
Greg Ward7642f5c2000-03-31 16:47:40 +000047 except ImportError:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000048 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.")
Greg Ward7642f5c2000-03-31 16:47:40 +000052 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000053
54if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000055 HKEYS = (hkey_mod.HKEY_USERS,
56 hkey_mod.HKEY_CURRENT_USER,
57 hkey_mod.HKEY_LOCAL_MACHINE,
58 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000059
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000060def read_keys(base, key):
61 """Return list of registry keys."""
Fred Drakeb94b8492001-12-06 20:51:35 +000062
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000063 try:
64 handle = RegOpenKeyEx(base, key)
65 except RegError:
66 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000067 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000068 i = 0
69 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000070 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000071 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000072 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000073 break
74 L.append(k)
75 i = i + 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000076 return L
77
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000078def read_values(base, key):
79 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000080
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000081 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:
Greg Ward1b9c6f72000-02-08 02:39:44 +000090 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000091 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000092 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000093 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:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000105 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000106 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000107
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000108class MacroExpander:
Greg Ward62e33932000-02-10 02:52:42 +0000109
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000110 def __init__(self, version):
111 self.macros = {}
112 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000113
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000114 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
Tim Peters182b5ac2004-07-18 06:16:08 +0000120
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000121 def load_macros(self, version):
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000122 vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000123 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")
Tim Peters26be2062004-11-28 01:10:01 +0000127 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: #
Fredrik Lundhcb328f32004-11-24 22:31:11 +0000133 raise DistutilsPlatformError, \
Martin v. Löwis77621582006-07-30 13:27:31 +0000134 ("""Python was built with Visual Studio 2003;
135extensions must be built with a compiler than can generate compatible binaries.
136Visual Studio 2003 was not found on this system. If you have Cygwin installed,
137you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000138
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000139 p = r"Software\Microsoft\NET Framework Setup\Product"
140 for base in HKEYS:
141 try:
142 h = RegOpenKeyEx(base, p)
143 except RegError:
144 continue
145 key = RegEnumKey(h, 0)
146 d = read_values(base, r"%s\%s" % (p, key))
147 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000148
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000149 def sub(self, s):
150 for k, v in self.macros.items():
151 s = string.replace(s, k, v)
152 return s
Greg Ward69988092000-02-11 02:47:15 +0000153
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000154def get_build_version():
155 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000156
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000157 For Python 2.3 and up, the version number is included in
158 sys.version. For earlier versions, assume the compiler is MSVC 6.
159 """
Greg Ward62e33932000-02-10 02:52:42 +0000160
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000161 prefix = "MSC v."
162 i = string.find(sys.version, prefix)
163 if i == -1:
164 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000165 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000166 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000167 majorVersion = int(s[:-2]) - 6
168 minorVersion = int(s[2:3]) / 10.0
169 # I don't think paths are affected by minor version in version 6
170 if majorVersion == 6:
171 minorVersion = 0
172 if majorVersion >= 6:
173 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000174 # else we don't know what version of the compiler this is
175 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000176
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000177def get_build_architecture():
178 """Return the processor architecture.
179
180 Possible results are "Intel", "Itanium", or "AMD64".
181 """
182
183 prefix = " bit ("
184 i = string.find(sys.version, prefix)
185 if i == -1:
186 return "Intel"
187 j = string.find(sys.version, ")", i)
188 return sys.version[i+len(prefix):j]
Tim Peters32cbc962006-02-20 21:42:18 +0000189
Neal Norwitz8f35f442007-04-01 18:24:22 +0000190def normalize_and_reduce_paths(paths):
191 """Return a list of normalized paths with duplicates removed.
192
193 The current order of paths is maintained.
194 """
195 # Paths are normalized so things like: /a and /a/ aren't both preserved.
196 reduced_paths = []
197 for p in paths:
198 np = os.path.normpath(p)
199 # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
200 if np not in reduced_paths:
201 reduced_paths.append(np)
202 return reduced_paths
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000203
Greg Warddbd12761999-08-29 18:15:07 +0000204
Greg Ward3d50b901999-09-08 02:36:01 +0000205class MSVCCompiler (CCompiler) :
206 """Concrete class that implements an interface to Microsoft Visual C++,
207 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000208
Greg Warddf178f91999-09-29 12:29:10 +0000209 compiler_type = 'msvc'
210
Greg Ward992c8f92000-06-25 02:31:16 +0000211 # Just set this so CCompiler's constructor doesn't barf. We currently
212 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
213 # as it really isn't necessary for this sort of single-compiler class.
214 # Would be nice to have a consistent interface with UnixCCompiler,
215 # though, so it's worth thinking about.
216 executables = {}
217
Greg Ward32c4a8a2000-03-06 03:40:29 +0000218 # Private class data (need to distinguish C from C++ source for compiler)
219 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000220 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000221 _rc_extensions = ['.rc']
222 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000223
224 # Needed for the filename generation methods provided by the
225 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000226 src_extensions = (_c_extensions + _cpp_extensions +
227 _rc_extensions + _mc_extensions)
228 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000229 obj_extension = '.obj'
230 static_lib_extension = '.lib'
231 shared_lib_extension = '.dll'
232 static_lib_format = shared_lib_format = '%s%s'
233 exe_extension = '.exe'
234
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000235 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000236 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000237 self.__version = get_build_version()
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000238 self.__arch = get_build_architecture()
239 if self.__arch == "Intel":
240 # x86
241 if self.__version >= 7:
242 self.__root = r"Software\Microsoft\VisualStudio"
243 self.__macros = MacroExpander(self.__version)
244 else:
245 self.__root = r"Software\Microsoft\Devstudio"
246 self.__product = "Visual Studio version %s" % self.__version
Greg Ward69988092000-02-11 02:47:15 +0000247 else:
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000248 # Win64. Assume this was built with the platform SDK
249 self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
Tim Peters32cbc962006-02-20 21:42:18 +0000250
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000251 self.initialized = False
252
253 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000254 self.__paths = []
Guido van Rossum8bc09652008-02-21 18:18:37 +0000255 if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000256 # Assume that the SDK set up everything alright; don't try to be
257 # smarter
258 self.cc = "cl.exe"
259 self.linker = "link.exe"
260 self.lib = "lib.exe"
261 self.rc = "rc.exe"
262 self.mc = "mc.exe"
263 else:
264 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000265
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000266 if len (self.__paths) == 0:
267 raise DistutilsPlatformError, \
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000268 ("Python was built with %s, "
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000269 "and extensions need to be built with the same "
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000270 "version of the compiler, but it isn't installed." % self.__product)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000271
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000272 self.cc = self.find_exe("cl.exe")
273 self.linker = self.find_exe("link.exe")
274 self.lib = self.find_exe("lib.exe")
275 self.rc = self.find_exe("rc.exe") # resource compiler
276 self.mc = self.find_exe("mc.exe") # message compiler
277 self.set_path_env_var('lib')
278 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000279
280 # extend the MSVC path with the current path
281 try:
282 for p in string.split(os.environ['path'], ';'):
283 self.__paths.append(p)
284 except KeyError:
285 pass
Neal Norwitz8f35f442007-04-01 18:24:22 +0000286 self.__paths = normalize_and_reduce_paths(self.__paths)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000287 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000288
Greg Warddbd12761999-08-29 18:15:07 +0000289 self.preprocess_options = None
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000290 if self.__arch == "Intel":
291 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
292 '/DNDEBUG']
293 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
294 '/Z7', '/D_DEBUG']
295 else:
296 # Win64
297 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
298 '/DNDEBUG']
299 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
Tim Peters32cbc962006-02-20 21:42:18 +0000300 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000301
Greg Ward1b9c6f72000-02-08 02:39:44 +0000302 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000303 if self.__version >= 7:
304 self.ldflags_shared_debug = [
305 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
306 ]
307 else:
308 self.ldflags_shared_debug = [
309 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
310 ]
Greg Warddbd12761999-08-29 18:15:07 +0000311 self.ldflags_static = [ '/nologo']
312
Tim Petersa733bd92005-03-12 19:05:58 +0000313 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000314
315 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000316
Greg Ward9c0ea132000-09-19 23:56:43 +0000317 def object_filenames (self,
318 source_filenames,
319 strip_dir=0,
320 output_dir=''):
321 # Copied from ccompiler.py, extended to return .res as 'object'-file
322 # for .rc input file
323 if output_dir is None: output_dir = ''
324 obj_names = []
325 for src_name in source_filenames:
326 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000327 base = os.path.splitdrive(base)[1] # Chop off the drive
328 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000329 if ext not in self.src_extensions:
330 # Better to raise an exception instead of silently continuing
331 # and later complain about sources and targets having
332 # different lengths
333 raise CompileError ("Don't know how to compile %s" % src_name)
334 if strip_dir:
335 base = os.path.basename (base)
336 if ext in self._rc_extensions:
337 obj_names.append (os.path.join (output_dir,
338 base + self.res_extension))
339 elif ext in self._mc_extensions:
340 obj_names.append (os.path.join (output_dir,
341 base + self.res_extension))
342 else:
343 obj_names.append (os.path.join (output_dir,
344 base + self.obj_extension))
345 return obj_names
346
347 # object_filenames ()
348
349
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000350 def compile(self, sources,
351 output_dir=None, macros=None, include_dirs=None, debug=0,
352 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000353
Brett Cannon3304a142005-03-05 05:28:45 +0000354 if not self.initialized: self.initialize()
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000355 macros, objects, extra_postargs, pp_opts, build = \
356 self._setup_compile(output_dir, macros, include_dirs, sources,
357 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000358
Greg Ward32c4a8a2000-03-06 03:40:29 +0000359 compile_opts = extra_preargs or []
360 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000361 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000362 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000363 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000364 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000365
Thomas Heller9436a752003-12-05 20:12:23 +0000366 for obj in objects:
367 try:
368 src, ext = build[obj]
369 except KeyError:
370 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000371 if debug:
372 # pass the full pathname to MSVC in debug mode,
373 # this allows the debugger to find the source file
374 # without asking the user to browse for it
375 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000376
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000377 if ext in self._c_extensions:
378 input_opt = "/Tc" + src
379 elif ext in self._cpp_extensions:
380 input_opt = "/Tp" + src
381 elif ext in self._rc_extensions:
382 # compile .RC to .RES file
383 input_opt = src
384 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000385 try:
Thomas Heller95827942003-01-31 20:40:15 +0000386 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000387 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000388 except DistutilsExecError, msg:
389 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000390 continue
391 elif ext in self._mc_extensions:
392
393 # Compile .MC to .RC file to .RES file.
394 # * '-h dir' specifies the directory for the
395 # generated include file
396 # * '-r dir' specifies the target directory of the
397 # generated RC file and the binary message resource
398 # it includes
399 #
400 # For now (since there are no options to change this),
401 # we use the source-directory for the include file and
402 # the build directory for the RC file and message
403 # resources. This works at least for win32all.
404
405 h_dir = os.path.dirname (src)
406 rc_dir = os.path.dirname (obj)
407 try:
408 # first compile .MC to .RC and .H file
409 self.spawn ([self.mc] +
410 ['-h', h_dir, '-r', rc_dir] + [src])
411 base, _ = os.path.splitext (os.path.basename (src))
412 rc_file = os.path.join (rc_dir, base + '.rc')
413 # then compile .RC to .RES file
414 self.spawn ([self.rc] +
415 ["/fo" + obj] + [rc_file])
416
417 except DistutilsExecError, msg:
418 raise CompileError, msg
419 continue
420 else:
421 # how to handle this file?
422 raise CompileError (
423 "Don't know how to compile %s to %s" % \
424 (src, obj))
425
426 output_opt = "/Fo" + obj
427 try:
428 self.spawn ([self.cc] + compile_opts + pp_opts +
429 [input_opt, output_opt] +
430 extra_postargs)
431 except DistutilsExecError, msg:
432 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000433
Greg Ward32c4a8a2000-03-06 03:40:29 +0000434 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000435
Greg Ward32c4a8a2000-03-06 03:40:29 +0000436 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000437
438
Greg Ward09fc5422000-03-10 01:49:26 +0000439 def create_static_lib (self,
440 objects,
441 output_libname,
442 output_dir=None,
443 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000444 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000445
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000446 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000447 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000448 output_filename = \
449 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000450
Greg Ward32c4a8a2000-03-06 03:40:29 +0000451 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000452 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000453 if debug:
454 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000455 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000456 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000457 except DistutilsExecError, msg:
458 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000459
Greg Ward32c4a8a2000-03-06 03:40:29 +0000460 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000461 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000462
Greg Ward09fc5422000-03-10 01:49:26 +0000463 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000464
Greg Ward42406482000-09-27 02:08:14 +0000465 def link (self,
466 target_desc,
467 objects,
468 output_filename,
469 output_dir=None,
470 libraries=None,
471 library_dirs=None,
472 runtime_library_dirs=None,
473 export_symbols=None,
474 debug=0,
475 extra_preargs=None,
476 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000477 build_temp=None,
478 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000479
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000480 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000481 (objects, output_dir) = self._fix_object_args (objects, output_dir)
482 (libraries, library_dirs, runtime_library_dirs) = \
483 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
484
Greg Wardf70c6032000-04-19 02:16:49 +0000485 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000486 self.warn ("I don't know what to do with 'runtime_library_dirs': "
487 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000488
Greg Wardd03f88a2000-03-18 15:19:51 +0000489 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000490 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000491 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000492 if output_dir is not None:
493 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000494
Greg Ward32c4a8a2000-03-06 03:40:29 +0000495 if self._need_link (objects, output_filename):
496
Greg Ward42406482000-09-27 02:08:14 +0000497 if target_desc == CCompiler.EXECUTABLE:
498 if debug:
499 ldflags = self.ldflags_shared_debug[1:]
500 else:
501 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000502 else:
Greg Ward42406482000-09-27 02:08:14 +0000503 if debug:
504 ldflags = self.ldflags_shared_debug
505 else:
506 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000507
Greg Ward5299b6a2000-05-20 13:23:21 +0000508 export_opts = []
509 for sym in (export_symbols or []):
510 export_opts.append("/EXPORT:" + sym)
511
Fred Drakeb94b8492001-12-06 20:51:35 +0000512 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000513 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000514
Greg Ward159eb922000-08-02 00:00:30 +0000515 # The MSVC linker generates .lib and .exp files, which cannot be
516 # suppressed by any linker switches. The .lib files may even be
517 # needed! Make sure they are generated in the temporary build
518 # directory. Since they have different names for debug and release
519 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000520 if export_symbols is not None:
521 (dll_name, dll_ext) = os.path.splitext(
522 os.path.basename(output_filename))
523 implib_file = os.path.join(
524 os.path.dirname(objects[0]),
525 self.library_filename(dll_name))
526 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000527
Greg Ward32c4a8a2000-03-06 03:40:29 +0000528 if extra_preargs:
529 ld_args[:0] = extra_preargs
530 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000531 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000532
533 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000534 try:
Greg Ward42406482000-09-27 02:08:14 +0000535 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000536 except DistutilsExecError, msg:
537 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000538
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000539 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000540 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000541
Greg Ward42406482000-09-27 02:08:14 +0000542 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000543
544
Greg Ward32c4a8a2000-03-06 03:40:29 +0000545 # -- Miscellaneous methods -----------------------------------------
546 # These are all used by the 'gen_lib_options() function, in
547 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000548
549 def library_dir_option (self, dir):
550 return "/LIBPATH:" + dir
551
Greg Wardd03f88a2000-03-18 15:19:51 +0000552 def runtime_library_dir_option (self, dir):
553 raise DistutilsPlatformError, \
554 "don't know how to set runtime library search path for MSVC++"
555
Greg Wardc74138d1999-10-03 20:47:52 +0000556 def library_option (self, lib):
557 return self.library_filename (lib)
558
559
Greg Wardd1425642000-08-04 01:29:27 +0000560 def find_library_file (self, dirs, lib, debug=0):
561 # Prefer a debugging library if found (and requested), but deal
562 # with it if we don't have one.
563 if debug:
564 try_names = [lib + "_d", lib]
565 else:
566 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000567 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000568 for name in try_names:
569 libfile = os.path.join(dir, self.library_filename (name))
570 if os.path.exists(libfile):
571 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000572 else:
573 # Oops, didn't find it in *any* of 'dirs'
574 return None
575
576 # find_library_file ()
577
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000578 # Helper methods for using the MSVC registry settings
579
580 def find_exe(self, exe):
581 """Return path to an MSVC executable program.
582
583 Tries to find the program in several places: first, one of the
584 MSVC program search paths from the registry; next, the directories
585 in the PATH environment variable. If any of those work, return an
586 absolute path that is known to exist. If none of them work, just
587 return the original program name, 'exe'.
588 """
589
590 for p in self.__paths:
591 fn = os.path.join(os.path.abspath(p), exe)
592 if os.path.isfile(fn):
593 return fn
594
595 # didn't find it; try existing path
596 for p in string.split(os.environ['Path'],';'):
597 fn = os.path.join(os.path.abspath(p),exe)
598 if os.path.isfile(fn):
599 return fn
600
601 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000602
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000603 def get_msvc_paths(self, path, platform='x86'):
604 """Get a list of devstudio directories (include, lib or path).
605
606 Return a list of strings. The list will be empty if unable to
607 access the registry or appropriate registry keys not found.
608 """
609
610 if not _can_read_reg:
611 return []
612
613 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000614 if self.__version >= 7:
615 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
616 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000617 else:
618 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000619 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000620
621 for base in HKEYS:
622 d = read_values(base, key)
623 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000624 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000625 return string.split(self.__macros.sub(d[path]), ";")
626 else:
627 return string.split(d[path], ";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000628 # MSVC 6 seems to create the registry entries we need only when
629 # the GUI is run.
630 if self.__version == 6:
631 for base in HKEYS:
632 if read_values(base, r"%s\6.0" % self.__root) is not None:
633 self.warn("It seems you have Visual Studio 6 installed, "
634 "but the expected registry settings are not present.\n"
635 "You must at least run the Visual Studio GUI once "
636 "so that these entries are created.")
Trent Micke96b2292006-04-25 00:34:50 +0000637 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000638 return []
639
640 def set_path_env_var(self, name):
641 """Set environment variable 'name' to an MSVC path type value.
642
643 This is equivalent to a SET command prior to execution of spawned
644 commands.
645 """
646
647 if name == "lib":
648 p = self.get_msvc_paths("library")
649 else:
650 p = self.get_msvc_paths(name)
651 if p:
652 os.environ[name] = string.join(p, ';')
Christian Heimes3305c522007-12-03 13:47:29 +0000653
654
655if get_build_version() >= 8.0:
656 log.debug("Importing new compiler from distutils.msvc9compiler")
657 OldMSVCCompiler = MSVCCompiler
658 from distutils.msvc9compiler import MSVCCompiler
659 from distutils.msvc9compiler import get_build_architecture
660 from distutils.msvc9compiler import MacroExpander