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