blob: 7be0ba223df721be9a5d4aff3bfe740ab74e1225 [file] [log] [blame]
Greg Ward3f81cf71999-07-10 02:03:53 +00001"""distutils.ccompiler
2
3Contains CCompiler, an abstract base class that defines the interface
4for the Distutils compiler abstraction model."""
5
6# created 1999/07/05, Greg Ward
7
8__rcsid__ = "$Id$"
9
10import os
11from types import *
12from copy import copy
13from distutils.errors import *
14
15
16class CCompiler:
17 """Abstract base class to define the interface that must be implemented
18 by real compiler abstraction classes. Might have some use as a
19 place for shared code, but it's not yet clear what code can be
20 shared between compiler abstraction models for different platforms.
21
22 The basic idea behind a compiler abstraction class is that each
23 instance can be used for all the compile/link steps in building
24 a single project. Thus, attributes common to all of those compile
25 and link steps -- include directories, macros to define, libraries
26 to link against, etc. -- are attributes of the compiler instance.
27 To allow for variability in how individual files are treated,
28 most (all?) of those attributes may be varied on a per-compilation
29 or per-link basis."""
30
31
32 # XXX things not handled by this compiler abstraction model:
33 # * client can't provide additional options for a compiler,
34 # e.g. warning, optimization, debugging flags. Perhaps this
35 # should be the domain of concrete compiler abstraction classes
36 # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base
37 # class should have methods for the common ones.
38 # * can't put output files (object files, libraries, whatever)
39 # into a separate directory from their inputs. Should this be
40 # handled by an 'output_dir' attribute of the whole object, or a
41 # parameter to the compile/link_* methods, or both?
42 # * can't completely override the include or library searchg
43 # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2".
44 # I'm not sure how widely supported this is even by POSIX
45 # compilers, much less on other platforms. And I'm even less
46 # sure how useful it is; probably for cross-compiling, but I
47 # have no intention of supporting that.
48 # * can't do really freaky things with the library list/library
49 # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against
50 # different versions of libfoo.a in different locations. I
51 # think this is useless without the ability to null out the
52 # library search path anyways.
53 # * don't deal with verbose and dry-run flags -- probably a
54 # CCompiler object should just drag them around the way the
55 # Distribution object does (either that or we have to drag
56 # around a Distribution object, which is what Command objects
57 # do... but might be kind of annoying)
58
59
60 def __init__ (self):
61
62 # 'macros': a list of macro definitions (or undefinitions). A
63 # macro definition is a 2-tuple (name, value), where the value is
64 # either a string or None (no explicit value). A macro
65 # undefinition is a 1-tuple (name,).
66 self.macros = []
67
68
69 # 'include_dirs': a list of directories to search for include files
70 self.include_dirs = []
71
72 # 'libraries': a list of libraries to include in any link
73 # (library names, not filenames: eg. "foo" not "libfoo.a")
74 self.libraries = []
75
76 # 'library_dirs': a list of directories to search for libraries
77 self.library_dirs = []
78
79 # 'objects': a list of object files (or similar, such as explicitly
80 # named library files) to include on any link
81 self.objects = []
82
83 # __init__ ()
84
85
86 def _find_macro (self, name):
87 i = 0
88 for defn in self.macros:
89 if defn[0] == name:
90 return i
91 i = i + 1
92
93 return None
94
95
96 def _check_macro_definitions (self, definitions):
97 """Ensures that every element of 'definitions' is a valid macro
98 definition, ie. either (name,value) 2-tuple or a (name,)
99 tuple. Do nothing if all definitions are OK, raise
100 TypeError otherwise."""
101
102 for defn in definitions:
103 if not (type (defn) is TupleType and
104 (len (defn) == 1 or
105 (len (defn) == 2 and
106 (type (defn[1]) is StringType or defn[1] is None))) and
107 type (defn[0]) is StringType):
108 raise TypeError, \
109 ("invalid macro definition '%s': " % defn) + \
110 "must be tuple (string,), (string, string), or " + \
111 "(string, None)"
112
113
114 # -- Bookkeeping methods -------------------------------------------
115
116 def define_macro (self, name, value=None):
117 """Define a preprocessor macro for all compilations driven by
118 this compiler object. The optional parameter 'value' should be
119 a string; if it is not supplied, then the macro will be defined
120 without an explicit value and the exact outcome depends on the
121 compiler used (XXX true? does ANSI say anything about this?)"""
122
123 # Delete from the list of macro definitions/undefinitions if
124 # already there (so that this one will take precedence).
125 i = self._find_macro (name)
126 if i is not None:
127 del self.macros[i]
128
129 defn = (name, value)
130 self.macros.append (defn)
131
132
133 def undefine_macro (self, name):
134 """Undefine a preprocessor macro for all compilations driven by
135 this compiler object. If the same macro is defined by
136 'define_macro()' and undefined by 'undefine_macro()' the last
137 call takes precedence (including multiple redefinitions or
138 undefinitions). If the macro is redefined/undefined on a
139 per-compilation basis (ie. in the call to 'compile()'), then
140 that takes precedence."""
141
142 # Delete from the list of macro definitions/undefinitions if
143 # already there (so that this one will take precedence).
144 i = self._find_macro (name)
145 if i is not None:
146 del self.macros[i]
147
148 undefn = (name,)
149 self.macros.append (undefn)
150
151
152 def add_include_dir (self, dir):
153 """Add 'dir' to the list of directories that will be searched
154 for header files. The compiler is instructed to search
155 directories in the order in which they are supplied by
156 successive calls to 'add_include_dir()'."""
157 self.include_dirs.append (dir)
158
159 def set_include_dirs (self, dirs):
160 """Set the list of directories that will be searched to 'dirs'
161 (a list of strings). Overrides any preceding calls to
162 'add_include_dir()'; subsequence calls to 'add_include_dir()'
163 add to the list passed to 'set_include_dirs()'. This does
164 not affect any list of standard include directories that
165 the compiler may search by default."""
166 self.include_dirs = copy (dirs)
167
168
169 def add_library (self, libname):
170 """Add 'libname' to the list of libraries that will be included
171 in all links driven by this compiler object. Note that
172 'libname' should *not* be the name of a file containing a
173 library, but the name of the library itself: the actual filename
174 will be inferred by the linker, the compiler, or the compiler
175 abstraction class (depending on the platform).
176
177 The linker will be instructed to link against libraries in the
178 order they were supplied to 'add_library()' and/or
179 'set_libraries()'. It is perfectly valid to duplicate library
180 names; the linker will be instructed to link against libraries
181 as many times as they are mentioned."""
182 self.libraries.append (libname)
183
184 def set_libraries (self, libnames):
185 """Set the list of libraries to be included in all links driven
186 by this compiler object to 'libnames' (a list of strings).
187 This does not affect any standard system libraries that the
188 linker may include by default."""
189
190 self.libraries = copy (libnames)
191
192
193 def add_library_dir (self, dir):
194 """Add 'dir' to the list of directories that will be searched for
195 libraries specified to 'add_library()' and 'set_libraries()'.
196 The linker will be instructed to search for libraries in the
197 order they are supplied to 'add_library_dir()' and/or
198 'set_library_dirs()'."""
199 self.library_dirs.append (dir)
200
201 def set_library_dirs (self, dirs):
202 """Set the list of library search directories to 'dirs' (a list
203 of strings). This does not affect any standard library
204 search path that the linker may search by default."""
205 self.library_dirs = copy (dirs)
206
207
208 def add_link_object (self, object):
209 """Add 'object' to the list of object files (or analogues, such
210 as explictly named library files or the output of "resource
211 compilers") to be included in every link driven by this
212 compiler object."""
213 self.objects.append (object)
214
215 def set_link_objects (self, objects):
216 """Set the list of object files (or analogues) to be included
217 in every link to 'objects'. This does not affect any
218 standard object files that the linker may include by default
219 (such as system libraries)."""
220 self.objects = copy (objects)
221
222
223 # -- Worker methods ------------------------------------------------
224 # (must be implemented by subclasses)
225
226 def compile (self,
227 sources,
228 macros=None,
229 includes=None):
230 """Compile one or more C/C++ source files. 'sources' must be
231 a list of strings, each one the name of a C/C++ source
232 file. Return a list of the object filenames generated
233 (one for each source filename in 'sources').
234
235 'macros', if given, must be a list of macro definitions. A
236 macro definition is either a (name, value) 2-tuple or a (name,)
237 1-tuple. The former defines a macro; if the value is None, the
238 macro is defined without an explicit value. The 1-tuple case
239 undefines a macro. Later definitions/redefinitions/
240 undefinitions take precedence.
241
242 'includes', if given, must be a list of strings, the directories
243 to add to the default include file search path for this
244 compilation only."""
245 pass
246
247
248 # XXX this is kind of useless without 'link_binary()' or
249 # 'link_executable()' or something -- or maybe 'link_static_lib()'
250 # should not exist at all, and we just have 'link_binary()'?
251 def link_static_lib (self,
252 objects,
253 output_libname,
254 libraries=None,
255 library_dirs=None):
256 """Link a bunch of stuff together to create a static library
257 file. The "bunch of stuff" consists of the list of object
258 files supplied as 'objects', the extra object files supplied
259 to 'add_link_object()' and/or 'set_link_objects()', the
260 libraries supplied to 'add_library()' and/or
261 'set_libraries()', and the libraries supplied as 'libraries'
262 (if any).
263
264 'output_libname' should be a library name, not a filename;
265 the filename will be inferred from the library name.
266
267 'library_dirs', if supplied, should be a list of additional
268 directories to search on top of the system default and those
269 supplied to 'add_library_dir()' and/or 'set_library_dirs()'."""
270
271 pass
272
273
274 # XXX what's better/more consistent/more universally understood
275 # terminology: "shared library" or "dynamic library"?
276
277 def link_shared_lib (self,
278 objects,
279 output_libname,
280 libraries=None,
281 library_dirs=None):
282 """Link a bunch of stuff together to create a shared library
283 file. Has the same effect as 'link_static_lib()' except
284 that the filename inferred from 'output_libname' will most
285 likely be different, and the type of file generated will
286 almost certainly be different."""
287 pass
288
289 def link_shared_object (self,
290 objects,
291 output_filename,
292 libraries=None,
293 library_dirs=None):
294 """Link a bunch of stuff together to create a shared object
295 file. Much like 'link_shared_lib()', except the output
296 filename is explicitly supplied as 'output_filename'."""
297 pass
298
299# class CCompiler
300
301
302def new_compiler (plat=None):
303 """Generate a CCompiler instance for platform 'plat' (or the
304 current platform, if 'plat' not supplied). Really instantiates
305 some concrete subclass of CCompiler, of course."""
306
307 if plat is None: plat = os.name
308 if plat == 'posix':
309 from unixccompiler import UnixCCompiler
310 return UnixCCompiler ()
311 else:
312 raise DistutilsPlatformError, \
313 "don't know how to compile C/C++ code on platform %s" % plat