blob: 65a50cc79a4a839713c62277a4a4180e0fe18c13 [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
Greg Warddf178f91999-09-29 12:29:10 +00004for the Microsoft Visual Studio."""
Greg Warddbd12761999-08-29 18:15:07 +00005
Andrew M. Kuchlinga6483d22002-11-14 02:25:42 +00006# Written by Perry Stoll
Greg Ward32c4a8a2000-03-06 03:40:29 +00007# hacked by Robin Becker and Thomas Heller to do a better job of
8# finding DevStudio (through the registry)
9
Andrew M. Kuchlingd448f662002-11-19 13:12:28 +000010# This module should be kept compatible with Python 1.5.2.
11
Greg Ward3ce77fd2000-03-02 01:49:45 +000012__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000013
Greg Ward32c4a8a2000-03-06 03:40:29 +000014import sys, os, string
15from types import *
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:
48 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000049
50if _can_read_reg:
51 HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT
52 HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE
53 HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER
54 HKEY_USERS = hkey_mod.HKEY_USERS
Fred Drakeb94b8492001-12-06 20:51:35 +000055
56
Greg Ward7642f5c2000-03-31 16:47:40 +000057
Greg Ward62e33932000-02-10 02:52:42 +000058def get_devstudio_versions ():
Greg Ward62e33932000-02-10 02:52:42 +000059 """Get list of devstudio versions from the Windows registry. Return a
Greg Ward69988092000-02-11 02:47:15 +000060 list of strings containing version numbers; the list will be
Greg Ward62e33932000-02-10 02:52:42 +000061 empty if we were unable to access the registry (eg. couldn't import
62 a registry-access module) or the appropriate registry keys weren't
Greg Ward69988092000-02-11 02:47:15 +000063 found."""
64
Greg Ward7642f5c2000-03-31 16:47:40 +000065 if not _can_read_reg:
Greg Ward62e33932000-02-10 02:52:42 +000066 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000067
68 K = 'Software\\Microsoft\\Devstudio'
69 L = []
Greg Ward1027e3f2000-03-31 16:53:42 +000070 for base in (HKEY_CLASSES_ROOT,
71 HKEY_LOCAL_MACHINE,
72 HKEY_CURRENT_USER,
73 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +000074 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000075 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +000076 i = 0
77 while 1:
78 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000079 p = RegEnumKey(k,i)
Greg Ward1b9c6f72000-02-08 02:39:44 +000080 if p[0] in '123456789' and p not in L:
81 L.append(p)
Greg Ward1027e3f2000-03-31 16:53:42 +000082 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000083 break
84 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +000085 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000086 pass
87 L.sort()
88 L.reverse()
89 return L
90
Greg Ward62e33932000-02-10 02:52:42 +000091# get_devstudio_versions ()
92
93
94def get_msvc_paths (path, version='6.0', platform='x86'):
Greg Ward69988092000-02-11 02:47:15 +000095 """Get a list of devstudio directories (include, lib or path). Return
96 a list of strings; will be empty list if unable to access the
97 registry or appropriate registry keys not found."""
Fred Drakeb94b8492001-12-06 20:51:35 +000098
Greg Ward7642f5c2000-03-31 16:47:40 +000099 if not _can_read_reg:
Greg Ward69988092000-02-11 02:47:15 +0000100 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +0000101
102 L = []
Greg Ward62e33932000-02-10 02:52:42 +0000103 if path=='lib':
104 path= 'Library'
Greg Ward1b9c6f72000-02-08 02:39:44 +0000105 path = string.upper(path + ' Dirs')
Greg Ward62e33932000-02-10 02:52:42 +0000106 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
107 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
108 (version,platform)
Greg Ward1027e3f2000-03-31 16:53:42 +0000109 for base in (HKEY_CLASSES_ROOT,
110 HKEY_LOCAL_MACHINE,
111 HKEY_CURRENT_USER,
112 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +0000113 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000114 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +0000115 i = 0
116 while 1:
117 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000118 (p,v,t) = RegEnumValue(k,i)
Greg Ward62e33932000-02-10 02:52:42 +0000119 if string.upper(p) == path:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000120 V = string.split(v,';')
121 for v in V:
Thomas Heller745b4602002-02-08 14:41:31 +0000122 if hasattr(v, "encode"):
123 try:
124 v = v.encode("mbcs")
125 except UnicodeError:
126 pass
Greg Ward62e33932000-02-10 02:52:42 +0000127 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000128 L.append(v)
129 break
130 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000131 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000132 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000133 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000134 pass
135 return L
136
Greg Ward62e33932000-02-10 02:52:42 +0000137# get_msvc_paths()
138
139
Greg Ward69988092000-02-11 02:47:15 +0000140def find_exe (exe, version_number):
141 """Try to find an MSVC executable program 'exe' (from version
142 'version_number' of MSVC) in several places: first, one of the MSVC
143 program search paths from the registry; next, the directories in the
144 PATH environment variable. If any of those work, return an absolute
145 path that is known to exist. If none of them work, just return the
146 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000147
Greg Ward69988092000-02-11 02:47:15 +0000148 for p in get_msvc_paths ('path', version_number):
149 fn = os.path.join (os.path.abspath(p), exe)
150 if os.path.isfile(fn):
151 return fn
152
153 # didn't find it; try existing path
154 for p in string.split (os.environ['Path'],';'):
155 fn = os.path.join(os.path.abspath(p),exe)
156 if os.path.isfile(fn):
157 return fn
158
Fred Drakeb94b8492001-12-06 20:51:35 +0000159 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000160
Greg Ward62e33932000-02-10 02:52:42 +0000161
Greg Ward5de8cee2000-02-11 02:52:39 +0000162def set_path_env_var (name, version_number):
163 """Set environment variable 'name' to an MSVC path type value obtained
164 from 'get_msvc_paths()'. This is equivalent to a SET command prior
165 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000166
Greg Ward5de8cee2000-02-11 02:52:39 +0000167 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000168 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000169 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000170
Greg Warddbd12761999-08-29 18:15:07 +0000171
Greg Ward3d50b901999-09-08 02:36:01 +0000172class MSVCCompiler (CCompiler) :
173 """Concrete class that implements an interface to Microsoft Visual C++,
174 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000175
Greg Warddf178f91999-09-29 12:29:10 +0000176 compiler_type = 'msvc'
177
Greg Ward992c8f92000-06-25 02:31:16 +0000178 # Just set this so CCompiler's constructor doesn't barf. We currently
179 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
180 # as it really isn't necessary for this sort of single-compiler class.
181 # Would be nice to have a consistent interface with UnixCCompiler,
182 # though, so it's worth thinking about.
183 executables = {}
184
Greg Ward32c4a8a2000-03-06 03:40:29 +0000185 # Private class data (need to distinguish C from C++ source for compiler)
186 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000187 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000188 _rc_extensions = ['.rc']
189 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000190
191 # Needed for the filename generation methods provided by the
192 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000193 src_extensions = (_c_extensions + _cpp_extensions +
194 _rc_extensions + _mc_extensions)
195 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000196 obj_extension = '.obj'
197 static_lib_extension = '.lib'
198 shared_lib_extension = '.dll'
199 static_lib_format = shared_lib_format = '%s%s'
200 exe_extension = '.exe'
201
202
Greg Warddbd12761999-08-29 18:15:07 +0000203 def __init__ (self,
204 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000205 dry_run=0,
206 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000207
Greg Wardc74138d1999-10-03 20:47:52 +0000208 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000209 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000210
Greg Ward5de8cee2000-02-11 02:52:39 +0000211 if versions:
212 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000213
Greg Ward41b4dd62000-03-29 04:13:00 +0000214 self.cc = find_exe("cl.exe", version)
Greg Ward42406482000-09-27 02:08:14 +0000215 self.linker = find_exe("link.exe", version)
Greg Ward41b4dd62000-03-29 04:13:00 +0000216 self.lib = find_exe("lib.exe", version)
Greg Ward9c0ea132000-09-19 23:56:43 +0000217 self.rc = find_exe("rc.exe", version) # resource compiler
218 self.mc = find_exe("mc.exe", version) # message compiler
Greg Ward5de8cee2000-02-11 02:52:39 +0000219 set_path_env_var ('lib', version)
220 set_path_env_var ('include', version)
221 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000222 try:
223 for p in string.split(os.environ['path'],';'):
224 path.append(p)
225 except KeyError:
226 pass
227 os.environ['path'] = string.join(path,';')
228 else:
229 # devstudio not found in the registry
230 self.cc = "cl.exe"
Greg Ward42406482000-09-27 02:08:14 +0000231 self.linker = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000232 self.lib = "lib.exe"
Greg Ward9c0ea132000-09-19 23:56:43 +0000233 self.rc = "rc.exe"
234 self.mc = "mc.exe"
Greg Ward69988092000-02-11 02:47:15 +0000235
Greg Warddbd12761999-08-29 18:15:07 +0000236 self.preprocess_options = None
Jeremy Hylton2683ac72002-06-18 19:08:40 +0000237 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
238 '/DNDEBUG']
Greg Ward8a98cd92000-08-31 00:31:07 +0000239 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
240 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000241
Greg Ward1b9c6f72000-02-08 02:39:44 +0000242 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000243 self.ldflags_shared_debug = [
244 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
245 ]
Greg Warddbd12761999-08-29 18:15:07 +0000246 self.ldflags_static = [ '/nologo']
247
Greg Warddbd12761999-08-29 18:15:07 +0000248
249 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000250
Greg Ward9c0ea132000-09-19 23:56:43 +0000251 def object_filenames (self,
252 source_filenames,
253 strip_dir=0,
254 output_dir=''):
255 # Copied from ccompiler.py, extended to return .res as 'object'-file
256 # for .rc input file
257 if output_dir is None: output_dir = ''
258 obj_names = []
259 for src_name in source_filenames:
260 (base, ext) = os.path.splitext (src_name)
261 if ext not in self.src_extensions:
262 # Better to raise an exception instead of silently continuing
263 # and later complain about sources and targets having
264 # different lengths
265 raise CompileError ("Don't know how to compile %s" % src_name)
266 if strip_dir:
267 base = os.path.basename (base)
268 if ext in self._rc_extensions:
269 obj_names.append (os.path.join (output_dir,
270 base + self.res_extension))
271 elif ext in self._mc_extensions:
272 obj_names.append (os.path.join (output_dir,
273 base + self.res_extension))
274 else:
275 obj_names.append (os.path.join (output_dir,
276 base + self.obj_extension))
277 return obj_names
278
279 # object_filenames ()
280
281
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000282 def compile(self, sources,
283 output_dir=None, macros=None, include_dirs=None, debug=0,
284 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000285
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000286 macros, objects, extra_postargs, pp_opts, build = \
287 self._setup_compile(output_dir, macros, include_dirs, sources,
288 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000289
Greg Ward32c4a8a2000-03-06 03:40:29 +0000290 compile_opts = extra_preargs or []
291 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000292 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000293 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000294 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000295 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000296
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000297 for obj, (src, ext) in build.items():
298 if debug:
299 # pass the full pathname to MSVC in debug mode,
300 # this allows the debugger to find the source file
301 # without asking the user to browse for it
302 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000303
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000304 if ext in self._c_extensions:
305 input_opt = "/Tc" + src
306 elif ext in self._cpp_extensions:
307 input_opt = "/Tp" + src
308 elif ext in self._rc_extensions:
309 # compile .RC to .RES file
310 input_opt = src
311 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000312 try:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000313 self.spawn ([self.rc] +
314 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000315 except DistutilsExecError, msg:
316 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000317 continue
318 elif ext in self._mc_extensions:
319
320 # Compile .MC to .RC file to .RES file.
321 # * '-h dir' specifies the directory for the
322 # generated include file
323 # * '-r dir' specifies the target directory of the
324 # generated RC file and the binary message resource
325 # it includes
326 #
327 # For now (since there are no options to change this),
328 # we use the source-directory for the include file and
329 # the build directory for the RC file and message
330 # resources. This works at least for win32all.
331
332 h_dir = os.path.dirname (src)
333 rc_dir = os.path.dirname (obj)
334 try:
335 # first compile .MC to .RC and .H file
336 self.spawn ([self.mc] +
337 ['-h', h_dir, '-r', rc_dir] + [src])
338 base, _ = os.path.splitext (os.path.basename (src))
339 rc_file = os.path.join (rc_dir, base + '.rc')
340 # then compile .RC to .RES file
341 self.spawn ([self.rc] +
342 ["/fo" + obj] + [rc_file])
343
344 except DistutilsExecError, msg:
345 raise CompileError, msg
346 continue
347 else:
348 # how to handle this file?
349 raise CompileError (
350 "Don't know how to compile %s to %s" % \
351 (src, obj))
352
353 output_opt = "/Fo" + obj
354 try:
355 self.spawn ([self.cc] + compile_opts + pp_opts +
356 [input_opt, output_opt] +
357 extra_postargs)
358 except DistutilsExecError, msg:
359 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000360
Greg Ward32c4a8a2000-03-06 03:40:29 +0000361 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000362
Greg Ward32c4a8a2000-03-06 03:40:29 +0000363 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000364
365
Greg Ward09fc5422000-03-10 01:49:26 +0000366 def create_static_lib (self,
367 objects,
368 output_libname,
369 output_dir=None,
370 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000371 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000372
Greg Ward2f557a22000-03-26 21:42:28 +0000373 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000374 output_filename = \
375 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000376
Greg Ward32c4a8a2000-03-06 03:40:29 +0000377 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000378 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000379 if debug:
380 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000381 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000382 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000383 except DistutilsExecError, msg:
384 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000385
Greg Ward32c4a8a2000-03-06 03:40:29 +0000386 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000387 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000388
Greg Ward09fc5422000-03-10 01:49:26 +0000389 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000390
Greg Ward42406482000-09-27 02:08:14 +0000391 def link (self,
392 target_desc,
393 objects,
394 output_filename,
395 output_dir=None,
396 libraries=None,
397 library_dirs=None,
398 runtime_library_dirs=None,
399 export_symbols=None,
400 debug=0,
401 extra_preargs=None,
402 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000403 build_temp=None,
404 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000405
Greg Ward2f557a22000-03-26 21:42:28 +0000406 (objects, output_dir) = self._fix_object_args (objects, output_dir)
407 (libraries, library_dirs, runtime_library_dirs) = \
408 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
409
Greg Wardf70c6032000-04-19 02:16:49 +0000410 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000411 self.warn ("I don't know what to do with 'runtime_library_dirs': "
412 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000413
Greg Wardd03f88a2000-03-18 15:19:51 +0000414 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000415 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000416 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000417 if output_dir is not None:
418 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000419
Greg Ward32c4a8a2000-03-06 03:40:29 +0000420 if self._need_link (objects, output_filename):
421
Greg Ward42406482000-09-27 02:08:14 +0000422 if target_desc == CCompiler.EXECUTABLE:
423 if debug:
424 ldflags = self.ldflags_shared_debug[1:]
425 else:
426 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000427 else:
Greg Ward42406482000-09-27 02:08:14 +0000428 if debug:
429 ldflags = self.ldflags_shared_debug
430 else:
431 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000432
Greg Ward5299b6a2000-05-20 13:23:21 +0000433 export_opts = []
434 for sym in (export_symbols or []):
435 export_opts.append("/EXPORT:" + sym)
436
Fred Drakeb94b8492001-12-06 20:51:35 +0000437 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000438 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000439
Greg Ward159eb922000-08-02 00:00:30 +0000440 # The MSVC linker generates .lib and .exp files, which cannot be
441 # suppressed by any linker switches. The .lib files may even be
442 # needed! Make sure they are generated in the temporary build
443 # directory. Since they have different names for debug and release
444 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000445 if export_symbols is not None:
446 (dll_name, dll_ext) = os.path.splitext(
447 os.path.basename(output_filename))
448 implib_file = os.path.join(
449 os.path.dirname(objects[0]),
450 self.library_filename(dll_name))
451 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000452
Greg Ward32c4a8a2000-03-06 03:40:29 +0000453 if extra_preargs:
454 ld_args[:0] = extra_preargs
455 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000456 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000457
458 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000459 try:
Greg Ward42406482000-09-27 02:08:14 +0000460 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000461 except DistutilsExecError, msg:
462 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000463
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000464 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000465 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000466
Greg Ward42406482000-09-27 02:08:14 +0000467 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000468
469
Greg Ward32c4a8a2000-03-06 03:40:29 +0000470 # -- Miscellaneous methods -----------------------------------------
471 # These are all used by the 'gen_lib_options() function, in
472 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000473
474 def library_dir_option (self, dir):
475 return "/LIBPATH:" + dir
476
Greg Wardd03f88a2000-03-18 15:19:51 +0000477 def runtime_library_dir_option (self, dir):
478 raise DistutilsPlatformError, \
479 "don't know how to set runtime library search path for MSVC++"
480
Greg Wardc74138d1999-10-03 20:47:52 +0000481 def library_option (self, lib):
482 return self.library_filename (lib)
483
484
Greg Wardd1425642000-08-04 01:29:27 +0000485 def find_library_file (self, dirs, lib, debug=0):
486 # Prefer a debugging library if found (and requested), but deal
487 # with it if we don't have one.
488 if debug:
489 try_names = [lib + "_d", lib]
490 else:
491 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000492 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000493 for name in try_names:
494 libfile = os.path.join(dir, self.library_filename (name))
495 if os.path.exists(libfile):
496 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000497 else:
498 # Oops, didn't find it in *any* of 'dirs'
499 return None
500
501 # find_library_file ()
502
Greg Warddbd12761999-08-29 18:15:07 +0000503# class MSVCCompiler