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