blob: ade8172d3bbbc29e5ac340cb0e73c93e1798d169 [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
6
7# created 1999/08/19, Perry Stoll
Greg Ward32c4a8a2000-03-06 03:40:29 +00008# hacked by Robin Becker and Thomas Heller to do a better job of
9# finding DevStudio (through the registry)
10
Greg Ward3ce77fd2000-03-02 01:49:45 +000011__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000012
Greg Ward32c4a8a2000-03-06 03:40:29 +000013import sys, os, string
14from types import *
Greg Ward3add77f2000-05-30 02:02:49 +000015from distutils.errors import \
16 DistutilsExecError, DistutilsPlatformError, \
Greg Wardd1517112000-05-30 01:56:44 +000017 CompileError, LibError, LinkError
Greg Ward3add77f2000-05-30 02:02:49 +000018from distutils.ccompiler import \
19 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000020from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000021
Greg Ward7642f5c2000-03-31 16:47:40 +000022_can_read_reg = 0
23try:
Greg Ward1b5ec762000-06-30 19:37:59 +000024 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000025
Greg Ward7642f5c2000-03-31 16:47:40 +000026 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000027 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000028
Greg Wardcd079c42000-06-29 22:59:10 +000029 RegOpenKeyEx = _winreg.OpenKeyEx
30 RegEnumKey = _winreg.EnumKey
31 RegEnumValue = _winreg.EnumValue
32 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000033
Greg Ward7642f5c2000-03-31 16:47:40 +000034except ImportError:
35 try:
36 import win32api
37 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000038 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000039 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000040
41 RegOpenKeyEx = win32api.RegOpenKeyEx
42 RegEnumKey = win32api.RegEnumKey
43 RegEnumValue = win32api.RegEnumValue
44 RegError = win32api.error
45
Greg Ward7642f5c2000-03-31 16:47:40 +000046 except ImportError:
47 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000048
49if _can_read_reg:
50 HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT
51 HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE
52 HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER
53 HKEY_USERS = hkey_mod.HKEY_USERS
Fred Drakeb94b8492001-12-06 20:51:35 +000054
55
Greg Ward7642f5c2000-03-31 16:47:40 +000056
Greg Ward62e33932000-02-10 02:52:42 +000057def get_devstudio_versions ():
Greg Ward62e33932000-02-10 02:52:42 +000058 """Get list of devstudio versions from the Windows registry. Return a
Greg Ward69988092000-02-11 02:47:15 +000059 list of strings containing version numbers; the list will be
Greg Ward62e33932000-02-10 02:52:42 +000060 empty if we were unable to access the registry (eg. couldn't import
61 a registry-access module) or the appropriate registry keys weren't
Greg Ward69988092000-02-11 02:47:15 +000062 found."""
63
Greg Ward7642f5c2000-03-31 16:47:40 +000064 if not _can_read_reg:
Greg Ward62e33932000-02-10 02:52:42 +000065 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000066
67 K = 'Software\\Microsoft\\Devstudio'
68 L = []
Greg Ward1027e3f2000-03-31 16:53:42 +000069 for base in (HKEY_CLASSES_ROOT,
70 HKEY_LOCAL_MACHINE,
71 HKEY_CURRENT_USER,
72 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +000073 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000074 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +000075 i = 0
76 while 1:
77 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000078 p = RegEnumKey(k,i)
Greg Ward1b9c6f72000-02-08 02:39:44 +000079 if p[0] in '123456789' and p not in L:
80 L.append(p)
Greg Ward1027e3f2000-03-31 16:53:42 +000081 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000082 break
83 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +000084 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000085 pass
86 L.sort()
87 L.reverse()
88 return L
89
Greg Ward62e33932000-02-10 02:52:42 +000090# get_devstudio_versions ()
91
92
93def get_msvc_paths (path, version='6.0', platform='x86'):
Greg Ward69988092000-02-11 02:47:15 +000094 """Get a list of devstudio directories (include, lib or path). Return
95 a list of strings; will be empty list if unable to access the
96 registry or appropriate registry keys not found."""
Fred Drakeb94b8492001-12-06 20:51:35 +000097
Greg Ward7642f5c2000-03-31 16:47:40 +000098 if not _can_read_reg:
Greg Ward69988092000-02-11 02:47:15 +000099 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +0000100
101 L = []
Greg Ward62e33932000-02-10 02:52:42 +0000102 if path=='lib':
103 path= 'Library'
Greg Ward1b9c6f72000-02-08 02:39:44 +0000104 path = string.upper(path + ' Dirs')
Greg Ward62e33932000-02-10 02:52:42 +0000105 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
106 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
107 (version,platform)
Greg Ward1027e3f2000-03-31 16:53:42 +0000108 for base in (HKEY_CLASSES_ROOT,
109 HKEY_LOCAL_MACHINE,
110 HKEY_CURRENT_USER,
111 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +0000112 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000113 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +0000114 i = 0
115 while 1:
116 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000117 (p,v,t) = RegEnumValue(k,i)
Greg Ward62e33932000-02-10 02:52:42 +0000118 if string.upper(p) == path:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000119 V = string.split(v,';')
120 for v in V:
Thomas Heller745b4602002-02-08 14:41:31 +0000121 if hasattr(v, "encode"):
122 try:
123 v = v.encode("mbcs")
124 except UnicodeError:
125 pass
Greg Ward62e33932000-02-10 02:52:42 +0000126 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000127 L.append(v)
128 break
129 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000130 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000131 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000132 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000133 pass
134 return L
135
Greg Ward62e33932000-02-10 02:52:42 +0000136# get_msvc_paths()
137
138
Greg Ward69988092000-02-11 02:47:15 +0000139def find_exe (exe, version_number):
140 """Try to find an MSVC executable program 'exe' (from version
141 'version_number' of MSVC) in several places: first, one of the MSVC
142 program search paths from the registry; next, the directories in the
143 PATH environment variable. If any of those work, return an absolute
144 path that is known to exist. If none of them work, just return the
145 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000146
Greg Ward69988092000-02-11 02:47:15 +0000147 for p in get_msvc_paths ('path', version_number):
148 fn = os.path.join (os.path.abspath(p), exe)
149 if os.path.isfile(fn):
150 return fn
151
152 # didn't find it; try existing path
153 for p in string.split (os.environ['Path'],';'):
154 fn = os.path.join(os.path.abspath(p),exe)
155 if os.path.isfile(fn):
156 return fn
157
Fred Drakeb94b8492001-12-06 20:51:35 +0000158 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000159
Greg Ward62e33932000-02-10 02:52:42 +0000160
Greg Ward5de8cee2000-02-11 02:52:39 +0000161def set_path_env_var (name, version_number):
162 """Set environment variable 'name' to an MSVC path type value obtained
163 from 'get_msvc_paths()'. This is equivalent to a SET command prior
164 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000165
Greg Ward5de8cee2000-02-11 02:52:39 +0000166 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000167 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000168 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +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
201
Greg Warddbd12761999-08-29 18:15:07 +0000202 def __init__ (self,
203 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000204 dry_run=0,
205 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000206
Greg Wardc74138d1999-10-03 20:47:52 +0000207 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000208 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000209
Greg Ward5de8cee2000-02-11 02:52:39 +0000210 if versions:
211 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000212
Greg Ward41b4dd62000-03-29 04:13:00 +0000213 self.cc = find_exe("cl.exe", version)
Greg Ward42406482000-09-27 02:08:14 +0000214 self.linker = find_exe("link.exe", version)
Greg Ward41b4dd62000-03-29 04:13:00 +0000215 self.lib = find_exe("lib.exe", version)
Greg Ward9c0ea132000-09-19 23:56:43 +0000216 self.rc = find_exe("rc.exe", version) # resource compiler
217 self.mc = find_exe("mc.exe", version) # message compiler
Greg Ward5de8cee2000-02-11 02:52:39 +0000218 set_path_env_var ('lib', version)
219 set_path_env_var ('include', version)
220 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000221 try:
222 for p in string.split(os.environ['path'],';'):
223 path.append(p)
224 except KeyError:
225 pass
226 os.environ['path'] = string.join(path,';')
227 else:
228 # devstudio not found in the registry
229 self.cc = "cl.exe"
Greg Ward42406482000-09-27 02:08:14 +0000230 self.linker = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000231 self.lib = "lib.exe"
Greg Ward9c0ea132000-09-19 23:56:43 +0000232 self.rc = "rc.exe"
233 self.mc = "mc.exe"
Greg Ward69988092000-02-11 02:47:15 +0000234
Greg Warddbd12761999-08-29 18:15:07 +0000235 self.preprocess_options = None
Greg Ward8a98cd92000-08-31 00:31:07 +0000236 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ]
237 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
238 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000239
Greg Ward1b9c6f72000-02-08 02:39:44 +0000240 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000241 self.ldflags_shared_debug = [
242 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
243 ]
Greg Warddbd12761999-08-29 18:15:07 +0000244 self.ldflags_static = [ '/nologo']
245
Greg Warddbd12761999-08-29 18:15:07 +0000246
247 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000248
Greg Ward9c0ea132000-09-19 23:56:43 +0000249 def object_filenames (self,
250 source_filenames,
251 strip_dir=0,
252 output_dir=''):
253 # Copied from ccompiler.py, extended to return .res as 'object'-file
254 # for .rc input file
255 if output_dir is None: output_dir = ''
256 obj_names = []
257 for src_name in source_filenames:
258 (base, ext) = os.path.splitext (src_name)
259 if ext not in self.src_extensions:
260 # Better to raise an exception instead of silently continuing
261 # and later complain about sources and targets having
262 # different lengths
263 raise CompileError ("Don't know how to compile %s" % src_name)
264 if strip_dir:
265 base = os.path.basename (base)
266 if ext in self._rc_extensions:
267 obj_names.append (os.path.join (output_dir,
268 base + self.res_extension))
269 elif ext in self._mc_extensions:
270 obj_names.append (os.path.join (output_dir,
271 base + self.res_extension))
272 else:
273 obj_names.append (os.path.join (output_dir,
274 base + self.obj_extension))
275 return obj_names
276
277 # object_filenames ()
278
279
Greg Warddbd12761999-08-29 18:15:07 +0000280 def compile (self,
281 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000282 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000283 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000284 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000285 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000286 extra_preargs=None,
287 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000288
Greg Ward32c4a8a2000-03-06 03:40:29 +0000289 (output_dir, macros, include_dirs) = \
290 self._fix_compile_args (output_dir, macros, include_dirs)
291 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000292
Greg Ward32c4a8a2000-03-06 03:40:29 +0000293 if extra_postargs is None:
294 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000295
Greg Ward32c4a8a2000-03-06 03:40:29 +0000296 pp_opts = gen_preprocess_options (macros, include_dirs)
297 compile_opts = extra_preargs or []
298 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000299 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000300 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000301 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000302 compile_opts.extend (self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000303
Greg Ward32c4a8a2000-03-06 03:40:29 +0000304 for i in range (len (sources)):
305 src = sources[i] ; obj = objects[i]
306 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000307
Greg Ward32c4a8a2000-03-06 03:40:29 +0000308 if skip_sources[src]:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000309 log.debug("skipping %s (%s up-to-date)", src, obj)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000310 else:
Greg Ward9c0ea132000-09-19 23:56:43 +0000311 self.mkpath (os.path.dirname (obj))
312
Thomas Heller69d31b72002-04-25 17:29:45 +0000313 if debug:
314 # pass the full pathname to MSVC in debug mode,
315 # this allows the debugger to find the source file
316 # without asking the user to browse for it
317 src = os.path.abspath(src)
318
Greg Ward32c4a8a2000-03-06 03:40:29 +0000319 if ext in self._c_extensions:
320 input_opt = "/Tc" + src
321 elif ext in self._cpp_extensions:
322 input_opt = "/Tp" + src
Greg Ward9c0ea132000-09-19 23:56:43 +0000323 elif ext in self._rc_extensions:
324 # compile .RC to .RES file
325 input_opt = src
326 output_opt = "/fo" + obj
327 try:
328 self.spawn ([self.rc] +
329 [output_opt] + [input_opt])
330 except DistutilsExecError, msg:
331 raise CompileError, msg
332 continue
333 elif ext in self._mc_extensions:
334
335 # Compile .MC to .RC file to .RES file.
336 # * '-h dir' specifies the directory for the
337 # generated include file
338 # * '-r dir' specifies the target directory of the
339 # generated RC file and the binary message resource
340 # it includes
341 #
342 # For now (since there are no options to change this),
343 # we use the source-directory for the include file and
344 # the build directory for the RC file and message
345 # resources. This works at least for win32all.
346
347 h_dir = os.path.dirname (src)
348 rc_dir = os.path.dirname (obj)
349 try:
350 # first compile .MC to .RC and .H file
351 self.spawn ([self.mc] +
352 ['-h', h_dir, '-r', rc_dir] + [src])
353 base, _ = os.path.splitext (os.path.basename (src))
354 rc_file = os.path.join (rc_dir, base + '.rc')
355 # then compile .RC to .RES file
356 self.spawn ([self.rc] +
357 ["/fo" + obj] + [rc_file])
358
359 except DistutilsExecError, msg:
360 raise CompileError, msg
361 continue
362 else:
363 # how to handle this file?
364 raise CompileError (
365 "Don't know how to compile %s to %s" % \
366 (src, obj))
Greg Warddbd12761999-08-29 18:15:07 +0000367
Greg Ward32c4a8a2000-03-06 03:40:29 +0000368 output_opt = "/Fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000369 try:
370 self.spawn ([self.cc] + compile_opts + pp_opts +
371 [input_opt, output_opt] +
372 extra_postargs)
373 except DistutilsExecError, msg:
374 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000375
Greg Ward32c4a8a2000-03-06 03:40:29 +0000376 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000377
Greg Ward32c4a8a2000-03-06 03:40:29 +0000378 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000379
380
Greg Ward09fc5422000-03-10 01:49:26 +0000381 def create_static_lib (self,
382 objects,
383 output_libname,
384 output_dir=None,
385 debug=0,
386 extra_preargs=None,
387 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000388
Greg Ward2f557a22000-03-26 21:42:28 +0000389 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000390 output_filename = \
391 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000392
Greg Ward32c4a8a2000-03-06 03:40:29 +0000393 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000394 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000395 if debug:
396 pass # XXX what goes here?
397 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000398 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000399 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000400 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000401 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000402 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000403 except DistutilsExecError, msg:
404 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000405
Greg Ward32c4a8a2000-03-06 03:40:29 +0000406 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000407 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000408
Greg Ward09fc5422000-03-10 01:49:26 +0000409 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000410
Greg Ward42406482000-09-27 02:08:14 +0000411 def link (self,
412 target_desc,
413 objects,
414 output_filename,
415 output_dir=None,
416 libraries=None,
417 library_dirs=None,
418 runtime_library_dirs=None,
419 export_symbols=None,
420 debug=0,
421 extra_preargs=None,
422 extra_postargs=None,
423 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000424
Greg Ward2f557a22000-03-26 21:42:28 +0000425 (objects, output_dir) = self._fix_object_args (objects, output_dir)
426 (libraries, library_dirs, runtime_library_dirs) = \
427 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
428
Greg Wardf70c6032000-04-19 02:16:49 +0000429 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000430 self.warn ("I don't know what to do with 'runtime_library_dirs': "
431 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000432
Greg Wardd03f88a2000-03-18 15:19:51 +0000433 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000434 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000435 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000436 if output_dir is not None:
437 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000438
Greg Ward32c4a8a2000-03-06 03:40:29 +0000439 if self._need_link (objects, output_filename):
440
Greg Ward42406482000-09-27 02:08:14 +0000441 if target_desc == CCompiler.EXECUTABLE:
442 if debug:
443 ldflags = self.ldflags_shared_debug[1:]
444 else:
445 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000446 else:
Greg Ward42406482000-09-27 02:08:14 +0000447 if debug:
448 ldflags = self.ldflags_shared_debug
449 else:
450 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000451
Greg Ward5299b6a2000-05-20 13:23:21 +0000452 export_opts = []
453 for sym in (export_symbols or []):
454 export_opts.append("/EXPORT:" + sym)
455
Fred Drakeb94b8492001-12-06 20:51:35 +0000456 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000457 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000458
Greg Ward159eb922000-08-02 00:00:30 +0000459 # The MSVC linker generates .lib and .exp files, which cannot be
460 # suppressed by any linker switches. The .lib files may even be
461 # needed! Make sure they are generated in the temporary build
462 # directory. Since they have different names for debug and release
463 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000464 if export_symbols is not None:
465 (dll_name, dll_ext) = os.path.splitext(
466 os.path.basename(output_filename))
467 implib_file = os.path.join(
468 os.path.dirname(objects[0]),
469 self.library_filename(dll_name))
470 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000471
Greg Ward32c4a8a2000-03-06 03:40:29 +0000472 if extra_preargs:
473 ld_args[:0] = extra_preargs
474 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000475 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000476
477 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000478 try:
Greg Ward42406482000-09-27 02:08:14 +0000479 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000480 except DistutilsExecError, msg:
481 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000482
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000483 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000484 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000485
Greg Ward42406482000-09-27 02:08:14 +0000486 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000487
488
Greg Ward32c4a8a2000-03-06 03:40:29 +0000489 # -- Miscellaneous methods -----------------------------------------
490 # These are all used by the 'gen_lib_options() function, in
491 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000492
493 def library_dir_option (self, dir):
494 return "/LIBPATH:" + dir
495
Greg Wardd03f88a2000-03-18 15:19:51 +0000496 def runtime_library_dir_option (self, dir):
497 raise DistutilsPlatformError, \
498 "don't know how to set runtime library search path for MSVC++"
499
Greg Wardc74138d1999-10-03 20:47:52 +0000500 def library_option (self, lib):
501 return self.library_filename (lib)
502
503
Greg Wardd1425642000-08-04 01:29:27 +0000504 def find_library_file (self, dirs, lib, debug=0):
505 # Prefer a debugging library if found (and requested), but deal
506 # with it if we don't have one.
507 if debug:
508 try_names = [lib + "_d", lib]
509 else:
510 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000511 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000512 for name in try_names:
513 libfile = os.path.join(dir, self.library_filename (name))
514 if os.path.exists(libfile):
515 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000516 else:
517 # Oops, didn't find it in *any* of 'dirs'
518 return None
519
520 # find_library_file ()
521
Greg Warddbd12761999-08-29 18:15:07 +0000522# class MSVCCompiler