diff options
author | Greg Ward <gward@python.net> | 2000-03-06 03:40:29 (GMT) |
---|---|---|
committer | Greg Ward <gward@python.net> | 2000-03-06 03:40:29 (GMT) |
commit | 32c4a8a0ee74ab932c693de3c8658f4fe57c1ca9 (patch) | |
tree | 5180654fe8178af8320c4cc3efb51f0f6999a107 /Lib/distutils/msvccompiler.py | |
parent | eb3f75e636316c7ee1edeb42b4ae2c0de9665f8c (diff) | |
download | cpython-32c4a8a0ee74ab932c693de3c8658f4fe57c1ca9.zip cpython-32c4a8a0ee74ab932c693de3c8658f4fe57c1ca9.tar.gz cpython-32c4a8a0ee74ab932c693de3c8658f4fe57c1ca9.tar.bz2 |
Serious overhaul of the C compiler interface and the two classes that
implement it (so far):
* moved filename generation methods into CCompiler base class,
driven by data supplied by implementation classes
* moved a bunch of common code from UnixCCompiler to convenience
methods in CCompiler
* overhauled MSVCCompiler's compile/link methods to look and act
as much as possible like UnixCCompiler's, in order to regularize
both interface and behaviour (especially by using those new
convenience methods)
Diffstat (limited to 'Lib/distutils/msvccompiler.py')
-rw-r--r-- | Lib/distutils/msvccompiler.py | 235 |
1 files changed, 105 insertions, 130 deletions
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index 2dd8dc1..847c611 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -5,12 +5,13 @@ for the Microsoft Visual Studio.""" # created 1999/08/19, Perry Stoll -# +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) + __revision__ = "$Id$" -import os -import sys -import string +import sys, os, string +from types import * from distutils.errors import * from distutils.ccompiler import \ CCompiler, gen_preprocess_options, gen_lib_options @@ -137,6 +138,20 @@ class MSVCCompiler (CCompiler) : compiler_type = 'msvc' + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc','.cpp'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = _c_extensions + _cpp_extensions + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + def __init__ (self, verbose=0, dry_run=0, @@ -169,9 +184,7 @@ class MSVCCompiler (CCompiler) : self.preprocess_options = None self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3' ] - self.compile_options_debug = [ - '/nologo', '/Od', '/MDd', '/W3', '/Z7', '/D_DEBUG' - ] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] self.ldflags_shared_debug = [ @@ -181,21 +194,7 @@ class MSVCCompiler (CCompiler) : # -- Worker methods ------------------------------------------------ - # (must be implemented by subclasses) - _c_extensions = [ '.c' ] - _cpp_extensions = [ '.cc', '.cpp' ] - - _obj_ext = '.obj' - _exe_ext = '.exe' - _shared_lib_ext = '.dll' - _static_lib_ext = '.lib' - - # XXX the 'output_dir' parameter is ignored by the methods in this - # class! I just put it in to be consistent with CCompiler and - # UnixCCompiler, but someone who actually knows Visual C++ will - # have to make it work... - def compile (self, sources, output_dir=None, @@ -205,48 +204,43 @@ class MSVCCompiler (CCompiler) : extra_preargs=None, extra_postargs=None): - if macros is None: - macros = [] - if include_dirs is None: - include_dirs = [] - - objectFiles = [] + (output_dir, macros, include_dirs) = \ + self._fix_compile_args (output_dir, macros, include_dirs) + (objects, skip_sources) = self._prep_compile (sources, output_dir) - base_pp_opts = \ - gen_preprocess_options (self.macros + macros, - self.include_dirs + include_dirs) - - base_pp_opts.append('/c') + if extra_postargs is None: + extra_postargs = [] + pp_opts = gen_preprocess_options (macros, include_dirs) + compile_opts = extra_preargs or [] + compile_opts.append ('/c') if debug: - compile_options = self.compile_options_debug + compile_opts.extend (self.compile_options_debug) else: - compile_options = self.compile_options + compile_opts.extend (self.compile_options) - for srcFile in sources: - base,ext = os.path.splitext(srcFile) - objFile = base + ".obj" + for i in range (len (sources)): + src = sources[i] ; obj = objects[i] + ext = (os.path.splitext (src))[1] - if ext in self._c_extensions: - fileOpt = "/Tc" - elif ext in self._cpp_extensions: - fileOpt = "/Tp" + if skip_sources[src]: + self.announce ("skipping %s (%s up-to-date)" % (src, obj)) + else: + if ext in self._c_extensions: + input_opt = "/Tc" + src + elif ext in self._cpp_extensions: + input_opt = "/Tp" + src - inputOpt = fileOpt + srcFile - outputOpt = "/Fo" + objFile + output_opt = "/Fo" + obj - cc_args = compile_options + \ - base_pp_opts + \ - [outputOpt, inputOpt] + self.mkpath (os.path.dirname (obj)) + self.spawn ([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs) - if extra_preargs: - cc_args[:0] = extra_preargs - if extra_postargs: - cc_args.extend (extra_postargs) + return objects - self.spawn ([self.cc] + cc_args) - objectFiles.append( objFile ) - return objectFiles + # compile () # XXX the signature of this method is different from CCompiler and @@ -263,25 +257,30 @@ class MSVCCompiler (CCompiler) : extra_preargs=None, extra_postargs=None): - if libraries is None: - libraries = [] - if library_dirs is None: - library_dirs = [] + (objects, output_dir, libraries, library_dirs) = \ + self._fix_link_args (objects, output_dir, takes_libs=1, + libraries=libraries, + library_dirs=library_dirs) - lib_opts = gen_lib_options (self.libraries + libraries, - self.library_dirs + library_dirs, - "%s.lib", "/LIBPATH:%s") - - ld_args = self.ldflags_static + lib_opts + \ - objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend (extra_postargs) + output_filename = \ + self.library_filename (output_libname, output_dir=output_dir) + + if self._need_link (objects, output_filename): + lib_opts = gen_lib_options (libraries, library_dirs, + "%s.lib", "/LIBPATH:%s") + ld_args = self.ldflags_static + lib_opts + \ + objects + ['/OUT:' + output_filename] + if debug: + pass # XXX what goes here? + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend (extra_postargs) + self.spawn ([self.link] + ld_args) + else: + self.announce ("skipping %s (up-to-date)" % output_filename) - self.spawn ( [ self.link ] + ld_args ) + # link_static_lib () def link_shared_lib (self, @@ -294,8 +293,6 @@ class MSVCCompiler (CCompiler) : extra_preargs=None, extra_postargs=None): - # XXX should we sanity check the library name? (eg. no - # slashes) self.link_shared_object (objects, self.shared_library_name(output_libname), output_dir=output_dir, @@ -315,70 +312,48 @@ class MSVCCompiler (CCompiler) : debug=0, extra_preargs=None, extra_postargs=None): - """Link a bunch of stuff together to create a shared object - file. Much like 'link_shared_lib()', except the output - filename is explicitly supplied as 'output_filename'.""" - if libraries is None: - libraries = [] - if library_dirs is None: - library_dirs = [] - - lib_opts = gen_lib_options (self, - self.library_dirs + library_dirs, - self.libraries + libraries) - - if debug: - ldflags = self.ldflags_shared_debug - basename, ext = os.path.splitext (output_filename) - #XXX not sure this belongs here - # extensions in debug_mode are named 'module_d.pyd' - output_filename = basename + '_d' + ext - else: - ldflags = self.ldflags_shared - - ld_args = ldflags + lib_opts + \ - objects + ['/OUT:' + output_filename] - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend (extra_postargs) - - self.spawn ( [ self.link ] + ld_args ) - - # -- Filename mangling methods ------------------------------------- - - def _change_extensions( self, filenames, newExtension ): - object_filenames = [] - - for srcFile in filenames: - base,ext = os.path.splitext( srcFile ) - # XXX should we strip off any existing path? - object_filenames.append( base + newExtension ) - - return object_filenames + (objects, output_dir, libraries, library_dirs) = \ + self._fix_link_args (objects, output_dir, takes_libs=1, + libraries=libraries, library_dirs=library_dirs) + + lib_opts = gen_lib_options (self, library_dirs, libraries) + if type (output_dir) not in (StringType, NoneType): + raise TypeError, "'output_dir' must be a string or None" + if output_dir is not None: + output_filename = os.path.join (output_dir, output_filename) + + if self._need_link (objects, output_filename): + + if debug: + ldflags = self.ldflags_shared_debug + # XXX not sure this belongs here + # extensions in debug_mode are named 'module_d.pyd' + basename, ext = os.path.splitext (output_filename) + output_filename = basename + '_d' + ext + else: + ldflags = self.ldflags_shared + + ld_args = ldflags + lib_opts + \ + objects + ['/OUT:' + output_filename] - def object_filenames (self, source_filenames): - """Return the list of object filenames corresponding to each - specified source filename.""" - return self._change_extensions( source_filenames, self._obj_ext ) + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend (extra_postargs) - def shared_object_filename (self, source_filename): - """Return the shared object filename corresponding to a - specified source filename.""" - return self._change_extensions( source_filenames, self._shared_lib_ext ) + self.mkpath (os.path.dirname (output_filename)) + self.spawn ([self.link] + ld_args) - def library_filename (self, libname): - """Return the static library filename corresponding to the - specified library name.""" - return "%s%s" %( libname, self._static_lib_ext ) + else: + self.announce ("skipping %s (up-to-date)" % output_filename) - def shared_library_filename (self, libname): - """Return the shared library filename corresponding to the - specified library name.""" - return "%s%s" %( libname, self._shared_lib_ext ) + # link_shared_object () + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. def library_dir_option (self, dir): return "/LIBPATH:" + dir |