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 16from distutils.errors import DistutilsExecError, CompileError 17from distutils.ccompiler import \ 18 CCompiler, gen_preprocess_options 19from distutils.dep_util import newer 20 21class BCPPCompiler(CCompiler) : 22 """Concrete class that implements an interface to the Borland C/C++ 23 compiler, as defined by the CCompiler abstract class. 24 """ 25 26 compiler_type = 'bcpp' 27 28 # Just set this so CCompiler's constructor doesn't barf. We currently 29 # don't use the 'set_executables()' bureaucracy provided by CCompiler, 30 # as it really isn't necessary for this sort of single-compiler class. 31 # Would be nice to have a consistent interface with UnixCCompiler, 32 # though, so it's worth thinking about. 33 executables = {} 34 35 # Private class data (need to distinguish C from C++ source for compiler) 36 _c_extensions = ['.c'] 37 _cpp_extensions = ['.cc', '.cpp', '.cxx'] 38 39 # Needed for the filename generation methods provided by the 40 # base class, CCompiler. 41 src_extensions = _c_extensions + _cpp_extensions 42 obj_extension = '.obj' 43 static_lib_extension = '.lib' 44 shared_lib_extension = '.dll' 45 static_lib_format = shared_lib_format = '%s%s' 46 exe_extension = '.exe' 47 48 49 def __init__ (self, 50 verbose=0, 51 dry_run=0, 52 force=0): 53 54 CCompiler.__init__ (self, verbose, dry_run, force) 55 56 # These executables are assumed to all be in the path. 57 # Borland doesn't seem to use any special registry settings to 58 # indicate their installation locations. 59 60 self.cc = "bcc32.exe" 61 self.linker = "ilink32.exe" 62 self.lib = "tlib.exe" 63 64 self.preprocess_options = None 65 self.compile_options = ['/tWM', '/O2', '/q', '/g0'] 66 self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] 67 68 self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] 69 self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] 70 self.ldflags_static = [] 71 self.ldflags_exe = ['/Gn', '/q', '/x'] 72 self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] 73 74 75 # -- Worker methods ------------------------------------------------ 76 77 def preprocess (self, 78 source, 79 output_file=None, 80 macros=None, 81 include_dirs=None, 82 extra_preargs=None, 83 extra_postargs=None): 84 85 (_, macros, include_dirs) = \ 86 self._fix_compile_args(None, macros, include_dirs) 87 pp_opts = gen_preprocess_options(macros, include_dirs) 88 pp_args = ['cpp32.exe'] + pp_opts 89 if output_file is not None: 90 pp_args.append('-o' + output_file) 91 if extra_preargs: 92 pp_args[:0] = extra_preargs 93 if extra_postargs: 94 pp_args.extend(extra_postargs) 95 pp_args.append(source) 96 97 # We need to preprocess: either we're being forced to, or the 98 # source file is newer than the target (or the target doesn't 99 # exist). 100 if self.force or output_file is None or newer(source, output_file): 101 if output_file: 102 self.mkpath(os.path.dirname(output_file)) 103 try: 104 self.spawn(pp_args) 105 except DistutilsExecError as msg: 106 print(msg) 107 raise CompileError(msg) 108 109 # preprocess() 110