distutils unixccompiler contains the unixccompiler class a subclass of ccompiler that handles the typical unixstyle commandline c compiler macros defined with dnamevalue macros undefined with uname include search directories specified with idir libraries specified with lllib library search directories specified with ldir compile handled by cc or similar executable with c option compiles c to o link static library handled by ar command possibly with ranlib link shared library handled by cc shared xxx things not currently handled optimizationdebugwarning flags we just use whatever s in python s makefile and live with it is this adequate if not we might have to have a bunch of subclasses gnuccompiler sgiccompiler sunccompiler and i suspect down that road lies madness even if we don t know a warning flag from an optimization flag we need some way for outsiders to feed preprocessorcompilerlinker flags in to us eg a sysadmin might want to mandate certain flags via a site config file or a user might want to set something for compiling this module distribution only via the setup py command line whatever as long as these options come from something on the current system they can be as systemdependent as they like and we should just happily stuff them into the preprocessorcompilerlinker options and carry on these are used by ccompiler in two places the constructor sets instance attributes preprocessor compiler etc from them and setexecutable allows any of these to be set the defaults here are pretty generic they will probably have to be set by an outsider eg using information discovered by the sysconfig about building python extensions needed for the filename generation methods provided by the base class ccompiler nb whoever instantiatesuses a particular unixccompiler instance should set sharedlibext we set a reasonable common default here but it s not necessarily used on all unices we need to preprocess either we re being forced to or we re generating output to stdout or there s a target output file and the source file is newer than the target or the target doesn t exist xxx things not currently handled optimization debug warning flags we just use whatever s in python s makefile and live with it is this adequate if not we might have to have a bunch of subclasses gnuccompiler sgiccompiler sunccompiler and i suspect down that road lies madness even if we don t know a warning flag from an optimization flag we need some way for outsiders to feed preprocessor compiler linker flags in to us eg a sysadmin might want to mandate certain flags via a site config file or a user might want to set something for compiling this module distribution only via the setup py command line whatever as long as these options come from something on the current system they can be as system dependent as they like and we should just happily stuff them into the preprocessor compiler linker options and carry on these are used by ccompiler in two places the constructor sets instance attributes preprocessor compiler etc from them and set_executable allows any of these to be set the defaults here are pretty generic they will probably have to be set by an outsider eg using information discovered by the sysconfig about building python extensions needed for the filename generation methods provided by the base class ccompiler nb whoever instantiates uses a particular unixccompiler instance should set shared_lib_ext we set a reasonable common default here but it s not necessarily used on all unices we need to preprocess either we re being forced to or we re generating output to stdout or there s a target output file and the source file is newer than the target or the target doesn t exist
import os, sys

from distutils.dep_util import newer
from distutils.ccompiler import CCompiler, gen_preprocess_options
from distutils.errors import DistutilsExecError, CompileError

















class UnixCCompiler(CCompiler):

    compiler_type = 'unix'

    
    
    
    
    
    
    executables = {'preprocessor' : None,
                   'compiler'     : ["cc"],
                   'compiler_so'  : ["cc"],
                   'compiler_cxx' : ["cc"],
                   'linker_so'    : ["cc", "-shared"],
                   'linker_exe'   : ["cc"],
                   'archiver'     : ["ar", "-cr"],
                   'ranlib'       : None,
                  }

    if sys.platform[:6] == "darwin":
        executables['ranlib'] = ["ranlib"]

    
    
    
    
    

    src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]
    obj_extension = ".o"
    static_lib_extension = ".a"
    shared_lib_extension = ".so"
    dylib_lib_extension = ".dylib"
    xcode_stub_lib_extension = ".tbd"
    static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
    xcode_stub_lib_format = dylib_lib_format
    if sys.platform == "cygwin":
        exe_extension = ".exe"

    def preprocess(self, source, output_file=None, macros=None,
                   include_dirs=None, extra_preargs=None, extra_postargs=None):
        fixed_args = self._fix_compile_args(None, macros, include_dirs)
        ignore, macros, include_dirs = fixed_args
        pp_opts = gen_preprocess_options(macros, include_dirs)
        pp_args = self.preprocessor + pp_opts
        if output_file:
            pp_args.extend(['-o', output_file])
        if extra_preargs:
            pp_args[:0] = extra_preargs
        if extra_postargs:
            pp_args.extend(extra_postargs)
        pp_args.append(source)

        
        
        
        
        if self.force or output_file is None or newer(source, output_file):
            if output_file:
                self.mkpath(os.path.dirname(output_file))
            try:
                self.spawn(pp_args)
            except DistutilsExecError as msg:
                raise CompileError(msg)