blob: 6acd4efd0d5aa0454e963c5d230a494dbf7903a7 [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 Wardcd079c42000-06-29 22:59:10 +000023 import _winreg
Greg Ward7642f5c2000-03-31 16:47:40 +000024 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000025 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000026
Greg Wardcd079c42000-06-29 22:59:10 +000027 RegOpenKeyEx = _winreg.OpenKeyEx
28 RegEnumKey = _winreg.EnumKey
29 RegEnumValue = _winreg.EnumValue
30 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000031
Greg Ward7642f5c2000-03-31 16:47:40 +000032except ImportError:
33 try:
34 import win32api
35 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000036 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000037 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000038
39 RegOpenKeyEx = win32api.RegOpenKeyEx
40 RegEnumKey = win32api.RegEnumKey
41 RegEnumValue = win32api.RegEnumValue
42 RegError = win32api.error
43
Greg Ward7642f5c2000-03-31 16:47:40 +000044 except ImportError:
45 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000046
47if _can_read_reg:
48 HKEY_CLASSES_ROOT = hkey_mod.HKEY_CLASSES_ROOT
49 HKEY_LOCAL_MACHINE = hkey_mod.HKEY_LOCAL_MACHINE
50 HKEY_CURRENT_USER = hkey_mod.HKEY_CURRENT_USER
51 HKEY_USERS = hkey_mod.HKEY_USERS
Greg Ward1027e3f2000-03-31 16:53:42 +000052
Greg Ward7642f5c2000-03-31 16:47:40 +000053
54
Greg Ward62e33932000-02-10 02:52:42 +000055def get_devstudio_versions ():
Greg Ward62e33932000-02-10 02:52:42 +000056 """Get list of devstudio versions from the Windows registry. Return a
Greg Ward69988092000-02-11 02:47:15 +000057 list of strings containing version numbers; the list will be
Greg Ward62e33932000-02-10 02:52:42 +000058 empty if we were unable to access the registry (eg. couldn't import
59 a registry-access module) or the appropriate registry keys weren't
Greg Ward69988092000-02-11 02:47:15 +000060 found."""
61
Greg Ward7642f5c2000-03-31 16:47:40 +000062 if not _can_read_reg:
Greg Ward62e33932000-02-10 02:52:42 +000063 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000064
65 K = 'Software\\Microsoft\\Devstudio'
66 L = []
Greg Ward1027e3f2000-03-31 16:53:42 +000067 for base in (HKEY_CLASSES_ROOT,
68 HKEY_LOCAL_MACHINE,
69 HKEY_CURRENT_USER,
70 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +000071 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000072 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +000073 i = 0
74 while 1:
75 try:
Greg Ward1027e3f2000-03-31 16:53:42 +000076 p = RegEnumKey(k,i)
Greg Ward1b9c6f72000-02-08 02:39:44 +000077 if p[0] in '123456789' and p not in L:
78 L.append(p)
Greg Ward1027e3f2000-03-31 16:53:42 +000079 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000080 break
81 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +000082 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +000083 pass
84 L.sort()
85 L.reverse()
86 return L
87
Greg Ward62e33932000-02-10 02:52:42 +000088# get_devstudio_versions ()
89
90
91def get_msvc_paths (path, version='6.0', platform='x86'):
Greg Ward69988092000-02-11 02:47:15 +000092 """Get a list of devstudio directories (include, lib or path). Return
93 a list of strings; will be empty list if unable to access the
94 registry or appropriate registry keys not found."""
95
Greg Ward7642f5c2000-03-31 16:47:40 +000096 if not _can_read_reg:
Greg Ward69988092000-02-11 02:47:15 +000097 return []
Greg Ward1b9c6f72000-02-08 02:39:44 +000098
99 L = []
Greg Ward62e33932000-02-10 02:52:42 +0000100 if path=='lib':
101 path= 'Library'
Greg Ward1b9c6f72000-02-08 02:39:44 +0000102 path = string.upper(path + ' Dirs')
Greg Ward62e33932000-02-10 02:52:42 +0000103 K = ('Software\\Microsoft\\Devstudio\\%s\\' +
104 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
105 (version,platform)
Greg Ward1027e3f2000-03-31 16:53:42 +0000106 for base in (HKEY_CLASSES_ROOT,
107 HKEY_LOCAL_MACHINE,
108 HKEY_CURRENT_USER,
109 HKEY_USERS):
Greg Ward1b9c6f72000-02-08 02:39:44 +0000110 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000111 k = RegOpenKeyEx(base,K)
Greg Ward1b9c6f72000-02-08 02:39:44 +0000112 i = 0
113 while 1:
114 try:
Greg Ward1027e3f2000-03-31 16:53:42 +0000115 (p,v,t) = RegEnumValue(k,i)
Greg Ward62e33932000-02-10 02:52:42 +0000116 if string.upper(p) == path:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000117 V = string.split(v,';')
118 for v in V:
Greg Ward62e33932000-02-10 02:52:42 +0000119 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000120 L.append(v)
121 break
122 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000123 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000124 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000125 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000126 pass
127 return L
128
Greg Ward62e33932000-02-10 02:52:42 +0000129# get_msvc_paths()
130
131
Greg Ward69988092000-02-11 02:47:15 +0000132def find_exe (exe, version_number):
133 """Try to find an MSVC executable program 'exe' (from version
134 'version_number' of MSVC) in several places: first, one of the MSVC
135 program search paths from the registry; next, the directories in the
136 PATH environment variable. If any of those work, return an absolute
137 path that is known to exist. If none of them work, just return the
138 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000139
Greg Ward69988092000-02-11 02:47:15 +0000140 for p in get_msvc_paths ('path', version_number):
141 fn = os.path.join (os.path.abspath(p), exe)
142 if os.path.isfile(fn):
143 return fn
144
145 # didn't find it; try existing path
146 for p in string.split (os.environ['Path'],';'):
147 fn = os.path.join(os.path.abspath(p),exe)
148 if os.path.isfile(fn):
149 return fn
150
151 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000152
Greg Ward62e33932000-02-10 02:52:42 +0000153
Greg Ward5de8cee2000-02-11 02:52:39 +0000154def set_path_env_var (name, version_number):
155 """Set environment variable 'name' to an MSVC path type value obtained
156 from 'get_msvc_paths()'. This is equivalent to a SET command prior
157 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000158
Greg Ward5de8cee2000-02-11 02:52:39 +0000159 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000160 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000161 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000162
Greg Warddbd12761999-08-29 18:15:07 +0000163
Greg Ward3d50b901999-09-08 02:36:01 +0000164class MSVCCompiler (CCompiler) :
165 """Concrete class that implements an interface to Microsoft Visual C++,
166 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000167
Greg Warddf178f91999-09-29 12:29:10 +0000168 compiler_type = 'msvc'
169
Greg Ward992c8f92000-06-25 02:31:16 +0000170 # Just set this so CCompiler's constructor doesn't barf. We currently
171 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
172 # as it really isn't necessary for this sort of single-compiler class.
173 # Would be nice to have a consistent interface with UnixCCompiler,
174 # though, so it's worth thinking about.
175 executables = {}
176
Greg Ward32c4a8a2000-03-06 03:40:29 +0000177 # Private class data (need to distinguish C from C++ source for compiler)
178 _c_extensions = ['.c']
179 _cpp_extensions = ['.cc','.cpp']
180
181 # Needed for the filename generation methods provided by the
182 # base class, CCompiler.
183 src_extensions = _c_extensions + _cpp_extensions
184 obj_extension = '.obj'
185 static_lib_extension = '.lib'
186 shared_lib_extension = '.dll'
187 static_lib_format = shared_lib_format = '%s%s'
188 exe_extension = '.exe'
189
190
Greg Warddbd12761999-08-29 18:15:07 +0000191 def __init__ (self,
192 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000193 dry_run=0,
194 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000195
Greg Wardc74138d1999-10-03 20:47:52 +0000196 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000197 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000198
Greg Ward5de8cee2000-02-11 02:52:39 +0000199 if versions:
200 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000201
Greg Ward41b4dd62000-03-29 04:13:00 +0000202 self.cc = find_exe("cl.exe", version)
203 self.link = find_exe("link.exe", version)
204 self.lib = find_exe("lib.exe", version)
Greg Ward5de8cee2000-02-11 02:52:39 +0000205 set_path_env_var ('lib', version)
206 set_path_env_var ('include', version)
207 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000208 try:
209 for p in string.split(os.environ['path'],';'):
210 path.append(p)
211 except KeyError:
212 pass
213 os.environ['path'] = string.join(path,';')
214 else:
215 # devstudio not found in the registry
216 self.cc = "cl.exe"
217 self.link = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000218 self.lib = "lib.exe"
Greg Ward69988092000-02-11 02:47:15 +0000219
Greg Warddbd12761999-08-29 18:15:07 +0000220 self.preprocess_options = None
Greg Ward69988092000-02-11 02:47:15 +0000221 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3' ]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000222 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000223
Greg Ward1b9c6f72000-02-08 02:39:44 +0000224 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000225 self.ldflags_shared_debug = [
226 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
227 ]
Greg Warddbd12761999-08-29 18:15:07 +0000228 self.ldflags_static = [ '/nologo']
229
Greg Warddbd12761999-08-29 18:15:07 +0000230
231 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000232
Greg Warddbd12761999-08-29 18:15:07 +0000233 def compile (self,
234 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000235 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000236 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000237 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000238 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000239 extra_preargs=None,
240 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000241
Greg Ward32c4a8a2000-03-06 03:40:29 +0000242 (output_dir, macros, include_dirs) = \
243 self._fix_compile_args (output_dir, macros, include_dirs)
244 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000245
Greg Ward32c4a8a2000-03-06 03:40:29 +0000246 if extra_postargs is None:
247 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000248
Greg Ward32c4a8a2000-03-06 03:40:29 +0000249 pp_opts = gen_preprocess_options (macros, include_dirs)
250 compile_opts = extra_preargs or []
251 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000252 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000253 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000254 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000255 compile_opts.extend (self.compile_options)
Greg Warddbd12761999-08-29 18:15:07 +0000256
Greg Ward32c4a8a2000-03-06 03:40:29 +0000257 for i in range (len (sources)):
258 src = sources[i] ; obj = objects[i]
259 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000260
Greg Ward32c4a8a2000-03-06 03:40:29 +0000261 if skip_sources[src]:
262 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
263 else:
264 if ext in self._c_extensions:
265 input_opt = "/Tc" + src
266 elif ext in self._cpp_extensions:
267 input_opt = "/Tp" + src
Greg Warddbd12761999-08-29 18:15:07 +0000268
Greg Ward32c4a8a2000-03-06 03:40:29 +0000269 output_opt = "/Fo" + obj
Greg Warddbd12761999-08-29 18:15:07 +0000270
Greg Ward32c4a8a2000-03-06 03:40:29 +0000271 self.mkpath (os.path.dirname (obj))
Greg Wardd1517112000-05-30 01:56:44 +0000272 try:
273 self.spawn ([self.cc] + compile_opts + pp_opts +
274 [input_opt, output_opt] +
275 extra_postargs)
276 except DistutilsExecError, msg:
277 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000278
Greg Ward32c4a8a2000-03-06 03:40:29 +0000279 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000280
Greg Ward32c4a8a2000-03-06 03:40:29 +0000281 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000282
283
Greg Ward09fc5422000-03-10 01:49:26 +0000284 def create_static_lib (self,
285 objects,
286 output_libname,
287 output_dir=None,
288 debug=0,
289 extra_preargs=None,
290 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000291
Greg Ward2f557a22000-03-26 21:42:28 +0000292 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000293 output_filename = \
294 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000295
Greg Ward32c4a8a2000-03-06 03:40:29 +0000296 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000297 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000298 if debug:
299 pass # XXX what goes here?
300 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000301 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000302 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000303 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000304 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000305 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000306 except DistutilsExecError, msg:
307 raise LibError, msg
308
Greg Ward32c4a8a2000-03-06 03:40:29 +0000309 else:
310 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000311
Greg Ward09fc5422000-03-10 01:49:26 +0000312 # create_static_lib ()
Greg Warddbd12761999-08-29 18:15:07 +0000313
314
315 def link_shared_lib (self,
316 objects,
317 output_libname,
Greg Warddf178f91999-09-29 12:29:10 +0000318 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000319 libraries=None,
320 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000321 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000322 export_symbols=None,
Greg Ward386b8442000-02-09 02:18:39 +0000323 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000324 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000325 extra_postargs=None,
326 build_temp=None):
Greg Warddf178f91999-09-29 12:29:10 +0000327
Greg Warddf178f91999-09-29 12:29:10 +0000328 self.link_shared_object (objects,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000329 self.shared_library_name(output_libname),
330 output_dir=output_dir,
331 libraries=libraries,
332 library_dirs=library_dirs,
Greg Ward5299b6a2000-05-20 13:23:21 +0000333 runtime_library_dirs=runtime_library_dirs,
334 export_symbols=export_symbols,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000335 debug=debug,
336 extra_preargs=extra_preargs,
Greg Wardbfc79d62000-06-28 01:29:09 +0000337 extra_postargs=extra_postargs,
338 build_temp=build_temp)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000339
Greg Warddbd12761999-08-29 18:15:07 +0000340
341 def link_shared_object (self,
342 objects,
343 output_filename,
Greg Warddf178f91999-09-29 12:29:10 +0000344 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000345 libraries=None,
346 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000347 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000348 export_symbols=None,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000349 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000350 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000351 extra_postargs=None,
352 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000353
Greg Ward2f557a22000-03-26 21:42:28 +0000354 (objects, output_dir) = self._fix_object_args (objects, output_dir)
355 (libraries, library_dirs, runtime_library_dirs) = \
356 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
357
Greg Wardf70c6032000-04-19 02:16:49 +0000358 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000359 self.warn ("I don't know what to do with 'runtime_library_dirs': "
360 + str (runtime_library_dirs))
Greg Warddbd12761999-08-29 18:15:07 +0000361
Greg Wardd03f88a2000-03-18 15:19:51 +0000362 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000363 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000364 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000365 if output_dir is not None:
366 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000367
Greg Ward32c4a8a2000-03-06 03:40:29 +0000368 if self._need_link (objects, output_filename):
369
370 if debug:
371 ldflags = self.ldflags_shared_debug
Greg Ward32c4a8a2000-03-06 03:40:29 +0000372 else:
373 ldflags = self.ldflags_shared
374
Greg Ward5299b6a2000-05-20 13:23:21 +0000375 export_opts = []
376 for sym in (export_symbols or []):
377 export_opts.append("/EXPORT:" + sym)
378
379 ld_args = (ldflags + lib_opts + export_opts +
380 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000381
382 if extra_preargs:
383 ld_args[:0] = extra_preargs
384 if extra_postargs:
385 ld_args.extend (extra_postargs)
386
Greg Ward02a1a2b2000-04-15 22:15:07 +0000387 print "link_shared_object():"
388 print " output_filename =", output_filename
389 print " mkpath'ing:", os.path.dirname (output_filename)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000390 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000391 try:
392 self.spawn ([self.link] + ld_args)
393 except DistutilsExecError, msg:
394 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000395
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000396 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000397 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000398
Greg Ward32c4a8a2000-03-06 03:40:29 +0000399 # link_shared_object ()
Greg Wardf70c6032000-04-19 02:16:49 +0000400
401
402 def link_executable (self,
403 objects,
404 output_progname,
405 output_dir=None,
406 libraries=None,
407 library_dirs=None,
408 runtime_library_dirs=None,
409 debug=0,
410 extra_preargs=None,
411 extra_postargs=None):
412
413 (objects, output_dir) = self._fix_object_args (objects, output_dir)
414 (libraries, library_dirs, runtime_library_dirs) = \
415 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
416
417 if runtime_library_dirs:
418 self.warn ("I don't know what to do with 'runtime_library_dirs': "
419 + str (runtime_library_dirs))
420
421 lib_opts = gen_lib_options (self,
422 library_dirs, runtime_library_dirs,
423 libraries)
424 output_filename = output_progname + self.exe_extension
425 if output_dir is not None:
426 output_filename = os.path.join (output_dir, output_filename)
427
428 if self._need_link (objects, output_filename):
429
430 if debug:
431 ldflags = self.ldflags_shared_debug[1:]
432 else:
433 ldflags = self.ldflags_shared[1:]
434
435 ld_args = ldflags + lib_opts + \
436 objects + ['/OUT:' + output_filename]
437
438 if extra_preargs:
439 ld_args[:0] = extra_preargs
440 if extra_postargs:
441 ld_args.extend (extra_postargs)
442
443 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000444 try:
445 self.spawn ([self.link] + ld_args)
446 except DistutilsExecError, msg:
447 raise LinkError, msg
Greg Wardf70c6032000-04-19 02:16:49 +0000448 else:
449 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000450
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000451
Greg Ward32c4a8a2000-03-06 03:40:29 +0000452 # -- Miscellaneous methods -----------------------------------------
453 # These are all used by the 'gen_lib_options() function, in
454 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000455
456 def library_dir_option (self, dir):
457 return "/LIBPATH:" + dir
458
Greg Wardd03f88a2000-03-18 15:19:51 +0000459 def runtime_library_dir_option (self, dir):
460 raise DistutilsPlatformError, \
461 "don't know how to set runtime library search path for MSVC++"
462
Greg Wardc74138d1999-10-03 20:47:52 +0000463 def library_option (self, lib):
464 return self.library_filename (lib)
465
466
467 def find_library_file (self, dirs, lib):
468
469 for dir in dirs:
470 libfile = os.path.join (dir, self.library_filename (lib))
471 if os.path.exists (libfile):
472 return libfile
473
474 else:
475 # Oops, didn't find it in *any* of 'dirs'
476 return None
477
478 # find_library_file ()
479
Greg Warddbd12761999-08-29 18:15:07 +0000480# class MSVCCompiler