diff options
Diffstat (limited to 'Lib/distutils/unixccompiler.py')
| -rw-r--r-- | Lib/distutils/unixccompiler.py | 237 | 
1 files changed, 52 insertions, 185 deletions
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index 7765faf..35390de 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -20,10 +20,9 @@ __revision__ = "$Id$"  import string, re, os  from types import *  from copy import copy -from sysconfig import \ +from distutils.sysconfig import \       CC, CCSHARED, CFLAGS, OPT, LDSHARED, LDFLAGS, RANLIB, AR, SO -from ccompiler import CCompiler, gen_preprocess_options, gen_lib_options -from util import move_file, newer_pairwise, newer_group +from distutils.ccompiler import CCompiler, gen_preprocess_options, gen_lib_options  # XXX Things not currently handled:  #   * optimization/debug/warning flags; we just use whatever's in Python's @@ -55,10 +54,13 @@ class UnixCCompiler (CCompiler):      compiler_type = 'unix' -    _obj_ext = '.o' -    _exe_ext = '' -    _shared_lib_ext = SO -    _static_lib_ext = '.a' +    # Needed for the filename generation methods provided by the +    # base class, CCompiler. +    src_extensions = [".c",".C",".cc",".cxx",".cpp"] +    obj_extension = ".o" +    static_lib_extension = ".a" +    shared_lib_extension = ".so" +    static_lib_format = shared_lib_format = "lib%s%s"      # Command to create a static library: seems to be pretty consistent      # across the major Unices.  Might have to move down into the @@ -96,66 +98,24 @@ class UnixCCompiler (CCompiler):          self.ld_exec = self.cc +    # __init__ () +      def compile (self,                   sources,                   output_dir=None, -                 keep_dir=0,                   macros=None,                   include_dirs=None,                   debug=0,                   extra_preargs=None,                   extra_postargs=None): -        if type (output_dir) not in (StringType, NoneType): -            raise TypeError, "'output_dir' must be a string or None" -        if output_dir is None: -            output_dir = self.output_dir -        if macros is None: -            macros = [] -        if include_dirs is None: -            include_dirs = [] - -        if type (macros) is not ListType: -            raise TypeError, \ -                  "'macros' (if supplied) must be a list of tuples" -        if type (include_dirs) not in (ListType, TupleType): -            raise TypeError, \ -                  "'include_dirs' (if supplied) must be a list of strings" -        include_dirs = list (include_dirs) - -        pp_opts = gen_preprocess_options (self.macros + macros, -                                          self.include_dirs + include_dirs) - -        # So we can mangle 'sources' without hurting the caller's data -        orig_sources = sources -        sources = copy (sources) - -        # Get the list of expected output (object) files and drop files we -        # don't have to recompile.  (Simplistic check -- we just compare the -        # source and object file, no deep dependency checking involving -        # header files.  Hmmm.) -        objects = self.object_filenames (sources, -                                         output_dir=output_dir, -                                         keep_dir=keep_dir) -        all_objects = copy (objects)    # preserve full list to return - -        if not self.force: -            skipped = newer_pairwise (sources, objects) -            for skipped_pair in skipped: -                self.announce ("skipping %s (%s up-to-date)" % skipped_pair) - -        # Build list of (source,object) tuples for convenience -        srcobj = [] -        for i in range (len (sources)): -            srcobj.append ((sources[i], objects[i])) +        (output_dir, macros, include_dirs) = \ +            self._fix_compile_args (output_dir, macros, include_dirs) +        (objects, skip_sources) = self._prep_compile (sources, output_dir) -        # Compile all source files that weren't eliminated by -        # 'newer_pairwise()'. -        # XXX use of ccflags_shared means we're blithely assuming -        # that we're compiling for inclusion in a shared object! -        # (will have to fix this when I add the ability to build a -        # new Python) +        # Figure out the options for the compiler command line. +        pp_opts = gen_preprocess_options (macros, include_dirs)          cc_args = ['-c'] + pp_opts + self.ccflags + self.ccflags_shared          if debug:              cc_args[:0] = ['-g'] @@ -164,44 +124,21 @@ class UnixCCompiler (CCompiler):          if extra_postargs is None:              extra_postargs = [] -        if output_dir is not None: -            self.mkpath (output_dir) -        for (source,object) in srcobj: -            self.spawn ([self.cc] + cc_args + -                        [source, '-o', object] + -                        extra_postargs) - -        # Have to re-fetch list of object filenames, because we want to -        # return *all* of them, including those that weren't recompiled on -        # this call! -        return all_objects - - -    def _fix_link_args (self, output_dir, libraries, library_dirs): -        """Fixes up the arguments supplied to the 'link_*' methods: -           if output_dir is None, use self.output_dir; ensure that -           libraries and library_dirs are both lists (could be None or -           tuples on input -- both are converted to lists).  Return -           a tuple of the three input arguments.""" - -        if output_dir is None: -            output_dir = self.output_dir -        if libraries is None: -            libraries = [] -        if library_dirs is None: -            library_dirs = [] -         -        if type (libraries) not in (ListType, TupleType): -            raise TypeError, \ -                  "'libraries' (if supplied) must be a list of strings" -        if type (library_dirs) not in (ListType, TupleType): -            raise TypeError, \ -                  "'library_dirs' (if supplied) must be a list of strings" -        libraries = list (libraries) -        library_dirs = list (library_dirs) +        # Compile all source files that weren't eliminated by +        # '_prep_compile()'.         +        for i in range (len (sources)): +            src = sources[i] ; obj = objects[i] +            if skip_sources[src]: +                self.announce ("skipping %s (%s up-to-date)" % (src, obj)) +            else: +                self.mkpath (os.path.dirname (obj)) +                self.spawn ([self.cc] + cc_args + [src, '-o', obj] + extra_postargs) -        return (output_dir, libraries, library_dirs) +        # Return *all* object filenames, not just the ones we just built. +        return objects +    # compile () +          def link_static_lib (self,                           objects, @@ -209,35 +146,17 @@ class UnixCCompiler (CCompiler):                           output_dir=None,                           debug=0): -        if type (objects) not in (ListType, TupleType): -            raise TypeError, \ -                  "'objects' must be a list or tuple of strings" -        objects = list (objects) -             -        if type (output_dir) not in (StringType, NoneType): -            raise TypeError, "'output_dir' must be a string or None" -        if output_dir is None: -            output_dir = self.output_dir +        (objects, output_dir) = self._fix_link_args (objects, output_dir, takes_libs=0) -        output_filename = self.library_filename (output_libname) -        if output_dir is not None: -            output_filename = os.path.join (output_dir, output_filename) +        output_filename = \ +            self.library_filename (output_libname, output_dir=output_dir) -        # Check timestamps: if any of the object files are newer than -        # the library file, *or* if "force" is true, then we'll -        # recreate the library. -        if not self.force: -            if self.dry_run: -                newer = newer_group (objects, output_filename, missing='newer') -            else: -                newer = newer_group (objects, output_filename) - -        if self.force or newer: +        if self._need_link (objects, output_filename):              self.mkpath (os.path.dirname (output_filename))              self.spawn ([self.archiver,                           self.archiver_options,                           output_filename] + -                        objects) +                        objects + self.objects)          else:              self.announce ("skipping %s (up-to-date)" % output_filename) @@ -253,11 +172,9 @@ class UnixCCompiler (CCompiler):                           debug=0,                           extra_preargs=None,                           extra_postargs=None): -        # XXX should we sanity check the library name? (eg. no -        # slashes)          self.link_shared_object (              objects, -            "lib%s%s" % (output_libname, self._shared_lib_ext), +            self.shared_library_filename (output_libname),              output_dir,              libraries,              library_dirs, @@ -276,30 +193,19 @@ class UnixCCompiler (CCompiler):                              extra_preargs=None,                              extra_postargs=None): -        (output_dir, libraries, library_dirs) = \ -            self._fix_link_args (output_dir, libraries, 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, -                                    self.library_dirs + library_dirs, -                                    self.libraries + libraries) +        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 any of the input object files are newer than the output shared -        # object, relink.  Again, this is a simplistic dependency check: -        # doesn't look at any of the libraries we might be linking with. - -        if not self.force: -            if self.dry_run: -                newer = newer_group (objects, output_filename, missing='newer') -            else: -                newer = newer_group (objects, output_filename) - -        if self.force or newer: -            ld_args = self.ldflags_shared + objects + \ -                      lib_opts + ['-o', output_filename] +        if self._need_link (objects, output_filename): +            ld_args = (self.ldflags_shared + objects + self.objects +  +                       lib_opts + ['-o', output_filename])              if debug:                  ld_args[:0] = ['-g']              if extra_preargs: @@ -324,25 +230,17 @@ class UnixCCompiler (CCompiler):                           extra_preargs=None,                           extra_postargs=None): -        (output_dir, libraries, library_dirs) = \ -            self._fix_link_args (output_dir, libraries, 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, -                                    self.library_dirs + library_dirs, -                                    self.libraries + libraries) +        lib_opts = gen_lib_options (self, library_dirs, libraries)          output_filename = output_progname # Unix-ism!          if output_dir is not None:              output_filename = os.path.join (output_dir, output_filename) -        # Same ol' simplistic-but-still-useful dependency check. -        if not self.force: -            if self.dry_run: -                newer = newer_group (objects, output_filename, missing='newer') -            else: -                newer = newer_group (objects, output_filename) - -        if self.force or newer: -            ld_args = objects + lib_opts + ['-o', output_filename] +        if self._need_link (objects, output_filename): +            ld_args = objects + self.objects + lib_opts + ['-o', output_filename]              if debug:                  ld_args[:0] = ['-g']              if extra_preargs: @@ -357,41 +255,10 @@ class UnixCCompiler (CCompiler):      # link_executable () -    # -- Filename-mangling (etc.) methods ------------------------------ - -    def object_filenames (self, source_filenames, -                          keep_dir=0, output_dir=None): -        outnames = [] -        for inname in source_filenames: -            outname = re.sub (r'\.(c|C|cc|cxx|cpp)$', self._obj_ext, inname) -            if not keep_dir: -                outname = os.path.basename (outname) -            if output_dir is not None: -                outname = os.path.join (output_dir, outname) -            outnames.append (outname) -        return outnames - -    def shared_object_filename (self, source_filename, -                                keep_dir=0, output_dir=None): -        outname = re.sub (r'\.(c|C|cc|cxx|cpp)$', self._shared_lib_ext) -        if not keep_dir: -            outname = os.path.basename (outname) -        if output_dir is not None: -            outname = os.path.join (output_dir, outname) -        return outname - - -    def library_filename (self, libname): -        (dirname, basename) = os.path.split (libname) -        return os.path.join (dirname, -                             "lib%s%s" % (basename, self._static_lib_ext)) - -    def shared_library_filename (self, libname): -        (dirname, basename) = os.path.split (libname) -        return os.path.join (dirname, -                             "lib%s%s" % (basename, self._shared_lib_ext)) - - +    # -- Miscellaneous methods ----------------------------------------- +    # These are all used by the 'gen_lib_options() function, in +    # ccompiler.py. +          def library_dir_option (self, dir):          return "-L" + dir  | 
