blob: 73cd44258ccd43fb29f01aae2ff42e9a4d428160 [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
Greg Ward62e33932000-02-10 02:52:42 +000020
Greg Ward7642f5c2000-03-31 16:47:40 +000021_can_read_reg = 0
22try:
Greg Ward1b5ec762000-06-30 19:37:59 +000023 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000024
Greg Ward7642f5c2000-03-31 16:47:40 +000025 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000026 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000027
Greg Wardcd079c42000-06-29 22:59:10 +000028 RegOpenKeyEx = _winreg.OpenKeyEx
29 RegEnumKey = _winreg.EnumKey
30 RegEnumValue = _winreg.EnumValue
31 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000032
Greg Ward7642f5c2000-03-31 16:47:40 +000033except ImportError:
34 try:
35 import win32api
36 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000037 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000038 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000039
40 RegOpenKeyEx = win32api.RegOpenKeyEx
41 RegEnumKey = win32api.RegEnumKey
42 RegEnumValue = win32api.RegEnumValue
43 RegError = win32api.error
44
Greg Ward7642f5c2000-03-31 16:47:40 +000045 except ImportError:
46 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000047
48if _can_read_reg:
49 HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT
50 HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE
51 HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER
52 HKEY_USERS = hkey_mod.HKEY_USERS
Fred Drakeb94b8492001-12-06 20:51:35 +000053
54
Greg Ward7642f5c2000-03-31 16:47:40 +000055
Greg Ward62e33932000-02-10 02:52:42 +000056def get_devstudio_versions ():
Greg Ward62e33932000-02-10 02:52:42 +000057 """Get list of devstudio versions from the Windows registry. Return a
Greg Ward69988092000-02-11 02:47:15 +000058 list of strings containing version numbers; the list will be
Greg Ward62e33932000-02-10 02:52:42 +000059 empty if we were unable to access the registry (eg. couldn't import
60 a registry-access module) or the appropriate registry keys weren't
Greg Ward69988092000-02-11 02:47:15 +000061 found."""
62
Greg Ward7642f5c2000-03-31 16:47:40 +000063 if not _can_read_reg:
Greg Ward62e33932000-02-10 02:52:42 +000064 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000065
66 K = 'Software\\Microsoft\\Devstudio'
67 L = []
Greg Ward1027e3f2000-03-31 16:53:42 +000068 for base in (HKEY_CLASSES_ROOT,
69 HKEY_LOCAL_MACHINE,
70 HKEY_CURRENT_USER,
71 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +000072 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000073 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +000074 i = 0
75 while 1:
76 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000077 p = RegEnumKey(k,i)
Greg Ward1b9c6f72000-02-08 02:39:44 +000078 if p[0] in '123456789' and p not in L:
79 L.append(p)
Greg Ward1027e3f2000-03-31 16:53:42 +000080 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000081 break
82 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +000083 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000084 pass
85 L.sort()
86 L.reverse()
87 return L
88
Greg Ward62e33932000-02-10 02:52:42 +000089# get_devstudio_versions ()
90
91
92def get_msvc_paths (path, version='6.0', platform='x86'):
Greg Ward69988092000-02-11 02:47:15 +000093 """Get a list of devstudio directories (include, lib or path). Return
94 a list of strings; will be empty list if unable to access the
95 registry or appropriate registry keys not found."""
Fred Drakeb94b8492001-12-06 20:51:35 +000096
Greg Ward7642f5c2000-03-31 16:47:40 +000097 if not _can_read_reg:
Greg Ward69988092000-02-11 02:47:15 +000098 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000099
100 L = []
Greg Ward62e33932000-02-10 02:52:42 +0000101 if path=='lib':
102 path= 'Library'
Greg Ward1b9c6f72000-02-08 02:39:44 +0000103 path = string.upper(path + ' Dirs')
Greg Ward62e33932000-02-10 02:52:42 +0000104 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
105 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
106 (version,platform)
Greg Ward1027e3f2000-03-31 16:53:42 +0000107 for base in (HKEY_CLASSES_ROOT,
108 HKEY_LOCAL_MACHINE,
109 HKEY_CURRENT_USER,
110 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +0000111 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000112 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +0000113 i = 0
114 while 1:
115 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000116 (p,v,t) = RegEnumValue(k,i)
Greg Ward62e33932000-02-10 02:52:42 +0000117 if string.upper(p) == path:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000118 V = string.split(v,';')
119 for v in V:
Thomas Heller745b4602002-02-08 14:41:31 +0000120 if hasattr(v, "encode"):
121 try:
122 v = v.encode("mbcs")
123 except UnicodeError:
124 pass
Greg Ward62e33932000-02-10 02:52:42 +0000125 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000126 L.append(v)
127 break
128 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000129 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000130 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000131 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000132 pass
133 return L
134
Greg Ward62e33932000-02-10 02:52:42 +0000135# get_msvc_paths()
136
137
Greg Ward69988092000-02-11 02:47:15 +0000138def find_exe (exe, version_number):
139 """Try to find an MSVC executable program 'exe' (from version
140 'version_number' of MSVC) in several places: first, one of the MSVC
141 program search paths from the registry; next, the directories in the
142 PATH environment variable. If any of those work, return an absolute
143 path that is known to exist. If none of them work, just return the
144 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000145
Greg Ward69988092000-02-11 02:47:15 +0000146 for p in get_msvc_paths ('path', version_number):
147 fn = os.path.join (os.path.abspath(p), exe)
148 if os.path.isfile(fn):
149 return fn
150
151 # didn't find it; try existing path
152 for p in string.split (os.environ['Path'],';'):
153 fn = os.path.join(os.path.abspath(p),exe)
154 if os.path.isfile(fn):
155 return fn
156
Fred Drakeb94b8492001-12-06 20:51:35 +0000157 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000158
Greg Ward62e33932000-02-10 02:52:42 +0000159
Greg Ward5de8cee2000-02-11 02:52:39 +0000160def set_path_env_var (name, version_number):
161 """Set environment variable 'name' to an MSVC path type value obtained
162 from 'get_msvc_paths()'. This is equivalent to a SET command prior
163 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000164
Greg Ward5de8cee2000-02-11 02:52:39 +0000165 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000166 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000167 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000168
Greg Warddbd12761999-08-29 18:15:07 +0000169
Greg Ward3d50b901999-09-08 02:36:01 +0000170class MSVCCompiler (CCompiler) :
171 """Concrete class that implements an interface to Microsoft Visual C++,
172 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000173
Greg Warddf178f91999-09-29 12:29:10 +0000174 compiler_type = 'msvc'
175
Greg Ward992c8f92000-06-25 02:31:16 +0000176 # Just set this so CCompiler's constructor doesn't barf. We currently
177 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
178 # as it really isn't necessary for this sort of single-compiler class.
179 # Would be nice to have a consistent interface with UnixCCompiler,
180 # though, so it's worth thinking about.
181 executables = {}
182
Greg Ward32c4a8a2000-03-06 03:40:29 +0000183 # Private class data (need to distinguish C from C++ source for compiler)
184 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000185 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000186 _rc_extensions = ['.rc']
187 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000188
189 # Needed for the filename generation methods provided by the
190 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000191 src_extensions = (_c_extensions + _cpp_extensions +
192 _rc_extensions + _mc_extensions)
193 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000194 obj_extension = '.obj'
195 static_lib_extension = '.lib'
196 shared_lib_extension = '.dll'
197 static_lib_format = shared_lib_format = '%s%s'
198 exe_extension = '.exe'
199
200
Greg Warddbd12761999-08-29 18:15:07 +0000201 def __init__ (self,
202 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000203 dry_run=0,
204 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000205
Greg Wardc74138d1999-10-03 20:47:52 +0000206 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000207 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000208
Greg Ward5de8cee2000-02-11 02:52:39 +0000209 if versions:
210 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000211
Greg Ward41b4dd62000-03-29 04:13:00 +0000212 self.cc = find_exe("cl.exe", version)
Greg Ward42406482000-09-27 02:08:14 +0000213 self.linker = find_exe("link.exe", version)
Greg Ward41b4dd62000-03-29 04:13:00 +0000214 self.lib = find_exe("lib.exe", version)
Greg Ward9c0ea132000-09-19 23:56:43 +0000215 self.rc = find_exe("rc.exe", version) # resource compiler
216 self.mc = find_exe("mc.exe", version) # message compiler
Greg Ward5de8cee2000-02-11 02:52:39 +0000217 set_path_env_var ('lib', version)
218 set_path_env_var ('include', version)
219 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000220 try:
221 for p in string.split(os.environ['path'],';'):
222 path.append(p)
223 except KeyError:
224 pass
225 os.environ['path'] = string.join(path,';')
226 else:
227 # devstudio not found in the registry
228 self.cc = "cl.exe"
Greg Ward42406482000-09-27 02:08:14 +0000229 self.linker = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000230 self.lib = "lib.exe"
Greg Ward9c0ea132000-09-19 23:56:43 +0000231 self.rc = "rc.exe"
232 self.mc = "mc.exe"
Greg Ward69988092000-02-11 02:47:15 +0000233
Greg Warddbd12761999-08-29 18:15:07 +0000234 self.preprocess_options = None
Greg Ward8a98cd92000-08-31 00:31:07 +0000235 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ]
236 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
237 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000238
Greg Ward1b9c6f72000-02-08 02:39:44 +0000239 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000240 self.ldflags_shared_debug = [
241 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
242 ]
Greg Warddbd12761999-08-29 18:15:07 +0000243 self.ldflags_static = [ '/nologo']
244
Greg Warddbd12761999-08-29 18:15:07 +0000245
246 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000247
Greg Ward9c0ea132000-09-19 23:56:43 +0000248 def object_filenames (self,
249 source_filenames,
250 strip_dir=0,
251 output_dir=''):
252 # Copied from ccompiler.py, extended to return .res as 'object'-file
253 # for .rc input file
254 if output_dir is None: output_dir = ''
255 obj_names = []
256 for src_name in source_filenames:
257 (base, ext) = os.path.splitext (src_name)
258 if ext not in self.src_extensions:
259 # Better to raise an exception instead of silently continuing
260 # and later complain about sources and targets having
261 # different lengths
262 raise CompileError ("Don't know how to compile %s" % src_name)
263 if strip_dir:
264 base = os.path.basename (base)
265 if ext in self._rc_extensions:
266 obj_names.append (os.path.join (output_dir,
267 base + self.res_extension))
268 elif ext in self._mc_extensions:
269 obj_names.append (os.path.join (output_dir,
270 base + self.res_extension))
271 else:
272 obj_names.append (os.path.join (output_dir,
273 base + self.obj_extension))
274 return obj_names
275
276 # object_filenames ()
277
278
Greg Warddbd12761999-08-29 18:15:07 +0000279 def compile (self,
280 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000281 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000282 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000283 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000284 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000285 extra_preargs=None,
286 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000287
Greg Ward32c4a8a2000-03-06 03:40:29 +0000288 (output_dir, macros, include_dirs) = \
289 self._fix_compile_args (output_dir, macros, include_dirs)
290 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000291
Greg Ward32c4a8a2000-03-06 03:40:29 +0000292 if extra_postargs is None:
293 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000294
Greg Ward32c4a8a2000-03-06 03:40:29 +0000295 pp_opts = gen_preprocess_options (macros, include_dirs)
296 compile_opts = extra_preargs or []
297 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000298 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000299 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000300 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000301 compile_opts.extend (self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000302
Greg Ward32c4a8a2000-03-06 03:40:29 +0000303 for i in range (len (sources)):
304 src = sources[i] ; obj = objects[i]
305 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000306
Greg Ward32c4a8a2000-03-06 03:40:29 +0000307 if skip_sources[src]:
308 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
309 else:
Greg Ward9c0ea132000-09-19 23:56:43 +0000310 self.mkpath (os.path.dirname (obj))
311
Thomas Heller69d31b72002-04-25 17:29:45 +0000312 if debug:
313 # pass the full pathname to MSVC in debug mode,
314 # this allows the debugger to find the source file
315 # without asking the user to browse for it
316 src = os.path.abspath(src)
317
Greg Ward32c4a8a2000-03-06 03:40:29 +0000318 if ext in self._c_extensions:
319 input_opt = "/Tc" + src
320 elif ext in self._cpp_extensions:
321 input_opt = "/Tp" + src
Greg Ward9c0ea132000-09-19 23:56:43 +0000322 elif ext in self._rc_extensions:
323 # compile .RC to .RES file
324 input_opt = src
325 output_opt = "/fo" + obj
326 try:
327 self.spawn ([self.rc] +
328 [output_opt] + [input_opt])
329 except DistutilsExecError, msg:
330 raise CompileError, msg
331 continue
332 elif ext in self._mc_extensions:
333
334 # Compile .MC to .RC file to .RES file.
335 # * '-h dir' specifies the directory for the
336 # generated include file
337 # * '-r dir' specifies the target directory of the
338 # generated RC file and the binary message resource
339 # it includes
340 #
341 # For now (since there are no options to change this),
342 # we use the source-directory for the include file and
343 # the build directory for the RC file and message
344 # resources. This works at least for win32all.
345
346 h_dir = os.path.dirname (src)
347 rc_dir = os.path.dirname (obj)
348 try:
349 # first compile .MC to .RC and .H file
350 self.spawn ([self.mc] +
351 ['-h', h_dir, '-r', rc_dir] + [src])
352 base, _ = os.path.splitext (os.path.basename (src))
353 rc_file = os.path.join (rc_dir, base + '.rc')
354 # then compile .RC to .RES file
355 self.spawn ([self.rc] +
356 ["/fo" + obj] + [rc_file])
357
358 except DistutilsExecError, msg:
359 raise CompileError, msg
360 continue
361 else:
362 # how to handle this file?
363 raise CompileError (
364 "Don't know how to compile %s to %s" % \
365 (src, obj))
Greg Warddbd12761999-08-29 18:15:07 +0000366
Greg Ward32c4a8a2000-03-06 03:40:29 +0000367 output_opt = "/Fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000368 try:
369 self.spawn ([self.cc] + compile_opts + pp_opts +
370 [input_opt, output_opt] +
371 extra_postargs)
372 except DistutilsExecError, msg:
373 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000374
Greg Ward32c4a8a2000-03-06 03:40:29 +0000375 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000376
Greg Ward32c4a8a2000-03-06 03:40:29 +0000377 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000378
379
Greg Ward09fc5422000-03-10 01:49:26 +0000380 def create_static_lib (self,
381 objects,
382 output_libname,
383 output_dir=None,
384 debug=0,
385 extra_preargs=None,
386 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000387
Greg Ward2f557a22000-03-26 21:42:28 +0000388 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000389 output_filename = \
390 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000391
Greg Ward32c4a8a2000-03-06 03:40:29 +0000392 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000393 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000394 if debug:
395 pass # XXX what goes here?
396 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000397 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000398 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000399 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000400 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000401 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000402 except DistutilsExecError, msg:
403 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000404
Greg Ward32c4a8a2000-03-06 03:40:29 +0000405 else:
406 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000407
Greg Ward09fc5422000-03-10 01:49:26 +0000408 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000409
Greg Ward42406482000-09-27 02:08:14 +0000410 def link (self,
411 target_desc,
412 objects,
413 output_filename,
414 output_dir=None,
415 libraries=None,
416 library_dirs=None,
417 runtime_library_dirs=None,
418 export_symbols=None,
419 debug=0,
420 extra_preargs=None,
421 extra_postargs=None,
422 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000423
Greg Ward2f557a22000-03-26 21:42:28 +0000424 (objects, output_dir) = self._fix_object_args (objects, output_dir)
425 (libraries, library_dirs, runtime_library_dirs) = \
426 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
427
Greg Wardf70c6032000-04-19 02:16:49 +0000428 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000429 self.warn ("I don't know what to do with 'runtime_library_dirs': "
430 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000431
Greg Wardd03f88a2000-03-18 15:19:51 +0000432 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000433 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000434 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000435 if output_dir is not None:
436 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000437
Greg Ward32c4a8a2000-03-06 03:40:29 +0000438 if self._need_link (objects, output_filename):
439
Greg Ward42406482000-09-27 02:08:14 +0000440 if target_desc == CCompiler.EXECUTABLE:
441 if debug:
442 ldflags = self.ldflags_shared_debug[1:]
443 else:
444 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000445 else:
Greg Ward42406482000-09-27 02:08:14 +0000446 if debug:
447 ldflags = self.ldflags_shared_debug
448 else:
449 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000450
Greg Ward5299b6a2000-05-20 13:23:21 +0000451 export_opts = []
452 for sym in (export_symbols or []):
453 export_opts.append("/EXPORT:" + sym)
454
Fred Drakeb94b8492001-12-06 20:51:35 +0000455 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000456 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000457
Greg Ward159eb922000-08-02 00:00:30 +0000458 # The MSVC linker generates .lib and .exp files, which cannot be
459 # suppressed by any linker switches. The .lib files may even be
460 # needed! Make sure they are generated in the temporary build
461 # directory. Since they have different names for debug and release
462 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000463 if export_symbols is not None:
464 (dll_name, dll_ext) = os.path.splitext(
465 os.path.basename(output_filename))
466 implib_file = os.path.join(
467 os.path.dirname(objects[0]),
468 self.library_filename(dll_name))
469 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000470
Greg Ward32c4a8a2000-03-06 03:40:29 +0000471 if extra_preargs:
472 ld_args[:0] = extra_preargs
473 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000474 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000475
476 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000477 try:
Greg Ward42406482000-09-27 02:08:14 +0000478 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000479 except DistutilsExecError, msg:
480 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000481
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000482 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000483 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000484
Greg Ward42406482000-09-27 02:08:14 +0000485 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000486
487
Greg Ward32c4a8a2000-03-06 03:40:29 +0000488 # -- Miscellaneous methods -----------------------------------------
489 # These are all used by the 'gen_lib_options() function, in
490 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000491
492 def library_dir_option (self, dir):
493 return "/LIBPATH:" + dir
494
Greg Wardd03f88a2000-03-18 15:19:51 +0000495 def runtime_library_dir_option (self, dir):
496 raise DistutilsPlatformError, \
497 "don't know how to set runtime library search path for MSVC++"
498
Greg Wardc74138d1999-10-03 20:47:52 +0000499 def library_option (self, lib):
500 return self.library_filename (lib)
501
502
Greg Wardd1425642000-08-04 01:29:27 +0000503 def find_library_file (self, dirs, lib, debug=0):
504 # Prefer a debugging library if found (and requested), but deal
505 # with it if we don't have one.
506 if debug:
507 try_names = [lib + "_d", lib]
508 else:
509 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000510 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000511 for name in try_names:
512 libfile = os.path.join(dir, self.library_filename (name))
513 if os.path.exists(libfile):
514 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000515 else:
516 # Oops, didn't find it in *any* of 'dirs'
517 return None
518
519 # find_library_file ()
520
Greg Warddbd12761999-08-29 18:15:07 +0000521# class MSVCCompiler