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)