blob: d38afb72238d3bb1ad8e03f489008cc3cf276af2 [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
Greg Ward32c4a8a2000-03-06 03:40:29 +000013import sys, os, string
Greg Ward3add77f2000-05-30 02:02:49 +000014from distutils.errors import \
15 DistutilsExecError, DistutilsPlatformError, \
Greg Wardd1517112000-05-30 01:56:44 +000016 CompileError, LibError, LinkError
Greg Ward3add77f2000-05-30 02:02:49 +000017from 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
Greg Ward7642f5c2000-03-31 16:47:40 +000021_can_read_reg = 0
22try:
Greg Ward1b5ec762000-06-30 19:37:59 +000023 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000024
Greg Ward7642f5c2000-03-31 16:47:40 +000025 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000026 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000027
Greg Wardcd079c42000-06-29 22:59:10 +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
Greg Ward7642f5c2000-03-31 16:47:40 +000037 _can_read_reg = 1
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
44
Greg Ward7642f5c2000-03-31 16:47:40 +000045 except ImportError:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000046 log.info("Warning: Can't read registry to find the "
47 "necessary compiler setting\n"
48 "Make sure that Python modules _winreg, "
49 "win32api or win32con are installed.")
Greg Ward7642f5c2000-03-31 16:47:40 +000050 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000051
52if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000053 HKEYS = (hkey_mod.HKEY_USERS,
54 hkey_mod.HKEY_CURRENT_USER,
55 hkey_mod.HKEY_LOCAL_MACHINE,
56 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000057
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000058def read_keys(base, key):
59 """Return list of registry keys."""
Fred Drakeb94b8492001-12-06 20:51:35 +000060
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000061 try:
62 handle = RegOpenKeyEx(base, key)
63 except RegError:
64 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000065 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000066 i = 0
67 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000068 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000069 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000070 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000071 break
72 L.append(k)
73 i = i + 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000074 return L
75
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000076def read_values(base, key):
77 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000078
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000079 All names are converted to lowercase.
80 """
81 try:
82 handle = RegOpenKeyEx(base, key)
83 except RegError:
84 return None
85 d = {}
86 i = 0
87 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000088 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000089 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000090 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000091 break
92 name = name.lower()
93 d[convert_mbcs(name)] = convert_mbcs(value)
94 i = i + 1
95 return d
96
97def convert_mbcs(s):
98 enc = getattr(s, "encode", None)
99 if enc is not None:
100 try:
101 s = enc("mbcs")
102 except UnicodeError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000103 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000104 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000105
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000106class MacroExpander:
Greg Ward62e33932000-02-10 02:52:42 +0000107
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000108 def __init__(self, version):
109 self.macros = {}
110 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000111
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000112 def set_macro(self, macro, path, key):
113 for base in HKEYS:
114 d = read_values(base, path)
115 if d:
116 self.macros["$(%s)" % macro] = d[key]
117 break
Tim Peters182b5ac2004-07-18 06:16:08 +0000118
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000119 def load_macros(self, version):
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000120 vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000121 self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
122 self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
123 net = r"Software\Microsoft\.NETFramework"
124 self.set_macro("FrameworkDir", net, "installroot")
Tim Peters26be2062004-11-28 01:10:01 +0000125 try:
126 if version > 7.0:
127 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
128 else:
129 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
130 except KeyError, exc: #
Fredrik Lundhcb328f32004-11-24 22:31:11 +0000131 raise DistutilsPlatformError, \
Martin v. Löwis77621582006-07-30 13:27:31 +0000132 ("""Python was built with Visual Studio 2003;
133extensions must be built with a compiler than can generate compatible binaries.
134Visual Studio 2003 was not found on this system. If you have Cygwin installed,
135you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000136
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000137 p = r"Software\Microsoft\NET Framework Setup\Product"
138 for base in HKEYS:
139 try:
140 h = RegOpenKeyEx(base, p)
141 except RegError:
142 continue
143 key = RegEnumKey(h, 0)
144 d = read_values(base, r"%s\%s" % (p, key))
145 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000146
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000147 def sub(self, s):
148 for k, v in self.macros.items():
149 s = string.replace(s, k, v)
150 return s
Greg Ward69988092000-02-11 02:47:15 +0000151
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000152def get_build_version():
153 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000154
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000155 For Python 2.3 and up, the version number is included in
156 sys.version. For earlier versions, assume the compiler is MSVC 6.
157 """
Greg Ward62e33932000-02-10 02:52:42 +0000158
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000159 prefix = "MSC v."
160 i = string.find(sys.version, prefix)
161 if i == -1:
162 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000163 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000164 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000165 majorVersion = int(s[:-2]) - 6
166 minorVersion = int(s[2:3]) / 10.0
167 # I don't think paths are affected by minor version in version 6
168 if majorVersion == 6:
169 minorVersion = 0
170 if majorVersion >= 6:
171 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000172 # else we don't know what version of the compiler this is
173 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000174
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000175def get_build_architecture():
176 """Return the processor architecture.
177
178 Possible results are "Intel", "Itanium", or "AMD64".
179 """
180
181 prefix = " bit ("
182 i = string.find(sys.version, prefix)
183 if i == -1:
184 return "Intel"
185 j = string.find(sys.version, ")", i)
186 return sys.version[i+len(prefix):j]
Tim Peters32cbc962006-02-20 21:42:18 +0000187
Neal Norwitz8f35f442007-04-01 18:24:22 +0000188def normalize_and_reduce_paths(paths):
189 """Return a list of normalized paths with duplicates removed.
190
191 The current order of paths is maintained.
192 """
193 # Paths are normalized so things like: /a and /a/ aren't both preserved.
194 reduced_paths = []
195 for p in paths:
196 np = os.path.normpath(p)
197 # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
198 if np not in reduced_paths:
199 reduced_paths.append(np)
200 return reduced_paths
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000201
Greg Warddbd12761999-08-29 18:15:07 +0000202
Greg Ward3d50b901999-09-08 02:36:01 +0000203class MSVCCompiler (CCompiler) :
204 """Concrete class that implements an interface to Microsoft Visual C++,
205 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000206
Greg Warddf178f91999-09-29 12:29:10 +0000207 compiler_type = 'msvc'
208
Greg Ward992c8f92000-06-25 02:31:16 +0000209 # Just set this so CCompiler's constructor doesn't barf. We currently
210 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
211 # as it really isn't necessary for this sort of single-compiler class.
212 # Would be nice to have a consistent interface with UnixCCompiler,
213 # though, so it's worth thinking about.
214 executables = {}
215
Greg Ward32c4a8a2000-03-06 03:40:29 +0000216 # Private class data (need to distinguish C from C++ source for compiler)
217 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000218 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000219 _rc_extensions = ['.rc']
220 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000221
222 # Needed for the filename generation methods provided by the
223 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000224 src_extensions = (_c_extensions + _cpp_extensions +
225 _rc_extensions + _mc_extensions)
226 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000227 obj_extension = '.obj'
228 static_lib_extension = '.lib'
229 shared_lib_extension = '.dll'
230 static_lib_format = shared_lib_format = '%s%s'
231 exe_extension = '.exe'
232
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000233 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000234 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000235 self.__version = get_build_version()
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000236 self.__arch = get_build_architecture()
237 if self.__arch == "Intel":
238 # x86
239 if self.__version >= 7:
240 self.__root = r"Software\Microsoft\VisualStudio"
241 self.__macros = MacroExpander(self.__version)
242 else:
243 self.__root = r"Software\Microsoft\Devstudio"
244 self.__product = "Visual Studio version %s" % self.__version
Greg Ward69988092000-02-11 02:47:15 +0000245 else:
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000246 # Win64. Assume this was built with the platform SDK
247 self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
Tim Peters32cbc962006-02-20 21:42:18 +0000248
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000249 self.initialized = False
250
251 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000252 self.__paths = []
Guido van Rossum8bc09652008-02-21 18:18:37 +0000253 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 +0000254 # Assume that the SDK set up everything alright; don't try to be
255 # smarter
256 self.cc = "cl.exe"
257 self.linker = "link.exe"
258 self.lib = "lib.exe"
259 self.rc = "rc.exe"
260 self.mc = "mc.exe"
261 else:
262 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000263
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000264 if len (self.__paths) == 0:
265 raise DistutilsPlatformError, \
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000266 ("Python was built with %s, "
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000267 "and extensions need to be built with the same "
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000268 "version of the compiler, but it isn't installed." % self.__product)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000269
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000270 self.cc = self.find_exe("cl.exe")
271 self.linker = self.find_exe("link.exe")
272 self.lib = self.find_exe("lib.exe")
273 self.rc = self.find_exe("rc.exe") # resource compiler
274 self.mc = self.find_exe("mc.exe") # message compiler
275 self.set_path_env_var('lib')
276 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000277
278 # extend the MSVC path with the current path
279 try:
280 for p in string.split(os.environ['path'], ';'):
281 self.__paths.append(p)
282 except KeyError:
283 pass
Neal Norwitz8f35f442007-04-01 18:24:22 +0000284 self.__paths = normalize_and_reduce_paths(self.__paths)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000285 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000286
Greg Warddbd12761999-08-29 18:15:07 +0000287 self.preprocess_options = None
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000288 if self.__arch == "Intel":
289 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
290 '/DNDEBUG']
291 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
292 '/Z7', '/D_DEBUG']
293 else:
294 # Win64
295 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
296 '/DNDEBUG']
297 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
Tim Peters32cbc962006-02-20 21:42:18 +0000298 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000299
Greg Ward1b9c6f72000-02-08 02:39:44 +0000300 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000301 if self.__version >= 7:
302 self.ldflags_shared_debug = [
303 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
304 ]
305 else:
306 self.ldflags_shared_debug = [
307 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
308 ]
Greg Warddbd12761999-08-29 18:15:07 +0000309 self.ldflags_static = [ '/nologo']
310
Tim Petersa733bd92005-03-12 19:05:58 +0000311 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000312
313 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000314
Greg Ward9c0ea132000-09-19 23:56:43 +0000315 def object_filenames (self,
316 source_filenames,
317 strip_dir=0,
318 output_dir=''):
319 # Copied from ccompiler.py, extended to return .res as 'object'-file
320 # for .rc input file
321 if output_dir is None: output_dir = ''
322 obj_names = []
323 for src_name in source_filenames:
324 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000325 base = os.path.splitdrive(base)[1] # Chop off the drive
326 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000327 if ext not in self.src_extensions:
328 # Better to raise an exception instead of silently continuing
329 # and later complain about sources and targets having
330 # different lengths
331 raise CompileError ("Don't know how to compile %s" % src_name)
332 if strip_dir:
333 base = os.path.basename (base)
334 if ext in self._rc_extensions:
335 obj_names.append (os.path.join (output_dir,
336 base + self.res_extension))
337 elif ext in self._mc_extensions:
338 obj_names.append (os.path.join (output_dir,
339 base + self.res_extension))
340 else:
341 obj_names.append (os.path.join (output_dir,
342 base + self.obj_extension))
343 return obj_names
344
345 # object_filenames ()
346
347
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000348 def compile(self, sources,
349 output_dir=None, macros=None, include_dirs=None, debug=0,
350 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000351
Brett Cannon3304a142005-03-05 05:28:45 +0000352 if not self.initialized: self.initialize()
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000353 macros, objects, extra_postargs, pp_opts, build = \
354 self._setup_compile(output_dir, macros, include_dirs, sources,
355 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000356
Greg Ward32c4a8a2000-03-06 03:40:29 +0000357 compile_opts = extra_preargs or []
358 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000359 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000360 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000361 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000362 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000363
Thomas Heller9436a752003-12-05 20:12:23 +0000364 for obj in objects:
365 try:
366 src, ext = build[obj]
367 except KeyError:
368 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000369 if debug:
370 # pass the full pathname to MSVC in debug mode,
371 # this allows the debugger to find the source file
372 # without asking the user to browse for it
373 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000374
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000375 if ext in self._c_extensions:
376 input_opt = "/Tc" + src
377 elif ext in self._cpp_extensions:
378 input_opt = "/Tp" + src
379 elif ext in self._rc_extensions:
380 # compile .RC to .RES file
381 input_opt = src
382 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000383 try:
Thomas Heller95827942003-01-31 20:40:15 +0000384 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000385 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000386 except DistutilsExecError, msg:
387 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000388 continue
389 elif ext in self._mc_extensions:
390
391 # Compile .MC to .RC file to .RES file.
392 # * '-h dir' specifies the directory for the
393 # generated include file
394 # * '-r dir' specifies the target directory of the
395 # generated RC file and the binary message resource
396 # it includes
397 #
398 # For now (since there are no options to change this),
399 # we use the source-directory for the include file and
400 # the build directory for the RC file and message
401 # resources. This works at least for win32all.
402
403 h_dir = os.path.dirname (src)
404 rc_dir = os.path.dirname (obj)
405 try:
406 # first compile .MC to .RC and .H file
407 self.spawn ([self.mc] +
408 ['-h', h_dir, '-r', rc_dir] + [src])
409 base, _ = os.path.splitext (os.path.basename (src))
410 rc_file = os.path.join (rc_dir, base + '.rc')
411 # then compile .RC to .RES file
412 self.spawn ([self.rc] +
413 ["/fo" + obj] + [rc_file])
414
415 except DistutilsExecError, msg:
416 raise CompileError, msg
417 continue
418 else:
419 # how to handle this file?
420 raise CompileError (
421 "Don't know how to compile %s to %s" % \
422 (src, obj))
423
424 output_opt = "/Fo" + obj
425 try:
426 self.spawn ([self.cc] + compile_opts + pp_opts +
427 [input_opt, output_opt] +
428 extra_postargs)
429 except DistutilsExecError, msg:
430 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000431
Greg Ward32c4a8a2000-03-06 03:40:29 +0000432 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000433
Greg Ward32c4a8a2000-03-06 03:40:29 +0000434 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000435
436
Greg Ward09fc5422000-03-10 01:49:26 +0000437 def create_static_lib (self,
438 objects,
439 output_libname,
440 output_dir=None,
441 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000442 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000443
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000444 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000445 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000446 output_filename = \
447 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000448
Greg Ward32c4a8a2000-03-06 03:40:29 +0000449 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000450 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000451 if debug:
452 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000453 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000454 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000455 except DistutilsExecError, msg:
456 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000457
Greg Ward32c4a8a2000-03-06 03:40:29 +0000458 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000459 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000460
Greg Ward09fc5422000-03-10 01:49:26 +0000461 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000462
Greg Ward42406482000-09-27 02:08:14 +0000463 def link (self,
464 target_desc,
465 objects,
466 output_filename,
467 output_dir=None,
468 libraries=None,
469 library_dirs=None,
470 runtime_library_dirs=None,
471 export_symbols=None,
472 debug=0,
473 extra_preargs=None,
474 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000475 build_temp=None,
476 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000477
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000478 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000479 (objects, output_dir) = self._fix_object_args (objects, output_dir)
480 (libraries, library_dirs, runtime_library_dirs) = \
481 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
482
Greg Wardf70c6032000-04-19 02:16:49 +0000483 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000484 self.warn ("I don't know what to do with 'runtime_library_dirs': "
485 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000486
Greg Wardd03f88a2000-03-18 15:19:51 +0000487 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000488 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000489 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000490 if output_dir is not None:
491 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000492
Greg Ward32c4a8a2000-03-06 03:40:29 +0000493 if self._need_link (objects, output_filename):
494
Greg Ward42406482000-09-27 02:08:14 +0000495 if target_desc == CCompiler.EXECUTABLE:
496 if debug:
497 ldflags = self.ldflags_shared_debug[1:]
498 else:
499 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000500 else:
Greg Ward42406482000-09-27 02:08:14 +0000501 if debug:
502 ldflags = self.ldflags_shared_debug
503 else:
504 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000505
Greg Ward5299b6a2000-05-20 13:23:21 +0000506 export_opts = []
507 for sym in (export_symbols or []):
508 export_opts.append("/EXPORT:" + sym)
509
Fred Drakeb94b8492001-12-06 20:51:35 +0000510 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000511 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000512
Greg Ward159eb922000-08-02 00:00:30 +0000513 # The MSVC linker generates .lib and .exp files, which cannot be
514 # suppressed by any linker switches. The .lib files may even be
515 # needed! Make sure they are generated in the temporary build
516 # directory. Since they have different names for debug and release
517 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000518 if export_symbols is not None:
519 (dll_name, dll_ext) = os.path.splitext(
520 os.path.basename(output_filename))
521 implib_file = os.path.join(
522 os.path.dirname(objects[0]),
523 self.library_filename(dll_name))
524 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000525
Greg Ward32c4a8a2000-03-06 03:40:29 +0000526 if extra_preargs:
527 ld_args[:0] = extra_preargs
528 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000529 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000530
531 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000532 try:
Greg Ward42406482000-09-27 02:08:14 +0000533 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000534 except DistutilsExecError, msg:
535 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000536
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000537 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000538 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000539
Greg Ward42406482000-09-27 02:08:14 +0000540 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000541
542
Greg Ward32c4a8a2000-03-06 03:40:29 +0000543 # -- Miscellaneous methods -----------------------------------------
544 # These are all used by the 'gen_lib_options() function, in
545 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000546
547 def library_dir_option (self, dir):
548 return "/LIBPATH:" + dir
549
Greg Wardd03f88a2000-03-18 15:19:51 +0000550 def runtime_library_dir_option (self, dir):
551 raise DistutilsPlatformError, \
552 "don't know how to set runtime library search path for MSVC++"
553
Greg Wardc74138d1999-10-03 20:47:52 +0000554 def library_option (self, lib):
555 return self.library_filename (lib)
556
557
Greg Wardd1425642000-08-04 01:29:27 +0000558 def find_library_file (self, dirs, lib, debug=0):
559 # Prefer a debugging library if found (and requested), but deal
560 # with it if we don't have one.
561 if debug:
562 try_names = [lib + "_d", lib]
563 else:
564 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000565 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000566 for name in try_names:
567 libfile = os.path.join(dir, self.library_filename (name))
568 if os.path.exists(libfile):
569 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000570 else:
571 # Oops, didn't find it in *any* of 'dirs'
572 return None
573
574 # find_library_file ()
575
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000576 # Helper methods for using the MSVC registry settings
577
578 def find_exe(self, exe):
579 """Return path to an MSVC executable program.
580
581 Tries to find the program in several places: first, one of the
582 MSVC program search paths from the registry; next, the directories
583 in the PATH environment variable. If any of those work, return an
584 absolute path that is known to exist. If none of them work, just
585 return the original program name, 'exe'.
586 """
587
588 for p in self.__paths:
589 fn = os.path.join(os.path.abspath(p), exe)
590 if os.path.isfile(fn):
591 return fn
592
593 # didn't find it; try existing path
594 for p in string.split(os.environ['Path'],';'):
595 fn = os.path.join(os.path.abspath(p),exe)
596 if os.path.isfile(fn):
597 return fn
598
599 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000600
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000601 def get_msvc_paths(self, path, platform='x86'):
602 """Get a list of devstudio directories (include, lib or path).
603
604 Return a list of strings. The list will be empty if unable to
605 access the registry or appropriate registry keys not found.
606 """
607
608 if not _can_read_reg:
609 return []
610
611 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000612 if self.__version >= 7:
613 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
614 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000615 else:
616 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000617 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000618
619 for base in HKEYS:
620 d = read_values(base, key)
621 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000622 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000623 return string.split(self.__macros.sub(d[path]), ";")
624 else:
625 return string.split(d[path], ";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000626 # MSVC 6 seems to create the registry entries we need only when
627 # the GUI is run.
628 if self.__version == 6:
629 for base in HKEYS:
630 if read_values(base, r"%s\6.0" % self.__root) is not None:
631 self.warn("It seems you have Visual Studio 6 installed, "
632 "but the expected registry settings are not present.\n"
633 "You must at least run the Visual Studio GUI once "
634 "so that these entries are created.")
Trent Micke96b2292006-04-25 00:34:50 +0000635 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000636 return []
637
638 def set_path_env_var(self, name):
639 """Set environment variable 'name' to an MSVC path type value.
640
641 This is equivalent to a SET command prior to execution of spawned
642 commands.
643 """
644
645 if name == "lib":
646 p = self.get_msvc_paths("library")
647 else:
648 p = self.get_msvc_paths(name)
649 if p:
650 os.environ[name] = string.join(p, ';')
Christian Heimes3305c522007-12-03 13:47:29 +0000651
652
653if get_build_version() >= 8.0:
654 log.debug("Importing new compiler from distutils.msvc9compiler")
655 OldMSVCCompiler = MSVCCompiler
656 from distutils.msvc9compiler import MSVCCompiler
Mark Hammond495cf992008-04-07 01:53:39 +0000657 # get_build_architecture not really relevant now we support cross-compile
Christian Heimes3305c522007-12-03 13:47:29 +0000658 from distutils.msvc9compiler import MacroExpander