1*cda5da8dSAndroid Build Coastguard Worker"""distutils.cygwinccompiler 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerProvides the CygwinCCompiler class, a subclass of UnixCCompiler that 4*cda5da8dSAndroid Build Coastguard Workerhandles the Cygwin port of the GNU C compiler to Windows. It also contains 5*cda5da8dSAndroid Build Coastguard Workerthe Mingw32CCompiler class which handles the mingw32 port of GCC (same as 6*cda5da8dSAndroid Build Coastguard Workercygwin in no-cygwin mode). 7*cda5da8dSAndroid Build Coastguard Worker""" 8*cda5da8dSAndroid Build Coastguard Worker 9*cda5da8dSAndroid Build Coastguard Worker# problems: 10*cda5da8dSAndroid Build Coastguard Worker# 11*cda5da8dSAndroid Build Coastguard Worker# * if you use a msvc compiled python version (1.5.2) 12*cda5da8dSAndroid Build Coastguard Worker# 1. you have to insert a __GNUC__ section in its config.h 13*cda5da8dSAndroid Build Coastguard Worker# 2. you have to generate an import library for its dll 14*cda5da8dSAndroid Build Coastguard Worker# - create a def-file for python??.dll 15*cda5da8dSAndroid Build Coastguard Worker# - create an import library using 16*cda5da8dSAndroid Build Coastguard Worker# dlltool --dllname python15.dll --def python15.def \ 17*cda5da8dSAndroid Build Coastguard Worker# --output-lib libpython15.a 18*cda5da8dSAndroid Build Coastguard Worker# 19*cda5da8dSAndroid Build Coastguard Worker# see also http://starship.python.net/crew/kernr/mingw32/Notes.html 20*cda5da8dSAndroid Build Coastguard Worker# 21*cda5da8dSAndroid Build Coastguard Worker# * We put export_symbols in a def-file, and don't use 22*cda5da8dSAndroid Build Coastguard Worker# --export-all-symbols because it doesn't worked reliable in some 23*cda5da8dSAndroid Build Coastguard Worker# tested configurations. And because other windows compilers also 24*cda5da8dSAndroid Build Coastguard Worker# need their symbols specified this no serious problem. 25*cda5da8dSAndroid Build Coastguard Worker# 26*cda5da8dSAndroid Build Coastguard Worker# tested configurations: 27*cda5da8dSAndroid Build Coastguard Worker# 28*cda5da8dSAndroid Build Coastguard Worker# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works 29*cda5da8dSAndroid Build Coastguard Worker# (after patching python's config.h and for C++ some other include files) 30*cda5da8dSAndroid Build Coastguard Worker# see also http://starship.python.net/crew/kernr/mingw32/Notes.html 31*cda5da8dSAndroid Build Coastguard Worker# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works 32*cda5da8dSAndroid Build Coastguard Worker# (ld doesn't support -shared, so we use dllwrap) 33*cda5da8dSAndroid Build Coastguard Worker# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now 34*cda5da8dSAndroid Build Coastguard Worker# - its dllwrap doesn't work, there is a bug in binutils 2.10.90 35*cda5da8dSAndroid Build Coastguard Worker# see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html 36*cda5da8dSAndroid Build Coastguard Worker# - using gcc -mdll instead dllwrap doesn't work without -static because 37*cda5da8dSAndroid Build Coastguard Worker# it tries to link against dlls instead their import libraries. (If 38*cda5da8dSAndroid Build Coastguard Worker# it finds the dll first.) 39*cda5da8dSAndroid Build Coastguard Worker# By specifying -static we force ld to link against the import libraries, 40*cda5da8dSAndroid Build Coastguard Worker# this is windows standard and there are normally not the necessary symbols 41*cda5da8dSAndroid Build Coastguard Worker# in the dlls. 42*cda5da8dSAndroid Build Coastguard Worker# *** only the version of June 2000 shows these problems 43*cda5da8dSAndroid Build Coastguard Worker# * cygwin gcc 3.2/ld 2.13.90 works 44*cda5da8dSAndroid Build Coastguard Worker# (ld supports -shared) 45*cda5da8dSAndroid Build Coastguard Worker# * mingw gcc 3.2/ld 2.13 works 46*cda5da8dSAndroid Build Coastguard Worker# (ld supports -shared) 47*cda5da8dSAndroid Build Coastguard Worker 48*cda5da8dSAndroid Build Coastguard Workerimport os 49*cda5da8dSAndroid Build Coastguard Workerimport sys 50*cda5da8dSAndroid Build Coastguard Workerimport copy 51*cda5da8dSAndroid Build Coastguard Workerfrom subprocess import Popen, PIPE, check_output 52*cda5da8dSAndroid Build Coastguard Workerimport re 53*cda5da8dSAndroid Build Coastguard Worker 54*cda5da8dSAndroid Build Coastguard Workerfrom distutils.unixccompiler import UnixCCompiler 55*cda5da8dSAndroid Build Coastguard Workerfrom distutils.file_util import write_file 56*cda5da8dSAndroid Build Coastguard Workerfrom distutils.errors import (DistutilsExecError, CCompilerError, 57*cda5da8dSAndroid Build Coastguard Worker CompileError, UnknownFileError) 58*cda5da8dSAndroid Build Coastguard Workerfrom distutils.version import LooseVersion 59*cda5da8dSAndroid Build Coastguard Workerfrom distutils.spawn import find_executable 60*cda5da8dSAndroid Build Coastguard Worker 61*cda5da8dSAndroid Build Coastguard Workerdef get_msvcr(): 62*cda5da8dSAndroid Build Coastguard Worker """Include the appropriate MSVC runtime library if Python was built 63*cda5da8dSAndroid Build Coastguard Worker with MSVC 7.0 or later. 64*cda5da8dSAndroid Build Coastguard Worker """ 65*cda5da8dSAndroid Build Coastguard Worker msc_pos = sys.version.find('MSC v.') 66*cda5da8dSAndroid Build Coastguard Worker if msc_pos != -1: 67*cda5da8dSAndroid Build Coastguard Worker msc_ver = sys.version[msc_pos+6:msc_pos+10] 68*cda5da8dSAndroid Build Coastguard Worker if msc_ver == '1300': 69*cda5da8dSAndroid Build Coastguard Worker # MSVC 7.0 70*cda5da8dSAndroid Build Coastguard Worker return ['msvcr70'] 71*cda5da8dSAndroid Build Coastguard Worker elif msc_ver == '1310': 72*cda5da8dSAndroid Build Coastguard Worker # MSVC 7.1 73*cda5da8dSAndroid Build Coastguard Worker return ['msvcr71'] 74*cda5da8dSAndroid Build Coastguard Worker elif msc_ver == '1400': 75*cda5da8dSAndroid Build Coastguard Worker # VS2005 / MSVC 8.0 76*cda5da8dSAndroid Build Coastguard Worker return ['msvcr80'] 77*cda5da8dSAndroid Build Coastguard Worker elif msc_ver == '1500': 78*cda5da8dSAndroid Build Coastguard Worker # VS2008 / MSVC 9.0 79*cda5da8dSAndroid Build Coastguard Worker return ['msvcr90'] 80*cda5da8dSAndroid Build Coastguard Worker elif msc_ver == '1600': 81*cda5da8dSAndroid Build Coastguard Worker # VS2010 / MSVC 10.0 82*cda5da8dSAndroid Build Coastguard Worker return ['msvcr100'] 83*cda5da8dSAndroid Build Coastguard Worker else: 84*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Unknown MS Compiler version %s " % msc_ver) 85*cda5da8dSAndroid Build Coastguard Worker 86*cda5da8dSAndroid Build Coastguard Worker 87*cda5da8dSAndroid Build Coastguard Workerclass CygwinCCompiler(UnixCCompiler): 88*cda5da8dSAndroid Build Coastguard Worker """ Handles the Cygwin port of the GNU C compiler to Windows. 89*cda5da8dSAndroid Build Coastguard Worker """ 90*cda5da8dSAndroid Build Coastguard Worker compiler_type = 'cygwin' 91*cda5da8dSAndroid Build Coastguard Worker obj_extension = ".o" 92*cda5da8dSAndroid Build Coastguard Worker static_lib_extension = ".a" 93*cda5da8dSAndroid Build Coastguard Worker shared_lib_extension = ".dll" 94*cda5da8dSAndroid Build Coastguard Worker static_lib_format = "lib%s%s" 95*cda5da8dSAndroid Build Coastguard Worker shared_lib_format = "%s%s" 96*cda5da8dSAndroid Build Coastguard Worker exe_extension = ".exe" 97*cda5da8dSAndroid Build Coastguard Worker 98*cda5da8dSAndroid Build Coastguard Worker def __init__(self, verbose=0, dry_run=0, force=0): 99*cda5da8dSAndroid Build Coastguard Worker 100*cda5da8dSAndroid Build Coastguard Worker UnixCCompiler.__init__(self, verbose, dry_run, force) 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Worker status, details = check_config_h() 103*cda5da8dSAndroid Build Coastguard Worker self.debug_print("Python's GCC status: %s (details: %s)" % 104*cda5da8dSAndroid Build Coastguard Worker (status, details)) 105*cda5da8dSAndroid Build Coastguard Worker if status is not CONFIG_H_OK: 106*cda5da8dSAndroid Build Coastguard Worker self.warn( 107*cda5da8dSAndroid Build Coastguard Worker "Python's pyconfig.h doesn't seem to support your compiler. " 108*cda5da8dSAndroid Build Coastguard Worker "Reason: %s. " 109*cda5da8dSAndroid Build Coastguard Worker "Compiling may fail because of undefined preprocessor macros." 110*cda5da8dSAndroid Build Coastguard Worker % details) 111*cda5da8dSAndroid Build Coastguard Worker 112*cda5da8dSAndroid Build Coastguard Worker self.gcc_version, self.ld_version, self.dllwrap_version = \ 113*cda5da8dSAndroid Build Coastguard Worker get_versions() 114*cda5da8dSAndroid Build Coastguard Worker self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % 115*cda5da8dSAndroid Build Coastguard Worker (self.gcc_version, 116*cda5da8dSAndroid Build Coastguard Worker self.ld_version, 117*cda5da8dSAndroid Build Coastguard Worker self.dllwrap_version) ) 118*cda5da8dSAndroid Build Coastguard Worker 119*cda5da8dSAndroid Build Coastguard Worker # ld_version >= "2.10.90" and < "2.13" should also be able to use 120*cda5da8dSAndroid Build Coastguard Worker # gcc -mdll instead of dllwrap 121*cda5da8dSAndroid Build Coastguard Worker # Older dllwraps had own version numbers, newer ones use the 122*cda5da8dSAndroid Build Coastguard Worker # same as the rest of binutils ( also ld ) 123*cda5da8dSAndroid Build Coastguard Worker # dllwrap 2.10.90 is buggy 124*cda5da8dSAndroid Build Coastguard Worker if self.ld_version >= "2.10.90": 125*cda5da8dSAndroid Build Coastguard Worker self.linker_dll = "gcc" 126*cda5da8dSAndroid Build Coastguard Worker else: 127*cda5da8dSAndroid Build Coastguard Worker self.linker_dll = "dllwrap" 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Worker # ld_version >= "2.13" support -shared so use it instead of 130*cda5da8dSAndroid Build Coastguard Worker # -mdll -static 131*cda5da8dSAndroid Build Coastguard Worker if self.ld_version >= "2.13": 132*cda5da8dSAndroid Build Coastguard Worker shared_option = "-shared" 133*cda5da8dSAndroid Build Coastguard Worker else: 134*cda5da8dSAndroid Build Coastguard Worker shared_option = "-mdll -static" 135*cda5da8dSAndroid Build Coastguard Worker 136*cda5da8dSAndroid Build Coastguard Worker # Hard-code GCC because that's what this is all about. 137*cda5da8dSAndroid Build Coastguard Worker # XXX optimization, warnings etc. should be customizable. 138*cda5da8dSAndroid Build Coastguard Worker self.set_executables(compiler='gcc -mcygwin -O -Wall', 139*cda5da8dSAndroid Build Coastguard Worker compiler_so='gcc -mcygwin -mdll -O -Wall', 140*cda5da8dSAndroid Build Coastguard Worker compiler_cxx='g++ -mcygwin -O -Wall', 141*cda5da8dSAndroid Build Coastguard Worker linker_exe='gcc -mcygwin', 142*cda5da8dSAndroid Build Coastguard Worker linker_so=('%s -mcygwin %s' % 143*cda5da8dSAndroid Build Coastguard Worker (self.linker_dll, shared_option))) 144*cda5da8dSAndroid Build Coastguard Worker 145*cda5da8dSAndroid Build Coastguard Worker # cygwin and mingw32 need different sets of libraries 146*cda5da8dSAndroid Build Coastguard Worker if self.gcc_version == "2.91.57": 147*cda5da8dSAndroid Build Coastguard Worker # cygwin shouldn't need msvcrt, but without the dlls will crash 148*cda5da8dSAndroid Build Coastguard Worker # (gcc version 2.91.57) -- perhaps something about initialization 149*cda5da8dSAndroid Build Coastguard Worker self.dll_libraries=["msvcrt"] 150*cda5da8dSAndroid Build Coastguard Worker self.warn( 151*cda5da8dSAndroid Build Coastguard Worker "Consider upgrading to a newer version of gcc") 152*cda5da8dSAndroid Build Coastguard Worker else: 153*cda5da8dSAndroid Build Coastguard Worker # Include the appropriate MSVC runtime library if Python was built 154*cda5da8dSAndroid Build Coastguard Worker # with MSVC 7.0 or later. 155*cda5da8dSAndroid Build Coastguard Worker self.dll_libraries = get_msvcr() 156*cda5da8dSAndroid Build Coastguard Worker 157*cda5da8dSAndroid Build Coastguard Worker def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): 158*cda5da8dSAndroid Build Coastguard Worker """Compiles the source by spawning GCC and windres if needed.""" 159*cda5da8dSAndroid Build Coastguard Worker if ext == '.rc' or ext == '.res': 160*cda5da8dSAndroid Build Coastguard Worker # gcc needs '.res' and '.rc' compiled to object files !!! 161*cda5da8dSAndroid Build Coastguard Worker try: 162*cda5da8dSAndroid Build Coastguard Worker self.spawn(["windres", "-i", src, "-o", obj]) 163*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 164*cda5da8dSAndroid Build Coastguard Worker raise CompileError(msg) 165*cda5da8dSAndroid Build Coastguard Worker else: # for other files use the C-compiler 166*cda5da8dSAndroid Build Coastguard Worker try: 167*cda5da8dSAndroid Build Coastguard Worker self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + 168*cda5da8dSAndroid Build Coastguard Worker extra_postargs) 169*cda5da8dSAndroid Build Coastguard Worker except DistutilsExecError as msg: 170*cda5da8dSAndroid Build Coastguard Worker raise CompileError(msg) 171*cda5da8dSAndroid Build Coastguard Worker 172*cda5da8dSAndroid Build Coastguard Worker def link(self, target_desc, objects, output_filename, output_dir=None, 173*cda5da8dSAndroid Build Coastguard Worker libraries=None, library_dirs=None, runtime_library_dirs=None, 174*cda5da8dSAndroid Build Coastguard Worker export_symbols=None, debug=0, extra_preargs=None, 175*cda5da8dSAndroid Build Coastguard Worker extra_postargs=None, build_temp=None, target_lang=None): 176*cda5da8dSAndroid Build Coastguard Worker """Link the objects.""" 177*cda5da8dSAndroid Build Coastguard Worker # use separate copies, so we can modify the lists 178*cda5da8dSAndroid Build Coastguard Worker extra_preargs = copy.copy(extra_preargs or []) 179*cda5da8dSAndroid Build Coastguard Worker libraries = copy.copy(libraries or []) 180*cda5da8dSAndroid Build Coastguard Worker objects = copy.copy(objects or []) 181*cda5da8dSAndroid Build Coastguard Worker 182*cda5da8dSAndroid Build Coastguard Worker # Additional libraries 183*cda5da8dSAndroid Build Coastguard Worker libraries.extend(self.dll_libraries) 184*cda5da8dSAndroid Build Coastguard Worker 185*cda5da8dSAndroid Build Coastguard Worker # handle export symbols by creating a def-file 186*cda5da8dSAndroid Build Coastguard Worker # with executables this only works with gcc/ld as linker 187*cda5da8dSAndroid Build Coastguard Worker if ((export_symbols is not None) and 188*cda5da8dSAndroid Build Coastguard Worker (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): 189*cda5da8dSAndroid Build Coastguard Worker # (The linker doesn't do anything if output is up-to-date. 190*cda5da8dSAndroid Build Coastguard Worker # So it would probably better to check if we really need this, 191*cda5da8dSAndroid Build Coastguard Worker # but for this we had to insert some unchanged parts of 192*cda5da8dSAndroid Build Coastguard Worker # UnixCCompiler, and this is not what we want.) 193*cda5da8dSAndroid Build Coastguard Worker 194*cda5da8dSAndroid Build Coastguard Worker # we want to put some files in the same directory as the 195*cda5da8dSAndroid Build Coastguard Worker # object files are, build_temp doesn't help much 196*cda5da8dSAndroid Build Coastguard Worker # where are the object files 197*cda5da8dSAndroid Build Coastguard Worker temp_dir = os.path.dirname(objects[0]) 198*cda5da8dSAndroid Build Coastguard Worker # name of dll to give the helper files the same base name 199*cda5da8dSAndroid Build Coastguard Worker (dll_name, dll_extension) = os.path.splitext( 200*cda5da8dSAndroid Build Coastguard Worker os.path.basename(output_filename)) 201*cda5da8dSAndroid Build Coastguard Worker 202*cda5da8dSAndroid Build Coastguard Worker # generate the filenames for these files 203*cda5da8dSAndroid Build Coastguard Worker def_file = os.path.join(temp_dir, dll_name + ".def") 204*cda5da8dSAndroid Build Coastguard Worker lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") 205*cda5da8dSAndroid Build Coastguard Worker 206*cda5da8dSAndroid Build Coastguard Worker # Generate .def file 207*cda5da8dSAndroid Build Coastguard Worker contents = [ 208*cda5da8dSAndroid Build Coastguard Worker "LIBRARY %s" % os.path.basename(output_filename), 209*cda5da8dSAndroid Build Coastguard Worker "EXPORTS"] 210*cda5da8dSAndroid Build Coastguard Worker for sym in export_symbols: 211*cda5da8dSAndroid Build Coastguard Worker contents.append(sym) 212*cda5da8dSAndroid Build Coastguard Worker self.execute(write_file, (def_file, contents), 213*cda5da8dSAndroid Build Coastguard Worker "writing %s" % def_file) 214*cda5da8dSAndroid Build Coastguard Worker 215*cda5da8dSAndroid Build Coastguard Worker # next add options for def-file and to creating import libraries 216*cda5da8dSAndroid Build Coastguard Worker 217*cda5da8dSAndroid Build Coastguard Worker # dllwrap uses different options than gcc/ld 218*cda5da8dSAndroid Build Coastguard Worker if self.linker_dll == "dllwrap": 219*cda5da8dSAndroid Build Coastguard Worker extra_preargs.extend(["--output-lib", lib_file]) 220*cda5da8dSAndroid Build Coastguard Worker # for dllwrap we have to use a special option 221*cda5da8dSAndroid Build Coastguard Worker extra_preargs.extend(["--def", def_file]) 222*cda5da8dSAndroid Build Coastguard Worker # we use gcc/ld here and can be sure ld is >= 2.9.10 223*cda5da8dSAndroid Build Coastguard Worker else: 224*cda5da8dSAndroid Build Coastguard Worker # doesn't work: bfd_close build\...\libfoo.a: Invalid operation 225*cda5da8dSAndroid Build Coastguard Worker #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) 226*cda5da8dSAndroid Build Coastguard Worker # for gcc/ld the def-file is specified as any object files 227*cda5da8dSAndroid Build Coastguard Worker objects.append(def_file) 228*cda5da8dSAndroid Build Coastguard Worker 229*cda5da8dSAndroid Build Coastguard Worker #end: if ((export_symbols is not None) and 230*cda5da8dSAndroid Build Coastguard Worker # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): 231*cda5da8dSAndroid Build Coastguard Worker 232*cda5da8dSAndroid Build Coastguard Worker # who wants symbols and a many times larger output file 233*cda5da8dSAndroid Build Coastguard Worker # should explicitly switch the debug mode on 234*cda5da8dSAndroid Build Coastguard Worker # otherwise we let dllwrap/ld strip the output file 235*cda5da8dSAndroid Build Coastguard Worker # (On my machine: 10KiB < stripped_file < ??100KiB 236*cda5da8dSAndroid Build Coastguard Worker # unstripped_file = stripped_file + XXX KiB 237*cda5da8dSAndroid Build Coastguard Worker # ( XXX=254 for a typical python extension)) 238*cda5da8dSAndroid Build Coastguard Worker if not debug: 239*cda5da8dSAndroid Build Coastguard Worker extra_preargs.append("-s") 240*cda5da8dSAndroid Build Coastguard Worker 241*cda5da8dSAndroid Build Coastguard Worker UnixCCompiler.link(self, target_desc, objects, output_filename, 242*cda5da8dSAndroid Build Coastguard Worker output_dir, libraries, library_dirs, 243*cda5da8dSAndroid Build Coastguard Worker runtime_library_dirs, 244*cda5da8dSAndroid Build Coastguard Worker None, # export_symbols, we do this in our def-file 245*cda5da8dSAndroid Build Coastguard Worker debug, extra_preargs, extra_postargs, build_temp, 246*cda5da8dSAndroid Build Coastguard Worker target_lang) 247*cda5da8dSAndroid Build Coastguard Worker 248*cda5da8dSAndroid Build Coastguard Worker # -- Miscellaneous methods ----------------------------------------- 249*cda5da8dSAndroid Build Coastguard Worker 250*cda5da8dSAndroid Build Coastguard Worker def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): 251*cda5da8dSAndroid Build Coastguard Worker """Adds supports for rc and res files.""" 252*cda5da8dSAndroid Build Coastguard Worker if output_dir is None: 253*cda5da8dSAndroid Build Coastguard Worker output_dir = '' 254*cda5da8dSAndroid Build Coastguard Worker obj_names = [] 255*cda5da8dSAndroid Build Coastguard Worker for src_name in source_filenames: 256*cda5da8dSAndroid Build Coastguard Worker # use normcase to make sure '.rc' is really '.rc' and not '.RC' 257*cda5da8dSAndroid Build Coastguard Worker base, ext = os.path.splitext(os.path.normcase(src_name)) 258*cda5da8dSAndroid Build Coastguard Worker if ext not in (self.src_extensions + ['.rc','.res']): 259*cda5da8dSAndroid Build Coastguard Worker raise UnknownFileError("unknown file type '%s' (from '%s')" % \ 260*cda5da8dSAndroid Build Coastguard Worker (ext, src_name)) 261*cda5da8dSAndroid Build Coastguard Worker if strip_dir: 262*cda5da8dSAndroid Build Coastguard Worker base = os.path.basename (base) 263*cda5da8dSAndroid Build Coastguard Worker if ext in ('.res', '.rc'): 264*cda5da8dSAndroid Build Coastguard Worker # these need to be compiled to object files 265*cda5da8dSAndroid Build Coastguard Worker obj_names.append (os.path.join(output_dir, 266*cda5da8dSAndroid Build Coastguard Worker base + ext + self.obj_extension)) 267*cda5da8dSAndroid Build Coastguard Worker else: 268*cda5da8dSAndroid Build Coastguard Worker obj_names.append (os.path.join(output_dir, 269*cda5da8dSAndroid Build Coastguard Worker base + self.obj_extension)) 270*cda5da8dSAndroid Build Coastguard Worker return obj_names 271*cda5da8dSAndroid Build Coastguard Worker 272*cda5da8dSAndroid Build Coastguard Worker# the same as cygwin plus some additional parameters 273*cda5da8dSAndroid Build Coastguard Workerclass Mingw32CCompiler(CygwinCCompiler): 274*cda5da8dSAndroid Build Coastguard Worker """ Handles the Mingw32 port of the GNU C compiler to Windows. 275*cda5da8dSAndroid Build Coastguard Worker """ 276*cda5da8dSAndroid Build Coastguard Worker compiler_type = 'mingw32' 277*cda5da8dSAndroid Build Coastguard Worker 278*cda5da8dSAndroid Build Coastguard Worker def __init__(self, verbose=0, dry_run=0, force=0): 279*cda5da8dSAndroid Build Coastguard Worker 280*cda5da8dSAndroid Build Coastguard Worker CygwinCCompiler.__init__ (self, verbose, dry_run, force) 281*cda5da8dSAndroid Build Coastguard Worker 282*cda5da8dSAndroid Build Coastguard Worker # ld_version >= "2.13" support -shared so use it instead of 283*cda5da8dSAndroid Build Coastguard Worker # -mdll -static 284*cda5da8dSAndroid Build Coastguard Worker if self.ld_version >= "2.13": 285*cda5da8dSAndroid Build Coastguard Worker shared_option = "-shared" 286*cda5da8dSAndroid Build Coastguard Worker else: 287*cda5da8dSAndroid Build Coastguard Worker shared_option = "-mdll -static" 288*cda5da8dSAndroid Build Coastguard Worker 289*cda5da8dSAndroid Build Coastguard Worker # A real mingw32 doesn't need to specify a different entry point, 290*cda5da8dSAndroid Build Coastguard Worker # but cygwin 2.91.57 in no-cygwin-mode needs it. 291*cda5da8dSAndroid Build Coastguard Worker if self.gcc_version <= "2.91.57": 292*cda5da8dSAndroid Build Coastguard Worker entry_point = '--entry _DllMain@12' 293*cda5da8dSAndroid Build Coastguard Worker else: 294*cda5da8dSAndroid Build Coastguard Worker entry_point = '' 295*cda5da8dSAndroid Build Coastguard Worker 296*cda5da8dSAndroid Build Coastguard Worker if is_cygwingcc(): 297*cda5da8dSAndroid Build Coastguard Worker raise CCompilerError( 298*cda5da8dSAndroid Build Coastguard Worker 'Cygwin gcc cannot be used with --compiler=mingw32') 299*cda5da8dSAndroid Build Coastguard Worker 300*cda5da8dSAndroid Build Coastguard Worker self.set_executables(compiler='gcc -O -Wall', 301*cda5da8dSAndroid Build Coastguard Worker compiler_so='gcc -mdll -O -Wall', 302*cda5da8dSAndroid Build Coastguard Worker compiler_cxx='g++ -O -Wall', 303*cda5da8dSAndroid Build Coastguard Worker linker_exe='gcc', 304*cda5da8dSAndroid Build Coastguard Worker linker_so='%s %s %s' 305*cda5da8dSAndroid Build Coastguard Worker % (self.linker_dll, shared_option, 306*cda5da8dSAndroid Build Coastguard Worker entry_point)) 307*cda5da8dSAndroid Build Coastguard Worker # Maybe we should also append -mthreads, but then the finished 308*cda5da8dSAndroid Build Coastguard Worker # dlls need another dll (mingwm10.dll see Mingw32 docs) 309*cda5da8dSAndroid Build Coastguard Worker # (-mthreads: Support thread-safe exception handling on `Mingw32') 310*cda5da8dSAndroid Build Coastguard Worker 311*cda5da8dSAndroid Build Coastguard Worker # no additional libraries needed 312*cda5da8dSAndroid Build Coastguard Worker self.dll_libraries=[] 313*cda5da8dSAndroid Build Coastguard Worker 314*cda5da8dSAndroid Build Coastguard Worker # Include the appropriate MSVC runtime library if Python was built 315*cda5da8dSAndroid Build Coastguard Worker # with MSVC 7.0 or later. 316*cda5da8dSAndroid Build Coastguard Worker self.dll_libraries = get_msvcr() 317*cda5da8dSAndroid Build Coastguard Worker 318*cda5da8dSAndroid Build Coastguard Worker# Because these compilers aren't configured in Python's pyconfig.h file by 319*cda5da8dSAndroid Build Coastguard Worker# default, we should at least warn the user if he is using an unmodified 320*cda5da8dSAndroid Build Coastguard Worker# version. 321*cda5da8dSAndroid Build Coastguard Worker 322*cda5da8dSAndroid Build Coastguard WorkerCONFIG_H_OK = "ok" 323*cda5da8dSAndroid Build Coastguard WorkerCONFIG_H_NOTOK = "not ok" 324*cda5da8dSAndroid Build Coastguard WorkerCONFIG_H_UNCERTAIN = "uncertain" 325*cda5da8dSAndroid Build Coastguard Worker 326*cda5da8dSAndroid Build Coastguard Workerdef check_config_h(): 327*cda5da8dSAndroid Build Coastguard Worker """Check if the current Python installation appears amenable to building 328*cda5da8dSAndroid Build Coastguard Worker extensions with GCC. 329*cda5da8dSAndroid Build Coastguard Worker 330*cda5da8dSAndroid Build Coastguard Worker Returns a tuple (status, details), where 'status' is one of the following 331*cda5da8dSAndroid Build Coastguard Worker constants: 332*cda5da8dSAndroid Build Coastguard Worker 333*cda5da8dSAndroid Build Coastguard Worker - CONFIG_H_OK: all is well, go ahead and compile 334*cda5da8dSAndroid Build Coastguard Worker - CONFIG_H_NOTOK: doesn't look good 335*cda5da8dSAndroid Build Coastguard Worker - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h 336*cda5da8dSAndroid Build Coastguard Worker 337*cda5da8dSAndroid Build Coastguard Worker 'details' is a human-readable string explaining the situation. 338*cda5da8dSAndroid Build Coastguard Worker 339*cda5da8dSAndroid Build Coastguard Worker Note there are two ways to conclude "OK": either 'sys.version' contains 340*cda5da8dSAndroid Build Coastguard Worker the string "GCC" (implying that this Python was built with GCC), or the 341*cda5da8dSAndroid Build Coastguard Worker installed "pyconfig.h" contains the string "__GNUC__". 342*cda5da8dSAndroid Build Coastguard Worker """ 343*cda5da8dSAndroid Build Coastguard Worker 344*cda5da8dSAndroid Build Coastguard Worker # XXX since this function also checks sys.version, it's not strictly a 345*cda5da8dSAndroid Build Coastguard Worker # "pyconfig.h" check -- should probably be renamed... 346*cda5da8dSAndroid Build Coastguard Worker 347*cda5da8dSAndroid Build Coastguard Worker from distutils import sysconfig 348*cda5da8dSAndroid Build Coastguard Worker 349*cda5da8dSAndroid Build Coastguard Worker # if sys.version contains GCC then python was compiled with GCC, and the 350*cda5da8dSAndroid Build Coastguard Worker # pyconfig.h file should be OK 351*cda5da8dSAndroid Build Coastguard Worker if "GCC" in sys.version: 352*cda5da8dSAndroid Build Coastguard Worker return CONFIG_H_OK, "sys.version mentions 'GCC'" 353*cda5da8dSAndroid Build Coastguard Worker 354*cda5da8dSAndroid Build Coastguard Worker # let's see if __GNUC__ is mentioned in python.h 355*cda5da8dSAndroid Build Coastguard Worker fn = sysconfig.get_config_h_filename() 356*cda5da8dSAndroid Build Coastguard Worker try: 357*cda5da8dSAndroid Build Coastguard Worker config_h = open(fn) 358*cda5da8dSAndroid Build Coastguard Worker try: 359*cda5da8dSAndroid Build Coastguard Worker if "__GNUC__" in config_h.read(): 360*cda5da8dSAndroid Build Coastguard Worker return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn 361*cda5da8dSAndroid Build Coastguard Worker else: 362*cda5da8dSAndroid Build Coastguard Worker return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn 363*cda5da8dSAndroid Build Coastguard Worker finally: 364*cda5da8dSAndroid Build Coastguard Worker config_h.close() 365*cda5da8dSAndroid Build Coastguard Worker except OSError as exc: 366*cda5da8dSAndroid Build Coastguard Worker return (CONFIG_H_UNCERTAIN, 367*cda5da8dSAndroid Build Coastguard Worker "couldn't read '%s': %s" % (fn, exc.strerror)) 368*cda5da8dSAndroid Build Coastguard Worker 369*cda5da8dSAndroid Build Coastguard WorkerRE_VERSION = re.compile(br'(\d+\.\d+(\.\d+)*)') 370*cda5da8dSAndroid Build Coastguard Worker 371*cda5da8dSAndroid Build Coastguard Workerdef _find_exe_version(cmd): 372*cda5da8dSAndroid Build Coastguard Worker """Find the version of an executable by running `cmd` in the shell. 373*cda5da8dSAndroid Build Coastguard Worker 374*cda5da8dSAndroid Build Coastguard Worker If the command is not found, or the output does not match 375*cda5da8dSAndroid Build Coastguard Worker `RE_VERSION`, returns None. 376*cda5da8dSAndroid Build Coastguard Worker """ 377*cda5da8dSAndroid Build Coastguard Worker executable = cmd.split()[0] 378*cda5da8dSAndroid Build Coastguard Worker if find_executable(executable) is None: 379*cda5da8dSAndroid Build Coastguard Worker return None 380*cda5da8dSAndroid Build Coastguard Worker out = Popen(cmd, shell=True, stdout=PIPE).stdout 381*cda5da8dSAndroid Build Coastguard Worker try: 382*cda5da8dSAndroid Build Coastguard Worker out_string = out.read() 383*cda5da8dSAndroid Build Coastguard Worker finally: 384*cda5da8dSAndroid Build Coastguard Worker out.close() 385*cda5da8dSAndroid Build Coastguard Worker result = RE_VERSION.search(out_string) 386*cda5da8dSAndroid Build Coastguard Worker if result is None: 387*cda5da8dSAndroid Build Coastguard Worker return None 388*cda5da8dSAndroid Build Coastguard Worker # LooseVersion works with strings 389*cda5da8dSAndroid Build Coastguard Worker # so we need to decode our bytes 390*cda5da8dSAndroid Build Coastguard Worker return LooseVersion(result.group(1).decode()) 391*cda5da8dSAndroid Build Coastguard Worker 392*cda5da8dSAndroid Build Coastguard Workerdef get_versions(): 393*cda5da8dSAndroid Build Coastguard Worker """ Try to find out the versions of gcc, ld and dllwrap. 394*cda5da8dSAndroid Build Coastguard Worker 395*cda5da8dSAndroid Build Coastguard Worker If not possible it returns None for it. 396*cda5da8dSAndroid Build Coastguard Worker """ 397*cda5da8dSAndroid Build Coastguard Worker commands = ['gcc -dumpversion', 'ld -v', 'dllwrap --version'] 398*cda5da8dSAndroid Build Coastguard Worker return tuple([_find_exe_version(cmd) for cmd in commands]) 399*cda5da8dSAndroid Build Coastguard Worker 400*cda5da8dSAndroid Build Coastguard Workerdef is_cygwingcc(): 401*cda5da8dSAndroid Build Coastguard Worker '''Try to determine if the gcc that would be used is from cygwin.''' 402*cda5da8dSAndroid Build Coastguard Worker out_string = check_output(['gcc', '-dumpmachine']) 403*cda5da8dSAndroid Build Coastguard Worker return out_string.strip().endswith(b'cygwin') 404