blob: 1cd0f91d5f970feab24ebcc06c144ac9f129cbf1 [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
Greg Ward3ce77fd2000-03-02 01:49:45 +000011__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000012
Tarek Ziadé36797272010-07-22 12:50:05 +000013import sys, os
14from distutils.errors import \
15 DistutilsExecError, DistutilsPlatformError, \
16 CompileError, LibError, LinkError
17from distutils.ccompiler import \
18 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000019from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000020
Collin Winter5b7e9d72007-08-30 03:52:21 +000021_can_read_reg = False
Greg Ward7642f5c2000-03-31 16:47:40 +000022try:
Georg Brandl38feaf02008-05-25 07:45:51 +000023 import winreg
Greg Ward83c38702000-06-29 23:04:59 +000024
Collin Winter5b7e9d72007-08-30 03:52:21 +000025 _can_read_reg = True
Georg Brandl38feaf02008-05-25 07:45:51 +000026 hkey_mod = winreg
Greg Ward19ce1662000-03-31 19:04:25 +000027
Georg Brandl38feaf02008-05-25 07:45:51 +000028 RegOpenKeyEx = winreg.OpenKeyEx
29 RegEnumKey = winreg.EnumKey
30 RegEnumValue = winreg.EnumValue
31 RegError = winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000032
Greg Ward7642f5c2000-03-31 16:47:40 +000033except ImportError:
34 try:
35 import win32api
36 import win32con
Collin Winter5b7e9d72007-08-30 03:52:21 +000037 _can_read_reg = True
Greg Ward1027e3f2000-03-31 16:53:42 +000038 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000039
40 RegOpenKeyEx = win32api.RegOpenKeyEx
41 RegEnumKey = win32api.RegEnumKey
42 RegEnumValue = win32api.RegEnumValue
43 RegError = win32api.error
Greg Ward7642f5c2000-03-31 16:47:40 +000044 except ImportError:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000045 log.info("Warning: Can't read registry to find the "
46 "necessary compiler setting\n"
Georg Brandl38feaf02008-05-25 07:45:51 +000047 "Make sure that Python modules winreg, "
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000048 "win32api or win32con are installed.")
Greg Ward7642f5c2000-03-31 16:47:40 +000049 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000050
51if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000052 HKEYS = (hkey_mod.HKEY_USERS,
53 hkey_mod.HKEY_CURRENT_USER,
54 hkey_mod.HKEY_LOCAL_MACHINE,
55 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000056
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000057def read_keys(base, key):
58 """Return list of registry keys."""
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000059 try:
60 handle = RegOpenKeyEx(base, key)
61 except RegError:
62 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000063 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000064 i = 0
Collin Winter5b7e9d72007-08-30 03:52:21 +000065 while True:
Greg Ward1b9c6f72000-02-08 02:39:44 +000066 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000067 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000068 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000069 break
70 L.append(k)
Collin Winter5b7e9d72007-08-30 03:52:21 +000071 i += 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000072 return L
73
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000074def read_values(base, key):
75 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000076
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000077 All names are converted to lowercase.
78 """
79 try:
80 handle = RegOpenKeyEx(base, key)
81 except RegError:
82 return None
83 d = {}
84 i = 0
Collin Winter5b7e9d72007-08-30 03:52:21 +000085 while True:
Greg Ward1b9c6f72000-02-08 02:39:44 +000086 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000087 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000088 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000089 break
90 name = name.lower()
91 d[convert_mbcs(name)] = convert_mbcs(value)
Collin Winter5b7e9d72007-08-30 03:52:21 +000092 i += 1
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000093 return d
94
95def convert_mbcs(s):
Christian Heimesd157e692007-11-17 11:46:54 +000096 dec = getattr(s, "decode", None)
97 if dec is not None:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000098 try:
Christian Heimesd157e692007-11-17 11:46:54 +000099 s = dec("mbcs")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000100 except UnicodeError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000101 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000102 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000103
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000104class MacroExpander:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000105 def __init__(self, version):
106 self.macros = {}
107 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000108
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000109 def set_macro(self, macro, path, key):
110 for base in HKEYS:
111 d = read_values(base, path)
112 if d:
113 self.macros["$(%s)" % macro] = d[key]
114 break
Tim Peters182b5ac2004-07-18 06:16:08 +0000115
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000116 def load_macros(self, version):
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000117 vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000118 self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
119 self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
120 net = r"Software\Microsoft\.NETFramework"
121 self.set_macro("FrameworkDir", net, "installroot")
Tim Peters26be2062004-11-28 01:10:01 +0000122 try:
123 if version > 7.0:
124 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
125 else:
126 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
Tarek Ziadé36797272010-07-22 12:50:05 +0000127 except KeyError as exc: #
Collin Winter5b7e9d72007-08-30 03:52:21 +0000128 raise DistutilsPlatformError(
129 """Python was built with Visual Studio 2003;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000130extensions must be built with a compiler than can generate compatible binaries.
131Visual Studio 2003 was not found on this system. If you have Cygwin installed,
132you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000133
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000134 p = r"Software\Microsoft\NET Framework Setup\Product"
135 for base in HKEYS:
136 try:
137 h = RegOpenKeyEx(base, p)
138 except RegError:
139 continue
140 key = RegEnumKey(h, 0)
141 d = read_values(base, r"%s\%s" % (p, key))
142 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000143
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000144 def sub(self, s):
145 for k, v in self.macros.items():
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000146 s = s.replace(k, v)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000147 return s
Greg Ward69988092000-02-11 02:47:15 +0000148
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000149def get_build_version():
150 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000151
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000152 For Python 2.3 and up, the version number is included in
153 sys.version. For earlier versions, assume the compiler is MSVC 6.
154 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000155 prefix = "MSC v."
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000156 i = sys.version.find(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000157 if i == -1:
158 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000159 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000160 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000161 majorVersion = int(s[:-2]) - 6
162 minorVersion = int(s[2:3]) / 10.0
163 # I don't think paths are affected by minor version in version 6
164 if majorVersion == 6:
165 minorVersion = 0
166 if majorVersion >= 6:
167 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000168 # else we don't know what version of the compiler this is
169 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000170
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000171def get_build_architecture():
172 """Return the processor architecture.
173
174 Possible results are "Intel", "Itanium", or "AMD64".
175 """
176
177 prefix = " bit ("
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000178 i = sys.version.find(prefix)
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000179 if i == -1:
180 return "Intel"
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000181 j = sys.version.find(")", i)
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000182 return sys.version[i+len(prefix):j]
Tim Peters32cbc962006-02-20 21:42:18 +0000183
Guido van Rossumd8faa362007-04-27 19:54:29 +0000184def normalize_and_reduce_paths(paths):
185 """Return a list of normalized paths with duplicates removed.
186
187 The current order of paths is maintained.
188 """
189 # Paths are normalized so things like: /a and /a/ aren't both preserved.
190 reduced_paths = []
191 for p in paths:
192 np = os.path.normpath(p)
193 # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
194 if np not in reduced_paths:
195 reduced_paths.append(np)
196 return reduced_paths
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000197
Greg Warddbd12761999-08-29 18:15:07 +0000198
Collin Winter5b7e9d72007-08-30 03:52:21 +0000199class MSVCCompiler(CCompiler) :
Greg Ward3d50b901999-09-08 02:36:01 +0000200 """Concrete class that implements an interface to Microsoft Visual C++,
201 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000202
Greg Warddf178f91999-09-29 12:29:10 +0000203 compiler_type = 'msvc'
204
Greg Ward992c8f92000-06-25 02:31:16 +0000205 # Just set this so CCompiler's constructor doesn't barf. We currently
206 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
207 # as it really isn't necessary for this sort of single-compiler class.
208 # Would be nice to have a consistent interface with UnixCCompiler,
209 # though, so it's worth thinking about.
210 executables = {}
211
Greg Ward32c4a8a2000-03-06 03:40:29 +0000212 # Private class data (need to distinguish C from C++ source for compiler)
213 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000214 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000215 _rc_extensions = ['.rc']
216 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000217
218 # Needed for the filename generation methods provided by the
219 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000220 src_extensions = (_c_extensions + _cpp_extensions +
221 _rc_extensions + _mc_extensions)
222 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000223 obj_extension = '.obj'
224 static_lib_extension = '.lib'
225 shared_lib_extension = '.dll'
226 static_lib_format = shared_lib_format = '%s%s'
227 exe_extension = '.exe'
228
Collin Winter5b7e9d72007-08-30 03:52:21 +0000229 def __init__(self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000230 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000231 self.__version = get_build_version()
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000232 self.__arch = get_build_architecture()
233 if self.__arch == "Intel":
234 # x86
235 if self.__version >= 7:
236 self.__root = r"Software\Microsoft\VisualStudio"
237 self.__macros = MacroExpander(self.__version)
238 else:
239 self.__root = r"Software\Microsoft\Devstudio"
240 self.__product = "Visual Studio version %s" % self.__version
Greg Ward69988092000-02-11 02:47:15 +0000241 else:
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000242 # Win64. Assume this was built with the platform SDK
243 self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
Tim Peters32cbc962006-02-20 21:42:18 +0000244
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000245 self.initialized = False
246
247 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000248 self.__paths = []
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000249 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 +0000250 # Assume that the SDK set up everything alright; don't try to be
251 # smarter
252 self.cc = "cl.exe"
253 self.linker = "link.exe"
254 self.lib = "lib.exe"
255 self.rc = "rc.exe"
256 self.mc = "mc.exe"
257 else:
258 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000259
Collin Winter5b7e9d72007-08-30 03:52:21 +0000260 if len(self.__paths) == 0:
261 raise DistutilsPlatformError("Python was built with %s, "
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000262 "and extensions need to be built with the same "
Collin Winter5b7e9d72007-08-30 03:52:21 +0000263 "version of the compiler, but it isn't installed."
264 % self.__product)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000265
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000266 self.cc = self.find_exe("cl.exe")
267 self.linker = self.find_exe("link.exe")
268 self.lib = self.find_exe("lib.exe")
269 self.rc = self.find_exe("rc.exe") # resource compiler
270 self.mc = self.find_exe("mc.exe") # message compiler
271 self.set_path_env_var('lib')
272 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000273
274 # extend the MSVC path with the current path
275 try:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000276 for p in os.environ['path'].split(';'):
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000277 self.__paths.append(p)
278 except KeyError:
279 pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000280 self.__paths = normalize_and_reduce_paths(self.__paths)
281 os.environ['path'] = ";".join(self.__paths)
Greg Ward69988092000-02-11 02:47:15 +0000282
Greg Warddbd12761999-08-29 18:15:07 +0000283 self.preprocess_options = None
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000284 if self.__arch == "Intel":
285 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
286 '/DNDEBUG']
287 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
288 '/Z7', '/D_DEBUG']
289 else:
290 # Win64
291 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
292 '/DNDEBUG']
293 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
Tim Peters32cbc962006-02-20 21:42:18 +0000294 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000295
Greg Ward1b9c6f72000-02-08 02:39:44 +0000296 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000297 if self.__version >= 7:
298 self.ldflags_shared_debug = [
299 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
300 ]
301 else:
302 self.ldflags_shared_debug = [
303 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
304 ]
Greg Warddbd12761999-08-29 18:15:07 +0000305 self.ldflags_static = [ '/nologo']
306
Tim Petersa733bd92005-03-12 19:05:58 +0000307 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000308
309 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000310
Collin Winter5b7e9d72007-08-30 03:52:21 +0000311 def object_filenames(self,
312 source_filenames,
313 strip_dir=0,
314 output_dir=''):
Greg Ward9c0ea132000-09-19 23:56:43 +0000315 # Copied from ccompiler.py, extended to return .res as 'object'-file
316 # for .rc input file
317 if output_dir is None: output_dir = ''
318 obj_names = []
319 for src_name in source_filenames:
320 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000321 base = os.path.splitdrive(base)[1] # Chop off the drive
322 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000323 if ext not in self.src_extensions:
324 # Better to raise an exception instead of silently continuing
325 # and later complain about sources and targets having
326 # different lengths
327 raise CompileError ("Don't know how to compile %s" % src_name)
328 if strip_dir:
329 base = os.path.basename (base)
330 if ext in self._rc_extensions:
331 obj_names.append (os.path.join (output_dir,
332 base + self.res_extension))
333 elif ext in self._mc_extensions:
334 obj_names.append (os.path.join (output_dir,
335 base + self.res_extension))
336 else:
337 obj_names.append (os.path.join (output_dir,
338 base + self.obj_extension))
339 return obj_names
340
Greg Ward9c0ea132000-09-19 23:56:43 +0000341
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000342 def compile(self, sources,
343 output_dir=None, macros=None, include_dirs=None, debug=0,
344 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000345
Collin Winter5b7e9d72007-08-30 03:52:21 +0000346 if not self.initialized:
347 self.initialize()
348 compile_info = self._setup_compile(output_dir, macros, include_dirs,
349 sources, depends, extra_postargs)
350 macros, objects, extra_postargs, pp_opts, build = compile_info
Greg Warddbd12761999-08-29 18:15:07 +0000351
Greg Ward32c4a8a2000-03-06 03:40:29 +0000352 compile_opts = extra_preargs or []
353 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000354 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000355 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000356 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000357 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000358
Thomas Heller9436a752003-12-05 20:12:23 +0000359 for obj in objects:
360 try:
361 src, ext = build[obj]
362 except KeyError:
363 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000364 if debug:
365 # pass the full pathname to MSVC in debug mode,
366 # this allows the debugger to find the source file
367 # without asking the user to browse for it
368 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000369
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000370 if ext in self._c_extensions:
371 input_opt = "/Tc" + src
372 elif ext in self._cpp_extensions:
373 input_opt = "/Tp" + src
374 elif ext in self._rc_extensions:
375 # compile .RC to .RES file
376 input_opt = src
377 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000378 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000379 self.spawn([self.rc] + pp_opts +
380 [output_opt] + [input_opt])
Guido van Rossumb940e112007-01-10 16:19:56 +0000381 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000382 raise CompileError(msg)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000383 continue
384 elif ext in self._mc_extensions:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000385 # Compile .MC to .RC file to .RES file.
386 # * '-h dir' specifies the directory for the
387 # generated include file
388 # * '-r dir' specifies the target directory of the
389 # generated RC file and the binary message resource
390 # it includes
391 #
392 # For now (since there are no options to change this),
393 # we use the source-directory for the include file and
394 # the build directory for the RC file and message
395 # resources. This works at least for win32all.
Collin Winter5b7e9d72007-08-30 03:52:21 +0000396 h_dir = os.path.dirname(src)
397 rc_dir = os.path.dirname(obj)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000398 try:
399 # first compile .MC to .RC and .H file
Collin Winter5b7e9d72007-08-30 03:52:21 +0000400 self.spawn([self.mc] +
401 ['-h', h_dir, '-r', rc_dir] + [src])
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000402 base, _ = os.path.splitext (os.path.basename (src))
403 rc_file = os.path.join (rc_dir, base + '.rc')
404 # then compile .RC to .RES file
Collin Winter5b7e9d72007-08-30 03:52:21 +0000405 self.spawn([self.rc] +
406 ["/fo" + obj] + [rc_file])
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000407
Guido van Rossumb940e112007-01-10 16:19:56 +0000408 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000409 raise CompileError(msg)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000410 continue
411 else:
412 # how to handle this file?
Collin Winter5b7e9d72007-08-30 03:52:21 +0000413 raise CompileError("Don't know how to compile %s to %s"
414 % (src, obj))
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000415
416 output_opt = "/Fo" + obj
417 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000418 self.spawn([self.cc] + compile_opts + pp_opts +
419 [input_opt, output_opt] +
420 extra_postargs)
Guido van Rossumb940e112007-01-10 16:19:56 +0000421 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000422 raise CompileError(msg)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000423
Greg Ward32c4a8a2000-03-06 03:40:29 +0000424 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000425
Greg Ward3d50b901999-09-08 02:36:01 +0000426
Collin Winter5b7e9d72007-08-30 03:52:21 +0000427 def create_static_lib(self,
428 objects,
429 output_libname,
430 output_dir=None,
431 debug=0,
432 target_lang=None):
Greg Ward3d50b901999-09-08 02:36:01 +0000433
Collin Winter5b7e9d72007-08-30 03:52:21 +0000434 if not self.initialized:
435 self.initialize()
436 (objects, output_dir) = self._fix_object_args(objects, output_dir)
437 output_filename = self.library_filename(output_libname,
438 output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000439
Collin Winter5b7e9d72007-08-30 03:52:21 +0000440 if self._need_link(objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000441 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000442 if debug:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000443 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000444 try:
Collin Winterfd519752007-08-30 18:46:25 +0000445 self.spawn([self.lib] + lib_args)
Guido van Rossumb940e112007-01-10 16:19:56 +0000446 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000447 raise LibError(msg)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000448 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000449 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000450
Fred Drakeb94b8492001-12-06 20:51:35 +0000451
Collin Winter5b7e9d72007-08-30 03:52:21 +0000452 def link(self,
453 target_desc,
454 objects,
455 output_filename,
456 output_dir=None,
457 libraries=None,
458 library_dirs=None,
459 runtime_library_dirs=None,
460 export_symbols=None,
461 debug=0,
462 extra_preargs=None,
463 extra_postargs=None,
464 build_temp=None,
465 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000466
Collin Winter5b7e9d72007-08-30 03:52:21 +0000467 if not self.initialized:
468 self.initialize()
469 (objects, output_dir) = self._fix_object_args(objects, output_dir)
470 fixed_args = self._fix_lib_args(libraries, library_dirs,
471 runtime_library_dirs)
472 (libraries, library_dirs, runtime_library_dirs) = fixed_args
Greg Ward2f557a22000-03-26 21:42:28 +0000473
Greg Wardf70c6032000-04-19 02:16:49 +0000474 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000475 self.warn ("I don't know what to do with 'runtime_library_dirs': "
476 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000477
Collin Winter5b7e9d72007-08-30 03:52:21 +0000478 lib_opts = gen_lib_options(self,
479 library_dirs, runtime_library_dirs,
480 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000481 if output_dir is not None:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000482 output_filename = os.path.join(output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000483
Collin Winter5b7e9d72007-08-30 03:52:21 +0000484 if self._need_link(objects, output_filename):
Greg Ward42406482000-09-27 02:08:14 +0000485 if target_desc == CCompiler.EXECUTABLE:
486 if debug:
487 ldflags = self.ldflags_shared_debug[1:]
488 else:
489 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000490 else:
Greg Ward42406482000-09-27 02:08:14 +0000491 if debug:
492 ldflags = self.ldflags_shared_debug
493 else:
494 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000495
Greg Ward5299b6a2000-05-20 13:23:21 +0000496 export_opts = []
497 for sym in (export_symbols or []):
498 export_opts.append("/EXPORT:" + sym)
499
Fred Drakeb94b8492001-12-06 20:51:35 +0000500 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000501 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000502
Greg Ward159eb922000-08-02 00:00:30 +0000503 # The MSVC linker generates .lib and .exp files, which cannot be
504 # suppressed by any linker switches. The .lib files may even be
505 # needed! Make sure they are generated in the temporary build
506 # directory. Since they have different names for debug and release
507 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000508 if export_symbols is not None:
509 (dll_name, dll_ext) = os.path.splitext(
510 os.path.basename(output_filename))
511 implib_file = os.path.join(
512 os.path.dirname(objects[0]),
513 self.library_filename(dll_name))
514 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000515
Greg Ward32c4a8a2000-03-06 03:40:29 +0000516 if extra_preargs:
517 ld_args[:0] = extra_preargs
518 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000519 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000520
Collin Winter5b7e9d72007-08-30 03:52:21 +0000521 self.mkpath(os.path.dirname(output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000522 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000523 self.spawn([self.linker] + ld_args)
Guido van Rossumb940e112007-01-10 16:19:56 +0000524 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000525 raise LinkError(msg)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000526
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000527 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000528 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000529
Greg Wardf70c6032000-04-19 02:16:49 +0000530
Greg Ward32c4a8a2000-03-06 03:40:29 +0000531 # -- Miscellaneous methods -----------------------------------------
532 # These are all used by the 'gen_lib_options() function, in
533 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000534
Collin Winter5b7e9d72007-08-30 03:52:21 +0000535 def library_dir_option(self, dir):
Greg Wardc74138d1999-10-03 20:47:52 +0000536 return "/LIBPATH:" + dir
537
Collin Winter5b7e9d72007-08-30 03:52:21 +0000538 def runtime_library_dir_option(self, dir):
539 raise DistutilsPlatformError(
540 "don't know how to set runtime library search path for MSVC++")
Greg Wardd03f88a2000-03-18 15:19:51 +0000541
Collin Winter5b7e9d72007-08-30 03:52:21 +0000542 def library_option(self, lib):
543 return self.library_filename(lib)
Greg Wardc74138d1999-10-03 20:47:52 +0000544
545
Collin Winter5b7e9d72007-08-30 03:52:21 +0000546 def find_library_file(self, dirs, lib, debug=0):
Greg Wardd1425642000-08-04 01:29:27 +0000547 # Prefer a debugging library if found (and requested), but deal
548 # with it if we don't have one.
549 if debug:
550 try_names = [lib + "_d", lib]
551 else:
552 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000553 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000554 for name in try_names:
555 libfile = os.path.join(dir, self.library_filename (name))
556 if os.path.exists(libfile):
557 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000558 else:
559 # Oops, didn't find it in *any* of 'dirs'
560 return None
561
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000562 # Helper methods for using the MSVC registry settings
563
564 def find_exe(self, exe):
565 """Return path to an MSVC executable program.
566
567 Tries to find the program in several places: first, one of the
568 MSVC program search paths from the registry; next, the directories
569 in the PATH environment variable. If any of those work, return an
570 absolute path that is known to exist. If none of them work, just
571 return the original program name, 'exe'.
572 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000573 for p in self.__paths:
574 fn = os.path.join(os.path.abspath(p), exe)
575 if os.path.isfile(fn):
576 return fn
577
578 # didn't find it; try existing path
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000579 for p in os.environ['Path'].split(';'):
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000580 fn = os.path.join(os.path.abspath(p),exe)
581 if os.path.isfile(fn):
582 return fn
583
584 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000585
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000586 def get_msvc_paths(self, path, platform='x86'):
587 """Get a list of devstudio directories (include, lib or path).
588
589 Return a list of strings. The list will be empty if unable to
590 access the registry or appropriate registry keys not found.
591 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000592 if not _can_read_reg:
593 return []
594
595 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000596 if self.__version >= 7:
597 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
598 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000599 else:
600 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000601 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000602
603 for base in HKEYS:
604 d = read_values(base, key)
605 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000606 if self.__version >= 7:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000607 return self.__macros.sub(d[path]).split(";")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000608 else:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000609 return d[path].split(";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000610 # MSVC 6 seems to create the registry entries we need only when
611 # the GUI is run.
612 if self.__version == 6:
613 for base in HKEYS:
614 if read_values(base, r"%s\6.0" % self.__root) is not None:
615 self.warn("It seems you have Visual Studio 6 installed, "
616 "but the expected registry settings are not present.\n"
617 "You must at least run the Visual Studio GUI once "
618 "so that these entries are created.")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000620 return []
621
622 def set_path_env_var(self, name):
623 """Set environment variable 'name' to an MSVC path type value.
624
625 This is equivalent to a SET command prior to execution of spawned
626 commands.
627 """
628
629 if name == "lib":
630 p = self.get_msvc_paths("library")
631 else:
632 p = self.get_msvc_paths(name)
633 if p:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000634 os.environ[name] = ';'.join(p)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000635
636
637if get_build_version() >= 8.0:
638 log.debug("Importing new compiler from distutils.msvc9compiler")
639 OldMSVCCompiler = MSVCCompiler
640 from distutils.msvc9compiler import MSVCCompiler
Christian Heimes5e696852008-04-09 08:37:03 +0000641 # get_build_architecture not really relevant now we support cross-compile
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000642 from distutils.msvc9compiler import MacroExpander