blob: 9ec3508c7612c7eb2fbdfdec84a768b016799004 [file] [log] [blame]
Greg Wardbfc79d62000-06-28 01:29:09 +00001"""distutils.msvccompiler
Greg Warddbd12761999-08-29 18:15:07 +00002
3Contains MSVCCompiler, an implementation of the abstract CCompiler class
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +00004for the Microsoft Visual Studio.
5"""
Greg Warddbd12761999-08-29 18:15:07 +00006
Andrew M. Kuchlinga6483d22002-11-14 02:25:42 +00007# Written by Perry Stoll
Greg Ward32c4a8a2000-03-06 03:40:29 +00008# hacked by Robin Becker and Thomas Heller to do a better job of
9# finding DevStudio (through the registry)
10
Martin v. Löwis5a6601c2004-11-10 22:23:15 +000011# This module should be kept compatible with Python 2.1.
Andrew M. Kuchlingd448f662002-11-19 13:12:28 +000012
Greg Ward3ce77fd2000-03-02 01:49:45 +000013__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000014
Greg Ward32c4a8a2000-03-06 03:40:29 +000015import sys, os, string
Greg Ward3add77f2000-05-30 02:02:49 +000016from distutils.errors import \
17 DistutilsExecError, DistutilsPlatformError, \
Greg Wardd1517112000-05-30 01:56:44 +000018 CompileError, LibError, LinkError
Greg Ward3add77f2000-05-30 02:02:49 +000019from distutils.ccompiler import \
20 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000021from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000022
Greg Ward7642f5c2000-03-31 16:47:40 +000023_can_read_reg = 0
24try:
Greg Ward1b5ec762000-06-30 19:37:59 +000025 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000026
Greg Ward7642f5c2000-03-31 16:47:40 +000027 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000028 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000029
Greg Wardcd079c42000-06-29 22:59:10 +000030 RegOpenKeyEx = _winreg.OpenKeyEx
31 RegEnumKey = _winreg.EnumKey
32 RegEnumValue = _winreg.EnumValue
33 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000034
Greg Ward7642f5c2000-03-31 16:47:40 +000035except ImportError:
36 try:
37 import win32api
38 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000039 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000040 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000041
42 RegOpenKeyEx = win32api.RegOpenKeyEx
43 RegEnumKey = win32api.RegEnumKey
44 RegEnumValue = win32api.RegEnumValue
45 RegError = win32api.error
46
Greg Ward7642f5c2000-03-31 16:47:40 +000047 except ImportError:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +000048 log.info("Warning: Can't read registry to find the "
49 "necessary compiler setting\n"
50 "Make sure that Python modules _winreg, "
51 "win32api or win32con are installed.")
Greg Ward7642f5c2000-03-31 16:47:40 +000052 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000053
54if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000055 HKEYS = (hkey_mod.HKEY_USERS,
56 hkey_mod.HKEY_CURRENT_USER,
57 hkey_mod.HKEY_LOCAL_MACHINE,
58 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000059
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000060def read_keys(base, key):
61 """Return list of registry keys."""
Fred Drakeb94b8492001-12-06 20:51:35 +000062
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000063 try:
64 handle = RegOpenKeyEx(base, key)
65 except RegError:
66 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000067 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000068 i = 0
69 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000070 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000071 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000072 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000073 break
74 L.append(k)
75 i = i + 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000076 return L
77
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000078def read_values(base, key):
79 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000080
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000081 All names are converted to lowercase.
82 """
83 try:
84 handle = RegOpenKeyEx(base, key)
85 except RegError:
86 return None
87 d = {}
88 i = 0
89 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000090 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000091 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000092 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000093 break
94 name = name.lower()
95 d[convert_mbcs(name)] = convert_mbcs(value)
96 i = i + 1
97 return d
98
99def convert_mbcs(s):
100 enc = getattr(s, "encode", None)
101 if enc is not None:
102 try:
103 s = enc("mbcs")
104 except UnicodeError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000105 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000106 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000107
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000108class MacroExpander:
Greg Ward62e33932000-02-10 02:52:42 +0000109
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000110 def __init__(self, version):
111 self.macros = {}
112 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000113
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000114 def set_macro(self, macro, path, key):
115 for base in HKEYS:
116 d = read_values(base, path)
117 if d:
118 self.macros["$(%s)" % macro] = d[key]
119 break
Tim Peters182b5ac2004-07-18 06:16:08 +0000120
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000121 def load_macros(self, version):
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000122 vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000123 self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
124 self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
125 net = r"Software\Microsoft\.NETFramework"
126 self.set_macro("FrameworkDir", net, "installroot")
Tim Peters26be2062004-11-28 01:10:01 +0000127 try:
128 if version > 7.0:
129 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
130 else:
131 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
132 except KeyError, exc: #
Fredrik Lundhcb328f32004-11-24 22:31:11 +0000133 raise DistutilsPlatformError, \
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000134 ("""Python was built with Visual Studio 2003;
135extensions must be built with a compiler than can generate compatible binaries.
136Visual Studio 2003 was not found on this system. If you have Cygwin installed,
137you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000138
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000139 p = r"Software\Microsoft\NET Framework Setup\Product"
140 for base in HKEYS:
141 try:
142 h = RegOpenKeyEx(base, p)
143 except RegError:
144 continue
145 key = RegEnumKey(h, 0)
146 d = read_values(base, r"%s\%s" % (p, key))
147 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000148
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000149 def sub(self, s):
150 for k, v in self.macros.items():
151 s = string.replace(s, k, v)
152 return s
Greg Ward69988092000-02-11 02:47:15 +0000153
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000154def get_build_version():
155 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000156
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000157 For Python 2.3 and up, the version number is included in
158 sys.version. For earlier versions, assume the compiler is MSVC 6.
159 """
Greg Ward62e33932000-02-10 02:52:42 +0000160
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000161 prefix = "MSC v."
162 i = string.find(sys.version, prefix)
163 if i == -1:
164 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000165 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000166 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000167 majorVersion = int(s[:-2]) - 6
168 minorVersion = int(s[2:3]) / 10.0
169 # I don't think paths are affected by minor version in version 6
170 if majorVersion == 6:
171 minorVersion = 0
172 if majorVersion >= 6:
173 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000174 # else we don't know what version of the compiler this is
175 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000176
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000177def get_build_architecture():
178 """Return the processor architecture.
179
180 Possible results are "Intel", "Itanium", or "AMD64".
181 """
182
183 prefix = " bit ("
184 i = string.find(sys.version, prefix)
185 if i == -1:
186 return "Intel"
187 j = string.find(sys.version, ")", i)
188 return sys.version[i+len(prefix):j]
Tim Peters32cbc962006-02-20 21:42:18 +0000189
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000190
Greg Warddbd12761999-08-29 18:15:07 +0000191
Greg Ward3d50b901999-09-08 02:36:01 +0000192class MSVCCompiler (CCompiler) :
193 """Concrete class that implements an interface to Microsoft Visual C++,
194 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000195
Greg Warddf178f91999-09-29 12:29:10 +0000196 compiler_type = 'msvc'
197
Greg Ward992c8f92000-06-25 02:31:16 +0000198 # Just set this so CCompiler's constructor doesn't barf. We currently
199 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
200 # as it really isn't necessary for this sort of single-compiler class.
201 # Would be nice to have a consistent interface with UnixCCompiler,
202 # though, so it's worth thinking about.
203 executables = {}
204
Greg Ward32c4a8a2000-03-06 03:40:29 +0000205 # Private class data (need to distinguish C from C++ source for compiler)
206 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000207 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000208 _rc_extensions = ['.rc']
209 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000210
211 # Needed for the filename generation methods provided by the
212 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000213 src_extensions = (_c_extensions + _cpp_extensions +
214 _rc_extensions + _mc_extensions)
215 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000216 obj_extension = '.obj'
217 static_lib_extension = '.lib'
218 shared_lib_extension = '.dll'
219 static_lib_format = shared_lib_format = '%s%s'
220 exe_extension = '.exe'
221
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000222 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000223 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000224 self.__version = get_build_version()
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000225 self.__arch = get_build_architecture()
226 if self.__arch == "Intel":
227 # x86
228 if self.__version >= 7:
229 self.__root = r"Software\Microsoft\VisualStudio"
230 self.__macros = MacroExpander(self.__version)
231 else:
232 self.__root = r"Software\Microsoft\Devstudio"
233 self.__product = "Visual Studio version %s" % self.__version
Greg Ward69988092000-02-11 02:47:15 +0000234 else:
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000235 # Win64. Assume this was built with the platform SDK
236 self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
Tim Peters32cbc962006-02-20 21:42:18 +0000237
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000238 self.initialized = False
239
240 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000241 self.__paths = []
Neal Norwitzf1a69c12006-08-20 16:25:10 +0000242 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 +0000243 # Assume that the SDK set up everything alright; don't try to be
244 # smarter
245 self.cc = "cl.exe"
246 self.linker = "link.exe"
247 self.lib = "lib.exe"
248 self.rc = "rc.exe"
249 self.mc = "mc.exe"
250 else:
251 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000252
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000253 if len (self.__paths) == 0:
254 raise DistutilsPlatformError, \
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000255 ("Python was built with %s, "
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000256 "and extensions need to be built with the same "
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000257 "version of the compiler, but it isn't installed." % self.__product)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000258
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000259 self.cc = self.find_exe("cl.exe")
260 self.linker = self.find_exe("link.exe")
261 self.lib = self.find_exe("lib.exe")
262 self.rc = self.find_exe("rc.exe") # resource compiler
263 self.mc = self.find_exe("mc.exe") # message compiler
264 self.set_path_env_var('lib')
265 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000266
267 # extend the MSVC path with the current path
268 try:
269 for p in string.split(os.environ['path'], ';'):
270 self.__paths.append(p)
271 except KeyError:
272 pass
273 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000274
Greg Warddbd12761999-08-29 18:15:07 +0000275 self.preprocess_options = None
Martin v. Löwisde2cde62006-02-20 12:26:58 +0000276 if self.__arch == "Intel":
277 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
278 '/DNDEBUG']
279 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
280 '/Z7', '/D_DEBUG']
281 else:
282 # Win64
283 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' ,
284 '/DNDEBUG']
285 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
Tim Peters32cbc962006-02-20 21:42:18 +0000286 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000287
Greg Ward1b9c6f72000-02-08 02:39:44 +0000288 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000289 if self.__version >= 7:
290 self.ldflags_shared_debug = [
291 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
292 ]
293 else:
294 self.ldflags_shared_debug = [
295 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
296 ]
Greg Warddbd12761999-08-29 18:15:07 +0000297 self.ldflags_static = [ '/nologo']
298
Tim Petersa733bd92005-03-12 19:05:58 +0000299 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000300
301 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000302
Greg Ward9c0ea132000-09-19 23:56:43 +0000303 def object_filenames (self,
304 source_filenames,
305 strip_dir=0,
306 output_dir=''):
307 # Copied from ccompiler.py, extended to return .res as 'object'-file
308 # for .rc input file
309 if output_dir is None: output_dir = ''
310 obj_names = []
311 for src_name in source_filenames:
312 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000313 base = os.path.splitdrive(base)[1] # Chop off the drive
314 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000315 if ext not in self.src_extensions:
316 # Better to raise an exception instead of silently continuing
317 # and later complain about sources and targets having
318 # different lengths
319 raise CompileError ("Don't know how to compile %s" % src_name)
320 if strip_dir:
321 base = os.path.basename (base)
322 if ext in self._rc_extensions:
323 obj_names.append (os.path.join (output_dir,
324 base + self.res_extension))
325 elif ext in self._mc_extensions:
326 obj_names.append (os.path.join (output_dir,
327 base + self.res_extension))
328 else:
329 obj_names.append (os.path.join (output_dir,
330 base + self.obj_extension))
331 return obj_names
332
333 # object_filenames ()
334
335
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000336 def compile(self, sources,
337 output_dir=None, macros=None, include_dirs=None, debug=0,
338 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000339
Brett Cannon3304a142005-03-05 05:28:45 +0000340 if not self.initialized: self.initialize()
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000341 macros, objects, extra_postargs, pp_opts, build = \
342 self._setup_compile(output_dir, macros, include_dirs, sources,
343 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000344
Greg Ward32c4a8a2000-03-06 03:40:29 +0000345 compile_opts = extra_preargs or []
346 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000347 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000348 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000349 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000350 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000351
Thomas Heller9436a752003-12-05 20:12:23 +0000352 for obj in objects:
353 try:
354 src, ext = build[obj]
355 except KeyError:
356 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000357 if debug:
358 # pass the full pathname to MSVC in debug mode,
359 # this allows the debugger to find the source file
360 # without asking the user to browse for it
361 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000362
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000363 if ext in self._c_extensions:
364 input_opt = "/Tc" + src
365 elif ext in self._cpp_extensions:
366 input_opt = "/Tp" + src
367 elif ext in self._rc_extensions:
368 # compile .RC to .RES file
369 input_opt = src
370 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000371 try:
Thomas Heller95827942003-01-31 20:40:15 +0000372 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000373 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000374 except DistutilsExecError, msg:
375 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000376 continue
377 elif ext in self._mc_extensions:
378
379 # Compile .MC to .RC file to .RES file.
380 # * '-h dir' specifies the directory for the
381 # generated include file
382 # * '-r dir' specifies the target directory of the
383 # generated RC file and the binary message resource
384 # it includes
385 #
386 # For now (since there are no options to change this),
387 # we use the source-directory for the include file and
388 # the build directory for the RC file and message
389 # resources. This works at least for win32all.
390
391 h_dir = os.path.dirname (src)
392 rc_dir = os.path.dirname (obj)
393 try:
394 # first compile .MC to .RC and .H file
395 self.spawn ([self.mc] +
396 ['-h', h_dir, '-r', rc_dir] + [src])
397 base, _ = os.path.splitext (os.path.basename (src))
398 rc_file = os.path.join (rc_dir, base + '.rc')
399 # then compile .RC to .RES file
400 self.spawn ([self.rc] +
401 ["/fo" + obj] + [rc_file])
402
403 except DistutilsExecError, msg:
404 raise CompileError, msg
405 continue
406 else:
407 # how to handle this file?
408 raise CompileError (
409 "Don't know how to compile %s to %s" % \
410 (src, obj))
411
412 output_opt = "/Fo" + obj
413 try:
414 self.spawn ([self.cc] + compile_opts + pp_opts +
415 [input_opt, output_opt] +
416 extra_postargs)
417 except DistutilsExecError, msg:
418 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000419
Greg Ward32c4a8a2000-03-06 03:40:29 +0000420 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000421
Greg Ward32c4a8a2000-03-06 03:40:29 +0000422 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000423
424
Greg Ward09fc5422000-03-10 01:49:26 +0000425 def create_static_lib (self,
426 objects,
427 output_libname,
428 output_dir=None,
429 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000430 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000431
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000432 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000433 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000434 output_filename = \
435 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000436
Greg Ward32c4a8a2000-03-06 03:40:29 +0000437 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000438 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000439 if debug:
440 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000441 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000442 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000443 except DistutilsExecError, msg:
444 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000445
Greg Ward32c4a8a2000-03-06 03:40:29 +0000446 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000447 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000448
Greg Ward09fc5422000-03-10 01:49:26 +0000449 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000450
Greg Ward42406482000-09-27 02:08:14 +0000451 def link (self,
452 target_desc,
453 objects,
454 output_filename,
455 output_dir=None,
456 libraries=None,
457 library_dirs=None,
458 runtime_library_dirs=None,
459 export_symbols=None,
460 debug=0,
461 extra_preargs=None,
462 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000463 build_temp=None,
464 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000465
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000466 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000467 (objects, output_dir) = self._fix_object_args (objects, output_dir)
468 (libraries, library_dirs, runtime_library_dirs) = \
469 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
470
Greg Wardf70c6032000-04-19 02:16:49 +0000471 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000472 self.warn ("I don't know what to do with 'runtime_library_dirs': "
473 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000474
Greg Wardd03f88a2000-03-18 15:19:51 +0000475 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000476 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000477 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000478 if output_dir is not None:
479 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000480
Greg Ward32c4a8a2000-03-06 03:40:29 +0000481 if self._need_link (objects, output_filename):
482
Greg Ward42406482000-09-27 02:08:14 +0000483 if target_desc == CCompiler.EXECUTABLE:
484 if debug:
485 ldflags = self.ldflags_shared_debug[1:]
486 else:
487 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000488 else:
Greg Ward42406482000-09-27 02:08:14 +0000489 if debug:
490 ldflags = self.ldflags_shared_debug
491 else:
492 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000493
Greg Ward5299b6a2000-05-20 13:23:21 +0000494 export_opts = []
495 for sym in (export_symbols or []):
496 export_opts.append("/EXPORT:" + sym)
497
Fred Drakeb94b8492001-12-06 20:51:35 +0000498 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000499 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000500
Greg Ward159eb922000-08-02 00:00:30 +0000501 # The MSVC linker generates .lib and .exp files, which cannot be
502 # suppressed by any linker switches. The .lib files may even be
503 # needed! Make sure they are generated in the temporary build
504 # directory. Since they have different names for debug and release
505 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000506 if export_symbols is not None:
507 (dll_name, dll_ext) = os.path.splitext(
508 os.path.basename(output_filename))
509 implib_file = os.path.join(
510 os.path.dirname(objects[0]),
511 self.library_filename(dll_name))
512 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000513
Greg Ward32c4a8a2000-03-06 03:40:29 +0000514 if extra_preargs:
515 ld_args[:0] = extra_preargs
516 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000517 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000518
519 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000520 try:
Greg Ward42406482000-09-27 02:08:14 +0000521 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000522 except DistutilsExecError, msg:
523 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000524
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000525 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000526 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000527
Greg Ward42406482000-09-27 02:08:14 +0000528 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000529
530
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
535 def library_dir_option (self, dir):
536 return "/LIBPATH:" + dir
537
Greg Wardd03f88a2000-03-18 15:19:51 +0000538 def runtime_library_dir_option (self, dir):
539 raise DistutilsPlatformError, \
540 "don't know how to set runtime library search path for MSVC++"
541
Greg Wardc74138d1999-10-03 20:47:52 +0000542 def library_option (self, lib):
543 return self.library_filename (lib)
544
545
Greg Wardd1425642000-08-04 01:29:27 +0000546 def find_library_file (self, dirs, lib, debug=0):
547 # 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
562 # find_library_file ()
563
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000564 # Helper methods for using the MSVC registry settings
565
566 def find_exe(self, exe):
567 """Return path to an MSVC executable program.
568
569 Tries to find the program in several places: first, one of the
570 MSVC program search paths from the registry; next, the directories
571 in the PATH environment variable. If any of those work, return an
572 absolute path that is known to exist. If none of them work, just
573 return the original program name, 'exe'.
574 """
575
576 for p in self.__paths:
577 fn = os.path.join(os.path.abspath(p), exe)
578 if os.path.isfile(fn):
579 return fn
580
581 # didn't find it; try existing path
582 for p in string.split(os.environ['Path'],';'):
583 fn = os.path.join(os.path.abspath(p),exe)
584 if os.path.isfile(fn):
585 return fn
586
587 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000588
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000589 def get_msvc_paths(self, path, platform='x86'):
590 """Get a list of devstudio directories (include, lib or path).
591
592 Return a list of strings. The list will be empty if unable to
593 access the registry or appropriate registry keys not found.
594 """
595
596 if not _can_read_reg:
597 return []
598
599 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000600 if self.__version >= 7:
601 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
602 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000603 else:
604 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000605 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000606
607 for base in HKEYS:
608 d = read_values(base, key)
609 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000610 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000611 return string.split(self.__macros.sub(d[path]), ";")
612 else:
613 return string.split(d[path], ";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000614 # MSVC 6 seems to create the registry entries we need only when
615 # the GUI is run.
616 if self.__version == 6:
617 for base in HKEYS:
618 if read_values(base, r"%s\6.0" % self.__root) is not None:
619 self.warn("It seems you have Visual Studio 6 installed, "
620 "but the expected registry settings are not present.\n"
621 "You must at least run the Visual Studio GUI once "
622 "so that these entries are created.")
Thomas Wouters477c8d52006-05-27 19:21:47 +0000623 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000624 return []
625
626 def set_path_env_var(self, name):
627 """Set environment variable 'name' to an MSVC path type value.
628
629 This is equivalent to a SET command prior to execution of spawned
630 commands.
631 """
632
633 if name == "lib":
634 p = self.get_msvc_paths("library")
635 else:
636 p = self.get_msvc_paths(name)
637 if p:
638 os.environ[name] = string.join(p, ';')