diff options
| author | Tarek Ziade <tarek@ziade.org> | 2010-11-11 17:51:58 +0100 |
|---|---|---|
| committer | Tarek Ziade <tarek@ziade.org> | 2010-11-11 17:51:58 +0100 |
| commit | 9b3dde4072db4356e4a08614e7b266f11a05554d (patch) | |
| tree | 81e93154eddae10e4fcf481a62152701f6aae7cd | |
| parent | cb7b234fa42bb5f66c4c004c46fbf89ccee78791 (diff) | |
| download | disutils2-9b3dde4072db4356e4a08614e7b266f11a05554d.tar.gz | |
moved general functions out of ccompiler
| -rw-r--r-- | distutils2/command/build_clib.py | 7 | ||||
| -rw-r--r-- | distutils2/command/build_ext.py | 4 | ||||
| -rw-r--r-- | distutils2/command/config.py | 7 | ||||
| -rw-r--r-- | distutils2/compiler/__init__.py | 269 | ||||
| -rw-r--r-- | distutils2/compiler/bcppcompiler.py | 6 | ||||
| -rw-r--r-- | distutils2/compiler/ccompiler.py | 273 | ||||
| -rw-r--r-- | distutils2/compiler/cygwinccompiler.py | 6 | ||||
| -rw-r--r-- | distutils2/compiler/emxccompiler.py | 3 | ||||
| -rw-r--r-- | distutils2/compiler/msvc9compiler.py | 6 | ||||
| -rw-r--r-- | distutils2/compiler/msvccompiler.py | 3 | ||||
| -rw-r--r-- | distutils2/compiler/unixccompiler.py | 10 | ||||
| -rw-r--r-- | distutils2/tests/test_ccompiler.py | 48 | ||||
| -rw-r--r-- | distutils2/tests/test_command_build_clib.py | 2 | ||||
| -rw-r--r-- | distutils2/tests/test_compiler.py | 62 |
14 files changed, 358 insertions, 348 deletions
diff --git a/distutils2/command/build_clib.py b/distutils2/command/build_clib.py index 5f20bb0..de49191 100644 --- a/distutils2/command/build_clib.py +++ b/distutils2/command/build_clib.py @@ -18,11 +18,12 @@ module.""" import os from distutils2.command.cmd import Command from distutils2.errors import DistutilsSetupError -from distutils2.compiler.ccompiler import customize_compiler +from distutils2.compiler import customize_compiler from distutils2 import logger + def show_compilers(): - from distutils2.compiler.ccompiler import show_compilers + from distutils2.compiler import show_compilers show_compilers() @@ -94,7 +95,7 @@ class build_clib(Command): return # Yech -- this is cut 'n pasted from build_ext.py! - from distutils2.compiler.ccompiler import new_compiler + from distutils2.compiler import new_compiler self.compiler = new_compiler(compiler=self.compiler, dry_run=self.dry_run, force=self.force) diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py index df71f1c..0d2831d 100644 --- a/distutils2/command/build_ext.py +++ b/distutils2/command/build_ext.py @@ -12,7 +12,7 @@ from distutils2.util import get_platform from distutils2.command.cmd import Command from distutils2.errors import (CCompilerError, CompileError, DistutilsError, DistutilsPlatformError, DistutilsSetupError) -from distutils2.compiler.ccompiler import customize_compiler +from distutils2.compiler import customize_compiler from distutils2.util import newer_group from distutils2.extension import Extension from distutils2 import logger @@ -334,7 +334,7 @@ class build_ext(Command): self.rpath.append(user_lib) def run(self): - from distutils2.compiler.ccompiler import new_compiler + from distutils2.compiler import new_compiler # 'self.extensions', as supplied by setup.py, is a list of # Extension instances. See the documentation for Extension (in diff --git a/distutils2/command/config.py b/distutils2/command/config.py index 20c3a2c..0f4ae9f 100644 --- a/distutils2/command/config.py +++ b/distutils2/command/config.py @@ -8,14 +8,12 @@ list of standard commands. Also, this is a good place to put common configure-like tasks: "try to compile this C code", or "figure out where this header file lives". """ - - import os import re from distutils2.command.cmd import Command from distutils2.errors import DistutilsExecError -from distutils2.compiler.ccompiler import customize_compiler +from distutils2.compiler import customize_compiler from distutils2 import logger LANG_EXT = {'c': '.c', 'c++': '.cxx'} @@ -95,7 +93,8 @@ class config(Command): """ # We do this late, and only on-demand, because this is an expensive # import. - from distutils2.compiler.ccompiler import CCompiler, new_compiler + from distutils2.compiler.ccompiler import CCompiler + from distutils2.compiler import new_compiler if not isinstance(self.compiler, CCompiler): self.compiler = new_compiler(compiler=self.compiler, dry_run=self.dry_run, force=1) diff --git a/distutils2/compiler/__init__.py b/distutils2/compiler/__init__.py index 139597f..81a327c 100644 --- a/distutils2/compiler/__init__.py +++ b/distutils2/compiler/__init__.py @@ -1,2 +1,271 @@ +import os +import sys +import re +from distutils2._backport import sysconfig +def customize_compiler(compiler): + """Do any platform-specific customization of a CCompiler instance. + + Mainly needed on Unix, so we can plug in the information that + varies across Unices and is stored in Python's Makefile. + """ + if compiler.compiler_type == "unix": + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ + sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + + if 'CC' in os.environ: + cc = os.environ['CC'] + if 'CXX' in os.environ: + cxx = os.environ['CXX'] + if 'LDSHARED' in os.environ: + ldshared = os.environ['LDSHARED'] + if 'CPP' in os.environ: + cpp = os.environ['CPP'] + else: + cpp = cc + " -E" # not always + if 'LDFLAGS' in os.environ: + ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + if 'CFLAGS' in os.environ: + cflags = opt + ' ' + os.environ['CFLAGS'] + ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if 'CPPFLAGS' in os.environ: + cpp = cpp + ' ' + os.environ['CPPFLAGS'] + cflags = cflags + ' ' + os.environ['CPPFLAGS'] + ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + if ar_flags is not None: + archiver = ar + ' ' + ar_flags + else: + # see if its the proper default value + # mmm I don't want to backport the makefile + archiver = ar + ' rc' + + cc_cmd = cc + ' ' + cflags + compiler.set_executables( + preprocessor=cpp, + compiler=cc_cmd, + compiler_so=cc_cmd + ' ' + ccshared, + compiler_cxx=cxx, + linker_so=ldshared, + linker_exe=cc, + archiver=archiver) + + compiler.shared_lib_extension = so_ext + + +# Map a sys.platform/os.name ('posix', 'nt') to the default compiler +# type for that platform. Keys are interpreted as re match +# patterns. Order is important; platform mappings are preferred over +# OS names. +_default_compilers = ( + + # Platform string mappings + + # on a cygwin built python we can use gcc like an ordinary UNIXish + # compiler + ('cygwin.*', 'unix'), + ('os2emx', 'emx'), + + # OS name mappings + ('posix', 'unix'), + ('nt', 'msvc'), + + ) + +def get_default_compiler(osname=None, platform=None): + """ Determine the default compiler to use for the given platform. + + osname should be one of the standard Python OS names (i.e. the + ones returned by os.name) and platform the common value + returned by sys.platform for the platform in question. + + The default values are os.name and sys.platform in case the + parameters are not given. + + """ + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + for pattern, compiler in _default_compilers: + if re.match(pattern, platform) is not None or \ + re.match(pattern, osname) is not None: + return compiler + # Default to Unix compiler + return 'unix' + +# Map compiler types to (module_name, class_name) pairs -- ie. where to +# find the code that implements an interface to this compiler. (The module +# is assumed to be in the 'distutils' package.) +compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', + "standard UNIX-style compiler"), + 'msvc': ('msvccompiler', 'MSVCCompiler', + "Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', + "Cygwin port of GNU C Compiler for Win32"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', + "Mingw32 port of GNU C Compiler for Win32"), + 'bcpp': ('bcppcompiler', 'BCPPCompiler', + "Borland C++ Compiler"), + 'emx': ('emxccompiler', 'EMXCCompiler', + "EMX port of GNU C Compiler for OS/2"), + } + +def show_compilers(): + """Print list of available compilers (used by the "--help-compiler" + options to "build", "build_ext", "build_clib"). + """ + # XXX this "knows" that the compiler option it's describing is + # "--compiler", which just happens to be the case for the three + # commands that use it. + from distutils2.fancy_getopt import FancyGetopt + compilers = [] + for compiler in compiler_class.keys(): + compilers.append(("compiler="+compiler, None, + compiler_class[compiler][2])) + compilers.sort() + pretty_printer = FancyGetopt(compilers) + pretty_printer.print_help("List of available compilers:") + + +def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): + """Generate an instance of some CCompiler subclass for the supplied + platform/compiler combination. 'plat' defaults to 'os.name' + (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler + for that platform. Currently only 'posix' and 'nt' are supported, and + the default compilers are "traditional Unix interface" (UnixCCompiler + class) and Visual C++ (MSVCCompiler class). Note that it's perfectly + possible to ask for a Unix compiler object under Windows, and a + Microsoft compiler object under Unix -- if you supply a value for + 'compiler', 'plat' is ignored. + """ + if plat is None: + plat = os.name + + try: + if compiler is None: + compiler = get_default_compiler(plat) + + (module_name, class_name, long_description) = compiler_class[compiler] + except KeyError: + msg = "don't know how to compile C/C++ code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError, msg + + try: + module_name = "distutils2.compiler." + module_name + __import__ (module_name) + module = sys.modules[module_name] + cls = vars(module)[class_name] + except ImportError: + raise DistutilsModuleError, \ + "can't compile C/C++ code: unable to load module '%s'" % \ + module_name + except KeyError: + raise DistutilsModuleError, \ + ("can't compile C/C++ code: unable to find class '%s' " + + "in module '%s'") % (class_name, module_name) + + # XXX The None is necessary to preserve backwards compatibility + # with classes that expect verbose to be the first positional + # argument. + return cls(None, dry_run, force) + + +def gen_preprocess_options(macros, include_dirs): + """Generate C pre-processor options (-D, -U, -I) as used by at least + two types of compilers: the typical Unix compiler and Visual C++. + 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) + means undefine (-U) macro 'name', and (name,value) means define (-D) + macro 'name' to 'value'. 'include_dirs' is just a list of directory + names to be added to the header file search path (-I). Returns a list + of command-line options suitable for either Unix compilers or Visual + C++. + """ + # 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 + # 'include_dirs'. 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 not (isinstance(macro, tuple) and + 1 <= len (macro) <= 2): + raise TypeError, \ + ("bad macro definition '%s': " + + "each element of 'macros' list must be a 1- or 2-tuple") % \ + macro + + 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 include_dirs: + pp_opts.append ("-I%s" % dir) + + return pp_opts + + +def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries): + """Generate linker options for searching library directories and + linking with specific libraries. + + 'libraries' and 'library_dirs' are, respectively, lists of library names + (not filenames!) and search directories. Returns a list of command-line + options suitable for use with some compiler (depending on the two format + strings passed in). + """ + lib_opts = [] + + for dir in library_dirs: + lib_opts.append(compiler.library_dir_option(dir)) + + for dir in runtime_library_dirs: + opt = compiler.runtime_library_dir_option(dir) + if isinstance(opt, list): + lib_opts.extend(opt) + else: + lib_opts.append(opt) + + # 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_dir, lib_name = os.path.split(lib) + if lib_dir != '': + lib_file = compiler.find_library_file([lib_dir], lib_name) + if lib_file is not None: + lib_opts.append(lib_file) + else: + compiler.warn("no library file corresponding to " + "'%s' found (skipping)" % lib) + else: + lib_opts.append(compiler.library_option(lib)) + + return lib_opts diff --git a/distutils2/compiler/bcppcompiler.py b/distutils2/compiler/bcppcompiler.py index 929994b..79f0815 100644 --- a/distutils2/compiler/bcppcompiler.py +++ b/distutils2/compiler/bcppcompiler.py @@ -10,17 +10,17 @@ for the Borland C++ compiler. # XXX looks like there's a LOT of overlap between these two classes: # someone should sit down and factor out the common code as # WindowsCCompiler! --GPW - - import os from distutils2.errors import (DistutilsExecError, CompileError, LibError, LinkError, UnknownFileError) -from distutils2.compiler.ccompiler import CCompiler, gen_preprocess_options +from distutils2.compiler.ccompiler import CCompiler +from distutils2.compiler import gen_preprocess_options from distutils2.file_util import write_file from distutils2.dep_util import newer from distutils2 import logger + class BCPPCompiler(CCompiler) : """Concrete class that implements an interface to the Borland C/C++ compiler, as defined by the CCompiler abstract class. diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py index 744b596..45c96e2 100644 --- a/distutils2/compiler/ccompiler.py +++ b/distutils2/compiler/ccompiler.py @@ -13,67 +13,7 @@ from distutils2.errors import (CompileError, LinkError, UnknownFileError, DistutilsPlatformError, DistutilsModuleError) from distutils2.util import split_quoted, execute, newer_group, spawn from distutils2 import logger - - -try: - import sysconfig -except ImportError: - from distutils2._backport import sysconfig - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ - sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SO', 'AR', - 'ARFLAGS') - - if 'CC' in os.environ: - cc = os.environ['CC'] - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = opt + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - if ar_flags is not None: - archiver = ar + ' ' + ar_flags - else: - # see if its the proper default value - # mmm I don't want to backport the makefile - archiver = ar + ' rc' - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = so_ext +from distutils2.compiler import gen_preprocess_options class CCompiler(object): """Abstract base class to define the interface that must be implemented @@ -945,214 +885,3 @@ main (int argc, char **argv) { head += part + os.sep return os.makedirs(name, mode) - - -# Map a sys.platform/os.name ('posix', 'nt') to the default compiler -# type for that platform. Keys are interpreted as re match -# patterns. Order is important; platform mappings are preferred over -# OS names. -_default_compilers = ( - - # Platform string mappings - - # on a cygwin built python we can use gcc like an ordinary UNIXish - # compiler - ('cygwin.*', 'unix'), - ('os2emx', 'emx'), - - # OS name mappings - ('posix', 'unix'), - ('nt', 'msvc'), - - ) - -def get_default_compiler(osname=None, platform=None): - """ Determine the default compiler to use for the given platform. - - osname should be one of the standard Python OS names (i.e. the - ones returned by os.name) and platform the common value - returned by sys.platform for the platform in question. - - The default values are os.name and sys.platform in case the - parameters are not given. - - """ - if osname is None: - osname = os.name - if platform is None: - platform = sys.platform - for pattern, compiler in _default_compilers: - if re.match(pattern, platform) is not None or \ - re.match(pattern, osname) is not None: - return compiler - # Default to Unix compiler - return 'unix' - -# Map compiler types to (module_name, class_name) pairs -- ie. where to -# find the code that implements an interface to this compiler. (The module -# is assumed to be in the 'distutils' package.) -compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', - "standard UNIX-style compiler"), - 'msvc': ('msvccompiler', 'MSVCCompiler', - "Microsoft Visual C++"), - 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', - "Cygwin port of GNU C Compiler for Win32"), - 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', - "Mingw32 port of GNU C Compiler for Win32"), - 'bcpp': ('bcppcompiler', 'BCPPCompiler', - "Borland C++ Compiler"), - 'emx': ('emxccompiler', 'EMXCCompiler', - "EMX port of GNU C Compiler for OS/2"), - } - -def show_compilers(): - """Print list of available compilers (used by the "--help-compiler" - options to "build", "build_ext", "build_clib"). - """ - # XXX this "knows" that the compiler option it's describing is - # "--compiler", which just happens to be the case for the three - # commands that use it. - from distutils2.fancy_getopt import FancyGetopt - compilers = [] - for compiler in compiler_class.keys(): - compilers.append(("compiler="+compiler, None, - compiler_class[compiler][2])) - compilers.sort() - pretty_printer = FancyGetopt(compilers) - pretty_printer.print_help("List of available compilers:") - - -def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): - """Generate an instance of some CCompiler subclass for the supplied - platform/compiler combination. 'plat' defaults to 'os.name' - (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler - for that platform. Currently only 'posix' and 'nt' are supported, and - the default compilers are "traditional Unix interface" (UnixCCompiler - class) and Visual C++ (MSVCCompiler class). Note that it's perfectly - possible to ask for a Unix compiler object under Windows, and a - Microsoft compiler object under Unix -- if you supply a value for - 'compiler', 'plat' is ignored. - """ - if plat is None: - plat = os.name - - try: - if compiler is None: - compiler = get_default_compiler(plat) - - (module_name, class_name, long_description) = compiler_class[compiler] - except KeyError: - msg = "don't know how to compile C/C++ code on platform '%s'" % plat - if compiler is not None: - msg = msg + " with '%s' compiler" % compiler - raise DistutilsPlatformError, msg - - try: - module_name = "distutils2.compiler." + module_name - __import__ (module_name) - module = sys.modules[module_name] - cls = vars(module)[class_name] - except ImportError: - raise DistutilsModuleError, \ - "can't compile C/C++ code: unable to load module '%s'" % \ - module_name - except KeyError: - raise DistutilsModuleError, \ - ("can't compile C/C++ code: unable to find class '%s' " + - "in module '%s'") % (class_name, module_name) - - # XXX The None is necessary to preserve backwards compatibility - # with classes that expect verbose to be the first positional - # argument. - return cls(None, dry_run, force) - - -def gen_preprocess_options(macros, include_dirs): - """Generate C pre-processor options (-D, -U, -I) as used by at least - two types of compilers: the typical Unix compiler and Visual C++. - 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) - means undefine (-U) macro 'name', and (name,value) means define (-D) - macro 'name' to 'value'. 'include_dirs' is just a list of directory - names to be added to the header file search path (-I). Returns a list - of command-line options suitable for either Unix compilers or Visual - C++. - """ - # 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 - # 'include_dirs'. 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 not (isinstance(macro, tuple) and - 1 <= len (macro) <= 2): - raise TypeError, \ - ("bad macro definition '%s': " + - "each element of 'macros' list must be a 1- or 2-tuple") % \ - macro - - 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 include_dirs: - pp_opts.append ("-I%s" % dir) - - return pp_opts - - -def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries): - """Generate linker options for searching library directories and - linking with specific libraries. - - 'libraries' and 'library_dirs' are, respectively, lists of library names - (not filenames!) and search directories. Returns a list of command-line - options suitable for use with some compiler (depending on the two format - strings passed in). - """ - lib_opts = [] - - for dir in library_dirs: - lib_opts.append(compiler.library_dir_option(dir)) - - for dir in runtime_library_dirs: - opt = compiler.runtime_library_dir_option(dir) - if isinstance(opt, list): - lib_opts.extend(opt) - else: - lib_opts.append(opt) - - # 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_dir, lib_name = os.path.split(lib) - if lib_dir != '': - lib_file = compiler.find_library_file([lib_dir], lib_name) - if lib_file is not None: - lib_opts.append(lib_file) - else: - compiler.warn("no library file corresponding to " - "'%s' found (skipping)" % lib) - else: - lib_opts.append(compiler.library_option(lib)) - - return lib_opts diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py index 1f195c1..7594353 100644 --- a/distutils2/compiler/cygwinccompiler.py +++ b/distutils2/compiler/cygwinccompiler.py @@ -56,10 +56,8 @@ from distutils2.compiler.unixccompiler import UnixCCompiler from distutils2.util import write_file from distutils2.errors import DistutilsExecError, CompileError, UnknownFileError from distutils2.util import get_compiler_versions -try: - import sysconfig -except ImportError: - from distutils2._backport import sysconfig +from distutils2._backport import sysconfig + def get_msvcr(): """Include the appropriate MSVC runtime library if Python was built diff --git a/distutils2/compiler/emxccompiler.py b/distutils2/compiler/emxccompiler.py index 3cef5de..cb3c883 100644 --- a/distutils2/compiler/emxccompiler.py +++ b/distutils2/compiler/emxccompiler.py @@ -18,8 +18,6 @@ handles the EMX port of the GNU C compiler to OS/2. # tested configurations: # # * EMX gcc 2.81/EMX 0.9d fix03 - - import os, sys, copy from warnings import warn @@ -27,6 +25,7 @@ from distutils2.compiler.unixccompiler import UnixCCompiler from distutils2.errors import DistutilsExecError, CompileError, UnknownFileError from distutils2.util import get_compiler_versions, write_file + class EMXCCompiler (UnixCCompiler): compiler_type = 'emx' diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py index 63a5570..940cf79 100644 --- a/distutils2/compiler/msvc9compiler.py +++ b/distutils2/compiler/msvc9compiler.py @@ -11,8 +11,6 @@ for older versions of VS in distutils.msvccompiler. # hacked by Robin Becker and Thomas Heller to do a better job of # finding DevStudio (through the registry) # ported to VS2005 and VS 2008 by Christian Heimes - - import os import subprocess import sys @@ -20,7 +18,8 @@ import re from distutils2.errors import (DistutilsExecError, DistutilsPlatformError, CompileError, LibError, LinkError) -from distutils2.compiler.ccompiler import CCompiler, gen_lib_options +from distutils2.compiler.ccompiler import CCompiler +from distutils2.compiler import gen_lib_options from distutils2 import logger from distutils2.util import get_platform @@ -49,6 +48,7 @@ PLAT_TO_VCVARS = { 'win-ia64' : 'ia64', } + class Reg(object): """Helper class to read values from the registry """ diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py index e24fb93..7436019 100644 --- a/distutils2/compiler/msvccompiler.py +++ b/distutils2/compiler/msvccompiler.py @@ -15,7 +15,8 @@ import string from distutils2.errors import (DistutilsExecError, DistutilsPlatformError, CompileError, LibError, LinkError) -from distutils2.compiler.ccompiler import CCompiler, gen_lib_options +from distutils2.compiler.ccompiler import CCompiler +from distutils2.compiler import gen_lib_options from distutils2 import logger _can_read_reg = 0 diff --git a/distutils2/compiler/unixccompiler.py b/distutils2/compiler/unixccompiler.py index 55c98f1..64988d1 100644 --- a/distutils2/compiler/unixccompiler.py +++ b/distutils2/compiler/unixccompiler.py @@ -18,16 +18,12 @@ import os, sys from types import StringType, NoneType from distutils2.util import newer -from distutils2.compiler.ccompiler import (CCompiler, gen_preprocess_options, - gen_lib_options) +from distutils2.compiler.ccompiler import CCompiler +from distutils2.compiler import gen_preprocess_options, gen_lib_options from distutils2.errors import (DistutilsExecError, CompileError, LibError, LinkError) from distutils2 import logger - -try: - import sysconfig -except ImportError: - from distutils2._backport import sysconfig +from distutils2._backport import sysconfig # XXX Things not currently handled: diff --git a/distutils2/tests/test_ccompiler.py b/distutils2/tests/test_ccompiler.py index 3ca5217..c7454fb 100644 --- a/distutils2/tests/test_ccompiler.py +++ b/distutils2/tests/test_ccompiler.py @@ -1,56 +1,12 @@ """Tests for distutils.ccompiler.""" -import os -from distutils2.tests import captured_stdout - -from distutils2.compiler.ccompiler import (gen_lib_options, CCompiler, - get_default_compiler, customize_compiler) +from distutils2.compiler.ccompiler import CCompiler from distutils2.tests import unittest, support -class FakeCompiler(object): - def library_dir_option(self, dir): - return "-L" + dir - - def runtime_library_dir_option(self, dir): - return ["-cool", "-R" + dir] - - def find_library_file(self, dirs, lib, debug=0): - return 'found' - - def library_option(self, lib): - return "-l" + lib class CCompilerTestCase(support.EnvironGuard, unittest.TestCase): - def test_gen_lib_options(self): - compiler = FakeCompiler() - libdirs = ['lib1', 'lib2'] - runlibdirs = ['runlib1'] - libs = [os.path.join('dir', 'name'), 'name2'] - - opts = gen_lib_options(compiler, libdirs, runlibdirs, libs) - wanted = ['-Llib1', '-Llib2', '-cool', '-Rrunlib1', 'found', - '-lname2'] - self.assertEqual(opts, wanted) - - def test_customize_compiler(self): - - # not testing if default compiler is not unix - if get_default_compiler() != 'unix': - return - - os.environ['AR'] = 'my_ar' - os.environ['ARFLAGS'] = '-arflags' - - # make sure AR gets caught - class compiler: - compiler_type = 'unix' - - def set_executables(self, **kw): - self.exes = kw + pass # XXX need some tests on CCompiler - comp = compiler() - customize_compiler(comp) - self.assertEqual(comp.exes['archiver'], 'my_ar -arflags') def test_suite(): return unittest.makeSuite(CCompilerTestCase) diff --git a/distutils2/tests/test_command_build_clib.py b/distutils2/tests/test_command_build_clib.py index a8557f4..b71cf5e 100644 --- a/distutils2/tests/test_command_build_clib.py +++ b/distutils2/tests/test_command_build_clib.py @@ -119,7 +119,7 @@ class BuildCLibTestCase(support.TempdirManager, # before we run the command, we want to make sure # all commands are present on the system # by creating a compiler and checking its executables - from distutils2.compiler.ccompiler import new_compiler, customize_compiler + from distutils2.compiler import new_compiler, customize_compiler compiler = new_compiler() customize_compiler(compiler) diff --git a/distutils2/tests/test_compiler.py b/distutils2/tests/test_compiler.py new file mode 100644 index 0000000..2ea9e13 --- /dev/null +++ b/distutils2/tests/test_compiler.py @@ -0,0 +1,62 @@ +"""Tests for distutils.compiler.""" +import os + +from distutils2.compiler import (get_default_compiler, customize_compiler, + gen_lib_options) +from distutils2.tests import unittest, support + + +class FakeCompiler(object): + def library_dir_option(self, dir): + return "-L" + dir + + def runtime_library_dir_option(self, dir): + return ["-cool", "-R" + dir] + + def find_library_file(self, dirs, lib, debug=0): + return 'found' + + def library_option(self, lib): + return "-l" + lib + + +class CompilerTestCase(support.EnvironGuard, unittest.TestCase): + + def test_customize_compiler(self): + + # not testing if default compiler is not unix + if get_default_compiler() != 'unix': + return + + os.environ['AR'] = 'my_ar' + os.environ['ARFLAGS'] = '-arflags' + + # make sure AR gets caught + class compiler: + compiler_type = 'unix' + + def set_executables(self, **kw): + self.exes = kw + + comp = compiler() + customize_compiler(comp) + self.assertEqual(comp.exes['archiver'], 'my_ar -arflags') + + def test_gen_lib_options(self): + compiler = FakeCompiler() + libdirs = ['lib1', 'lib2'] + runlibdirs = ['runlib1'] + libs = [os.path.join('dir', 'name'), 'name2'] + + opts = gen_lib_options(compiler, libdirs, runlibdirs, libs) + wanted = ['-Llib1', '-Llib2', '-cool', '-Rrunlib1', 'found', + '-lname2'] + self.assertEqual(opts, wanted) + + +def test_suite(): + return unittest.makeSuite(CompilerTestCase) + + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") |
