blob: 8460eea9677d89b711087196b46afc907262f7da [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
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000280 def compile(self, sources,
281 output_dir=None, macros=None, include_dirs=None, debug=0,
282 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000283
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000284 macros, objects, extra_postargs, pp_opts, build = \
285 self._setup_compile(output_dir, macros, include_dirs, sources,
286 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000287
Greg Ward32c4a8a2000-03-06 03:40:29 +0000288 compile_opts = extra_preargs or []
289 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000290 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000291 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000292 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000293 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000294
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000295 for obj, (src, ext) in build.items():
296 if debug:
297 # pass the full pathname to MSVC in debug mode,
298 # this allows the debugger to find the source file
299 # without asking the user to browse for it
300 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000301
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000302 if ext in self._c_extensions:
303 input_opt = "/Tc" + src
304 elif ext in self._cpp_extensions:
305 input_opt = "/Tp" + src
306 elif ext in self._rc_extensions:
307 # compile .RC to .RES file
308 input_opt = src
309 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000310 try:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000311 self.spawn ([self.rc] +
312 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000313 except DistutilsExecError, msg:
314 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000315 continue
316 elif ext in self._mc_extensions:
317
318 # Compile .MC to .RC file to .RES file.
319 # * '-h dir' specifies the directory for the
320 # generated include file
321 # * '-r dir' specifies the target directory of the
322 # generated RC file and the binary message resource
323 # it includes
324 #
325 # For now (since there are no options to change this),
326 # we use the source-directory for the include file and
327 # the build directory for the RC file and message
328 # resources. This works at least for win32all.
329
330 h_dir = os.path.dirname (src)
331 rc_dir = os.path.dirname (obj)
332 try:
333 # first compile .MC to .RC and .H file
334 self.spawn ([self.mc] +
335 ['-h', h_dir, '-r', rc_dir] + [src])
336 base, _ = os.path.splitext (os.path.basename (src))
337 rc_file = os.path.join (rc_dir, base + '.rc')
338 # then compile .RC to .RES file
339 self.spawn ([self.rc] +
340 ["/fo" + obj] + [rc_file])
341
342 except DistutilsExecError, msg:
343 raise CompileError, msg
344 continue
345 else:
346 # how to handle this file?
347 raise CompileError (
348 "Don't know how to compile %s to %s" % \
349 (src, obj))
350
351 output_opt = "/Fo" + obj
352 try:
353 self.spawn ([self.cc] + compile_opts + pp_opts +
354 [input_opt, output_opt] +
355 extra_postargs)
356 except DistutilsExecError, msg:
357 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000358
Greg Ward32c4a8a2000-03-06 03:40:29 +0000359 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000360
Greg Ward32c4a8a2000-03-06 03:40:29 +0000361 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000362
363
Greg Ward09fc5422000-03-10 01:49:26 +0000364 def create_static_lib (self,
365 objects,
366 output_libname,
367 output_dir=None,
368 debug=0,
369 extra_preargs=None,
370 extra_postargs=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?
380 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000381 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000382 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000383 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000384 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000385 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000386 except DistutilsExecError, msg:
387 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000388
Greg Ward32c4a8a2000-03-06 03:40:29 +0000389 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000390 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000391
Greg Ward09fc5422000-03-10 01:49:26 +0000392 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000393
Greg Ward42406482000-09-27 02:08:14 +0000394 def link (self,
395 target_desc,
396 objects,
397 output_filename,
398 output_dir=None,
399 libraries=None,
400 library_dirs=None,
401 runtime_library_dirs=None,
402 export_symbols=None,
403 debug=0,
404 extra_preargs=None,
405 extra_postargs=None,
406 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000407
Greg Ward2f557a22000-03-26 21:42:28 +0000408 (objects, output_dir) = self._fix_object_args (objects, output_dir)
409 (libraries, library_dirs, runtime_library_dirs) = \
410 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
411
Greg Wardf70c6032000-04-19 02:16:49 +0000412 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000413 self.warn ("I don't know what to do with 'runtime_library_dirs': "
414 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000415
Greg Wardd03f88a2000-03-18 15:19:51 +0000416 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000417 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000418 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000419 if output_dir is not None:
420 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000421
Greg Ward32c4a8a2000-03-06 03:40:29 +0000422 if self._need_link (objects, output_filename):
423
Greg Ward42406482000-09-27 02:08:14 +0000424 if target_desc == CCompiler.EXECUTABLE:
425 if debug:
426 ldflags = self.ldflags_shared_debug[1:]
427 else:
428 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000429 else:
Greg Ward42406482000-09-27 02:08:14 +0000430 if debug:
431 ldflags = self.ldflags_shared_debug
432 else:
433 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000434
Greg Ward5299b6a2000-05-20 13:23:21 +0000435 export_opts = []
436 for sym in (export_symbols or []):
437 export_opts.append("/EXPORT:" + sym)
438
Fred Drakeb94b8492001-12-06 20:51:35 +0000439 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000440 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000441
Greg Ward159eb922000-08-02 00:00:30 +0000442 # The MSVC linker generates .lib and .exp files, which cannot be
443 # suppressed by any linker switches. The .lib files may even be
444 # needed! Make sure they are generated in the temporary build
445 # directory. Since they have different names for debug and release
446 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000447 if export_symbols is not None:
448 (dll_name, dll_ext) = os.path.splitext(
449 os.path.basename(output_filename))
450 implib_file = os.path.join(
451 os.path.dirname(objects[0]),
452 self.library_filename(dll_name))
453 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000454
Greg Ward32c4a8a2000-03-06 03:40:29 +0000455 if extra_preargs:
456 ld_args[:0] = extra_preargs
457 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000458 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000459
460 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000461 try:
Greg Ward42406482000-09-27 02:08:14 +0000462 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000463 except DistutilsExecError, msg:
464 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000465
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000466 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000467 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000468
Greg Ward42406482000-09-27 02:08:14 +0000469 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000470
471
Greg Ward32c4a8a2000-03-06 03:40:29 +0000472 # -- Miscellaneous methods -----------------------------------------
473 # These are all used by the 'gen_lib_options() function, in
474 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000475
476 def library_dir_option (self, dir):
477 return "/LIBPATH:" + dir
478
Greg Wardd03f88a2000-03-18 15:19:51 +0000479 def runtime_library_dir_option (self, dir):
480 raise DistutilsPlatformError, \
481 "don't know how to set runtime library search path for MSVC++"
482
Greg Wardc74138d1999-10-03 20:47:52 +0000483 def library_option (self, lib):
484 return self.library_filename (lib)
485
486
Greg Wardd1425642000-08-04 01:29:27 +0000487 def find_library_file (self, dirs, lib, debug=0):
488 # Prefer a debugging library if found (and requested), but deal
489 # with it if we don't have one.
490 if debug:
491 try_names = [lib + "_d", lib]
492 else:
493 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000494 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000495 for name in try_names:
496 libfile = os.path.join(dir, self.library_filename (name))
497 if os.path.exists(libfile):
498 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000499 else:
500 # Oops, didn't find it in *any* of 'dirs'
501 return None
502
503 # find_library_file ()
504
Greg Warddbd12761999-08-29 18:15:07 +0000505# class MSVCCompiler