blob: c2bd77de4466e778561d0af56a5273bd8646bb1d [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
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
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
Jeremy Hylton2683ac72002-06-18 19:08:40 +0000236 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
237 '/DNDEBUG']
Greg Ward8a98cd92000-08-31 00:31:07 +0000238 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
239 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000240
Greg Ward1b9c6f72000-02-08 02:39:44 +0000241 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000242 self.ldflags_shared_debug = [
243 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
244 ]
Greg Warddbd12761999-08-29 18:15:07 +0000245 self.ldflags_static = [ '/nologo']
246
Greg Warddbd12761999-08-29 18:15:07 +0000247
248 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000249
Greg Ward9c0ea132000-09-19 23:56:43 +0000250 def object_filenames (self,
251 source_filenames,
252 strip_dir=0,
253 output_dir=''):
254 # Copied from ccompiler.py, extended to return .res as 'object'-file
255 # for .rc input file
256 if output_dir is None: output_dir = ''
257 obj_names = []
258 for src_name in source_filenames:
259 (base, ext) = os.path.splitext (src_name)
260 if ext not in self.src_extensions:
261 # Better to raise an exception instead of silently continuing
262 # and later complain about sources and targets having
263 # different lengths
264 raise CompileError ("Don't know how to compile %s" % src_name)
265 if strip_dir:
266 base = os.path.basename (base)
267 if ext in self._rc_extensions:
268 obj_names.append (os.path.join (output_dir,
269 base + self.res_extension))
270 elif ext in self._mc_extensions:
271 obj_names.append (os.path.join (output_dir,
272 base + self.res_extension))
273 else:
274 obj_names.append (os.path.join (output_dir,
275 base + self.obj_extension))
276 return obj_names
277
278 # object_filenames ()
279
280
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000281 def compile(self, sources,
282 output_dir=None, macros=None, include_dirs=None, debug=0,
283 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000284
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000285 macros, objects, extra_postargs, pp_opts, build = \
286 self._setup_compile(output_dir, macros, include_dirs, sources,
287 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000288
Greg Ward32c4a8a2000-03-06 03:40:29 +0000289 compile_opts = extra_preargs or []
290 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000291 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000292 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000293 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000294 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000295
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000296 for obj, (src, ext) in build.items():
297 if debug:
298 # pass the full pathname to MSVC in debug mode,
299 # this allows the debugger to find the source file
300 # without asking the user to browse for it
301 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000302
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000303 if ext in self._c_extensions:
304 input_opt = "/Tc" + src
305 elif ext in self._cpp_extensions:
306 input_opt = "/Tp" + src
307 elif ext in self._rc_extensions:
308 # compile .RC to .RES file
309 input_opt = src
310 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000311 try:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000312 self.spawn ([self.rc] +
313 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000314 except DistutilsExecError, msg:
315 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000316 continue
317 elif ext in self._mc_extensions:
318
319 # Compile .MC to .RC file to .RES file.
320 # * '-h dir' specifies the directory for the
321 # generated include file
322 # * '-r dir' specifies the target directory of the
323 # generated RC file and the binary message resource
324 # it includes
325 #
326 # For now (since there are no options to change this),
327 # we use the source-directory for the include file and
328 # the build directory for the RC file and message
329 # resources. This works at least for win32all.
330
331 h_dir = os.path.dirname (src)
332 rc_dir = os.path.dirname (obj)
333 try:
334 # first compile .MC to .RC and .H file
335 self.spawn ([self.mc] +
336 ['-h', h_dir, '-r', rc_dir] + [src])
337 base, _ = os.path.splitext (os.path.basename (src))
338 rc_file = os.path.join (rc_dir, base + '.rc')
339 # then compile .RC to .RES file
340 self.spawn ([self.rc] +
341 ["/fo" + obj] + [rc_file])
342
343 except DistutilsExecError, msg:
344 raise CompileError, msg
345 continue
346 else:
347 # how to handle this file?
348 raise CompileError (
349 "Don't know how to compile %s to %s" % \
350 (src, obj))
351
352 output_opt = "/Fo" + obj
353 try:
354 self.spawn ([self.cc] + compile_opts + pp_opts +
355 [input_opt, output_opt] +
356 extra_postargs)
357 except DistutilsExecError, msg:
358 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000359
Greg Ward32c4a8a2000-03-06 03:40:29 +0000360 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000361
Greg Ward32c4a8a2000-03-06 03:40:29 +0000362 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000363
364
Greg Ward09fc5422000-03-10 01:49:26 +0000365 def create_static_lib (self,
366 objects,
367 output_libname,
368 output_dir=None,
369 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000370 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000371
Greg Ward2f557a22000-03-26 21:42:28 +0000372 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000373 output_filename = \
374 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000375
Greg Ward32c4a8a2000-03-06 03:40:29 +0000376 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000377 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000378 if debug:
379 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000380 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000381 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000382 except DistutilsExecError, msg:
383 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000384
Greg Ward32c4a8a2000-03-06 03:40:29 +0000385 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000386 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000387
Greg Ward09fc5422000-03-10 01:49:26 +0000388 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000389
Greg Ward42406482000-09-27 02:08:14 +0000390 def link (self,
391 target_desc,
392 objects,
393 output_filename,
394 output_dir=None,
395 libraries=None,
396 library_dirs=None,
397 runtime_library_dirs=None,
398 export_symbols=None,
399 debug=0,
400 extra_preargs=None,
401 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000402 build_temp=None,
403 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000404
Greg Ward2f557a22000-03-26 21:42:28 +0000405 (objects, output_dir) = self._fix_object_args (objects, output_dir)
406 (libraries, library_dirs, runtime_library_dirs) = \
407 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
408
Greg Wardf70c6032000-04-19 02:16:49 +0000409 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000410 self.warn ("I don't know what to do with 'runtime_library_dirs': "
411 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000412
Greg Wardd03f88a2000-03-18 15:19:51 +0000413 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000414 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000415 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000416 if output_dir is not None:
417 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000418
Greg Ward32c4a8a2000-03-06 03:40:29 +0000419 if self._need_link (objects, output_filename):
420
Greg Ward42406482000-09-27 02:08:14 +0000421 if target_desc == CCompiler.EXECUTABLE:
422 if debug:
423 ldflags = self.ldflags_shared_debug[1:]
424 else:
425 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000426 else:
Greg Ward42406482000-09-27 02:08:14 +0000427 if debug:
428 ldflags = self.ldflags_shared_debug
429 else:
430 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000431
Greg Ward5299b6a2000-05-20 13:23:21 +0000432 export_opts = []
433 for sym in (export_symbols or []):
434 export_opts.append("/EXPORT:" + sym)
435
Fred Drakeb94b8492001-12-06 20:51:35 +0000436 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000437 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000438
Greg Ward159eb922000-08-02 00:00:30 +0000439 # The MSVC linker generates .lib and .exp files, which cannot be
440 # suppressed by any linker switches. The .lib files may even be
441 # needed! Make sure they are generated in the temporary build
442 # directory. Since they have different names for debug and release
443 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000444 if export_symbols is not None:
445 (dll_name, dll_ext) = os.path.splitext(
446 os.path.basename(output_filename))
447 implib_file = os.path.join(
448 os.path.dirname(objects[0]),
449 self.library_filename(dll_name))
450 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000451
Greg Ward32c4a8a2000-03-06 03:40:29 +0000452 if extra_preargs:
453 ld_args[:0] = extra_preargs
454 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000455 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000456
457 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000458 try:
Greg Ward42406482000-09-27 02:08:14 +0000459 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000460 except DistutilsExecError, msg:
461 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000462
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000463 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000464 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000465
Greg Ward42406482000-09-27 02:08:14 +0000466 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000467
468
Greg Ward32c4a8a2000-03-06 03:40:29 +0000469 # -- Miscellaneous methods -----------------------------------------
470 # These are all used by the 'gen_lib_options() function, in
471 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000472
473 def library_dir_option (self, dir):
474 return "/LIBPATH:" + dir
475
Greg Wardd03f88a2000-03-18 15:19:51 +0000476 def runtime_library_dir_option (self, dir):
477 raise DistutilsPlatformError, \
478 "don't know how to set runtime library search path for MSVC++"
479
Greg Wardc74138d1999-10-03 20:47:52 +0000480 def library_option (self, lib):
481 return self.library_filename (lib)
482
483
Greg Wardd1425642000-08-04 01:29:27 +0000484 def find_library_file (self, dirs, lib, debug=0):
485 # Prefer a debugging library if found (and requested), but deal
486 # with it if we don't have one.
487 if debug:
488 try_names = [lib + "_d", lib]
489 else:
490 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000491 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000492 for name in try_names:
493 libfile = os.path.join(dir, self.library_filename (name))
494 if os.path.exists(libfile):
495 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000496 else:
497 # Oops, didn't find it in *any* of 'dirs'
498 return None
499
500 # find_library_file ()
501
Greg Warddbd12761999-08-29 18:15:07 +0000502# class MSVCCompiler