Path: blob/main/Tools/c-analyzer/distutils/unixccompiler.py
12 views
"""distutils.unixccompiler12Contains the UnixCCompiler class, a subclass of CCompiler that handles3the "typical" Unix-style command-line C compiler:4* macros defined with -Dname[=value]5* macros undefined with -Uname6* include search directories specified with -Idir7* libraries specified with -lllib8* library search directories specified with -Ldir9* compile handled by 'cc' (or similar) executable with -c option:10compiles .c to .o11* link static library handled by 'ar' command (possibly with 'ranlib')12* link shared library handled by 'cc -shared'13"""1415import os, sys1617from distutils.dep_util import newer18from distutils.ccompiler import CCompiler, gen_preprocess_options19from distutils.errors import DistutilsExecError, CompileError2021# XXX Things not currently handled:22# * optimization/debug/warning flags; we just use whatever's in Python's23# Makefile and live with it. Is this adequate? If not, we might24# have to have a bunch of subclasses GNUCCompiler, SGICCompiler,25# SunCCompiler, and I suspect down that road lies madness.26# * even if we don't know a warning flag from an optimization flag,27# we need some way for outsiders to feed preprocessor/compiler/linker28# flags in to us -- eg. a sysadmin might want to mandate certain flags29# via a site config file, or a user might want to set something for30# compiling this module distribution only via the setup.py command31# line, whatever. As long as these options come from something on the32# current system, they can be as system-dependent as they like, and we33# should just happily stuff them into the preprocessor/compiler/linker34# options and carry on.353637class UnixCCompiler(CCompiler):3839compiler_type = 'unix'4041# These are used by CCompiler in two places: the constructor sets42# instance attributes 'preprocessor', 'compiler', etc. from them, and43# 'set_executable()' allows any of these to be set. The defaults here44# are pretty generic; they will probably have to be set by an outsider45# (eg. using information discovered by the sysconfig about building46# Python extensions).47executables = {'preprocessor' : None,48'compiler' : ["cc"],49'compiler_so' : ["cc"],50'compiler_cxx' : ["cc"],51'linker_so' : ["cc", "-shared"],52'linker_exe' : ["cc"],53'archiver' : ["ar", "-cr"],54'ranlib' : None,55}5657if sys.platform[:6] == "darwin":58executables['ranlib'] = ["ranlib"]5960# Needed for the filename generation methods provided by the base61# class, CCompiler. NB. whoever instantiates/uses a particular62# UnixCCompiler instance should set 'shared_lib_ext' -- we set a63# reasonable common default here, but it's not necessarily used on all64# Unices!6566src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]67obj_extension = ".o"68static_lib_extension = ".a"69shared_lib_extension = ".so"70dylib_lib_extension = ".dylib"71xcode_stub_lib_extension = ".tbd"72static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s"73xcode_stub_lib_format = dylib_lib_format74if sys.platform == "cygwin":75exe_extension = ".exe"7677def preprocess(self, source, output_file=None, macros=None,78include_dirs=None, extra_preargs=None, extra_postargs=None):79fixed_args = self._fix_compile_args(None, macros, include_dirs)80ignore, macros, include_dirs = fixed_args81pp_opts = gen_preprocess_options(macros, include_dirs)82pp_args = self.preprocessor + pp_opts83if output_file:84pp_args.extend(['-o', output_file])85if extra_preargs:86pp_args[:0] = extra_preargs87if extra_postargs:88pp_args.extend(extra_postargs)89pp_args.append(source)9091# We need to preprocess: either we're being forced to, or we're92# generating output to stdout, or there's a target output file and93# the source file is newer than the target (or the target doesn't94# exist).95if self.force or output_file is None or newer(source, output_file):96if output_file:97self.mkpath(os.path.dirname(output_file))98try:99self.spawn(pp_args)100except DistutilsExecError as msg:101raise CompileError(msg)102103104