blob: 35336642ae704f6f86e9ae13d3392acba59dbf42 [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:
Martin v. Löwis9635d0b2002-01-29 10:23:42 +0000120 try:
121 v = v.encode("mbcs")
122 except UnicodeError:
123 pass
Greg Ward62e33932000-02-10 02:52:42 +0000124 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000125 L.append(v)
126 break
127 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000128 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000129 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000130 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000131 pass
132 return L
133
Greg Ward62e33932000-02-10 02:52:42 +0000134# get_msvc_paths()
135
136
Greg Ward69988092000-02-11 02:47:15 +0000137def find_exe (exe, version_number):
138 """Try to find an MSVC executable program 'exe' (from version
139 'version_number' of MSVC) in several places: first, one of the MSVC
140 program search paths from the registry; next, the directories in the
141 PATH environment variable. If any of those work, return an absolute
142 path that is known to exist. If none of them work, just return the
143 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000144
Greg Ward69988092000-02-11 02:47:15 +0000145 for p in get_msvc_paths ('path', version_number):
146 fn = os.path.join (os.path.abspath(p), exe)
147 if os.path.isfile(fn):
148 return fn
149
150 # didn't find it; try existing path
151 for p in string.split (os.environ['Path'],';'):
152 fn = os.path.join(os.path.abspath(p),exe)
153 if os.path.isfile(fn):
154 return fn
155
Fred Drakeb94b8492001-12-06 20:51:35 +0000156 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000157
Greg Ward62e33932000-02-10 02:52:42 +0000158
Greg Ward5de8cee2000-02-11 02:52:39 +0000159def set_path_env_var (name, version_number):
160 """Set environment variable 'name' to an MSVC path type value obtained
161 from 'get_msvc_paths()'. This is equivalent to a SET command prior
162 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000163
Greg Ward5de8cee2000-02-11 02:52:39 +0000164 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000165 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000166 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000167
Greg Warddbd12761999-08-29 18:15:07 +0000168
Greg Ward3d50b901999-09-08 02:36:01 +0000169class MSVCCompiler (CCompiler) :
170 """Concrete class that implements an interface to Microsoft Visual C++,
171 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000172
Greg Warddf178f91999-09-29 12:29:10 +0000173 compiler_type = 'msvc'
174
Greg Ward992c8f92000-06-25 02:31:16 +0000175 # Just set this so CCompiler's constructor doesn't barf. We currently
176 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
177 # as it really isn't necessary for this sort of single-compiler class.
178 # Would be nice to have a consistent interface with UnixCCompiler,
179 # though, so it's worth thinking about.
180 executables = {}
181
Greg Ward32c4a8a2000-03-06 03:40:29 +0000182 # Private class data (need to distinguish C from C++ source for compiler)
183 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000184 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000185 _rc_extensions = ['.rc']
186 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000187
188 # Needed for the filename generation methods provided by the
189 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000190 src_extensions = (_c_extensions + _cpp_extensions +
191 _rc_extensions + _mc_extensions)
192 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000193 obj_extension = '.obj'
194 static_lib_extension = '.lib'
195 shared_lib_extension = '.dll'
196 static_lib_format = shared_lib_format = '%s%s'
197 exe_extension = '.exe'
198
199
Greg Warddbd12761999-08-29 18:15:07 +0000200 def __init__ (self,
201 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000202 dry_run=0,
203 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000204
Greg Wardc74138d1999-10-03 20:47:52 +0000205 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000206 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000207
Greg Ward5de8cee2000-02-11 02:52:39 +0000208 if versions:
209 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000210
Greg Ward41b4dd62000-03-29 04:13:00 +0000211 self.cc = find_exe("cl.exe", version)
Greg Ward42406482000-09-27 02:08:14 +0000212 self.linker = find_exe("link.exe", version)
Greg Ward41b4dd62000-03-29 04:13:00 +0000213 self.lib = find_exe("lib.exe", version)
Greg Ward9c0ea132000-09-19 23:56:43 +0000214 self.rc = find_exe("rc.exe", version) # resource compiler
215 self.mc = find_exe("mc.exe", version) # message compiler
Greg Ward5de8cee2000-02-11 02:52:39 +0000216 set_path_env_var ('lib', version)
217 set_path_env_var ('include', version)
218 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000219 try:
220 for p in string.split(os.environ['path'],';'):
221 path.append(p)
222 except KeyError:
223 pass
224 os.environ['path'] = string.join(path,';')
225 else:
226 # devstudio not found in the registry
227 self.cc = "cl.exe"
Greg Ward42406482000-09-27 02:08:14 +0000228 self.linker = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000229 self.lib = "lib.exe"
Greg Ward9c0ea132000-09-19 23:56:43 +0000230 self.rc = "rc.exe"
231 self.mc = "mc.exe"
Greg Ward69988092000-02-11 02:47:15 +0000232
Greg Warddbd12761999-08-29 18:15:07 +0000233 self.preprocess_options = None
Greg Ward8a98cd92000-08-31 00:31:07 +0000234 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ]
235 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
236 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000237
Greg Ward1b9c6f72000-02-08 02:39:44 +0000238 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000239 self.ldflags_shared_debug = [
240 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
241 ]
Greg Warddbd12761999-08-29 18:15:07 +0000242 self.ldflags_static = [ '/nologo']
243
Greg Warddbd12761999-08-29 18:15:07 +0000244
245 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000246
Greg Ward9c0ea132000-09-19 23:56:43 +0000247 def object_filenames (self,
248 source_filenames,
249 strip_dir=0,
250 output_dir=''):
251 # Copied from ccompiler.py, extended to return .res as 'object'-file
252 # for .rc input file
253 if output_dir is None: output_dir = ''
254 obj_names = []
255 for src_name in source_filenames:
256 (base, ext) = os.path.splitext (src_name)
257 if ext not in self.src_extensions:
258 # Better to raise an exception instead of silently continuing
259 # and later complain about sources and targets having
260 # different lengths
261 raise CompileError ("Don't know how to compile %s" % src_name)
262 if strip_dir:
263 base = os.path.basename (base)
264 if ext in self._rc_extensions:
265 obj_names.append (os.path.join (output_dir,
266 base + self.res_extension))
267 elif ext in self._mc_extensions:
268 obj_names.append (os.path.join (output_dir,
269 base + self.res_extension))
270 else:
271 obj_names.append (os.path.join (output_dir,
272 base + self.obj_extension))
273 return obj_names
274
275 # object_filenames ()
276
277
Greg Warddbd12761999-08-29 18:15:07 +0000278 def compile (self,
279 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000280 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000281 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000282 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000283 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000284 extra_preargs=None,
285 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000286
Greg Ward32c4a8a2000-03-06 03:40:29 +0000287 (output_dir, macros, include_dirs) = \
288 self._fix_compile_args (output_dir, macros, include_dirs)
289 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000290
Greg Ward32c4a8a2000-03-06 03:40:29 +0000291 if extra_postargs is None:
292 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000293
Greg Ward32c4a8a2000-03-06 03:40:29 +0000294 pp_opts = gen_preprocess_options (macros, include_dirs)
295 compile_opts = extra_preargs or []
296 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000297 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000298 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000299 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000300 compile_opts.extend (self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000301
Greg Ward32c4a8a2000-03-06 03:40:29 +0000302 for i in range (len (sources)):
303 src = sources[i] ; obj = objects[i]
304 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000305
Greg Ward32c4a8a2000-03-06 03:40:29 +0000306 if skip_sources[src]:
307 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
308 else:
Greg Ward9c0ea132000-09-19 23:56:43 +0000309 self.mkpath (os.path.dirname (obj))
310
Greg Ward32c4a8a2000-03-06 03:40:29 +0000311 if ext in self._c_extensions:
312 input_opt = "/Tc" + src
313 elif ext in self._cpp_extensions:
314 input_opt = "/Tp" + src
Greg Ward9c0ea132000-09-19 23:56:43 +0000315 elif ext in self._rc_extensions:
316 # compile .RC to .RES file
317 input_opt = src
318 output_opt = "/fo" + obj
319 try:
320 self.spawn ([self.rc] +
321 [output_opt] + [input_opt])
322 except DistutilsExecError, msg:
323 raise CompileError, msg
324 continue
325 elif ext in self._mc_extensions:
326
327 # Compile .MC to .RC file to .RES file.
328 # * '-h dir' specifies the directory for the
329 # generated include file
330 # * '-r dir' specifies the target directory of the
331 # generated RC file and the binary message resource
332 # it includes
333 #
334 # For now (since there are no options to change this),
335 # we use the source-directory for the include file and
336 # the build directory for the RC file and message
337 # resources. This works at least for win32all.
338
339 h_dir = os.path.dirname (src)
340 rc_dir = os.path.dirname (obj)
341 try:
342 # first compile .MC to .RC and .H file
343 self.spawn ([self.mc] +
344 ['-h', h_dir, '-r', rc_dir] + [src])
345 base, _ = os.path.splitext (os.path.basename (src))
346 rc_file = os.path.join (rc_dir, base + '.rc')
347 # then compile .RC to .RES file
348 self.spawn ([self.rc] +
349 ["/fo" + obj] + [rc_file])
350
351 except DistutilsExecError, msg:
352 raise CompileError, msg
353 continue
354 else:
355 # how to handle this file?
356 raise CompileError (
357 "Don't know how to compile %s to %s" % \
358 (src, obj))
Greg Warddbd12761999-08-29 18:15:07 +0000359
Greg Ward32c4a8a2000-03-06 03:40:29 +0000360 output_opt = "/Fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000361 try:
362 self.spawn ([self.cc] + compile_opts + pp_opts +
363 [input_opt, output_opt] +
364 extra_postargs)
365 except DistutilsExecError, msg:
366 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000367
Greg Ward32c4a8a2000-03-06 03:40:29 +0000368 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000369
Greg Ward32c4a8a2000-03-06 03:40:29 +0000370 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000371
372
Greg Ward09fc5422000-03-10 01:49:26 +0000373 def create_static_lib (self,
374 objects,
375 output_libname,
376 output_dir=None,
377 debug=0,
378 extra_preargs=None,
379 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000380
Greg Ward2f557a22000-03-26 21:42:28 +0000381 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000382 output_filename = \
383 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000384
Greg Ward32c4a8a2000-03-06 03:40:29 +0000385 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000386 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000387 if debug:
388 pass # XXX what goes here?
389 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000390 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000391 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000392 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000393 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000394 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000395 except DistutilsExecError, msg:
396 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000397
Greg Ward32c4a8a2000-03-06 03:40:29 +0000398 else:
399 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000400
Greg Ward09fc5422000-03-10 01:49:26 +0000401 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000402
Greg Ward42406482000-09-27 02:08:14 +0000403 def link (self,
404 target_desc,
405 objects,
406 output_filename,
407 output_dir=None,
408 libraries=None,
409 library_dirs=None,
410 runtime_library_dirs=None,
411 export_symbols=None,
412 debug=0,
413 extra_preargs=None,
414 extra_postargs=None,
415 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000416
Greg Ward2f557a22000-03-26 21:42:28 +0000417 (objects, output_dir) = self._fix_object_args (objects, output_dir)
418 (libraries, library_dirs, runtime_library_dirs) = \
419 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
420
Greg Wardf70c6032000-04-19 02:16:49 +0000421 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000422 self.warn ("I don't know what to do with 'runtime_library_dirs': "
423 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000424
Greg Wardd03f88a2000-03-18 15:19:51 +0000425 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000426 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000427 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000428 if output_dir is not None:
429 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000430
Greg Ward32c4a8a2000-03-06 03:40:29 +0000431 if self._need_link (objects, output_filename):
432
Greg Ward42406482000-09-27 02:08:14 +0000433 if target_desc == CCompiler.EXECUTABLE:
434 if debug:
435 ldflags = self.ldflags_shared_debug[1:]
436 else:
437 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000438 else:
Greg Ward42406482000-09-27 02:08:14 +0000439 if debug:
440 ldflags = self.ldflags_shared_debug
441 else:
442 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000443
Greg Ward5299b6a2000-05-20 13:23:21 +0000444 export_opts = []
445 for sym in (export_symbols or []):
446 export_opts.append("/EXPORT:" + sym)
447
Fred Drakeb94b8492001-12-06 20:51:35 +0000448 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000449 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000450
Greg Ward159eb922000-08-02 00:00:30 +0000451 # The MSVC linker generates .lib and .exp files, which cannot be
452 # suppressed by any linker switches. The .lib files may even be
453 # needed! Make sure they are generated in the temporary build
454 # directory. Since they have different names for debug and release
455 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000456 if export_symbols is not None:
457 (dll_name, dll_ext) = os.path.splitext(
458 os.path.basename(output_filename))
459 implib_file = os.path.join(
460 os.path.dirname(objects[0]),
461 self.library_filename(dll_name))
462 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000463
Greg Ward32c4a8a2000-03-06 03:40:29 +0000464 if extra_preargs:
465 ld_args[:0] = extra_preargs
466 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000467 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000468
469 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000470 try:
Greg Ward42406482000-09-27 02:08:14 +0000471 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000472 except DistutilsExecError, msg:
473 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000474
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000475 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000476 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000477
Greg Ward42406482000-09-27 02:08:14 +0000478 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000479
480
Greg Ward32c4a8a2000-03-06 03:40:29 +0000481 # -- Miscellaneous methods -----------------------------------------
482 # These are all used by the 'gen_lib_options() function, in
483 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000484
485 def library_dir_option (self, dir):
486 return "/LIBPATH:" + dir
487
Greg Wardd03f88a2000-03-18 15:19:51 +0000488 def runtime_library_dir_option (self, dir):
489 raise DistutilsPlatformError, \
490 "don't know how to set runtime library search path for MSVC++"
491
Greg Wardc74138d1999-10-03 20:47:52 +0000492 def library_option (self, lib):
493 return self.library_filename (lib)
494
495
Greg Wardd1425642000-08-04 01:29:27 +0000496 def find_library_file (self, dirs, lib, debug=0):
497 # Prefer a debugging library if found (and requested), but deal
498 # with it if we don't have one.
499 if debug:
500 try_names = [lib + "_d", lib]
501 else:
502 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000503 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000504 for name in try_names:
505 libfile = os.path.join(dir, self.library_filename (name))
506 if os.path.exists(libfile):
507 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000508 else:
509 # Oops, didn't find it in *any* of 'dirs'
510 return None
511
512 # find_library_file ()
513
Greg Warddbd12761999-08-29 18:15:07 +0000514# class MSVCCompiler