diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index ff66f913be5..f328232bc02 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -11,23 +11,13 @@ __rcsid__ = "$Id$" import os import sys from distutils.errors import * -from distutils.ccompiler import CCompiler +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options -class MSVCCompiler ( CCompiler) : - """Abstract base class to define the interface that must be implemented - by real compiler abstraction classes. Might have some use as a - place for shared code, but it's not yet clear what code can be - shared between compiler abstraction models for different platforms. - - The basic idea behind a compiler abstraction class is that each - instance can be used for all the compile/link steps in building - a single project. Thus, attributes common to all of those compile - and link steps -- include directories, macros to define, libraries - to link against, etc. -- are attributes of the compiler instance. - To allow for variability in how individual files are treated, - most (all?) of those attributes may be varied on a per-compilation - or per-link basis.""" +class MSVCCompiler (CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" def __init__ (self, verbose=0, @@ -35,11 +25,9 @@ class MSVCCompiler ( CCompiler) : CCompiler.__init__ (self, verbose, dry_run) - # XXX This is a nasty dependency to add on something otherwise - # pretty clean. move it to build_ext under an nt - # specific part. - # shared libraries need to link against python15.lib + # pretty clean. move it to build_ext under an nt specific part. + # shared libraries need to link against python15.lib self.add_library ( "python" + sys.version[0] + sys.version[2] ) self.add_library_dir( os.path.join( sys.exec_prefix, 'libs' ) ) @@ -51,39 +39,15 @@ class MSVCCompiler ( CCompiler) : self.ldflags_shared = ['/DLL', '/nologo'] self.ldflags_static = [ '/nologo'] - # XXX things not handled by this compiler abstraction model: - # * client can't provide additional options for a compiler, - # e.g. warning, optimization, debugging flags. Perhaps this - # should be the domain of concrete compiler abstraction classes - # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base - # class should have methods for the common ones. - # * can't put output files (object files, libraries, whatever) - # into a separate directory from their inputs. Should this be - # handled by an 'output_dir' attribute of the whole object, or a - # parameter to the compile/link_* methods, or both? - # * can't completely override the include or library searchg - # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". - # I'm not sure how widely supported this is even by Unix - # compilers, much less on other platforms. And I'm even less - # sure how useful it is; maybe for cross-compiling, but - # support for that is a ways off. (And anyways, cross - # compilers probably have a dedicated binary with the - # right paths compiled in. I hope.) - # * can't do really freaky things with the library list/library - # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against - # different versions of libfoo.a in different locations. I - # think this is useless without the ability to null out the - # library search path anyways. - # -- Worker methods ------------------------------------------------ # (must be implemented by subclasses) _c_extensions = [ '.c' ] - _cpp_extensions = [ '.cc', 'cpp' ] + _cpp_extensions = [ '.cc', '.cpp' ] _obj_ext = '.obj' - _exe_ext = 'exe' + _exe_ext = '.exe' _shared_lib_ext = '.dll' _static_lib_ext = '.lib' @@ -114,8 +78,8 @@ class MSVCCompiler ( CCompiler) : objectFiles = [] - base_pp_opts = _gen_preprocess_options (self.macros + macros, - self.include_dirs + includes) + base_pp_opts = gen_preprocess_options (self.macros + macros, + self.include_dirs + includes) base_pp_opts.append('/c') @@ -133,14 +97,12 @@ class MSVCCompiler ( CCompiler) : pp_opts = base_pp_opts + [ outputOpt, inputOpt ] - returnCode = self.spawn( [ self.cc ] + self.compile_options + pp_opts ) - # XXX check for valid return code - + self.spawn( [ self.cc ] + self.compile_options + pp_opts) objectFiles.append( objFile ) - return objectFiles - + + # XXX this is kind of useless without 'link_binary()' or # 'link_executable()' or something -- or maybe 'link_static_lib()' # should not exist at all, and we just have 'link_binary()'? @@ -171,8 +133,9 @@ class MSVCCompiler ( CCompiler) : if build_info is None: build_info = {} - lib_opts = _gen_lib_options (self.libraries + libraries, - self.library_dirs + library_dirs) + lib_opts = gen_lib_options (self.libraries + libraries, + self.library_dirs + library_dirs, + "%s.lib", "/LIBPATH:%s") if build_info.has_key('def_file') : lib_opts.append('/DEF:' + build_info['def_file'] ) @@ -215,8 +178,9 @@ class MSVCCompiler ( CCompiler) : if build_info is None: build_info = {} - lib_opts = _gen_lib_options (self.libraries + libraries, - self.library_dirs + library_dirs) + lib_opts = gen_lib_options (self.libraries + libraries, + self.library_dirs + library_dirs, + "%s.lib", "/LIBPATH:%s") if build_info.has_key('def_file') : lib_opts.append('/DEF:' + build_info['def_file'] ) @@ -260,58 +224,3 @@ class MSVCCompiler ( CCompiler) : return "lib%s%s" %( libname, self._shared_lib_ext ) # class MSVCCompiler - -def _gen_preprocess_options (macros, includes): - - # XXX it would be nice (mainly aesthetic, and so we don't generate - # stupid-looking command lines) to go over 'macros' and eliminate - # redundant definitions/undefinitions (ie. ensure that only the - # latest mention of a particular macro winds up on the command - # line). I don't think it's essential, though, since most (all?) - # Unix C compilers only pay attention to the latest -D or -U - # mention of a macro on their command line. Similar situation for - # 'includes'. I'm punting on both for now. Anyways, weeding out - # redundancies like this should probably be the province of - # CCompiler, since the data structures used are inherited from it - # and therefore common to all CCompiler classes. - - - pp_opts = [] - for macro in macros: - if len (macro) == 1: # undefine this macro - pp_opts.append ("-U%s" % macro[0]) - elif len (macro) == 2: - if macro[1] is None: # define with no explicit value - pp_opts.append ("-D%s" % macro[0]) - else: - # XXX *don't* need to be clever about quoting the - # macro value here, because we're going to avoid the - # shell at all costs when we spawn the command! - pp_opts.append ("-D%s=%s" % macro) - - for dir in includes: - pp_opts.append ("-I%s" % dir) - - return pp_opts - -def _gen_lib_options (libraries, library_dirs): - - lib_opts = [] - - for dir in library_dirs: - lib_opts.append ("/LIBPATH:%s" % dir) - - # XXX it's important that we *not* remove redundant library mentions! - # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to - # resolve all symbols. I just hope we never have to say "-lfoo obj.o - # -lbar" to get things to work -- that's certainly a possibility, but a - # pretty nasty way to arrange your C code. - - for lib in libraries: - lib_opts.append ("%s.lib" % lib) # import libraries end in .lib - - return lib_opts - -# _gen_lib_options () - -