blob: 4d7159f0f92962ca5f59491e3c64f2001a3eb402 [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
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +00004for the Microsoft Visual Studio.
5"""
Greg Warddbd12761999-08-29 18:15:07 +00006
Andrew M. Kuchlinga6483d22002-11-14 02:25:42 +00007# Written by 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
Andrew M. Kuchlingd448f662002-11-19 13:12:28 +000011# This module should be kept compatible with Python 1.5.2.
12
Greg Ward3ce77fd2000-03-02 01:49:45 +000013__revision__ = "$Id$"
Greg Warddbd12761999-08-29 18:15:07 +000014
Greg Ward32c4a8a2000-03-06 03:40:29 +000015import sys, os, string
Greg Ward3add77f2000-05-30 02:02:49 +000016from distutils.errors import \
17 DistutilsExecError, DistutilsPlatformError, \
Greg Wardd1517112000-05-30 01:56:44 +000018 CompileError, LibError, LinkError
Greg Ward3add77f2000-05-30 02:02:49 +000019from distutils.ccompiler import \
20 CCompiler, gen_preprocess_options, gen_lib_options
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000021from distutils import log
Greg Ward62e33932000-02-10 02:52:42 +000022
Greg Ward7642f5c2000-03-31 16:47:40 +000023_can_read_reg = 0
24try:
Greg Ward1b5ec762000-06-30 19:37:59 +000025 import _winreg
Greg Ward83c38702000-06-29 23:04:59 +000026
Greg Ward7642f5c2000-03-31 16:47:40 +000027 _can_read_reg = 1
Greg Wardcd079c42000-06-29 22:59:10 +000028 hkey_mod = _winreg
Greg Ward19ce1662000-03-31 19:04:25 +000029
Greg Wardcd079c42000-06-29 22:59:10 +000030 RegOpenKeyEx = _winreg.OpenKeyEx
31 RegEnumKey = _winreg.EnumKey
32 RegEnumValue = _winreg.EnumValue
33 RegError = _winreg.error
Greg Ward19ce1662000-03-31 19:04:25 +000034
Greg Ward7642f5c2000-03-31 16:47:40 +000035except ImportError:
36 try:
37 import win32api
38 import win32con
Greg Ward7642f5c2000-03-31 16:47:40 +000039 _can_read_reg = 1
Greg Ward1027e3f2000-03-31 16:53:42 +000040 hkey_mod = win32con
Greg Ward19ce1662000-03-31 19:04:25 +000041
42 RegOpenKeyEx = win32api.RegOpenKeyEx
43 RegEnumKey = win32api.RegEnumKey
44 RegEnumValue = win32api.RegEnumValue
45 RegError = win32api.error
46
Greg Ward7642f5c2000-03-31 16:47:40 +000047 except ImportError:
48 pass
Greg Ward1027e3f2000-03-31 16:53:42 +000049
50if _can_read_reg:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000051 HKEYS = (hkey_mod.HKEY_USERS,
52 hkey_mod.HKEY_CURRENT_USER,
53 hkey_mod.HKEY_LOCAL_MACHINE,
54 hkey_mod.HKEY_CLASSES_ROOT)
Fred Drakeb94b8492001-12-06 20:51:35 +000055
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000056def read_keys(base, key):
57 """Return list of registry keys."""
Fred Drakeb94b8492001-12-06 20:51:35 +000058
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000059 try:
60 handle = RegOpenKeyEx(base, key)
61 except RegError:
62 return None
Greg Ward1b9c6f72000-02-08 02:39:44 +000063 L = []
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000064 i = 0
65 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000066 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000067 k = RegEnumKey(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000068 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000069 break
70 L.append(k)
71 i = i + 1
Greg Ward1b9c6f72000-02-08 02:39:44 +000072 return L
73
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000074def read_values(base, key):
75 """Return dict of registry keys and values.
Greg Ward62e33932000-02-10 02:52:42 +000076
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000077 All names are converted to lowercase.
78 """
79 try:
80 handle = RegOpenKeyEx(base, key)
81 except RegError:
82 return None
83 d = {}
84 i = 0
85 while 1:
Greg Ward1b9c6f72000-02-08 02:39:44 +000086 try:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000087 name, value, type = RegEnumValue(handle, i)
Greg Ward1027e3f2000-03-31 16:53:42 +000088 except RegError:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +000089 break
90 name = name.lower()
91 d[convert_mbcs(name)] = convert_mbcs(value)
92 i = i + 1
93 return d
94
95def convert_mbcs(s):
96 enc = getattr(s, "encode", None)
97 if enc is not None:
98 try:
99 s = enc("mbcs")
100 except UnicodeError:
Greg Ward1b9c6f72000-02-08 02:39:44 +0000101 pass
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000102 return s
Greg Ward1b9c6f72000-02-08 02:39:44 +0000103
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000104class MacroExpander:
Greg Ward62e33932000-02-10 02:52:42 +0000105
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000106 def __init__(self, version):
107 self.macros = {}
108 self.load_macros(version)
Greg Ward62e33932000-02-10 02:52:42 +0000109
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000110 def set_macro(self, macro, path, key):
111 for base in HKEYS:
112 d = read_values(base, path)
113 if d:
114 self.macros["$(%s)" % macro] = d[key]
115 break
116
117 def load_macros(self, version):
118 vsbase = r"Software\Microsoft\VisualStudio\%s.0" % version
119 self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
120 self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
121 net = r"Software\Microsoft\.NETFramework"
122 self.set_macro("FrameworkDir", net, "installroot")
123 self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
Greg Ward1b9c6f72000-02-08 02:39:44 +0000124
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000125 p = r"Software\Microsoft\NET Framework Setup\Product"
126 for base in HKEYS:
127 try:
128 h = RegOpenKeyEx(base, p)
129 except RegError:
130 continue
131 key = RegEnumKey(h, 0)
132 d = read_values(base, r"%s\%s" % (p, key))
133 self.macros["$(FrameworkVersion)"] = d["version"]
Greg Ward69988092000-02-11 02:47:15 +0000134
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000135 def sub(self, s):
136 for k, v in self.macros.items():
137 s = string.replace(s, k, v)
138 return s
Greg Ward69988092000-02-11 02:47:15 +0000139
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000140def get_build_version():
141 """Return the version of MSVC that was used to build Python.
Greg Ward1b9c6f72000-02-08 02:39:44 +0000142
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000143 For Python 2.3 and up, the version number is included in
144 sys.version. For earlier versions, assume the compiler is MSVC 6.
145 """
Greg Ward62e33932000-02-10 02:52:42 +0000146
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000147 prefix = "MSC v."
148 i = string.find(sys.version, prefix)
149 if i == -1:
150 return 6
151 i += len(prefix)
152 s, rest = sys.version[i:].split(" ", 1)
153 n = int(s[:-2])
154 if n == 12:
155 return 6
156 elif n == 13:
157 return 7
158 # else we don't know what version of the compiler this is
159 return None
160
Greg Warddbd12761999-08-29 18:15:07 +0000161
Greg Ward3d50b901999-09-08 02:36:01 +0000162class MSVCCompiler (CCompiler) :
163 """Concrete class that implements an interface to Microsoft Visual C++,
164 as defined by the CCompiler abstract class."""
Greg Warddbd12761999-08-29 18:15:07 +0000165
Greg Warddf178f91999-09-29 12:29:10 +0000166 compiler_type = 'msvc'
167
Greg Ward992c8f92000-06-25 02:31:16 +0000168 # Just set this so CCompiler's constructor doesn't barf. We currently
169 # don't use the 'set_executables()' bureaucracy provided by CCompiler,
170 # as it really isn't necessary for this sort of single-compiler class.
171 # Would be nice to have a consistent interface with UnixCCompiler,
172 # though, so it's worth thinking about.
173 executables = {}
174
Greg Ward32c4a8a2000-03-06 03:40:29 +0000175 # Private class data (need to distinguish C from C++ source for compiler)
176 _c_extensions = ['.c']
Greg Ward408e9ae2000-08-30 17:32:24 +0000177 _cpp_extensions = ['.cc', '.cpp', '.cxx']
Greg Ward9c0ea132000-09-19 23:56:43 +0000178 _rc_extensions = ['.rc']
179 _mc_extensions = ['.mc']
Greg Ward32c4a8a2000-03-06 03:40:29 +0000180
181 # Needed for the filename generation methods provided by the
182 # base class, CCompiler.
Greg Ward9c0ea132000-09-19 23:56:43 +0000183 src_extensions = (_c_extensions + _cpp_extensions +
184 _rc_extensions + _mc_extensions)
185 res_extension = '.res'
Greg Ward32c4a8a2000-03-06 03:40:29 +0000186 obj_extension = '.obj'
187 static_lib_extension = '.lib'
188 shared_lib_extension = '.dll'
189 static_lib_format = shared_lib_format = '%s%s'
190 exe_extension = '.exe'
191
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000192 def __init__ (self, verbose=0, dry_run=0, force=0):
Greg Wardc74138d1999-10-03 20:47:52 +0000193 CCompiler.__init__ (self, verbose, dry_run, force)
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000194 self.__version = get_build_version()
195 if self.__version == 7:
196 self.__root = r"Software\Microsoft\VisualStudio"
197 self.__macros = MacroExpander(self.__version)
Greg Ward69988092000-02-11 02:47:15 +0000198 else:
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000199 self.__root = r"Software\Microsoft\Devstudio"
200 self.__paths = self.get_msvc_paths("path")
201
202 self.cc = self.find_exe("cl.exe")
203 self.linker = self.find_exe("link.exe")
204 self.lib = self.find_exe("lib.exe")
205 self.rc = self.find_exe("rc.exe") # resource compiler
206 self.mc = self.find_exe("mc.exe") # message compiler
207 self.set_path_env_var('lib')
208 self.set_path_env_var('include')
209
210 # extend the MSVC path with the current path
211 try:
212 for p in string.split(os.environ['path'], ';'):
213 self.__paths.append(p)
214 except KeyError:
215 pass
216 os.environ['path'] = string.join(self.__paths, ';')
Greg Ward69988092000-02-11 02:47:15 +0000217
Greg Warddbd12761999-08-29 18:15:07 +0000218 self.preprocess_options = None
Jeremy Hylton2683ac72002-06-18 19:08:40 +0000219 self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' ,
220 '/DNDEBUG']
Greg Ward8a98cd92000-08-31 00:31:07 +0000221 self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
222 '/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 Ward9c0ea132000-09-19 23:56:43 +0000233 def object_filenames (self,
234 source_filenames,
235 strip_dir=0,
236 output_dir=''):
237 # Copied from ccompiler.py, extended to return .res as 'object'-file
238 # for .rc input file
239 if output_dir is None: output_dir = ''
240 obj_names = []
241 for src_name in source_filenames:
242 (base, ext) = os.path.splitext (src_name)
243 if ext not in self.src_extensions:
244 # Better to raise an exception instead of silently continuing
245 # and later complain about sources and targets having
246 # different lengths
247 raise CompileError ("Don't know how to compile %s" % src_name)
248 if strip_dir:
249 base = os.path.basename (base)
250 if ext in self._rc_extensions:
251 obj_names.append (os.path.join (output_dir,
252 base + self.res_extension))
253 elif ext in self._mc_extensions:
254 obj_names.append (os.path.join (output_dir,
255 base + self.res_extension))
256 else:
257 obj_names.append (os.path.join (output_dir,
258 base + self.obj_extension))
259 return obj_names
260
261 # object_filenames ()
262
263
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000264 def compile(self, sources,
265 output_dir=None, macros=None, include_dirs=None, debug=0,
266 extra_preargs=None, extra_postargs=None, depends=None):
Greg Warddbd12761999-08-29 18:15:07 +0000267
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000268 macros, objects, extra_postargs, pp_opts, build = \
269 self._setup_compile(output_dir, macros, include_dirs, sources,
270 depends, extra_postargs)
Greg Warddbd12761999-08-29 18:15:07 +0000271
Greg Ward32c4a8a2000-03-06 03:40:29 +0000272 compile_opts = extra_preargs or []
273 compile_opts.append ('/c')
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000274 if debug:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000275 compile_opts.extend(self.compile_options_debug)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000276 else:
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000277 compile_opts.extend(self.compile_options)
Fred Drakeb94b8492001-12-06 20:51:35 +0000278
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000279 for obj, (src, ext) in build.items():
280 if debug:
281 # pass the full pathname to MSVC in debug mode,
282 # this allows the debugger to find the source file
283 # without asking the user to browse for it
284 src = os.path.abspath(src)
Greg Warddbd12761999-08-29 18:15:07 +0000285
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000286 if ext in self._c_extensions:
287 input_opt = "/Tc" + src
288 elif ext in self._cpp_extensions:
289 input_opt = "/Tp" + src
290 elif ext in self._rc_extensions:
291 # compile .RC to .RES file
292 input_opt = src
293 output_opt = "/fo" + obj
Greg Wardd1517112000-05-30 01:56:44 +0000294 try:
Thomas Heller95827942003-01-31 20:40:15 +0000295 self.spawn ([self.rc] + pp_opts +
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000296 [output_opt] + [input_opt])
Greg Wardd1517112000-05-30 01:56:44 +0000297 except DistutilsExecError, msg:
298 raise CompileError, msg
Jeremy Hylton1bba31d2002-06-13 17:28:18 +0000299 continue
300 elif ext in self._mc_extensions:
301
302 # Compile .MC to .RC file to .RES file.
303 # * '-h dir' specifies the directory for the
304 # generated include file
305 # * '-r dir' specifies the target directory of the
306 # generated RC file and the binary message resource
307 # it includes
308 #
309 # For now (since there are no options to change this),
310 # we use the source-directory for the include file and
311 # the build directory for the RC file and message
312 # resources. This works at least for win32all.
313
314 h_dir = os.path.dirname (src)
315 rc_dir = os.path.dirname (obj)
316 try:
317 # first compile .MC to .RC and .H file
318 self.spawn ([self.mc] +
319 ['-h', h_dir, '-r', rc_dir] + [src])
320 base, _ = os.path.splitext (os.path.basename (src))
321 rc_file = os.path.join (rc_dir, base + '.rc')
322 # then compile .RC to .RES file
323 self.spawn ([self.rc] +
324 ["/fo" + obj] + [rc_file])
325
326 except DistutilsExecError, msg:
327 raise CompileError, msg
328 continue
329 else:
330 # how to handle this file?
331 raise CompileError (
332 "Don't know how to compile %s to %s" % \
333 (src, obj))
334
335 output_opt = "/Fo" + obj
336 try:
337 self.spawn ([self.cc] + compile_opts + pp_opts +
338 [input_opt, output_opt] +
339 extra_postargs)
340 except DistutilsExecError, msg:
341 raise CompileError, msg
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000342
Greg Ward32c4a8a2000-03-06 03:40:29 +0000343 return objects
Greg Warddbd12761999-08-29 18:15:07 +0000344
Greg Ward32c4a8a2000-03-06 03:40:29 +0000345 # compile ()
Greg Ward3d50b901999-09-08 02:36:01 +0000346
347
Greg Ward09fc5422000-03-10 01:49:26 +0000348 def create_static_lib (self,
349 objects,
350 output_libname,
351 output_dir=None,
352 debug=0,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000353 target_lang=None):
Greg Warddbd12761999-08-29 18:15:07 +0000354
Greg Ward2f557a22000-03-26 21:42:28 +0000355 (objects, output_dir) = self._fix_object_args (objects, output_dir)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000356 output_filename = \
357 self.library_filename (output_libname, output_dir=output_dir)
Greg Warddbd12761999-08-29 18:15:07 +0000358
Greg Ward32c4a8a2000-03-06 03:40:29 +0000359 if self._need_link (objects, output_filename):
Greg Ward09fc5422000-03-10 01:49:26 +0000360 lib_args = objects + ['/OUT:' + output_filename]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000361 if debug:
362 pass # XXX what goes here?
Greg Wardd1517112000-05-30 01:56:44 +0000363 try:
Greg Ward992c8f92000-06-25 02:31:16 +0000364 self.spawn ([self.lib] + lib_args)
Greg Wardd1517112000-05-30 01:56:44 +0000365 except DistutilsExecError, msg:
366 raise LibError, msg
Fred Drakeb94b8492001-12-06 20:51:35 +0000367
Greg Ward32c4a8a2000-03-06 03:40:29 +0000368 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000369 log.debug("skipping %s (up-to-date)", output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000370
Greg Ward09fc5422000-03-10 01:49:26 +0000371 # create_static_lib ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000372
Greg Ward42406482000-09-27 02:08:14 +0000373 def link (self,
374 target_desc,
375 objects,
376 output_filename,
377 output_dir=None,
378 libraries=None,
379 library_dirs=None,
380 runtime_library_dirs=None,
381 export_symbols=None,
382 debug=0,
383 extra_preargs=None,
384 extra_postargs=None,
Gustavo Niemeyer6b016852002-11-05 16:12:02 +0000385 build_temp=None,
386 target_lang=None):
Greg Ward32c4a8a2000-03-06 03:40:29 +0000387
Greg Ward2f557a22000-03-26 21:42:28 +0000388 (objects, output_dir) = self._fix_object_args (objects, output_dir)
389 (libraries, library_dirs, runtime_library_dirs) = \
390 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
391
Greg Wardf70c6032000-04-19 02:16:49 +0000392 if runtime_library_dirs:
Greg Ward2f557a22000-03-26 21:42:28 +0000393 self.warn ("I don't know what to do with 'runtime_library_dirs': "
394 + str (runtime_library_dirs))
Fred Drakeb94b8492001-12-06 20:51:35 +0000395
Greg Wardd03f88a2000-03-18 15:19:51 +0000396 lib_opts = gen_lib_options (self,
Greg Ward2f557a22000-03-26 21:42:28 +0000397 library_dirs, runtime_library_dirs,
Greg Wardd03f88a2000-03-18 15:19:51 +0000398 libraries)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000399 if output_dir is not None:
400 output_filename = os.path.join (output_dir, output_filename)
Greg Warddbd12761999-08-29 18:15:07 +0000401
Greg Ward32c4a8a2000-03-06 03:40:29 +0000402 if self._need_link (objects, output_filename):
403
Greg Ward42406482000-09-27 02:08:14 +0000404 if target_desc == CCompiler.EXECUTABLE:
405 if debug:
406 ldflags = self.ldflags_shared_debug[1:]
407 else:
408 ldflags = self.ldflags_shared[1:]
Greg Ward32c4a8a2000-03-06 03:40:29 +0000409 else:
Greg Ward42406482000-09-27 02:08:14 +0000410 if debug:
411 ldflags = self.ldflags_shared_debug
412 else:
413 ldflags = self.ldflags_shared
Greg Ward32c4a8a2000-03-06 03:40:29 +0000414
Greg Ward5299b6a2000-05-20 13:23:21 +0000415 export_opts = []
416 for sym in (export_symbols or []):
417 export_opts.append("/EXPORT:" + sym)
418
Fred Drakeb94b8492001-12-06 20:51:35 +0000419 ld_args = (ldflags + lib_opts + export_opts +
Greg Ward5299b6a2000-05-20 13:23:21 +0000420 objects + ['/OUT:' + output_filename])
Greg Ward32c4a8a2000-03-06 03:40:29 +0000421
Greg Ward159eb922000-08-02 00:00:30 +0000422 # The MSVC linker generates .lib and .exp files, which cannot be
423 # suppressed by any linker switches. The .lib files may even be
424 # needed! Make sure they are generated in the temporary build
425 # directory. Since they have different names for debug and release
426 # builds, they can go into the same directory.
Greg Ward42406482000-09-27 02:08:14 +0000427 if export_symbols is not None:
428 (dll_name, dll_ext) = os.path.splitext(
429 os.path.basename(output_filename))
430 implib_file = os.path.join(
431 os.path.dirname(objects[0]),
432 self.library_filename(dll_name))
433 ld_args.append ('/IMPLIB:' + implib_file)
Greg Ward159eb922000-08-02 00:00:30 +0000434
Greg Ward32c4a8a2000-03-06 03:40:29 +0000435 if extra_preargs:
436 ld_args[:0] = extra_preargs
437 if extra_postargs:
Greg Ward159eb922000-08-02 00:00:30 +0000438 ld_args.extend(extra_postargs)
Greg Ward32c4a8a2000-03-06 03:40:29 +0000439
440 self.mkpath (os.path.dirname (output_filename))
Greg Wardd1517112000-05-30 01:56:44 +0000441 try:
Greg Ward42406482000-09-27 02:08:14 +0000442 self.spawn ([self.linker] + ld_args)
Greg Wardd1517112000-05-30 01:56:44 +0000443 except DistutilsExecError, msg:
444 raise LinkError, msg
Greg Ward32c4a8a2000-03-06 03:40:29 +0000445
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000446 else:
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000447 log.debug("skipping %s (up-to-date)", output_filename)
Greg Ward4ba9b2e2000-02-10 02:15:52 +0000448
Greg Ward42406482000-09-27 02:08:14 +0000449 # link ()
Greg Wardf70c6032000-04-19 02:16:49 +0000450
451
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
Greg Wardd1425642000-08-04 01:29:27 +0000467 def find_library_file (self, dirs, lib, debug=0):
468 # Prefer a debugging library if found (and requested), but deal
469 # with it if we don't have one.
470 if debug:
471 try_names = [lib + "_d", lib]
472 else:
473 try_names = [lib]
Greg Wardc74138d1999-10-03 20:47:52 +0000474 for dir in dirs:
Greg Wardd1425642000-08-04 01:29:27 +0000475 for name in try_names:
476 libfile = os.path.join(dir, self.library_filename (name))
477 if os.path.exists(libfile):
478 return libfile
Greg Wardc74138d1999-10-03 20:47:52 +0000479 else:
480 # Oops, didn't find it in *any* of 'dirs'
481 return None
482
483 # find_library_file ()
484
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000485 # Helper methods for using the MSVC registry settings
486
487 def find_exe(self, exe):
488 """Return path to an MSVC executable program.
489
490 Tries to find the program in several places: first, one of the
491 MSVC program search paths from the registry; next, the directories
492 in the PATH environment variable. If any of those work, return an
493 absolute path that is known to exist. If none of them work, just
494 return the original program name, 'exe'.
495 """
496
497 for p in self.__paths:
498 fn = os.path.join(os.path.abspath(p), exe)
499 if os.path.isfile(fn):
500 return fn
501
502 # didn't find it; try existing path
503 for p in string.split(os.environ['Path'],';'):
504 fn = os.path.join(os.path.abspath(p),exe)
505 if os.path.isfile(fn):
506 return fn
507
508 return exe
509
510 def get_msvc_paths(self, path, platform='x86'):
511 """Get a list of devstudio directories (include, lib or path).
512
513 Return a list of strings. The list will be empty if unable to
514 access the registry or appropriate registry keys not found.
515 """
516
517 if not _can_read_reg:
518 return []
519
520 path = path + " dirs"
521 if self.__version == 7:
522 key = (r"%s\7.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
523 % (self.__root,))
524 else:
525 key = (r"%s\6.0\Build System\Components\Platforms"
Jeremy Hylton93724db2003-05-09 16:55:28 +0000526 r"\Win32 (%s)\Directories" % (self.__root, platform))
Jeremy Hylton9ddf6c32003-05-09 16:06:42 +0000527
528 for base in HKEYS:
529 d = read_values(base, key)
530 if d:
531 if self.__version == 7:
532 return string.split(self.__macros.sub(d[path]), ";")
533 else:
534 return string.split(d[path], ";")
535 return []
536
537 def set_path_env_var(self, name):
538 """Set environment variable 'name' to an MSVC path type value.
539
540 This is equivalent to a SET command prior to execution of spawned
541 commands.
542 """
543
544 if name == "lib":
545 p = self.get_msvc_paths("library")
546 else:
547 p = self.get_msvc_paths(name)
548 if p:
549 os.environ[name] = string.join(p, ';')
550