blob: d1de2fbfcb947be5e4f72df19c3a93f3da37cc1e [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
Tarek Ziadé36797272010-07-22 12:50:05 +000011import sys, os
12from distutils.errors import \
13 DistutilsExecError, DistutilsPlatformError, \
14 CompileError, LibError, LinkError
15from distutils.ccompiler import \
16 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000017from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000018
Collin Winter5b7e9d72007-08-30 03:52:21 +000019_can_read_reg = False
Greg Ward7642f5c2000-03-31 16:47:40 +000020try:
Georg Brandl38feaf02008-05-25 07:45:51 +000021 import winreg
Greg Ward83c38702000-06-29 23:04:59 +000022
Collin Winter5b7e9d72007-08-30 03:52:21 +000023 _can_read_reg = True
Georg Brandl38feaf02008-05-25 07:45:51 +000024 hkey_mod = winreg
Greg Ward19ce1662000-03-31 19:04:25 +000025
Georg Brandl38feaf02008-05-25 07:45:51 +000026 RegOpenKeyEx = winreg.OpenKeyEx
27 RegEnumKey = winreg.EnumKey
28 RegEnumValue = winreg.EnumValue
29 RegError = winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000030
Brett Cannoncd171c82013-07-04 17:43:24 -040031except ImportError:
Greg Ward7642f5c2000-03-31 16:47:40 +000032 try:
33 import win32api
34 import win32con
Collin Winter5b7e9d72007-08-30 03:52:21 +000035 _can_read_reg = True
Greg Ward1027e3f2000-03-31 16:53:42 +000036 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000037
38 RegOpenKeyEx = win32api.RegOpenKeyEx
39 RegEnumKey = win32api.RegEnumKey
40 RegEnumValue = win32api.RegEnumValue
41 RegError = win32api.error
Brett Cannoncd171c82013-07-04 17:43:24 -040042 except ImportError:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000043 log.info("Warning: Can't read registry to find the "
44 "necessary compiler setting\n"
Georg Brandl38feaf02008-05-25 07:45:51 +000045 "Make sure that Python modules winreg, "
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000046 "win32api or win32con are installed.")
Greg Ward7642f5c2000-03-31 16:47:40 +000047 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000048
49if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000050 HKEYS = (hkey_mod.HKEY_USERS,
51 hkey_mod.HKEY_CURRENT_USER,
52 hkey_mod.HKEY_LOCAL_MACHINE,
53 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000054
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000055def read_keys(base, key):
56 """Return list of registry keys."""
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000057 try:
58 handle = RegOpenKeyEx(base, key)
59 except RegError:
60 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000061 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000062 i = 0
Collin Winter5b7e9d72007-08-30 03:52:21 +000063 while True:
Greg Ward1b9c6f72000-02-08 02:39:44 +000064 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000065 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000066 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000067 break
68 L.append(k)
Collin Winter5b7e9d72007-08-30 03:52:21 +000069 i += 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000070 return L
71
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000072def read_values(base, key):
73 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000074
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000075 All names are converted to lowercase.
76 """
77 try:
78 handle = RegOpenKeyEx(base, key)
79 except RegError:
80 return None
81 d = {}
82 i = 0
Collin Winter5b7e9d72007-08-30 03:52:21 +000083 while True:
Greg Ward1b9c6f72000-02-08 02:39:44 +000084 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000085 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000086 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000087 break
88 name = name.lower()
89 d[convert_mbcs(name)] = convert_mbcs(value)
Collin Winter5b7e9d72007-08-30 03:52:21 +000090 i += 1
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000091 return d
92
93def convert_mbcs(s):
Christian Heimesd157e692007-11-17 11:46:54 +000094 dec = getattr(s, "decode", None)
95 if dec is not None:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000096 try:
Christian Heimesd157e692007-11-17 11:46:54 +000097 s = dec("mbcs")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000098 except UnicodeError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000099 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000100 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000101
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000102class MacroExpander:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000103 def __init__(self, version):
104 self.macros = {}
105 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000106
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000107 def set_macro(self, macro, path, key):
108 for base in HKEYS:
109 d = read_values(base, path)
110 if d:
111 self.macros["$(%s)" % macro] = d[key]
112 break
Tim Peters182b5ac2004-07-18 06:16:08 +0000113
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000114 def load_macros(self, version):
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000115 vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000116 self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
117 self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
118 net = r"Software\Microsoft\.NETFramework"
119 self.set_macro("FrameworkDir", net, "installroot")
Tim Peters26be2062004-11-28 01:10:01 +0000120 try:
121 if version > 7.0:
122 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
123 else:
124 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
Tarek Ziadé36797272010-07-22 12:50:05 +0000125 except KeyError as exc: #
Collin Winter5b7e9d72007-08-30 03:52:21 +0000126 raise DistutilsPlatformError(
127 """Python was built with Visual Studio 2003;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000128extensions must be built with a compiler than can generate compatible binaries.
129Visual Studio 2003 was not found on this system. If you have Cygwin installed,
130you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000131
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000132 p = r"Software\Microsoft\NET Framework Setup\Product"
133 for base in HKEYS:
134 try:
135 h = RegOpenKeyEx(base, p)
136 except RegError:
137 continue
138 key = RegEnumKey(h, 0)
139 d = read_values(base, r"%s\%s" % (p, key))
140 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000141
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000142 def sub(self, s):
143 for k, v in self.macros.items():
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000144 s = s.replace(k, v)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000145 return s
Greg Ward69988092000-02-11 02:47:15 +0000146
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000147def get_build_version():
148 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000149
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000150 For Python 2.3 and up, the version number is included in
151 sys.version. For earlier versions, assume the compiler is MSVC 6.
152 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000153 prefix = "MSC v."
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000154 i = sys.version.find(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000155 if i == -1:
156 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000157 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000158 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000159 majorVersion = int(s[:-2]) - 6
Steve Dower65e4cb12014-11-22 12:54:57 -0800160 if majorVersion >= 13:
161 # v13 was skipped and should be v14
162 majorVersion += 1
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000163 minorVersion = int(s[2:3]) / 10.0
164 # I don't think paths are affected by minor version in version 6
165 if majorVersion == 6:
166 minorVersion = 0
167 if majorVersion >= 6:
168 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000169 # else we don't know what version of the compiler this is
170 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000171
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000172def get_build_architecture():
173 """Return the processor architecture.
174
Zachary Ware49ce74e2017-09-06 15:45:25 -0700175 Possible results are "Intel" or "AMD64".
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000176 """
177
178 prefix = " bit ("
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000179 i = sys.version.find(prefix)
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000180 if i == -1:
181 return "Intel"
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000182 j = sys.version.find(")", i)
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000183 return sys.version[i+len(prefix):j]
Tim Peters32cbc962006-02-20 21:42:18 +0000184
Guido van Rossumd8faa362007-04-27 19:54:29 +0000185def normalize_and_reduce_paths(paths):
186 """Return a list of normalized paths with duplicates removed.
187
188 The current order of paths is maintained.
189 """
190 # Paths are normalized so things like: /a and /a/ aren't both preserved.
191 reduced_paths = []
192 for p in paths:
193 np = os.path.normpath(p)
194 # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
195 if np not in reduced_paths:
196 reduced_paths.append(np)
197 return reduced_paths
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000198
Greg Warddbd12761999-08-29 18:15:07 +0000199
Collin Winter5b7e9d72007-08-30 03:52:21 +0000200class MSVCCompiler(CCompiler) :
Greg Ward3d50b901999-09-08 02:36:01 +0000201 """Concrete class that implements an interface to Microsoft Visual C++,
202 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000203
Greg Warddf178f91999-09-29 12:29:10 +0000204 compiler_type = 'msvc'
205
Greg Ward992c8f92000-06-25 02:31:16 +0000206 # Just set this so CCompiler's constructor doesn't barf. We currently
207 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
208 # as it really isn't necessary for this sort of single-compiler class.
209 # Would be nice to have a consistent interface with UnixCCompiler,
210 # though, so it's worth thinking about.
211 executables = {}
212
Greg Ward32c4a8a2000-03-06 03:40:29 +0000213 # Private class data (need to distinguish C from C++ source for compiler)
214 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000215 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000216 _rc_extensions = ['.rc']
217 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000218
219 # Needed for the filename generation methods provided by the
220 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000221 src_extensions = (_c_extensions + _cpp_extensions +
222 _rc_extensions + _mc_extensions)
223 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000224 obj_extension = '.obj'
225 static_lib_extension = '.lib'
226 shared_lib_extension = '.dll'
227 static_lib_format = shared_lib_format = '%s%s'
228 exe_extension = '.exe'
229
Collin Winter5b7e9d72007-08-30 03:52:21 +0000230 def __init__(self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000231 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000232 self.__version = get_build_version()
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000233 self.__arch = get_build_architecture()
234 if self.__arch == "Intel":
235 # x86
236 if self.__version >= 7:
237 self.__root = r"Software\Microsoft\VisualStudio"
238 self.__macros = MacroExpander(self.__version)
239 else:
240 self.__root = r"Software\Microsoft\Devstudio"
241 self.__product = "Visual Studio version %s" % self.__version
Greg Ward69988092000-02-11 02:47:15 +0000242 else:
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000243 # Win64. Assume this was built with the platform SDK
244 self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
Tim Peters32cbc962006-02-20 21:42:18 +0000245
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000246 self.initialized = False
247
248 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000249 self.__paths = []
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000250 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 +0000251 # Assume that the SDK set up everything alright; don't try to be
252 # smarter
253 self.cc = "cl.exe"
254 self.linker = "link.exe"
255 self.lib = "lib.exe"
256 self.rc = "rc.exe"
257 self.mc = "mc.exe"
258 else:
259 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000260
Collin Winter5b7e9d72007-08-30 03:52:21 +0000261 if len(self.__paths) == 0:
262 raise DistutilsPlatformError("Python was built with %s, "
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000263 "and extensions need to be built with the same "
Collin Winter5b7e9d72007-08-30 03:52:21 +0000264 "version of the compiler, but it isn't installed."
265 % self.__product)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000266
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000267 self.cc = self.find_exe("cl.exe")
268 self.linker = self.find_exe("link.exe")
269 self.lib = self.find_exe("lib.exe")
270 self.rc = self.find_exe("rc.exe") # resource compiler
271 self.mc = self.find_exe("mc.exe") # message compiler
272 self.set_path_env_var('lib')
273 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000274
275 # extend the MSVC path with the current path
276 try:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000277 for p in os.environ['path'].split(';'):
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000278 self.__paths.append(p)
279 except KeyError:
280 pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000281 self.__paths = normalize_and_reduce_paths(self.__paths)
282 os.environ['path'] = ";".join(self.__paths)
Greg Ward69988092000-02-11 02:47:15 +0000283
Greg Warddbd12761999-08-29 18:15:07 +0000284 self.preprocess_options = None
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000285 if self.__arch == "Intel":
286 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
287 '/DNDEBUG']
288 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
289 '/Z7', '/D_DEBUG']
290 else:
291 # Win64
292 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
293 '/DNDEBUG']
294 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
Tim Peters32cbc962006-02-20 21:42:18 +0000295 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000296
Greg Ward1b9c6f72000-02-08 02:39:44 +0000297 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000298 if self.__version >= 7:
299 self.ldflags_shared_debug = [
300 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
301 ]
302 else:
303 self.ldflags_shared_debug = [
304 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
305 ]
Greg Warddbd12761999-08-29 18:15:07 +0000306 self.ldflags_static = [ '/nologo']
307
Tim Petersa733bd92005-03-12 19:05:58 +0000308 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000309
310 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000311
Collin Winter5b7e9d72007-08-30 03:52:21 +0000312 def object_filenames(self,
313 source_filenames,
314 strip_dir=0,
315 output_dir=''):
Greg Ward9c0ea132000-09-19 23:56:43 +0000316 # Copied from ccompiler.py, extended to return .res as 'object'-file
317 # for .rc input file
318 if output_dir is None: output_dir = ''
319 obj_names = []
320 for src_name in source_filenames:
321 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000322 base = os.path.splitdrive(base)[1] # Chop off the drive
323 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000324 if ext not in self.src_extensions:
325 # Better to raise an exception instead of silently continuing
326 # and later complain about sources and targets having
327 # different lengths
328 raise CompileError ("Don't know how to compile %s" % src_name)
329 if strip_dir:
330 base = os.path.basename (base)
331 if ext in self._rc_extensions:
332 obj_names.append (os.path.join (output_dir,
333 base + self.res_extension))
334 elif ext in self._mc_extensions:
335 obj_names.append (os.path.join (output_dir,
336 base + self.res_extension))
337 else:
338 obj_names.append (os.path.join (output_dir,
339 base + self.obj_extension))
340 return obj_names
341
Greg Ward9c0ea132000-09-19 23:56:43 +0000342
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000343 def compile(self, sources,
344 output_dir=None, macros=None, include_dirs=None, debug=0,
345 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000346
Collin Winter5b7e9d72007-08-30 03:52:21 +0000347 if not self.initialized:
348 self.initialize()
349 compile_info = self._setup_compile(output_dir, macros, include_dirs,
350 sources, depends, extra_postargs)
351 macros, objects, extra_postargs, pp_opts, build = compile_info
Greg Warddbd12761999-08-29 18:15:07 +0000352
Greg Ward32c4a8a2000-03-06 03:40:29 +0000353 compile_opts = extra_preargs or []
354 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000355 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000356 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000357 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000358 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000359
Thomas Heller9436a752003-12-05 20:12:23 +0000360 for obj in objects:
361 try:
362 src, ext = build[obj]
363 except KeyError:
364 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000365 if debug:
366 # pass the full pathname to MSVC in debug mode,
367 # this allows the debugger to find the source file
368 # without asking the user to browse for it
369 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000370
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000371 if ext in self._c_extensions:
372 input_opt = "/Tc" + src
373 elif ext in self._cpp_extensions:
374 input_opt = "/Tp" + src
375 elif ext in self._rc_extensions:
376 # compile .RC to .RES file
377 input_opt = src
378 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000379 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000380 self.spawn([self.rc] + pp_opts +
381 [output_opt] + [input_opt])
Guido van Rossumb940e112007-01-10 16:19:56 +0000382 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000383 raise CompileError(msg)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000384 continue
385 elif ext in self._mc_extensions:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000386 # Compile .MC to .RC file to .RES file.
387 # * '-h dir' specifies the directory for the
388 # generated include file
389 # * '-r dir' specifies the target directory of the
390 # generated RC file and the binary message resource
391 # it includes
392 #
393 # For now (since there are no options to change this),
394 # we use the source-directory for the include file and
395 # the build directory for the RC file and message
396 # resources. This works at least for win32all.
Collin Winter5b7e9d72007-08-30 03:52:21 +0000397 h_dir = os.path.dirname(src)
398 rc_dir = os.path.dirname(obj)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000399 try:
400 # first compile .MC to .RC and .H file
Collin Winter5b7e9d72007-08-30 03:52:21 +0000401 self.spawn([self.mc] +
402 ['-h', h_dir, '-r', rc_dir] + [src])
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000403 base, _ = os.path.splitext (os.path.basename (src))
404 rc_file = os.path.join (rc_dir, base + '.rc')
405 # then compile .RC to .RES file
Collin Winter5b7e9d72007-08-30 03:52:21 +0000406 self.spawn([self.rc] +
407 ["/fo" + obj] + [rc_file])
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000408
Guido van Rossumb940e112007-01-10 16:19:56 +0000409 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000410 raise CompileError(msg)
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000411 continue
412 else:
413 # how to handle this file?
Collin Winter5b7e9d72007-08-30 03:52:21 +0000414 raise CompileError("Don't know how to compile %s to %s"
415 % (src, obj))
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000416
417 output_opt = "/Fo" + obj
418 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000419 self.spawn([self.cc] + compile_opts + pp_opts +
420 [input_opt, output_opt] +
421 extra_postargs)
Guido van Rossumb940e112007-01-10 16:19:56 +0000422 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000423 raise CompileError(msg)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000424
Greg Ward32c4a8a2000-03-06 03:40:29 +0000425 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000426
Greg Ward3d50b901999-09-08 02:36:01 +0000427
Collin Winter5b7e9d72007-08-30 03:52:21 +0000428 def create_static_lib(self,
429 objects,
430 output_libname,
431 output_dir=None,
432 debug=0,
433 target_lang=None):
Greg Ward3d50b901999-09-08 02:36:01 +0000434
Collin Winter5b7e9d72007-08-30 03:52:21 +0000435 if not self.initialized:
436 self.initialize()
437 (objects, output_dir) = self._fix_object_args(objects, output_dir)
438 output_filename = self.library_filename(output_libname,
439 output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000440
Collin Winter5b7e9d72007-08-30 03:52:21 +0000441 if self._need_link(objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000442 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000443 if debug:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000444 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000445 try:
Collin Winterfd519752007-08-30 18:46:25 +0000446 self.spawn([self.lib] + lib_args)
Guido van Rossumb940e112007-01-10 16:19:56 +0000447 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000448 raise LibError(msg)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000449 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000450 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000451
Fred Drakeb94b8492001-12-06 20:51:35 +0000452
Collin Winter5b7e9d72007-08-30 03:52:21 +0000453 def link(self,
454 target_desc,
455 objects,
456 output_filename,
457 output_dir=None,
458 libraries=None,
459 library_dirs=None,
460 runtime_library_dirs=None,
461 export_symbols=None,
462 debug=0,
463 extra_preargs=None,
464 extra_postargs=None,
465 build_temp=None,
466 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000467
Collin Winter5b7e9d72007-08-30 03:52:21 +0000468 if not self.initialized:
469 self.initialize()
470 (objects, output_dir) = self._fix_object_args(objects, output_dir)
471 fixed_args = self._fix_lib_args(libraries, library_dirs,
472 runtime_library_dirs)
473 (libraries, library_dirs, runtime_library_dirs) = fixed_args
Greg Ward2f557a22000-03-26 21:42:28 +0000474
Greg Wardf70c6032000-04-19 02:16:49 +0000475 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000476 self.warn ("I don't know what to do with 'runtime_library_dirs': "
477 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000478
Collin Winter5b7e9d72007-08-30 03:52:21 +0000479 lib_opts = gen_lib_options(self,
480 library_dirs, runtime_library_dirs,
481 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000482 if output_dir is not None:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000483 output_filename = os.path.join(output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000484
Collin Winter5b7e9d72007-08-30 03:52:21 +0000485 if self._need_link(objects, output_filename):
Greg Ward42406482000-09-27 02:08:14 +0000486 if target_desc == CCompiler.EXECUTABLE:
487 if debug:
488 ldflags = self.ldflags_shared_debug[1:]
489 else:
490 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000491 else:
Greg Ward42406482000-09-27 02:08:14 +0000492 if debug:
493 ldflags = self.ldflags_shared_debug
494 else:
495 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000496
Greg Ward5299b6a2000-05-20 13:23:21 +0000497 export_opts = []
498 for sym in (export_symbols or []):
499 export_opts.append("/EXPORT:" + sym)
500
Fred Drakeb94b8492001-12-06 20:51:35 +0000501 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000502 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000503
Greg Ward159eb922000-08-02 00:00:30 +0000504 # The MSVC linker generates .lib and .exp files, which cannot be
505 # suppressed by any linker switches. The .lib files may even be
506 # needed! Make sure they are generated in the temporary build
507 # directory. Since they have different names for debug and release
508 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000509 if export_symbols is not None:
510 (dll_name, dll_ext) = os.path.splitext(
511 os.path.basename(output_filename))
512 implib_file = os.path.join(
513 os.path.dirname(objects[0]),
514 self.library_filename(dll_name))
515 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000516
Greg Ward32c4a8a2000-03-06 03:40:29 +0000517 if extra_preargs:
518 ld_args[:0] = extra_preargs
519 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000520 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000521
Collin Winter5b7e9d72007-08-30 03:52:21 +0000522 self.mkpath(os.path.dirname(output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000523 try:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000524 self.spawn([self.linker] + ld_args)
Guido van Rossumb940e112007-01-10 16:19:56 +0000525 except DistutilsExecError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000526 raise LinkError(msg)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000527
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000528 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000529 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000530
Greg Wardf70c6032000-04-19 02:16:49 +0000531
Greg Ward32c4a8a2000-03-06 03:40:29 +0000532 # -- Miscellaneous methods -----------------------------------------
533 # These are all used by the 'gen_lib_options() function, in
534 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000535
Collin Winter5b7e9d72007-08-30 03:52:21 +0000536 def library_dir_option(self, dir):
Greg Wardc74138d1999-10-03 20:47:52 +0000537 return "/LIBPATH:" + dir
538
Collin Winter5b7e9d72007-08-30 03:52:21 +0000539 def runtime_library_dir_option(self, dir):
540 raise DistutilsPlatformError(
541 "don't know how to set runtime library search path for MSVC++")
Greg Wardd03f88a2000-03-18 15:19:51 +0000542
Collin Winter5b7e9d72007-08-30 03:52:21 +0000543 def library_option(self, lib):
544 return self.library_filename(lib)
Greg Wardc74138d1999-10-03 20:47:52 +0000545
546
Collin Winter5b7e9d72007-08-30 03:52:21 +0000547 def find_library_file(self, dirs, lib, debug=0):
Greg Wardd1425642000-08-04 01:29:27 +0000548 # Prefer a debugging library if found (and requested), but deal
549 # with it if we don't have one.
550 if debug:
551 try_names = [lib + "_d", lib]
552 else:
553 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000554 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000555 for name in try_names:
556 libfile = os.path.join(dir, self.library_filename (name))
557 if os.path.exists(libfile):
558 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000559 else:
560 # Oops, didn't find it in *any* of 'dirs'
561 return None
562
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000563 # Helper methods for using the MSVC registry settings
564
565 def find_exe(self, exe):
566 """Return path to an MSVC executable program.
567
568 Tries to find the program in several places: first, one of the
569 MSVC program search paths from the registry; next, the directories
570 in the PATH environment variable. If any of those work, return an
571 absolute path that is known to exist. If none of them work, just
572 return the original program name, 'exe'.
573 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000574 for p in self.__paths:
575 fn = os.path.join(os.path.abspath(p), exe)
576 if os.path.isfile(fn):
577 return fn
578
579 # didn't find it; try existing path
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000580 for p in os.environ['Path'].split(';'):
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000581 fn = os.path.join(os.path.abspath(p),exe)
582 if os.path.isfile(fn):
583 return fn
584
585 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000586
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000587 def get_msvc_paths(self, path, platform='x86'):
588 """Get a list of devstudio directories (include, lib or path).
589
590 Return a list of strings. The list will be empty if unable to
591 access the registry or appropriate registry keys not found.
592 """
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000593 if not _can_read_reg:
594 return []
595
596 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000597 if self.__version >= 7:
598 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
599 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000600 else:
601 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000602 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000603
604 for base in HKEYS:
605 d = read_values(base, key)
606 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000607 if self.__version >= 7:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000608 return self.__macros.sub(d[path]).split(";")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000609 else:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000610 return d[path].split(";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000611 # MSVC 6 seems to create the registry entries we need only when
612 # the GUI is run.
613 if self.__version == 6:
614 for base in HKEYS:
615 if read_values(base, r"%s\6.0" % self.__root) is not None:
616 self.warn("It seems you have Visual Studio 6 installed, "
617 "but the expected registry settings are not present.\n"
618 "You must at least run the Visual Studio GUI once "
619 "so that these entries are created.")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000620 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000621 return []
622
623 def set_path_env_var(self, name):
624 """Set environment variable 'name' to an MSVC path type value.
625
626 This is equivalent to a SET command prior to execution of spawned
627 commands.
628 """
629
630 if name == "lib":
631 p = self.get_msvc_paths("library")
632 else:
633 p = self.get_msvc_paths(name)
634 if p:
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000635 os.environ[name] = ';'.join(p)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000636
637
638if get_build_version() >= 8.0:
639 log.debug("Importing new compiler from distutils.msvc9compiler")
640 OldMSVCCompiler = MSVCCompiler
641 from distutils.msvc9compiler import MSVCCompiler
Christian Heimes5e696852008-04-09 08:37:03 +0000642 # get_build_architecture not really relevant now we support cross-compile
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000643 from distutils.msvc9compiler import MacroExpander