blob: b65e5286a2cda7f5d0e82315c2da52b04f301a16 [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, \
134 ("The .NET Framework SDK needs to be installed before "
135 "building extensions for Python.")
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
Greg Warddbd12761999-08-29 18:15:07 +0000175
Greg Ward3d50b901999-09-08 02:36:01 +0000176class MSVCCompiler (CCompiler) :
177 """Concrete class that implements an interface to Microsoft Visual C++,
178 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000179
Greg Warddf178f91999-09-29 12:29:10 +0000180 compiler_type = 'msvc'
181
Greg Ward992c8f92000-06-25 02:31:16 +0000182 # Just set this so CCompiler's constructor doesn't barf. We currently
183 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
184 # as it really isn't necessary for this sort of single-compiler class.
185 # Would be nice to have a consistent interface with UnixCCompiler,
186 # though, so it's worth thinking about.
187 executables = {}
188
Greg Ward32c4a8a2000-03-06 03:40:29 +0000189 # Private class data (need to distinguish C from C++ source for compiler)
190 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000191 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000192 _rc_extensions = ['.rc']
193 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000194
195 # Needed for the filename generation methods provided by the
196 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000197 src_extensions = (_c_extensions + _cpp_extensions +
198 _rc_extensions + _mc_extensions)
199 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000200 obj_extension = '.obj'
201 static_lib_extension = '.lib'
202 shared_lib_extension = '.dll'
203 static_lib_format = shared_lib_format = '%s%s'
204 exe_extension = '.exe'
205
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000206 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000207 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000208 self.__version = get_build_version()
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000209 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000210 self.__root = r"Software\Microsoft\VisualStudio"
211 self.__macros = MacroExpander(self.__version)
Greg Ward69988092000-02-11 02:47:15 +0000212 else:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000213 self.__root = r"Software\Microsoft\Devstudio"
Martin v. Löwisc72dd382005-03-04 13:50:17 +0000214 self.initialized = False
215
216 def initialize(self):
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000217 self.__paths = []
218 if os.environ.has_key("MSSdk") and self.find_exe("cl.exe"):
219 # Assume that the SDK set up everything alright; don't try to be
220 # smarter
221 self.cc = "cl.exe"
222 self.linker = "link.exe"
223 self.lib = "lib.exe"
224 self.rc = "rc.exe"
225 self.mc = "mc.exe"
226 else:
227 self.__paths = self.get_msvc_paths("path")
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000228
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000229 if len (self.__paths) == 0:
230 raise DistutilsPlatformError, \
231 ("Python was built with version %s of Visual Studio, "
232 "and extensions need to be built with the same "
233 "version of the compiler, but it isn't installed." % self.__version)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000234
Martin v. Löwise46af8c2006-02-20 12:15:15 +0000235 self.cc = self.find_exe("cl.exe")
236 self.linker = self.find_exe("link.exe")
237 self.lib = self.find_exe("lib.exe")
238 self.rc = self.find_exe("rc.exe") # resource compiler
239 self.mc = self.find_exe("mc.exe") # message compiler
240 self.set_path_env_var('lib')
241 self.set_path_env_var('include')
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000242
243 # extend the MSVC path with the current path
244 try:
245 for p in string.split(os.environ['path'], ';'):
246 self.__paths.append(p)
247 except KeyError:
248 pass
249 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000250
Greg Warddbd12761999-08-29 18:15:07 +0000251 self.preprocess_options = None
Jeremy Hylton2683ac72002-06-18 19:08:40 +0000252 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
253 '/DNDEBUG']
Greg Ward8a98cd92000-08-31 00:31:07 +0000254 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
255 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000256
Greg Ward1b9c6f72000-02-08 02:39:44 +0000257 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000258 if self.__version >= 7:
259 self.ldflags_shared_debug = [
260 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
261 ]
262 else:
263 self.ldflags_shared_debug = [
264 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
265 ]
Greg Warddbd12761999-08-29 18:15:07 +0000266 self.ldflags_static = [ '/nologo']
267
Tim Petersa733bd92005-03-12 19:05:58 +0000268 self.initialized = True
Greg Warddbd12761999-08-29 18:15:07 +0000269
270 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000271
Greg Ward9c0ea132000-09-19 23:56:43 +0000272 def object_filenames (self,
273 source_filenames,
274 strip_dir=0,
275 output_dir=''):
276 # Copied from ccompiler.py, extended to return .res as 'object'-file
277 # for .rc input file
278 if output_dir is None: output_dir = ''
279 obj_names = []
280 for src_name in source_filenames:
281 (base, ext) = os.path.splitext (src_name)
Martin v. Löwisb813c532005-08-07 20:51:04 +0000282 base = os.path.splitdrive(base)[1] # Chop off the drive
283 base = base[os.path.isabs(base):] # If abs, chop off leading /
Greg Ward9c0ea132000-09-19 23:56:43 +0000284 if ext not in self.src_extensions:
285 # Better to raise an exception instead of silently continuing
286 # and later complain about sources and targets having
287 # different lengths
288 raise CompileError ("Don't know how to compile %s" % src_name)
289 if strip_dir:
290 base = os.path.basename (base)
291 if ext in self._rc_extensions:
292 obj_names.append (os.path.join (output_dir,
293 base + self.res_extension))
294 elif ext in self._mc_extensions:
295 obj_names.append (os.path.join (output_dir,
296 base + self.res_extension))
297 else:
298 obj_names.append (os.path.join (output_dir,
299 base + self.obj_extension))
300 return obj_names
301
302 # object_filenames ()
303
304
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000305 def compile(self, sources,
306 output_dir=None, macros=None, include_dirs=None, debug=0,
307 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000308
Brett Cannon3304a142005-03-05 05:28:45 +0000309 if not self.initialized: self.initialize()
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000310 macros, objects, extra_postargs, pp_opts, build = \
311 self._setup_compile(output_dir, macros, include_dirs, sources,
312 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000313
Greg Ward32c4a8a2000-03-06 03:40:29 +0000314 compile_opts = extra_preargs or []
315 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000316 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000317 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000318 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000319 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000320
Thomas Heller9436a752003-12-05 20:12:23 +0000321 for obj in objects:
322 try:
323 src, ext = build[obj]
324 except KeyError:
325 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000326 if debug:
327 # pass the full pathname to MSVC in debug mode,
328 # this allows the debugger to find the source file
329 # without asking the user to browse for it
330 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000331
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000332 if ext in self._c_extensions:
333 input_opt = "/Tc" + src
334 elif ext in self._cpp_extensions:
335 input_opt = "/Tp" + src
336 elif ext in self._rc_extensions:
337 # compile .RC to .RES file
338 input_opt = src
339 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000340 try:
Thomas Heller95827942003-01-31 20:40:15 +0000341 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000342 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000343 except DistutilsExecError, msg:
344 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000345 continue
346 elif ext in self._mc_extensions:
347
348 # Compile .MC to .RC file to .RES file.
349 # * '-h dir' specifies the directory for the
350 # generated include file
351 # * '-r dir' specifies the target directory of the
352 # generated RC file and the binary message resource
353 # it includes
354 #
355 # For now (since there are no options to change this),
356 # we use the source-directory for the include file and
357 # the build directory for the RC file and message
358 # resources. This works at least for win32all.
359
360 h_dir = os.path.dirname (src)
361 rc_dir = os.path.dirname (obj)
362 try:
363 # first compile .MC to .RC and .H file
364 self.spawn ([self.mc] +
365 ['-h', h_dir, '-r', rc_dir] + [src])
366 base, _ = os.path.splitext (os.path.basename (src))
367 rc_file = os.path.join (rc_dir, base + '.rc')
368 # then compile .RC to .RES file
369 self.spawn ([self.rc] +
370 ["/fo" + obj] + [rc_file])
371
372 except DistutilsExecError, msg:
373 raise CompileError, msg
374 continue
375 else:
376 # how to handle this file?
377 raise CompileError (
378 "Don't know how to compile %s to %s" % \
379 (src, obj))
380
381 output_opt = "/Fo" + obj
382 try:
383 self.spawn ([self.cc] + compile_opts + pp_opts +
384 [input_opt, output_opt] +
385 extra_postargs)
386 except DistutilsExecError, msg:
387 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000388
Greg Ward32c4a8a2000-03-06 03:40:29 +0000389 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000390
Greg Ward32c4a8a2000-03-06 03:40:29 +0000391 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000392
393
Greg Ward09fc5422000-03-10 01:49:26 +0000394 def create_static_lib (self,
395 objects,
396 output_libname,
397 output_dir=None,
398 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000399 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000400
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000401 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000402 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000403 output_filename = \
404 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000405
Greg Ward32c4a8a2000-03-06 03:40:29 +0000406 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000407 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000408 if debug:
409 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000410 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000411 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000412 except DistutilsExecError, msg:
413 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000414
Greg Ward32c4a8a2000-03-06 03:40:29 +0000415 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000416 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000417
Greg Ward09fc5422000-03-10 01:49:26 +0000418 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000419
Greg Ward42406482000-09-27 02:08:14 +0000420 def link (self,
421 target_desc,
422 objects,
423 output_filename,
424 output_dir=None,
425 libraries=None,
426 library_dirs=None,
427 runtime_library_dirs=None,
428 export_symbols=None,
429 debug=0,
430 extra_preargs=None,
431 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000432 build_temp=None,
433 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000434
Brett Cannon1bfd85b2005-03-05 05:32:14 +0000435 if not self.initialized: self.initialize()
Greg Ward2f557a22000-03-26 21:42:28 +0000436 (objects, output_dir) = self._fix_object_args (objects, output_dir)
437 (libraries, library_dirs, runtime_library_dirs) = \
438 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
439
Greg Wardf70c6032000-04-19 02:16:49 +0000440 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000441 self.warn ("I don't know what to do with 'runtime_library_dirs': "
442 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000443
Greg Wardd03f88a2000-03-18 15:19:51 +0000444 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000445 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000446 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000447 if output_dir is not None:
448 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000449
Greg Ward32c4a8a2000-03-06 03:40:29 +0000450 if self._need_link (objects, output_filename):
451
Greg Ward42406482000-09-27 02:08:14 +0000452 if target_desc == CCompiler.EXECUTABLE:
453 if debug:
454 ldflags = self.ldflags_shared_debug[1:]
455 else:
456 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000457 else:
Greg Ward42406482000-09-27 02:08:14 +0000458 if debug:
459 ldflags = self.ldflags_shared_debug
460 else:
461 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000462
Greg Ward5299b6a2000-05-20 13:23:21 +0000463 export_opts = []
464 for sym in (export_symbols or []):
465 export_opts.append("/EXPORT:" + sym)
466
Fred Drakeb94b8492001-12-06 20:51:35 +0000467 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000468 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000469
Greg Ward159eb922000-08-02 00:00:30 +0000470 # The MSVC linker generates .lib and .exp files, which cannot be
471 # suppressed by any linker switches. The .lib files may even be
472 # needed! Make sure they are generated in the temporary build
473 # directory. Since they have different names for debug and release
474 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000475 if export_symbols is not None:
476 (dll_name, dll_ext) = os.path.splitext(
477 os.path.basename(output_filename))
478 implib_file = os.path.join(
479 os.path.dirname(objects[0]),
480 self.library_filename(dll_name))
481 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000482
Greg Ward32c4a8a2000-03-06 03:40:29 +0000483 if extra_preargs:
484 ld_args[:0] = extra_preargs
485 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000486 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000487
488 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000489 try:
Greg Ward42406482000-09-27 02:08:14 +0000490 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000491 except DistutilsExecError, msg:
492 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000493
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000494 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000495 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000496
Greg Ward42406482000-09-27 02:08:14 +0000497 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000498
499
Greg Ward32c4a8a2000-03-06 03:40:29 +0000500 # -- Miscellaneous methods -----------------------------------------
501 # These are all used by the 'gen_lib_options() function, in
502 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000503
504 def library_dir_option (self, dir):
505 return "/LIBPATH:" + dir
506
Greg Wardd03f88a2000-03-18 15:19:51 +0000507 def runtime_library_dir_option (self, dir):
508 raise DistutilsPlatformError, \
509 "don't know how to set runtime library search path for MSVC++"
510
Greg Wardc74138d1999-10-03 20:47:52 +0000511 def library_option (self, lib):
512 return self.library_filename (lib)
513
514
Greg Wardd1425642000-08-04 01:29:27 +0000515 def find_library_file (self, dirs, lib, debug=0):
516 # Prefer a debugging library if found (and requested), but deal
517 # with it if we don't have one.
518 if debug:
519 try_names = [lib + "_d", lib]
520 else:
521 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000522 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000523 for name in try_names:
524 libfile = os.path.join(dir, self.library_filename (name))
525 if os.path.exists(libfile):
526 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000527 else:
528 # Oops, didn't find it in *any* of 'dirs'
529 return None
530
531 # find_library_file ()
532
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000533 # Helper methods for using the MSVC registry settings
534
535 def find_exe(self, exe):
536 """Return path to an MSVC executable program.
537
538 Tries to find the program in several places: first, one of the
539 MSVC program search paths from the registry; next, the directories
540 in the PATH environment variable. If any of those work, return an
541 absolute path that is known to exist. If none of them work, just
542 return the original program name, 'exe'.
543 """
544
545 for p in self.__paths:
546 fn = os.path.join(os.path.abspath(p), exe)
547 if os.path.isfile(fn):
548 return fn
549
550 # didn't find it; try existing path
551 for p in string.split(os.environ['Path'],';'):
552 fn = os.path.join(os.path.abspath(p),exe)
553 if os.path.isfile(fn):
554 return fn
555
556 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000557
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000558 def get_msvc_paths(self, path, platform='x86'):
559 """Get a list of devstudio directories (include, lib or path).
560
561 Return a list of strings. The list will be empty if unable to
562 access the registry or appropriate registry keys not found.
563 """
564
565 if not _can_read_reg:
566 return []
567
568 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000569 if self.__version >= 7:
570 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
571 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000572 else:
573 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000574 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000575
576 for base in HKEYS:
577 d = read_values(base, key)
578 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000579 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000580 return string.split(self.__macros.sub(d[path]), ";")
581 else:
582 return string.split(d[path], ";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000583 # MSVC 6 seems to create the registry entries we need only when
584 # the GUI is run.
585 if self.__version == 6:
586 for base in HKEYS:
587 if read_values(base, r"%s\6.0" % self.__root) is not None:
588 self.warn("It seems you have Visual Studio 6 installed, "
589 "but the expected registry settings are not present.\n"
590 "You must at least run the Visual Studio GUI once "
591 "so that these entries are created.")
592 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000593 return []
594
595 def set_path_env_var(self, name):
596 """Set environment variable 'name' to an MSVC path type value.
597
598 This is equivalent to a SET command prior to execution of spawned
599 commands.
600 """
601
602 if name == "lib":
603 p = self.get_msvc_paths("library")
604 else:
605 p = self.get_msvc_paths(name)
606 if p:
607 os.environ[name] = string.join(p, ';')