blob: dd9d8928ad7065575f165968f56a5f8235480986 [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")
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000127 if version > 7.0:
128 self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
129 else:
130 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
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():
144 s = string.replace(s, k, v)
145 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 """
Greg Ward62e33932000-02-10 02:52:42 +0000153
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000154 prefix = "MSC v."
155 i = string.find(sys.version, prefix)
156 if i == -1:
157 return 6
Marc-André Lemburgf0b5d172003-05-14 19:48:57 +0000158 i = i + len(prefix)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000159 s, rest = sys.version[i:].split(" ", 1)
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000160 majorVersion = int(s[:-2]) - 6
161 minorVersion = int(s[2:3]) / 10.0
162 # I don't think paths are affected by minor version in version 6
163 if majorVersion == 6:
164 minorVersion = 0
165 if majorVersion >= 6:
166 return majorVersion + minorVersion
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000167 # else we don't know what version of the compiler this is
168 return None
Tim Peters182b5ac2004-07-18 06:16:08 +0000169
Greg Warddbd12761999-08-29 18:15:07 +0000170
Greg Ward3d50b901999-09-08 02:36:01 +0000171class MSVCCompiler (CCompiler) :
172 """Concrete class that implements an interface to Microsoft Visual C++,
173 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000174
Greg Warddf178f91999-09-29 12:29:10 +0000175 compiler_type = 'msvc'
176
Greg Ward992c8f92000-06-25 02:31:16 +0000177 # Just set this so CCompiler's constructor doesn't barf. We currently
178 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
179 # as it really isn't necessary for this sort of single-compiler class.
180 # Would be nice to have a consistent interface with UnixCCompiler,
181 # though, so it's worth thinking about.
182 executables = {}
183
Greg Ward32c4a8a2000-03-06 03:40:29 +0000184 # Private class data (need to distinguish C from C++ source for compiler)
185 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000186 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000187 _rc_extensions = ['.rc']
188 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000189
190 # Needed for the filename generation methods provided by the
191 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000192 src_extensions = (_c_extensions + _cpp_extensions +
193 _rc_extensions + _mc_extensions)
194 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000195 obj_extension = '.obj'
196 static_lib_extension = '.lib'
197 shared_lib_extension = '.dll'
198 static_lib_format = shared_lib_format = '%s%s'
199 exe_extension = '.exe'
200
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000201 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000202 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000203 self.__version = get_build_version()
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000204 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000205 self.__root = r"Software\Microsoft\VisualStudio"
206 self.__macros = MacroExpander(self.__version)
Greg Ward69988092000-02-11 02:47:15 +0000207 else:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000208 self.__root = r"Software\Microsoft\Devstudio"
209 self.__paths = self.get_msvc_paths("path")
210
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000211 if len (self.__paths) == 0:
212 raise DistutilsPlatformError, \
213 ("Python was built with version %s of Visual Studio, "
214 "and extensions need to be built with the same "
215 "version of the compiler, but it isn't installed." % self.__version)
216
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000217 self.cc = self.find_exe("cl.exe")
218 self.linker = self.find_exe("link.exe")
219 self.lib = self.find_exe("lib.exe")
220 self.rc = self.find_exe("rc.exe") # resource compiler
221 self.mc = self.find_exe("mc.exe") # message compiler
222 self.set_path_env_var('lib')
223 self.set_path_env_var('include')
224
225 # extend the MSVC path with the current path
226 try:
227 for p in string.split(os.environ['path'], ';'):
228 self.__paths.append(p)
229 except KeyError:
230 pass
231 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000232
Greg Warddbd12761999-08-29 18:15:07 +0000233 self.preprocess_options = None
Jeremy Hylton2683ac72002-06-18 19:08:40 +0000234 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
235 '/DNDEBUG']
Greg Ward8a98cd92000-08-31 00:31:07 +0000236 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
237 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000238
Greg Ward1b9c6f72000-02-08 02:39:44 +0000239 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Thomas Heller41f70382004-11-10 09:01:41 +0000240 if self.__version >= 7:
241 self.ldflags_shared_debug = [
242 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
243 ]
244 else:
245 self.ldflags_shared_debug = [
246 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
247 ]
Greg Warddbd12761999-08-29 18:15:07 +0000248 self.ldflags_static = [ '/nologo']
249
Greg Warddbd12761999-08-29 18:15:07 +0000250
251 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000252
Greg Ward9c0ea132000-09-19 23:56:43 +0000253 def object_filenames (self,
254 source_filenames,
255 strip_dir=0,
256 output_dir=''):
257 # Copied from ccompiler.py, extended to return .res as 'object'-file
258 # for .rc input file
259 if output_dir is None: output_dir = ''
260 obj_names = []
261 for src_name in source_filenames:
262 (base, ext) = os.path.splitext (src_name)
263 if ext not in self.src_extensions:
264 # Better to raise an exception instead of silently continuing
265 # and later complain about sources and targets having
266 # different lengths
267 raise CompileError ("Don't know how to compile %s" % src_name)
268 if strip_dir:
269 base = os.path.basename (base)
270 if ext in self._rc_extensions:
271 obj_names.append (os.path.join (output_dir,
272 base + self.res_extension))
273 elif ext in self._mc_extensions:
274 obj_names.append (os.path.join (output_dir,
275 base + self.res_extension))
276 else:
277 obj_names.append (os.path.join (output_dir,
278 base + self.obj_extension))
279 return obj_names
280
281 # object_filenames ()
282
283
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000284 def compile(self, sources,
285 output_dir=None, macros=None, include_dirs=None, debug=0,
286 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000287
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000288 macros, objects, extra_postargs, pp_opts, build = \
289 self._setup_compile(output_dir, macros, include_dirs, sources,
290 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000291
Greg Ward32c4a8a2000-03-06 03:40:29 +0000292 compile_opts = extra_preargs or []
293 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000294 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000295 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000296 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000297 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000298
Thomas Heller9436a752003-12-05 20:12:23 +0000299 for obj in objects:
300 try:
301 src, ext = build[obj]
302 except KeyError:
303 continue
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000304 if debug:
305 # pass the full pathname to MSVC in debug mode,
306 # this allows the debugger to find the source file
307 # without asking the user to browse for it
308 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000309
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000310 if ext in self._c_extensions:
311 input_opt = "/Tc" + src
312 elif ext in self._cpp_extensions:
313 input_opt = "/Tp" + src
314 elif ext in self._rc_extensions:
315 # compile .RC to .RES file
316 input_opt = src
317 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000318 try:
Thomas Heller95827942003-01-31 20:40:15 +0000319 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000320 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000321 except DistutilsExecError, msg:
322 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000323 continue
324 elif ext in self._mc_extensions:
325
326 # Compile .MC to .RC file to .RES file.
327 # * '-h dir' specifies the directory for the
328 # generated include file
329 # * '-r dir' specifies the target directory of the
330 # generated RC file and the binary message resource
331 # it includes
332 #
333 # For now (since there are no options to change this),
334 # we use the source-directory for the include file and
335 # the build directory for the RC file and message
336 # resources. This works at least for win32all.
337
338 h_dir = os.path.dirname (src)
339 rc_dir = os.path.dirname (obj)
340 try:
341 # first compile .MC to .RC and .H file
342 self.spawn ([self.mc] +
343 ['-h', h_dir, '-r', rc_dir] + [src])
344 base, _ = os.path.splitext (os.path.basename (src))
345 rc_file = os.path.join (rc_dir, base + '.rc')
346 # then compile .RC to .RES file
347 self.spawn ([self.rc] +
348 ["/fo" + obj] + [rc_file])
349
350 except DistutilsExecError, msg:
351 raise CompileError, msg
352 continue
353 else:
354 # how to handle this file?
355 raise CompileError (
356 "Don't know how to compile %s to %s" % \
357 (src, obj))
358
359 output_opt = "/Fo" + obj
360 try:
361 self.spawn ([self.cc] + compile_opts + pp_opts +
362 [input_opt, output_opt] +
363 extra_postargs)
364 except DistutilsExecError, msg:
365 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000366
Greg Ward32c4a8a2000-03-06 03:40:29 +0000367 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000368
Greg Ward32c4a8a2000-03-06 03:40:29 +0000369 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000370
371
Greg Ward09fc5422000-03-10 01:49:26 +0000372 def create_static_lib (self,
373 objects,
374 output_libname,
375 output_dir=None,
376 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000377 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000378
Greg Ward2f557a22000-03-26 21:42:28 +0000379 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000380 output_filename = \
381 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000382
Greg Ward32c4a8a2000-03-06 03:40:29 +0000383 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000384 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000385 if debug:
386 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000387 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000388 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000389 except DistutilsExecError, msg:
390 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000391
Greg Ward32c4a8a2000-03-06 03:40:29 +0000392 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000393 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000394
Greg Ward09fc5422000-03-10 01:49:26 +0000395 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000396
Greg Ward42406482000-09-27 02:08:14 +0000397 def link (self,
398 target_desc,
399 objects,
400 output_filename,
401 output_dir=None,
402 libraries=None,
403 library_dirs=None,
404 runtime_library_dirs=None,
405 export_symbols=None,
406 debug=0,
407 extra_preargs=None,
408 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000409 build_temp=None,
410 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000411
Greg Ward2f557a22000-03-26 21:42:28 +0000412 (objects, output_dir) = self._fix_object_args (objects, output_dir)
413 (libraries, library_dirs, runtime_library_dirs) = \
414 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
415
Greg Wardf70c6032000-04-19 02:16:49 +0000416 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000417 self.warn ("I don't know what to do with 'runtime_library_dirs': "
418 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000419
Greg Wardd03f88a2000-03-18 15:19:51 +0000420 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000421 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000422 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000423 if output_dir is not None:
424 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000425
Greg Ward32c4a8a2000-03-06 03:40:29 +0000426 if self._need_link (objects, output_filename):
427
Greg Ward42406482000-09-27 02:08:14 +0000428 if target_desc == CCompiler.EXECUTABLE:
429 if debug:
430 ldflags = self.ldflags_shared_debug[1:]
431 else:
432 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000433 else:
Greg Ward42406482000-09-27 02:08:14 +0000434 if debug:
435 ldflags = self.ldflags_shared_debug
436 else:
437 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000438
Greg Ward5299b6a2000-05-20 13:23:21 +0000439 export_opts = []
440 for sym in (export_symbols or []):
441 export_opts.append("/EXPORT:" + sym)
442
Fred Drakeb94b8492001-12-06 20:51:35 +0000443 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000444 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000445
Greg Ward159eb922000-08-02 00:00:30 +0000446 # The MSVC linker generates .lib and .exp files, which cannot be
447 # suppressed by any linker switches. The .lib files may even be
448 # needed! Make sure they are generated in the temporary build
449 # directory. Since they have different names for debug and release
450 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000451 if export_symbols is not None:
452 (dll_name, dll_ext) = os.path.splitext(
453 os.path.basename(output_filename))
454 implib_file = os.path.join(
455 os.path.dirname(objects[0]),
456 self.library_filename(dll_name))
457 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000458
Greg Ward32c4a8a2000-03-06 03:40:29 +0000459 if extra_preargs:
460 ld_args[:0] = extra_preargs
461 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000462 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000463
464 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000465 try:
Greg Ward42406482000-09-27 02:08:14 +0000466 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000467 except DistutilsExecError, msg:
468 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000469
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000470 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000471 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000472
Greg Ward42406482000-09-27 02:08:14 +0000473 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000474
475
Greg Ward32c4a8a2000-03-06 03:40:29 +0000476 # -- Miscellaneous methods -----------------------------------------
477 # These are all used by the 'gen_lib_options() function, in
478 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000479
480 def library_dir_option (self, dir):
481 return "/LIBPATH:" + dir
482
Greg Wardd03f88a2000-03-18 15:19:51 +0000483 def runtime_library_dir_option (self, dir):
484 raise DistutilsPlatformError, \
485 "don't know how to set runtime library search path for MSVC++"
486
Greg Wardc74138d1999-10-03 20:47:52 +0000487 def library_option (self, lib):
488 return self.library_filename (lib)
489
490
Greg Wardd1425642000-08-04 01:29:27 +0000491 def find_library_file (self, dirs, lib, debug=0):
492 # Prefer a debugging library if found (and requested), but deal
493 # with it if we don't have one.
494 if debug:
495 try_names = [lib + "_d", lib]
496 else:
497 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000498 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000499 for name in try_names:
500 libfile = os.path.join(dir, self.library_filename (name))
501 if os.path.exists(libfile):
502 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000503 else:
504 # Oops, didn't find it in *any* of 'dirs'
505 return None
506
507 # find_library_file ()
508
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000509 # Helper methods for using the MSVC registry settings
510
511 def find_exe(self, exe):
512 """Return path to an MSVC executable program.
513
514 Tries to find the program in several places: first, one of the
515 MSVC program search paths from the registry; next, the directories
516 in the PATH environment variable. If any of those work, return an
517 absolute path that is known to exist. If none of them work, just
518 return the original program name, 'exe'.
519 """
520
521 for p in self.__paths:
522 fn = os.path.join(os.path.abspath(p), exe)
523 if os.path.isfile(fn):
524 return fn
525
526 # didn't find it; try existing path
527 for p in string.split(os.environ['Path'],';'):
528 fn = os.path.join(os.path.abspath(p),exe)
529 if os.path.isfile(fn):
530 return fn
531
532 return exe
Tim Peters182b5ac2004-07-18 06:16:08 +0000533
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000534 def get_msvc_paths(self, path, platform='x86'):
535 """Get a list of devstudio directories (include, lib or path).
536
537 Return a list of strings. The list will be empty if unable to
538 access the registry or appropriate registry keys not found.
539 """
540
541 if not _can_read_reg:
542 return []
543
544 path = path + " dirs"
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000545 if self.__version >= 7:
546 key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
547 % (self.__root, self.__version))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000548 else:
549 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000550 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000551
552 for base in HKEYS:
553 d = read_values(base, key)
554 if d:
Jeremy Hyltone9a92aa2003-07-17 14:41:07 +0000555 if self.__version >= 7:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000556 return string.split(self.__macros.sub(d[path]), ";")
557 else:
558 return string.split(d[path], ";")
Thomas Hellerb3105912003-11-28 19:42:56 +0000559 # MSVC 6 seems to create the registry entries we need only when
560 # the GUI is run.
561 if self.__version == 6:
562 for base in HKEYS:
563 if read_values(base, r"%s\6.0" % self.__root) is not None:
564 self.warn("It seems you have Visual Studio 6 installed, "
565 "but the expected registry settings are not present.\n"
566 "You must at least run the Visual Studio GUI once "
567 "so that these entries are created.")
568 break
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000569 return []
570
571 def set_path_env_var(self, name):
572 """Set environment variable 'name' to an MSVC path type value.
573
574 This is equivalent to a SET command prior to execution of spawned
575 commands.
576 """
577
578 if name == "lib":
579 p = self.get_msvc_paths("library")
580 else:
581 p = self.get_msvc_paths(name)
582 if p:
583 os.environ[name] = string.join(p, ';')