blob: ae5e2d767a6e8b512cc24dbca5d12010f91c509e [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 Ward83c38702000-06-29 23:04:59 +000023 try:
24 import _winreg
25 except ImportError:
26 import winreg # for pre-2000/06/29 CVS Python
27
Greg Ward7642f5c2000-03-31 16:47:40 +000028 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000029 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000030
Greg Wardcd079c42000-06-29 22:59:10 +000031 RegOpenKeyEx = _winreg.OpenKeyEx
32 RegEnumKey = _winreg.EnumKey
33 RegEnumValue = _winreg.EnumValue
34 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000035
Greg Ward7642f5c2000-03-31 16:47:40 +000036except ImportError:
37 try:
38 import win32api
39 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000040 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000041 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000042
43 RegOpenKeyEx = win32api.RegOpenKeyEx
44 RegEnumKey = win32api.RegEnumKey
45 RegEnumValue = win32api.RegEnumValue
46 RegError = win32api.error
47
Greg Ward7642f5c2000-03-31 16:47:40 +000048 except ImportError:
49 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000050
51if _can_read_reg:
52 HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT
53 HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE
54 HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER
55 HKEY_USERS = hkey_mod.HKEY_USERS
Greg Ward1027e3f2000-03-31 16:53:42 +000056
Greg Ward7642f5c2000-03-31 16:47:40 +000057
58
Greg Ward62e33932000-02-10 02:52:42 +000059def get_devstudio_versions ():
Greg Ward62e33932000-02-10 02:52:42 +000060 """Get list of devstudio versions from the Windows registry. Return a
Greg Ward69988092000-02-11 02:47:15 +000061 list of strings containing version numbers; the list will be
Greg Ward62e33932000-02-10 02:52:42 +000062 empty if we were unable to access the registry (eg. couldn't import
63 a registry-access module) or the appropriate registry keys weren't
Greg Ward69988092000-02-11 02:47:15 +000064 found."""
65
Greg Ward7642f5c2000-03-31 16:47:40 +000066 if not _can_read_reg:
Greg Ward62e33932000-02-10 02:52:42 +000067 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000068
69 K = 'Software\\Microsoft\\Devstudio'
70 L = []
Greg Ward1027e3f2000-03-31 16:53:42 +000071 for base in (HKEY_CLASSES_ROOT,
72 HKEY_LOCAL_MACHINE,
73 HKEY_CURRENT_USER,
74 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +000075 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000076 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +000077 i = 0
78 while 1:
79 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000080 p = RegEnumKey(k,i)
Greg Ward1b9c6f72000-02-08 02:39:44 +000081 if p[0] in '123456789' and p not in L:
82 L.append(p)
Greg Ward1027e3f2000-03-31 16:53:42 +000083 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000084 break
85 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +000086 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000087 pass
88 L.sort()
89 L.reverse()
90 return L
91
Greg Ward62e33932000-02-10 02:52:42 +000092# get_devstudio_versions ()
93
94
95def get_msvc_paths (path, version='6.0', platform='x86'):
Greg Ward69988092000-02-11 02:47:15 +000096 """Get a list of devstudio directories (include, lib or path). Return
97 a list of strings; will be empty list if unable to access the
98 registry or appropriate registry keys not found."""
99
Greg Ward7642f5c2000-03-31 16:47:40 +0000100 if not _can_read_reg:
Greg Ward69988092000-02-11 02:47:15 +0000101 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +0000102
103 L = []
Greg Ward62e33932000-02-10 02:52:42 +0000104 if path=='lib':
105 path= 'Library'
Greg Ward1b9c6f72000-02-08 02:39:44 +0000106 path = string.upper(path + ' Dirs')
Greg Ward62e33932000-02-10 02:52:42 +0000107 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
108 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
109 (version,platform)
Greg Ward1027e3f2000-03-31 16:53:42 +0000110 for base in (HKEY_CLASSES_ROOT,
111 HKEY_LOCAL_MACHINE,
112 HKEY_CURRENT_USER,
113 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +0000114 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000115 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +0000116 i = 0
117 while 1:
118 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000119 (p,v,t) = RegEnumValue(k,i)
Greg Ward62e33932000-02-10 02:52:42 +0000120 if string.upper(p) == path:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000121 V = string.split(v,';')
122 for v in V:
Greg Ward62e33932000-02-10 02:52:42 +0000123 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000124 L.append(v)
125 break
126 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000127 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000128 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000129 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000130 pass
131 return L
132
Greg Ward62e33932000-02-10 02:52:42 +0000133# get_msvc_paths()
134
135
Greg Ward69988092000-02-11 02:47:15 +0000136def find_exe (exe, version_number):
137 """Try to find an MSVC executable program 'exe' (from version
138 'version_number' of MSVC) in several places: first, one of the MSVC
139 program search paths from the registry; next, the directories in the
140 PATH environment variable. If any of those work, return an absolute
141 path that is known to exist. If none of them work, just return the
142 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000143
Greg Ward69988092000-02-11 02:47:15 +0000144 for p in get_msvc_paths ('path', version_number):
145 fn = os.path.join (os.path.abspath(p), exe)
146 if os.path.isfile(fn):
147 return fn
148
149 # didn't find it; try existing path
150 for p in string.split (os.environ['Path'],';'):
151 fn = os.path.join(os.path.abspath(p),exe)
152 if os.path.isfile(fn):
153 return fn
154
155 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000156
Greg Ward62e33932000-02-10 02:52:42 +0000157
Greg Ward5de8cee2000-02-11 02:52:39 +0000158def set_path_env_var (name, version_number):
159 """Set environment variable 'name' to an MSVC path type value obtained
160 from 'get_msvc_paths()'. This is equivalent to a SET command prior
161 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000162
Greg Ward5de8cee2000-02-11 02:52:39 +0000163 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000164 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000165 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000166
Greg Warddbd12761999-08-29 18:15:07 +0000167
Greg Ward3d50b901999-09-08 02:36:01 +0000168class MSVCCompiler (CCompiler) :
169 """Concrete class that implements an interface to Microsoft Visual C++,
170 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000171
Greg Warddf178f91999-09-29 12:29:10 +0000172 compiler_type = 'msvc'
173
Greg Ward992c8f92000-06-25 02:31:16 +0000174 # Just set this so CCompiler's constructor doesn't barf. We currently
175 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
176 # as it really isn't necessary for this sort of single-compiler class.
177 # Would be nice to have a consistent interface with UnixCCompiler,
178 # though, so it's worth thinking about.
179 executables = {}
180
Greg Ward32c4a8a2000-03-06 03:40:29 +0000181 # Private class data (need to distinguish C from C++ source for compiler)
182 _c_extensions = ['.c']
183 _cpp_extensions = ['.cc','.cpp']
184
185 # Needed for the filename generation methods provided by the
186 # base class, CCompiler.
187 src_extensions = _c_extensions + _cpp_extensions
188 obj_extension = '.obj'
189 static_lib_extension = '.lib'
190 shared_lib_extension = '.dll'
191 static_lib_format = shared_lib_format = '%s%s'
192 exe_extension = '.exe'
193
194
Greg Warddbd12761999-08-29 18:15:07 +0000195 def __init__ (self,
196 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000197 dry_run=0,
198 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000199
Greg Wardc74138d1999-10-03 20:47:52 +0000200 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000201 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000202
Greg Ward5de8cee2000-02-11 02:52:39 +0000203 if versions:
204 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000205
Greg Ward41b4dd62000-03-29 04:13:00 +0000206 self.cc = find_exe("cl.exe", version)
207 self.link = find_exe("link.exe", version)
208 self.lib = find_exe("lib.exe", version)
Greg Ward5de8cee2000-02-11 02:52:39 +0000209 set_path_env_var ('lib', version)
210 set_path_env_var ('include', version)
211 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000212 try:
213 for p in string.split(os.environ['path'],';'):
214 path.append(p)
215 except KeyError:
216 pass
217 os.environ['path'] = string.join(path,';')
218 else:
219 # devstudio not found in the registry
220 self.cc = "cl.exe"
221 self.link = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000222 self.lib = "lib.exe"
Greg Ward69988092000-02-11 02:47:15 +0000223
Greg Warddbd12761999-08-29 18:15:07 +0000224 self.preprocess_options = None
Greg Ward69988092000-02-11 02:47:15 +0000225 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3' ]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000226 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000227
Greg Ward1b9c6f72000-02-08 02:39:44 +0000228 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000229 self.ldflags_shared_debug = [
230 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
231 ]
Greg Warddbd12761999-08-29 18:15:07 +0000232 self.ldflags_static = [ '/nologo']
233
Greg Warddbd12761999-08-29 18:15:07 +0000234
235 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000236
Greg Warddbd12761999-08-29 18:15:07 +0000237 def compile (self,
238 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000239 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000240 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000241 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000242 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000243 extra_preargs=None,
244 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000245
Greg Ward32c4a8a2000-03-06 03:40:29 +0000246 (output_dir, macros, include_dirs) = \
247 self._fix_compile_args (output_dir, macros, include_dirs)
248 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000249
Greg Ward32c4a8a2000-03-06 03:40:29 +0000250 if extra_postargs is None:
251 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000252
Greg Ward32c4a8a2000-03-06 03:40:29 +0000253 pp_opts = gen_preprocess_options (macros, include_dirs)
254 compile_opts = extra_preargs or []
255 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000256 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000257 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000258 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000259 compile_opts.extend (self.compile_options)
Greg Warddbd12761999-08-29 18:15:07 +0000260
Greg Ward32c4a8a2000-03-06 03:40:29 +0000261 for i in range (len (sources)):
262 src = sources[i] ; obj = objects[i]
263 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000264
Greg Ward32c4a8a2000-03-06 03:40:29 +0000265 if skip_sources[src]:
266 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
267 else:
268 if ext in self._c_extensions:
269 input_opt = "/Tc" + src
270 elif ext in self._cpp_extensions:
271 input_opt = "/Tp" + src
Greg Warddbd12761999-08-29 18:15:07 +0000272
Greg Ward32c4a8a2000-03-06 03:40:29 +0000273 output_opt = "/Fo" + obj
Greg Warddbd12761999-08-29 18:15:07 +0000274
Greg Ward32c4a8a2000-03-06 03:40:29 +0000275 self.mkpath (os.path.dirname (obj))
Greg Wardd1517112000-05-30 01:56:44 +0000276 try:
277 self.spawn ([self.cc] + compile_opts + pp_opts +
278 [input_opt, output_opt] +
279 extra_postargs)
280 except DistutilsExecError, msg:
281 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000282
Greg Ward32c4a8a2000-03-06 03:40:29 +0000283 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000284
Greg Ward32c4a8a2000-03-06 03:40:29 +0000285 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000286
287
Greg Ward09fc5422000-03-10 01:49:26 +0000288 def create_static_lib (self,
289 objects,
290 output_libname,
291 output_dir=None,
292 debug=0,
293 extra_preargs=None,
294 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000295
Greg Ward2f557a22000-03-26 21:42:28 +0000296 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000297 output_filename = \
298 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000299
Greg Ward32c4a8a2000-03-06 03:40:29 +0000300 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000301 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000302 if debug:
303 pass # XXX what goes here?
304 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000305 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000306 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000307 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000308 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000309 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000310 except DistutilsExecError, msg:
311 raise LibError, msg
312
Greg Ward32c4a8a2000-03-06 03:40:29 +0000313 else:
314 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000315
Greg Ward09fc5422000-03-10 01:49:26 +0000316 # create_static_lib ()
Greg Warddbd12761999-08-29 18:15:07 +0000317
318
319 def link_shared_lib (self,
320 objects,
321 output_libname,
Greg Warddf178f91999-09-29 12:29:10 +0000322 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000323 libraries=None,
324 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000325 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000326 export_symbols=None,
Greg Ward386b8442000-02-09 02:18:39 +0000327 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000328 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000329 extra_postargs=None,
330 build_temp=None):
Greg Warddf178f91999-09-29 12:29:10 +0000331
Greg Warddf178f91999-09-29 12:29:10 +0000332 self.link_shared_object (objects,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000333 self.shared_library_name(output_libname),
334 output_dir=output_dir,
335 libraries=libraries,
336 library_dirs=library_dirs,
Greg Ward5299b6a2000-05-20 13:23:21 +0000337 runtime_library_dirs=runtime_library_dirs,
338 export_symbols=export_symbols,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000339 debug=debug,
340 extra_preargs=extra_preargs,
Greg Wardbfc79d62000-06-28 01:29:09 +0000341 extra_postargs=extra_postargs,
342 build_temp=build_temp)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000343
Greg Warddbd12761999-08-29 18:15:07 +0000344
345 def link_shared_object (self,
346 objects,
347 output_filename,
Greg Warddf178f91999-09-29 12:29:10 +0000348 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000349 libraries=None,
350 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000351 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000352 export_symbols=None,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000353 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000354 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000355 extra_postargs=None,
356 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000357
Greg Ward2f557a22000-03-26 21:42:28 +0000358 (objects, output_dir) = self._fix_object_args (objects, output_dir)
359 (libraries, library_dirs, runtime_library_dirs) = \
360 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
361
Greg Wardf70c6032000-04-19 02:16:49 +0000362 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000363 self.warn ("I don't know what to do with 'runtime_library_dirs': "
364 + str (runtime_library_dirs))
Greg Warddbd12761999-08-29 18:15:07 +0000365
Greg Wardd03f88a2000-03-18 15:19:51 +0000366 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000367 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000368 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000369 if output_dir is not None:
370 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000371
Greg Ward32c4a8a2000-03-06 03:40:29 +0000372 if self._need_link (objects, output_filename):
373
374 if debug:
375 ldflags = self.ldflags_shared_debug
Greg Ward32c4a8a2000-03-06 03:40:29 +0000376 else:
377 ldflags = self.ldflags_shared
378
Greg Ward5299b6a2000-05-20 13:23:21 +0000379 export_opts = []
380 for sym in (export_symbols or []):
381 export_opts.append("/EXPORT:" + sym)
382
383 ld_args = (ldflags + lib_opts + export_opts +
384 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000385
386 if extra_preargs:
387 ld_args[:0] = extra_preargs
388 if extra_postargs:
389 ld_args.extend (extra_postargs)
390
Greg Ward02a1a2b2000-04-15 22:15:07 +0000391 print "link_shared_object():"
392 print " output_filename =", output_filename
393 print " mkpath'ing:", os.path.dirname (output_filename)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000394 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000395 try:
396 self.spawn ([self.link] + ld_args)
397 except DistutilsExecError, msg:
398 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000399
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000400 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000401 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000402
Greg Ward32c4a8a2000-03-06 03:40:29 +0000403 # link_shared_object ()
Greg Wardf70c6032000-04-19 02:16:49 +0000404
405
406 def link_executable (self,
407 objects,
408 output_progname,
409 output_dir=None,
410 libraries=None,
411 library_dirs=None,
412 runtime_library_dirs=None,
413 debug=0,
414 extra_preargs=None,
415 extra_postargs=None):
416
417 (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
421 if runtime_library_dirs:
422 self.warn ("I don't know what to do with 'runtime_library_dirs': "
423 + str (runtime_library_dirs))
424
425 lib_opts = gen_lib_options (self,
426 library_dirs, runtime_library_dirs,
427 libraries)
428 output_filename = output_progname + self.exe_extension
429 if output_dir is not None:
430 output_filename = os.path.join (output_dir, output_filename)
431
432 if self._need_link (objects, output_filename):
433
434 if debug:
435 ldflags = self.ldflags_shared_debug[1:]
436 else:
437 ldflags = self.ldflags_shared[1:]
438
439 ld_args = ldflags + lib_opts + \
440 objects + ['/OUT:' + output_filename]
441
442 if extra_preargs:
443 ld_args[:0] = extra_preargs
444 if extra_postargs:
445 ld_args.extend (extra_postargs)
446
447 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000448 try:
449 self.spawn ([self.link] + ld_args)
450 except DistutilsExecError, msg:
451 raise LinkError, msg
Greg Wardf70c6032000-04-19 02:16:49 +0000452 else:
453 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000454
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000455
Greg Ward32c4a8a2000-03-06 03:40:29 +0000456 # -- Miscellaneous methods -----------------------------------------
457 # These are all used by the 'gen_lib_options() function, in
458 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000459
460 def library_dir_option (self, dir):
461 return "/LIBPATH:" + dir
462
Greg Wardd03f88a2000-03-18 15:19:51 +0000463 def runtime_library_dir_option (self, dir):
464 raise DistutilsPlatformError, \
465 "don't know how to set runtime library search path for MSVC++"
466
Greg Wardc74138d1999-10-03 20:47:52 +0000467 def library_option (self, lib):
468 return self.library_filename (lib)
469
470
471 def find_library_file (self, dirs, lib):
472
473 for dir in dirs:
474 libfile = os.path.join (dir, self.library_filename (lib))
475 if os.path.exists (libfile):
476 return libfile
477
478 else:
479 # Oops, didn't find it in *any* of 'dirs'
480 return None
481
482 # find_library_file ()
483
Greg Warddbd12761999-08-29 18:15:07 +0000484# class MSVCCompiler