]>
jfr.im git - dlqueue.git/blob - venv/lib/python3.11/site-packages/setuptools/_distutils/bcppcompiler.py
1 """distutils.bcppcompiler
3 Contains BorlandCCompiler, an implementation of the abstract CCompiler class
4 for the Borland C++ compiler.
7 # This implementation by Lyle Johnson, based on the original msvccompiler.py
8 # module and using the directions originally published by Gordon Williams.
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
25 from .ccompiler
import CCompiler
, gen_preprocess_options
26 from .file_util
import write_file
27 from .dep_util
import newer
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.",
39 class BCPPCompiler(CCompiler
):
40 """Concrete class that implements an interface to the Borland C/C++
41 compiler, as defined by the CCompiler abstract class.
44 compiler_type
= 'bcpp'
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.
53 # Private class data (need to distinguish C from C++ source for compiler)
54 _c_extensions
= ['.c']
55 _cpp_extensions
= ['.cc', '.cpp', '.cxx']
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'
66 def __init__(self
, verbose
=0, dry_run
=0, force
=0):
67 super().__init
__(verbose
, dry_run
, force
)
69 # These executables are assumed to all be in the path.
70 # Borland doesn't seem to use any special registry settings to
71 # indicate their installation locations.
74 self
.linker
= "ilink32.exe"
77 self
.preprocess_options
= None
78 self
.compile_options
= ['/tWM', '/O2', '/q', '/g0']
79 self
.compile_options_debug
= ['/tWM', '/Od', '/q', '/g0']
81 self
.ldflags_shared
= ['/Tpd', '/Gn', '/q', '/x']
82 self
.ldflags_shared_debug
= ['/Tpd', '/Gn', '/q', '/x']
83 self
.ldflags_static
= []
84 self
.ldflags_exe
= ['/Gn', '/q', '/x']
85 self
.ldflags_exe_debug
= ['/Gn', '/q', '/x', '/r']
87 # -- Worker methods ------------------------------------------------
89 def compile( # noqa: C901
100 macros
, objects
, extra_postargs
, pp_opts
, build
= self
._setup
_compile
(
101 output_dir
, macros
, include_dirs
, sources
, depends
, extra_postargs
103 compile_opts
= extra_preargs
or []
104 compile_opts
.append('-c')
106 compile_opts
.extend(self
.compile_options_debug
)
108 compile_opts
.extend(self
.compile_options
)
112 src
, ext
= build
[obj
]
115 # XXX why do the normpath here?
116 src
= os
.path
.normpath(src
)
117 obj
= os
.path
.normpath(obj
)
118 # XXX _setup_compile() did a mkpath() too but before the normpath.
119 # Is it possible to skip the normpath?
120 self
.mkpath(os
.path
.dirname(obj
))
123 # This is already a binary file -- skip it.
124 continue # the 'for' loop
126 # This needs to be compiled to a .res file -- do it now.
128 self
.spawn(["brcc32", "-fo", obj
, src
])
129 except DistutilsExecError
as msg
:
130 raise CompileError(msg
)
131 continue # the 'for' loop
133 # The next two are both for the real compiler.
134 if ext
in self
._c
_extensions
:
136 elif ext
in self
._cpp
_extensions
:
139 # Unknown file type -- no extra options. The compiler
140 # will probably fail, but let it just in case this is a
141 # file the compiler recognizes even if we don't.
144 output_opt
= "-o" + obj
146 # Compiler command line syntax is: "bcc32 [options] file(s)".
147 # Note that the source file names must appear at the end of
154 + [input_opt
, output_opt
]
158 except DistutilsExecError
as msg
:
159 raise CompileError(msg
)
165 def create_static_lib(
166 self
, objects
, output_libname
, output_dir
=None, debug
=0, target_lang
=None
168 (objects
, output_dir
) = self
._fix
_object
_args
(objects
, output_dir
)
169 output_filename
= self
.library_filename(output_libname
, output_dir
=output_dir
)
171 if self
._need
_link
(objects
, output_filename
):
172 lib_args
= [output_filename
, '/u'] + objects
174 pass # XXX what goes here?
176 self
.spawn([self
.lib
] + lib_args
)
177 except DistutilsExecError
as msg
:
180 log
.debug("skipping %s (up-to-date)", output_filename
)
182 # create_static_lib ()
184 def link( # noqa: C901
192 runtime_library_dirs
=None,
200 # XXX this ignores 'build_temp'! should follow the lead of
203 (objects
, output_dir
) = self
._fix
_object
_args
(objects
, output_dir
)
204 (libraries
, library_dirs
, runtime_library_dirs
) = self
._fix
_lib
_args
(
205 libraries
, library_dirs
, runtime_library_dirs
208 if runtime_library_dirs
:
210 "I don't know what to do with 'runtime_library_dirs': %s",
211 str(runtime_library_dirs
),
214 if output_dir
is not None:
215 output_filename
= os
.path
.join(output_dir
, output_filename
)
217 if self
._need
_link
(objects
, output_filename
):
218 # Figure out linker args based on type of target.
219 if target_desc
== CCompiler
.EXECUTABLE
:
220 startup_obj
= 'c0w32'
222 ld_args
= self
.ldflags_exe_debug
[:]
224 ld_args
= self
.ldflags_exe
[:]
226 startup_obj
= 'c0d32'
228 ld_args
= self
.ldflags_shared_debug
[:]
230 ld_args
= self
.ldflags_shared
[:]
232 # Create a temporary exports file for use by the linker
233 if export_symbols
is None:
236 head
, tail
= os
.path
.split(output_filename
)
237 modname
, ext
= os
.path
.splitext(tail
)
238 temp_dir
= os
.path
.dirname(objects
[0]) # preserve tree structure
239 def_file
= os
.path
.join(temp_dir
, '%s.def' % modname
)
240 contents
= ['EXPORTS']
241 for sym
in export_symbols
or []:
242 contents
.append(' {}=_{}'.format(sym
, sym
))
243 self
.execute(write_file
, (def_file
, contents
), "writing %s" % def_file
)
245 # Borland C++ has problems with '/' in paths
246 objects2
= map(os
.path
.normpath
, objects
)
247 # split objects in .obj and .res files
248 # Borland C++ needs them at different positions in the command line
249 objects
= [startup_obj
]
251 for file in objects2
:
252 (base
, ext
) = os
.path
.splitext(os
.path
.normcase(file))
254 resources
.append(file)
258 for ell
in library_dirs
:
259 ld_args
.append("/L%s" % os
.path
.normpath(ell
))
260 ld_args
.append("/L.") # we sometimes use relative paths
262 # list of object files
263 ld_args
.extend(objects
)
265 # XXX the command-line syntax for Borland C++ is a bit wonky;
266 # certain filenames are jammed together in one big string, but
267 # comma-delimited. This doesn't mesh too well with the
268 # Unix-centric attitude (with a DOS/Windows quoting hack) of
269 # 'spawn()', so constructing the argument list is a bit
270 # awkward. Note that doing the obvious thing and jamming all
271 # the filenames and commas into one argument would be wrong,
272 # because 'spawn()' would quote any filenames with spaces in
273 # them. Arghghh!. Apparently it works fine as coded...
275 # name of dll/exe file
276 ld_args
.extend([',', output_filename
])
277 # no map file and start libraries
280 for lib
in libraries
:
281 # see if we find it and if there is a bcpp specific lib
283 libfile
= self
.find_library_file(library_dirs
, lib
, debug
)
286 # probably a BCPP internal library -- don't warn
288 # full name which prefers bcpp_xxx.lib over xxx.lib
289 ld_args
.append(libfile
)
291 # some default libraries
292 ld_args
.extend(('import32', 'cw32mt'))
294 # def file for export symbols
295 ld_args
.extend([',', def_file
])
298 ld_args
.extend(resources
)
301 ld_args
[:0] = extra_preargs
303 ld_args
.extend(extra_postargs
)
305 self
.mkpath(os
.path
.dirname(output_filename
))
307 self
.spawn([self
.linker
] + ld_args
)
308 except DistutilsExecError
as msg
:
312 log
.debug("skipping %s (up-to-date)", output_filename
)
316 # -- Miscellaneous methods -----------------------------------------
318 def find_library_file(self
, dirs
, lib
, debug
=0):
319 # List of effective library names to try, in order of preference:
320 # xxx_bcpp.lib is better than xxx.lib
321 # and xxx_d.lib is better than xxx.lib if debug is set
323 # The "_bcpp" suffix is to handle a Python installation for people
324 # with multiple compilers (primarily Distutils hackers, I suspect
325 # ;-). The idea is they'd have one static library for each
326 # compiler they care about, since (almost?) every Windows compiler
327 # seems to have a different format for static libraries.
330 try_names
= (dlib
+ "_bcpp", lib
+ "_bcpp", dlib
, lib
)
332 try_names
= (lib
+ "_bcpp", lib
)
335 for name
in try_names
:
336 libfile
= os
.path
.join(dir, self
.library_filename(name
))
337 if os
.path
.exists(libfile
):
340 # Oops, didn't find it in *any* of 'dirs'
343 # overwrite the one from CCompiler to support rc and res-files
344 def object_filenames(self
, source_filenames
, strip_dir
=0, output_dir
=''):
345 if output_dir
is None:
348 for src_name
in source_filenames
:
349 # use normcase to make sure '.rc' is really '.rc' and not '.RC'
350 (base
, ext
) = os
.path
.splitext(os
.path
.normcase(src_name
))
351 if ext
not in (self
.src_extensions
+ ['.rc', '.res']):
352 raise UnknownFileError(
353 "unknown file type '{}' (from '{}')".format(ext
, src_name
)
356 base
= os
.path
.basename(base
)
358 # these can go unchanged
359 obj_names
.append(os
.path
.join(output_dir
, base
+ ext
))
361 # these need to be compiled to .res-files
362 obj_names
.append(os
.path
.join(output_dir
, base
+ '.res'))
364 obj_names
.append(os
.path
.join(output_dir
, base
+ self
.obj_extension
))
367 # object_filenames ()
378 (_
, macros
, include_dirs
) = self
._fix
_compile
_args
(None, macros
, include_dirs
)
379 pp_opts
= gen_preprocess_options(macros
, include_dirs
)
380 pp_args
= ['cpp32.exe'] + pp_opts
381 if output_file
is not None:
382 pp_args
.append('-o' + output_file
)
384 pp_args
[:0] = extra_preargs
386 pp_args
.extend(extra_postargs
)
387 pp_args
.append(source
)
389 # We need to preprocess: either we're being forced to, or the
390 # source file is newer than the target (or the target doesn't
392 if self
.force
or output_file
is None or newer(source
, output_file
):
394 self
.mkpath(os
.path
.dirname(output_file
))
397 except DistutilsExecError
as msg
:
399 raise CompileError(msg
)