(root)/
Python-3.12.0/
Tools/
c-analyzer/
distutils/
unixccompiler.py
       1  """distutils.unixccompiler
       2  
       3  Contains the UnixCCompiler class, a subclass of CCompiler that handles
       4  the "typical" Unix-style command-line C compiler:
       5    * macros defined with -Dname[=value]
       6    * macros undefined with -Uname
       7    * include search directories specified with -Idir
       8    * libraries specified with -lllib
       9    * library search directories specified with -Ldir
      10    * compile handled by 'cc' (or similar) executable with -c option:
      11      compiles .c to .o
      12    * link static library handled by 'ar' command (possibly with 'ranlib')
      13    * link shared library handled by 'cc -shared'
      14  """
      15  
      16  import os, sys, re
      17  
      18  from distutils.dep_util import newer
      19  from distutils.ccompiler import CCompiler, gen_preprocess_options
      20  from distutils.errors import DistutilsExecError, CompileError
      21  
      22  # XXX Things not currently handled:
      23  #   * optimization/debug/warning flags; we just use whatever's in Python's
      24  #     Makefile and live with it.  Is this adequate?  If not, we might
      25  #     have to have a bunch of subclasses GNUCCompiler, SGICCompiler,
      26  #     SunCCompiler, and I suspect down that road lies madness.
      27  #   * even if we don't know a warning flag from an optimization flag,
      28  #     we need some way for outsiders to feed preprocessor/compiler/linker
      29  #     flags in to us -- eg. a sysadmin might want to mandate certain flags
      30  #     via a site config file, or a user might want to set something for
      31  #     compiling this module distribution only via the setup.py command
      32  #     line, whatever.  As long as these options come from something on the
      33  #     current system, they can be as system-dependent as they like, and we
      34  #     should just happily stuff them into the preprocessor/compiler/linker
      35  #     options and carry on.
      36  
      37  
      38  class ESC[4;38;5;81mUnixCCompiler(ESC[4;38;5;149mCCompiler):
      39  
      40      compiler_type = 'unix'
      41  
      42      # These are used by CCompiler in two places: the constructor sets
      43      # instance attributes 'preprocessor', 'compiler', etc. from them, and
      44      # 'set_executable()' allows any of these to be set.  The defaults here
      45      # are pretty generic; they will probably have to be set by an outsider
      46      # (eg. using information discovered by the sysconfig about building
      47      # Python extensions).
      48      executables = {'preprocessor' : None,
      49                     'compiler'     : ["cc"],
      50                     'compiler_so'  : ["cc"],
      51                     'compiler_cxx' : ["cc"],
      52                     'linker_so'    : ["cc", "-shared"],
      53                     'linker_exe'   : ["cc"],
      54                     'archiver'     : ["ar", "-cr"],
      55                     'ranlib'       : None,
      56                    }
      57  
      58      if sys.platform[:6] == "darwin":
      59          executables['ranlib'] = ["ranlib"]
      60  
      61      # Needed for the filename generation methods provided by the base
      62      # class, CCompiler.  NB. whoever instantiates/uses a particular
      63      # UnixCCompiler instance should set 'shared_lib_ext' -- we set a
      64      # reasonable common default here, but it's not necessarily used on all
      65      # Unices!
      66  
      67      src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]
      68      obj_extension = ".o"
      69      static_lib_extension = ".a"
      70      shared_lib_extension = ".so"
      71      dylib_lib_extension = ".dylib"
      72      xcode_stub_lib_extension = ".tbd"
      73      static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"
      74      xcode_stub_lib_format = dylib_lib_format
      75      if sys.platform == "cygwin":
      76          exe_extension = ".exe"
      77  
      78      def preprocess(self, source, output_file=None, macros=None,
      79                     include_dirs=None, extra_preargs=None, extra_postargs=None):
      80          fixed_args = self._fix_compile_args(None, macros, include_dirs)
      81          ignore, macros, include_dirs = fixed_args
      82          pp_opts = gen_preprocess_options(macros, include_dirs)
      83          pp_args = self.preprocessor + pp_opts
      84          if output_file:
      85              pp_args.extend(['-o', output_file])
      86          if extra_preargs:
      87              pp_args[:0] = extra_preargs
      88          if extra_postargs:
      89              pp_args.extend(extra_postargs)
      90          pp_args.append(source)
      91  
      92          # We need to preprocess: either we're being forced to, or we're
      93          # generating output to stdout, or there's a target output file and
      94          # the source file is newer than the target (or the target doesn't
      95          # exist).
      96          if self.force or output_file is None or newer(source, output_file):
      97              if output_file:
      98                  self.mkpath(os.path.dirname(output_file))
      99              try:
     100                  self.spawn(pp_args)
     101              except DistutilsExecError as msg:
     102                  raise CompileError(msg)