]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/distutils/bcppcompiler.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / distutils / bcppcompiler.py
CommitLineData
4710c53d 1"""distutils.bcppcompiler\r
2\r
3Contains BorlandCCompiler, an implementation of the abstract CCompiler class\r
4for the Borland C++ compiler.\r
5"""\r
6\r
7# This implementation by Lyle Johnson, based on the original msvccompiler.py\r
8# module and using the directions originally published by Gordon Williams.\r
9\r
10# XXX looks like there's a LOT of overlap between these two classes:\r
11# someone should sit down and factor out the common code as\r
12# WindowsCCompiler! --GPW\r
13\r
14__revision__ = "$Id$"\r
15\r
16import os\r
17\r
18from distutils.errors import (DistutilsExecError, CompileError, LibError,\r
19 LinkError, UnknownFileError)\r
20from distutils.ccompiler import CCompiler, gen_preprocess_options\r
21from distutils.file_util import write_file\r
22from distutils.dep_util import newer\r
23from distutils import log\r
24\r
25class BCPPCompiler(CCompiler) :\r
26 """Concrete class that implements an interface to the Borland C/C++\r
27 compiler, as defined by the CCompiler abstract class.\r
28 """\r
29\r
30 compiler_type = 'bcpp'\r
31\r
32 # Just set this so CCompiler's constructor doesn't barf. We currently\r
33 # don't use the 'set_executables()' bureaucracy provided by CCompiler,\r
34 # as it really isn't necessary for this sort of single-compiler class.\r
35 # Would be nice to have a consistent interface with UnixCCompiler,\r
36 # though, so it's worth thinking about.\r
37 executables = {}\r
38\r
39 # Private class data (need to distinguish C from C++ source for compiler)\r
40 _c_extensions = ['.c']\r
41 _cpp_extensions = ['.cc', '.cpp', '.cxx']\r
42\r
43 # Needed for the filename generation methods provided by the\r
44 # base class, CCompiler.\r
45 src_extensions = _c_extensions + _cpp_extensions\r
46 obj_extension = '.obj'\r
47 static_lib_extension = '.lib'\r
48 shared_lib_extension = '.dll'\r
49 static_lib_format = shared_lib_format = '%s%s'\r
50 exe_extension = '.exe'\r
51\r
52\r
53 def __init__ (self,\r
54 verbose=0,\r
55 dry_run=0,\r
56 force=0):\r
57\r
58 CCompiler.__init__ (self, verbose, dry_run, force)\r
59\r
60 # These executables are assumed to all be in the path.\r
61 # Borland doesn't seem to use any special registry settings to\r
62 # indicate their installation locations.\r
63\r
64 self.cc = "bcc32.exe"\r
65 self.linker = "ilink32.exe"\r
66 self.lib = "tlib.exe"\r
67\r
68 self.preprocess_options = None\r
69 self.compile_options = ['/tWM', '/O2', '/q', '/g0']\r
70 self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0']\r
71\r
72 self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x']\r
73 self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x']\r
74 self.ldflags_static = []\r
75 self.ldflags_exe = ['/Gn', '/q', '/x']\r
76 self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r']\r
77\r
78\r
79 # -- Worker methods ------------------------------------------------\r
80\r
81 def compile(self, sources,\r
82 output_dir=None, macros=None, include_dirs=None, debug=0,\r
83 extra_preargs=None, extra_postargs=None, depends=None):\r
84\r
85 macros, objects, extra_postargs, pp_opts, build = \\r
86 self._setup_compile(output_dir, macros, include_dirs, sources,\r
87 depends, extra_postargs)\r
88 compile_opts = extra_preargs or []\r
89 compile_opts.append ('-c')\r
90 if debug:\r
91 compile_opts.extend (self.compile_options_debug)\r
92 else:\r
93 compile_opts.extend (self.compile_options)\r
94\r
95 for obj in objects:\r
96 try:\r
97 src, ext = build[obj]\r
98 except KeyError:\r
99 continue\r
100 # XXX why do the normpath here?\r
101 src = os.path.normpath(src)\r
102 obj = os.path.normpath(obj)\r
103 # XXX _setup_compile() did a mkpath() too but before the normpath.\r
104 # Is it possible to skip the normpath?\r
105 self.mkpath(os.path.dirname(obj))\r
106\r
107 if ext == '.res':\r
108 # This is already a binary file -- skip it.\r
109 continue # the 'for' loop\r
110 if ext == '.rc':\r
111 # This needs to be compiled to a .res file -- do it now.\r
112 try:\r
113 self.spawn (["brcc32", "-fo", obj, src])\r
114 except DistutilsExecError, msg:\r
115 raise CompileError, msg\r
116 continue # the 'for' loop\r
117\r
118 # The next two are both for the real compiler.\r
119 if ext in self._c_extensions:\r
120 input_opt = ""\r
121 elif ext in self._cpp_extensions:\r
122 input_opt = "-P"\r
123 else:\r
124 # Unknown file type -- no extra options. The compiler\r
125 # will probably fail, but let it just in case this is a\r
126 # file the compiler recognizes even if we don't.\r
127 input_opt = ""\r
128\r
129 output_opt = "-o" + obj\r
130\r
131 # Compiler command line syntax is: "bcc32 [options] file(s)".\r
132 # Note that the source file names must appear at the end of\r
133 # the command line.\r
134 try:\r
135 self.spawn ([self.cc] + compile_opts + pp_opts +\r
136 [input_opt, output_opt] +\r
137 extra_postargs + [src])\r
138 except DistutilsExecError, msg:\r
139 raise CompileError, msg\r
140\r
141 return objects\r
142\r
143 # compile ()\r
144\r
145\r
146 def create_static_lib (self,\r
147 objects,\r
148 output_libname,\r
149 output_dir=None,\r
150 debug=0,\r
151 target_lang=None):\r
152\r
153 (objects, output_dir) = self._fix_object_args (objects, output_dir)\r
154 output_filename = \\r
155 self.library_filename (output_libname, output_dir=output_dir)\r
156\r
157 if self._need_link (objects, output_filename):\r
158 lib_args = [output_filename, '/u'] + objects\r
159 if debug:\r
160 pass # XXX what goes here?\r
161 try:\r
162 self.spawn ([self.lib] + lib_args)\r
163 except DistutilsExecError, msg:\r
164 raise LibError, msg\r
165 else:\r
166 log.debug("skipping %s (up-to-date)", output_filename)\r
167\r
168 # create_static_lib ()\r
169\r
170\r
171 def link (self,\r
172 target_desc,\r
173 objects,\r
174 output_filename,\r
175 output_dir=None,\r
176 libraries=None,\r
177 library_dirs=None,\r
178 runtime_library_dirs=None,\r
179 export_symbols=None,\r
180 debug=0,\r
181 extra_preargs=None,\r
182 extra_postargs=None,\r
183 build_temp=None,\r
184 target_lang=None):\r
185\r
186 # XXX this ignores 'build_temp'! should follow the lead of\r
187 # msvccompiler.py\r
188\r
189 (objects, output_dir) = self._fix_object_args (objects, output_dir)\r
190 (libraries, library_dirs, runtime_library_dirs) = \\r
191 self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)\r
192\r
193 if runtime_library_dirs:\r
194 log.warn("I don't know what to do with 'runtime_library_dirs': %s",\r
195 str(runtime_library_dirs))\r
196\r
197 if output_dir is not None:\r
198 output_filename = os.path.join (output_dir, output_filename)\r
199\r
200 if self._need_link (objects, output_filename):\r
201\r
202 # Figure out linker args based on type of target.\r
203 if target_desc == CCompiler.EXECUTABLE:\r
204 startup_obj = 'c0w32'\r
205 if debug:\r
206 ld_args = self.ldflags_exe_debug[:]\r
207 else:\r
208 ld_args = self.ldflags_exe[:]\r
209 else:\r
210 startup_obj = 'c0d32'\r
211 if debug:\r
212 ld_args = self.ldflags_shared_debug[:]\r
213 else:\r
214 ld_args = self.ldflags_shared[:]\r
215\r
216\r
217 # Create a temporary exports file for use by the linker\r
218 if export_symbols is None:\r
219 def_file = ''\r
220 else:\r
221 head, tail = os.path.split (output_filename)\r
222 modname, ext = os.path.splitext (tail)\r
223 temp_dir = os.path.dirname(objects[0]) # preserve tree structure\r
224 def_file = os.path.join (temp_dir, '%s.def' % modname)\r
225 contents = ['EXPORTS']\r
226 for sym in (export_symbols or []):\r
227 contents.append(' %s=_%s' % (sym, sym))\r
228 self.execute(write_file, (def_file, contents),\r
229 "writing %s" % def_file)\r
230\r
231 # Borland C++ has problems with '/' in paths\r
232 objects2 = map(os.path.normpath, objects)\r
233 # split objects in .obj and .res files\r
234 # Borland C++ needs them at different positions in the command line\r
235 objects = [startup_obj]\r
236 resources = []\r
237 for file in objects2:\r
238 (base, ext) = os.path.splitext(os.path.normcase(file))\r
239 if ext == '.res':\r
240 resources.append(file)\r
241 else:\r
242 objects.append(file)\r
243\r
244\r
245 for l in library_dirs:\r
246 ld_args.append("/L%s" % os.path.normpath(l))\r
247 ld_args.append("/L.") # we sometimes use relative paths\r
248\r
249 # list of object files\r
250 ld_args.extend(objects)\r
251\r
252 # XXX the command-line syntax for Borland C++ is a bit wonky;\r
253 # certain filenames are jammed together in one big string, but\r
254 # comma-delimited. This doesn't mesh too well with the\r
255 # Unix-centric attitude (with a DOS/Windows quoting hack) of\r
256 # 'spawn()', so constructing the argument list is a bit\r
257 # awkward. Note that doing the obvious thing and jamming all\r
258 # the filenames and commas into one argument would be wrong,\r
259 # because 'spawn()' would quote any filenames with spaces in\r
260 # them. Arghghh!. Apparently it works fine as coded...\r
261\r
262 # name of dll/exe file\r
263 ld_args.extend([',',output_filename])\r
264 # no map file and start libraries\r
265 ld_args.append(',,')\r
266\r
267 for lib in libraries:\r
268 # see if we find it and if there is a bcpp specific lib\r
269 # (xxx_bcpp.lib)\r
270 libfile = self.find_library_file(library_dirs, lib, debug)\r
271 if libfile is None:\r
272 ld_args.append(lib)\r
273 # probably a BCPP internal library -- don't warn\r
274 else:\r
275 # full name which prefers bcpp_xxx.lib over xxx.lib\r
276 ld_args.append(libfile)\r
277\r
278 # some default libraries\r
279 ld_args.append ('import32')\r
280 ld_args.append ('cw32mt')\r
281\r
282 # def file for export symbols\r
283 ld_args.extend([',',def_file])\r
284 # add resource files\r
285 ld_args.append(',')\r
286 ld_args.extend(resources)\r
287\r
288\r
289 if extra_preargs:\r
290 ld_args[:0] = extra_preargs\r
291 if extra_postargs:\r
292 ld_args.extend(extra_postargs)\r
293\r
294 self.mkpath (os.path.dirname (output_filename))\r
295 try:\r
296 self.spawn ([self.linker] + ld_args)\r
297 except DistutilsExecError, msg:\r
298 raise LinkError, msg\r
299\r
300 else:\r
301 log.debug("skipping %s (up-to-date)", output_filename)\r
302\r
303 # link ()\r
304\r
305 # -- Miscellaneous methods -----------------------------------------\r
306\r
307\r
308 def find_library_file (self, dirs, lib, debug=0):\r
309 # List of effective library names to try, in order of preference:\r
310 # xxx_bcpp.lib is better than xxx.lib\r
311 # and xxx_d.lib is better than xxx.lib if debug is set\r
312 #\r
313 # The "_bcpp" suffix is to handle a Python installation for people\r
314 # with multiple compilers (primarily Distutils hackers, I suspect\r
315 # ;-). The idea is they'd have one static library for each\r
316 # compiler they care about, since (almost?) every Windows compiler\r
317 # seems to have a different format for static libraries.\r
318 if debug:\r
319 dlib = (lib + "_d")\r
320 try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib)\r
321 else:\r
322 try_names = (lib + "_bcpp", lib)\r
323\r
324 for dir in dirs:\r
325 for name in try_names:\r
326 libfile = os.path.join(dir, self.library_filename(name))\r
327 if os.path.exists(libfile):\r
328 return libfile\r
329 else:\r
330 # Oops, didn't find it in *any* of 'dirs'\r
331 return None\r
332\r
333 # overwrite the one from CCompiler to support rc and res-files\r
334 def object_filenames (self,\r
335 source_filenames,\r
336 strip_dir=0,\r
337 output_dir=''):\r
338 if output_dir is None: output_dir = ''\r
339 obj_names = []\r
340 for src_name in source_filenames:\r
341 # use normcase to make sure '.rc' is really '.rc' and not '.RC'\r
342 (base, ext) = os.path.splitext (os.path.normcase(src_name))\r
343 if ext not in (self.src_extensions + ['.rc','.res']):\r
344 raise UnknownFileError, \\r
345 "unknown file type '%s' (from '%s')" % \\r
346 (ext, src_name)\r
347 if strip_dir:\r
348 base = os.path.basename (base)\r
349 if ext == '.res':\r
350 # these can go unchanged\r
351 obj_names.append (os.path.join (output_dir, base + ext))\r
352 elif ext == '.rc':\r
353 # these need to be compiled to .res-files\r
354 obj_names.append (os.path.join (output_dir, base + '.res'))\r
355 else:\r
356 obj_names.append (os.path.join (output_dir,\r
357 base + self.obj_extension))\r
358 return obj_names\r
359\r
360 # object_filenames ()\r
361\r
362 def preprocess (self,\r
363 source,\r
364 output_file=None,\r
365 macros=None,\r
366 include_dirs=None,\r
367 extra_preargs=None,\r
368 extra_postargs=None):\r
369\r
370 (_, macros, include_dirs) = \\r
371 self._fix_compile_args(None, macros, include_dirs)\r
372 pp_opts = gen_preprocess_options(macros, include_dirs)\r
373 pp_args = ['cpp32.exe'] + pp_opts\r
374 if output_file is not None:\r
375 pp_args.append('-o' + output_file)\r
376 if extra_preargs:\r
377 pp_args[:0] = extra_preargs\r
378 if extra_postargs:\r
379 pp_args.extend(extra_postargs)\r
380 pp_args.append(source)\r
381\r
382 # We need to preprocess: either we're being forced to, or the\r
383 # source file is newer than the target (or the target doesn't\r
384 # exist).\r
385 if self.force or output_file is None or newer(source, output_file):\r
386 if output_file:\r
387 self.mkpath(os.path.dirname(output_file))\r
388 try:\r
389 self.spawn(pp_args)\r
390 except DistutilsExecError, msg:\r
391 print msg\r
392 raise CompileError, msg\r
393\r
394 # preprocess()\r