blob: ae08e7fdcf16b9ba281fff56c755570726dd46e8 [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
Greg Ward1027e3f2000-03-31 16:53:42 +000053
Greg Ward7642f5c2000-03-31 16:47:40 +000054
55
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."""
96
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:
Greg Ward62e33932000-02-10 02:52:42 +0000120 if v == '' or v in L: continue
Greg Ward1b9c6f72000-02-08 02:39:44 +0000121 L.append(v)
122 break
123 i = i + 1
Greg Ward1027e3f2000-03-31 16:53:42 +0000124 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000125 break
Greg Ward1027e3f2000-03-31 16:53:42 +0000126 except RegError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000127 pass
128 return L
129
Greg Ward62e33932000-02-10 02:52:42 +0000130# get_msvc_paths()
131
132
Greg Ward69988092000-02-11 02:47:15 +0000133def find_exe (exe, version_number):
134 """Try to find an MSVC executable program 'exe' (from version
135 'version_number' of MSVC) in several places: first, one of the MSVC
136 program search paths from the registry; next, the directories in the
137 PATH environment variable. If any of those work, return an absolute
138 path that is known to exist. If none of them work, just return the
139 original program name, 'exe'."""
Greg Ward1b9c6f72000-02-08 02:39:44 +0000140
Greg Ward69988092000-02-11 02:47:15 +0000141 for p in get_msvc_paths ('path', version_number):
142 fn = os.path.join (os.path.abspath(p), exe)
143 if os.path.isfile(fn):
144 return fn
145
146 # didn't find it; try existing path
147 for p in string.split (os.environ['Path'],';'):
148 fn = os.path.join(os.path.abspath(p),exe)
149 if os.path.isfile(fn):
150 return fn
151
152 return exe # last desperate hope
Greg Ward1b9c6f72000-02-08 02:39:44 +0000153
Greg Ward62e33932000-02-10 02:52:42 +0000154
Greg Ward5de8cee2000-02-11 02:52:39 +0000155def set_path_env_var (name, version_number):
156 """Set environment variable 'name' to an MSVC path type value obtained
157 from 'get_msvc_paths()'. This is equivalent to a SET command prior
158 to execution of spawned commands."""
Greg Ward69988092000-02-11 02:47:15 +0000159
Greg Ward5de8cee2000-02-11 02:52:39 +0000160 p = get_msvc_paths (name, version_number)
Greg Ward62e33932000-02-10 02:52:42 +0000161 if p:
Greg Ward5de8cee2000-02-11 02:52:39 +0000162 os.environ[name] = string.join (p,';')
Greg Ward62e33932000-02-10 02:52:42 +0000163
Greg Warddbd12761999-08-29 18:15:07 +0000164
Greg Ward3d50b901999-09-08 02:36:01 +0000165class MSVCCompiler (CCompiler) :
166 """Concrete class that implements an interface to Microsoft Visual C++,
167 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000168
Greg Warddf178f91999-09-29 12:29:10 +0000169 compiler_type = 'msvc'
170
Greg Ward992c8f92000-06-25 02:31:16 +0000171 # Just set this so CCompiler's constructor doesn't barf. We currently
172 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
173 # as it really isn't necessary for this sort of single-compiler class.
174 # Would be nice to have a consistent interface with UnixCCompiler,
175 # though, so it's worth thinking about.
176 executables = {}
177
Greg Ward32c4a8a2000-03-06 03:40:29 +0000178 # Private class data (need to distinguish C from C++ source for compiler)
179 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000180 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000181
182 # Needed for the filename generation methods provided by the
183 # base class, CCompiler.
184 src_extensions = _c_extensions + _cpp_extensions
185 obj_extension = '.obj'
186 static_lib_extension = '.lib'
187 shared_lib_extension = '.dll'
188 static_lib_format = shared_lib_format = '%s%s'
189 exe_extension = '.exe'
190
191
Greg Warddbd12761999-08-29 18:15:07 +0000192 def __init__ (self,
193 verbose=0,
Greg Wardc74138d1999-10-03 20:47:52 +0000194 dry_run=0,
195 force=0):
Greg Warddbd12761999-08-29 18:15:07 +0000196
Greg Wardc74138d1999-10-03 20:47:52 +0000197 CCompiler.__init__ (self, verbose, dry_run, force)
Greg Ward5de8cee2000-02-11 02:52:39 +0000198 versions = get_devstudio_versions ()
Greg Ward69988092000-02-11 02:47:15 +0000199
Greg Ward5de8cee2000-02-11 02:52:39 +0000200 if versions:
201 version = versions[0] # highest version
Greg Ward69988092000-02-11 02:47:15 +0000202
Greg Ward41b4dd62000-03-29 04:13:00 +0000203 self.cc = find_exe("cl.exe", version)
204 self.link = find_exe("link.exe", version)
205 self.lib = find_exe("lib.exe", version)
Greg Ward5de8cee2000-02-11 02:52:39 +0000206 set_path_env_var ('lib', version)
207 set_path_env_var ('include', version)
208 path=get_msvc_paths('path', version)
Greg Ward69988092000-02-11 02:47:15 +0000209 try:
210 for p in string.split(os.environ['path'],';'):
211 path.append(p)
212 except KeyError:
213 pass
214 os.environ['path'] = string.join(path,';')
215 else:
216 # devstudio not found in the registry
217 self.cc = "cl.exe"
218 self.link = "link.exe"
Greg Ward09fc5422000-03-10 01:49:26 +0000219 self.lib = "lib.exe"
Greg Ward69988092000-02-11 02:47:15 +0000220
Greg Warddbd12761999-08-29 18:15:07 +0000221 self.preprocess_options = None
Greg Ward8a98cd92000-08-31 00:31:07 +0000222 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ]
223 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
224 '/Z7', '/D_DEBUG']
Greg Warddbd12761999-08-29 18:15:07 +0000225
Greg Ward1b9c6f72000-02-08 02:39:44 +0000226 self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000227 self.ldflags_shared_debug = [
228 '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
229 ]
Greg Warddbd12761999-08-29 18:15:07 +0000230 self.ldflags_static = [ '/nologo']
231
Greg Warddbd12761999-08-29 18:15:07 +0000232
233 # -- Worker methods ------------------------------------------------
Greg Warddbd12761999-08-29 18:15:07 +0000234
Greg Warddbd12761999-08-29 18:15:07 +0000235 def compile (self,
236 sources,
Greg Warddf178f91999-09-29 12:29:10 +0000237 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000238 macros=None,
Greg Ward0bdd90a1999-12-12 17:19:58 +0000239 include_dirs=None,
Greg Ward386b8442000-02-09 02:18:39 +0000240 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000241 extra_preargs=None,
242 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000243
Greg Ward32c4a8a2000-03-06 03:40:29 +0000244 (output_dir, macros, include_dirs) = \
245 self._fix_compile_args (output_dir, macros, include_dirs)
246 (objects, skip_sources) = self._prep_compile (sources, output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000247
Greg Ward32c4a8a2000-03-06 03:40:29 +0000248 if extra_postargs is None:
249 extra_postargs = []
Greg Warddbd12761999-08-29 18:15:07 +0000250
Greg Ward32c4a8a2000-03-06 03:40:29 +0000251 pp_opts = gen_preprocess_options (macros, include_dirs)
252 compile_opts = extra_preargs or []
253 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000254 if debug:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000255 compile_opts.extend (self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000256 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000257 compile_opts.extend (self.compile_options)
Greg Warddbd12761999-08-29 18:15:07 +0000258
Greg Ward32c4a8a2000-03-06 03:40:29 +0000259 for i in range (len (sources)):
260 src = sources[i] ; obj = objects[i]
261 ext = (os.path.splitext (src))[1]
Greg Warddbd12761999-08-29 18:15:07 +0000262
Greg Ward32c4a8a2000-03-06 03:40:29 +0000263 if skip_sources[src]:
264 self.announce ("skipping %s (%s up-to-date)" % (src, obj))
265 else:
266 if ext in self._c_extensions:
267 input_opt = "/Tc" + src
268 elif ext in self._cpp_extensions:
269 input_opt = "/Tp" + src
Greg Warddbd12761999-08-29 18:15:07 +0000270
Greg Ward32c4a8a2000-03-06 03:40:29 +0000271 output_opt = "/Fo" + obj
Greg Warddbd12761999-08-29 18:15:07 +0000272
Greg Ward32c4a8a2000-03-06 03:40:29 +0000273 self.mkpath (os.path.dirname (obj))
Greg Wardd1517112000-05-30 01:56:44 +0000274 try:
275 self.spawn ([self.cc] + compile_opts + pp_opts +
276 [input_opt, output_opt] +
277 extra_postargs)
278 except DistutilsExecError, msg:
279 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000280
Greg Ward32c4a8a2000-03-06 03:40:29 +0000281 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000282
Greg Ward32c4a8a2000-03-06 03:40:29 +0000283 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000284
285
Greg Ward09fc5422000-03-10 01:49:26 +0000286 def create_static_lib (self,
287 objects,
288 output_libname,
289 output_dir=None,
290 debug=0,
291 extra_preargs=None,
292 extra_postargs=None):
Greg Warddbd12761999-08-29 18:15:07 +0000293
Greg Ward2f557a22000-03-26 21:42:28 +0000294 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000295 output_filename = \
296 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000297
Greg Ward32c4a8a2000-03-06 03:40:29 +0000298 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000299 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000300 if debug:
301 pass # XXX what goes here?
302 if extra_preargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000303 lib_args[:0] = extra_preargs
Greg Ward32c4a8a2000-03-06 03:40:29 +0000304 if extra_postargs:
Greg Ward09fc5422000-03-10 01:49:26 +0000305 lib_args.extend (extra_postargs)
Greg Wardd1517112000-05-30 01:56:44 +0000306 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000307 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000308 except DistutilsExecError, msg:
309 raise LibError, msg
310
Greg Ward32c4a8a2000-03-06 03:40:29 +0000311 else:
312 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000313
Greg Ward09fc5422000-03-10 01:49:26 +0000314 # create_static_lib ()
Greg Warddbd12761999-08-29 18:15:07 +0000315
316
317 def link_shared_lib (self,
318 objects,
319 output_libname,
Greg Warddf178f91999-09-29 12:29:10 +0000320 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000321 libraries=None,
322 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000323 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000324 export_symbols=None,
Greg Ward386b8442000-02-09 02:18:39 +0000325 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000326 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000327 extra_postargs=None,
328 build_temp=None):
Greg Warddf178f91999-09-29 12:29:10 +0000329
Greg Warddf178f91999-09-29 12:29:10 +0000330 self.link_shared_object (objects,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000331 self.shared_library_name(output_libname),
332 output_dir=output_dir,
333 libraries=libraries,
334 library_dirs=library_dirs,
Greg Ward5299b6a2000-05-20 13:23:21 +0000335 runtime_library_dirs=runtime_library_dirs,
336 export_symbols=export_symbols,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000337 debug=debug,
338 extra_preargs=extra_preargs,
Greg Wardbfc79d62000-06-28 01:29:09 +0000339 extra_postargs=extra_postargs,
340 build_temp=build_temp)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000341
Greg Warddbd12761999-08-29 18:15:07 +0000342
343 def link_shared_object (self,
344 objects,
345 output_filename,
Greg Warddf178f91999-09-29 12:29:10 +0000346 output_dir=None,
Greg Warddbd12761999-08-29 18:15:07 +0000347 libraries=None,
348 library_dirs=None,
Greg Ward2f557a22000-03-26 21:42:28 +0000349 runtime_library_dirs=None,
Greg Ward5299b6a2000-05-20 13:23:21 +0000350 export_symbols=None,
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000351 debug=0,
Greg Warddf178f91999-09-29 12:29:10 +0000352 extra_preargs=None,
Greg Wardbfc79d62000-06-28 01:29:09 +0000353 extra_postargs=None,
354 build_temp=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000355
Greg Ward2f557a22000-03-26 21:42:28 +0000356 (objects, output_dir) = self._fix_object_args (objects, output_dir)
357 (libraries, library_dirs, runtime_library_dirs) = \
358 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
359
Greg Wardf70c6032000-04-19 02:16:49 +0000360 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000361 self.warn ("I don't know what to do with 'runtime_library_dirs': "
362 + str (runtime_library_dirs))
Greg Warddbd12761999-08-29 18:15:07 +0000363
Greg Wardd03f88a2000-03-18 15:19:51 +0000364 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000365 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000366 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000367 if output_dir is not None:
368 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000369
Greg Ward32c4a8a2000-03-06 03:40:29 +0000370 if self._need_link (objects, output_filename):
371
372 if debug:
373 ldflags = self.ldflags_shared_debug
Greg Ward32c4a8a2000-03-06 03:40:29 +0000374 else:
375 ldflags = self.ldflags_shared
376
Greg Ward5299b6a2000-05-20 13:23:21 +0000377 export_opts = []
378 for sym in (export_symbols or []):
379 export_opts.append("/EXPORT:" + sym)
380
381 ld_args = (ldflags + lib_opts + export_opts +
382 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000383
Greg Ward159eb922000-08-02 00:00:30 +0000384 # The MSVC linker generates .lib and .exp files, which cannot be
385 # suppressed by any linker switches. The .lib files may even be
386 # needed! Make sure they are generated in the temporary build
387 # directory. Since they have different names for debug and release
388 # builds, they can go into the same directory.
389 (dll_name, dll_ext) = os.path.splitext(
390 os.path.basename(output_filename))
391 implib_file = os.path.join(
392 os.path.dirname(objects[0]),
393 self.library_filename(dll_name))
394 ld_args.append ('/IMPLIB:' + implib_file)
395
Greg Ward32c4a8a2000-03-06 03:40:29 +0000396 if extra_preargs:
397 ld_args[:0] = extra_preargs
398 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000399 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000400
401 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000402 try:
403 self.spawn ([self.link] + ld_args)
404 except DistutilsExecError, msg:
405 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000406
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000407 else:
Greg Ward32c4a8a2000-03-06 03:40:29 +0000408 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000409
Greg Ward32c4a8a2000-03-06 03:40:29 +0000410 # link_shared_object ()
Greg Wardf70c6032000-04-19 02:16:49 +0000411
412
413 def link_executable (self,
414 objects,
415 output_progname,
416 output_dir=None,
417 libraries=None,
418 library_dirs=None,
419 runtime_library_dirs=None,
420 debug=0,
421 extra_preargs=None,
422 extra_postargs=None):
423
424 (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
428 if runtime_library_dirs:
429 self.warn ("I don't know what to do with 'runtime_library_dirs': "
430 + str (runtime_library_dirs))
431
432 lib_opts = gen_lib_options (self,
433 library_dirs, runtime_library_dirs,
434 libraries)
435 output_filename = output_progname + self.exe_extension
436 if output_dir is not None:
437 output_filename = os.path.join (output_dir, output_filename)
438
439 if self._need_link (objects, output_filename):
440
441 if debug:
442 ldflags = self.ldflags_shared_debug[1:]
443 else:
444 ldflags = self.ldflags_shared[1:]
445
446 ld_args = ldflags + lib_opts + \
447 objects + ['/OUT:' + output_filename]
448
449 if extra_preargs:
450 ld_args[:0] = extra_preargs
451 if extra_postargs:
452 ld_args.extend (extra_postargs)
453
454 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000455 try:
456 self.spawn ([self.link] + ld_args)
457 except DistutilsExecError, msg:
458 raise LinkError, msg
Greg Wardf70c6032000-04-19 02:16:49 +0000459 else:
460 self.announce ("skipping %s (up-to-date)" % output_filename)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000461
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000462
Greg Ward32c4a8a2000-03-06 03:40:29 +0000463 # -- Miscellaneous methods -----------------------------------------
464 # These are all used by the 'gen_lib_options() function, in
465 # ccompiler.py.
Greg Wardc74138d1999-10-03 20:47:52 +0000466
467 def library_dir_option (self, dir):
468 return "/LIBPATH:" + dir
469
Greg Wardd03f88a2000-03-18 15:19:51 +0000470 def runtime_library_dir_option (self, dir):
471 raise DistutilsPlatformError, \
472 "don't know how to set runtime library search path for MSVC++"
473
Greg Wardc74138d1999-10-03 20:47:52 +0000474 def library_option (self, lib):
475 return self.library_filename (lib)
476
477
Greg Wardd1425642000-08-04 01:29:27 +0000478 def find_library_file (self, dirs, lib, debug=0):
479 # Prefer a debugging library if found (and requested), but deal
480 # with it if we don't have one.
481 if debug:
482 try_names = [lib + "_d", lib]
483 else:
484 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000485 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000486 for name in try_names:
487 libfile = os.path.join(dir, self.library_filename (name))
488 if os.path.exists(libfile):
489 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000490 else:
491 # Oops, didn't find it in *any* of 'dirs'
492 return None
493
494 # find_library_file ()
495
Greg Warddbd12761999-08-29 18:15:07 +0000496# class MSVCCompiler