cygwinccompiler.py (8354B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\cygwinccompiler.py 2 __revision__ = '$Id: cygwinccompiler.py 87602 2011-01-01 04:24:26Z richard.tew $' 3 import os, sys, copy 4 from distutils.ccompiler import gen_preprocess_options, gen_lib_options 5 from distutils.unixccompiler import UnixCCompiler 6 from distutils.file_util import write_file 7 from distutils.errors import DistutilsExecError, CompileError, UnknownFileError 8 from distutils import log 9 10 def get_msvcr(): 11 msc_pos = sys.version.find('MSC v.') 12 if msc_pos != -1: 13 msc_ver = sys.version[msc_pos + 6:msc_pos + 10] 14 if msc_ver == '1300': 15 return ['msvcr70'] 16 if msc_ver == '1310': 17 return ['msvcr71'] 18 if msc_ver == '1400': 19 return ['msvcr80'] 20 if msc_ver == '1500': 21 return ['msvcr90'] 22 raise ValueError('Unknown MS Compiler version %s ' % msc_ver) 23 24 25 class CygwinCCompiler(UnixCCompiler): 26 compiler_type = 'cygwin' 27 obj_extension = '.o' 28 static_lib_extension = '.a' 29 shared_lib_extension = '.dll' 30 static_lib_format = 'lib%s%s' 31 shared_lib_format = '%s%s' 32 exe_extension = '.exe' 33 34 def __init__(self, verbose = 0, dry_run = 0, force = 0): 35 UnixCCompiler.__init__(self, verbose, dry_run, force) 36 status, details = check_config_h() 37 self.debug_print("Python's GCC status: %s (details: %s)" % (status, details)) 38 if status is not CONFIG_H_OK: 39 self.warn("Python's pyconfig.h doesn't seem to support your compiler. Reason: %s. Compiling may fail because of undefined preprocessor macros." % details) 40 self.gcc_version, self.ld_version, self.dllwrap_version = get_versions() 41 self.debug_print(self.compiler_type + ': gcc %s, ld %s, dllwrap %s\n' % (self.gcc_version, self.ld_version, self.dllwrap_version)) 42 if self.ld_version >= '2.10.90': 43 self.linker_dll = 'gcc' 44 else: 45 self.linker_dll = 'dllwrap' 46 if self.ld_version >= '2.13': 47 shared_option = '-shared' 48 else: 49 shared_option = '-mdll -static' 50 self.set_executables(compiler='gcc -mcygwin -O -Wall', compiler_so='gcc -mcygwin -mdll -O -Wall', compiler_cxx='g++ -mcygwin -O -Wall', linker_exe='gcc -mcygwin', linker_so='%s -mcygwin %s' % (self.linker_dll, shared_option)) 51 if self.gcc_version == '2.91.57': 52 self.dll_libraries = ['msvcrt'] 53 self.warn('Consider upgrading to a newer version of gcc') 54 else: 55 self.dll_libraries = get_msvcr() 56 57 def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): 58 if ext == '.rc' or ext == '.res': 59 try: 60 self.spawn(['windres', 61 '-i', 62 src, 63 '-o', 64 obj]) 65 except DistutilsExecError as msg: 66 raise CompileError, msg 67 68 else: 69 try: 70 self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs) 71 except DistutilsExecError as msg: 72 raise CompileError, msg 73 74 def link(self, target_desc, objects, output_filename, output_dir = None, libraries = None, library_dirs = None, runtime_library_dirs = None, export_symbols = None, debug = 0, extra_preargs = None, extra_postargs = None, build_temp = None, target_lang = None): 75 extra_preargs = copy.copy(extra_preargs or []) 76 libraries = copy.copy(libraries or []) 77 objects = copy.copy(objects or []) 78 libraries.extend(self.dll_libraries) 79 if export_symbols is not None and (target_desc != self.EXECUTABLE or self.linker_dll == 'gcc'): 80 temp_dir = os.path.dirname(objects[0]) 81 dll_name, dll_extension = os.path.splitext(os.path.basename(output_filename)) 82 def_file = os.path.join(temp_dir, dll_name + '.def') 83 lib_file = os.path.join(temp_dir, 'lib' + dll_name + '.a') 84 contents = ['LIBRARY %s' % os.path.basename(output_filename), 'EXPORTS'] 85 for sym in export_symbols: 86 contents.append(sym) 87 88 self.execute(write_file, (def_file, contents), 'writing %s' % def_file) 89 if self.linker_dll == 'dllwrap': 90 extra_preargs.extend(['--output-lib', lib_file]) 91 extra_preargs.extend(['--def', def_file]) 92 else: 93 objects.append(def_file) 94 if not debug: 95 extra_preargs.append('-s') 96 UnixCCompiler.link(self, target_desc, objects, output_filename, output_dir, libraries, library_dirs, runtime_library_dirs, None, debug, extra_preargs, extra_postargs, build_temp, target_lang) 97 98 def object_filenames(self, source_filenames, strip_dir = 0, output_dir = ''): 99 if output_dir is None: 100 output_dir = '' 101 obj_names = [] 102 for src_name in source_filenames: 103 base, ext = os.path.splitext(os.path.normcase(src_name)) 104 if ext not in self.src_extensions + ['.rc', '.res']: 105 raise UnknownFileError, "unknown file type '%s' (from '%s')" % (ext, src_name) 106 if strip_dir: 107 base = os.path.basename(base) 108 if ext == '.res' or ext == '.rc': 109 obj_names.append(os.path.join(output_dir, base + ext + self.obj_extension)) 110 else: 111 obj_names.append(os.path.join(output_dir, base + self.obj_extension)) 112 113 return obj_names 114 115 116 class Mingw32CCompiler(CygwinCCompiler): 117 compiler_type = 'mingw32' 118 119 def __init__(self, verbose = 0, dry_run = 0, force = 0): 120 CygwinCCompiler.__init__(self, verbose, dry_run, force) 121 if self.ld_version >= '2.13': 122 shared_option = '-shared' 123 else: 124 shared_option = '-mdll -static' 125 if self.gcc_version <= '2.91.57': 126 entry_point = '--entry _DllMain@12' 127 else: 128 entry_point = '' 129 self.set_executables(compiler='gcc -mno-cygwin -O -Wall', compiler_so='gcc -mno-cygwin -mdll -O -Wall', compiler_cxx='g++ -mno-cygwin -O -Wall', linker_exe='gcc -mno-cygwin', linker_so='%s -mno-cygwin %s %s' % (self.linker_dll, shared_option, entry_point)) 130 self.dll_libraries = [] 131 self.dll_libraries = get_msvcr() 132 133 134 CONFIG_H_OK = 'ok' 135 CONFIG_H_NOTOK = 'not ok' 136 CONFIG_H_UNCERTAIN = 'uncertain' 137 138 def check_config_h(): 139 from distutils import sysconfig 140 import string 141 if string.find(sys.version, 'GCC') >= 0: 142 return (CONFIG_H_OK, "sys.version mentions 'GCC'") 143 fn = sysconfig.get_config_h_filename() 144 try: 145 f = open(fn) 146 try: 147 s = f.read() 148 finally: 149 f.close() 150 151 except IOError as exc: 152 return (CONFIG_H_UNCERTAIN, "couldn't read '%s': %s" % (fn, exc.strerror)) 153 154 if string.find(s, '__GNUC__') >= 0: 155 return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn) 156 else: 157 return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn) 158 159 160 def get_versions(): 161 from distutils.version import LooseVersion 162 from distutils.spawn import find_executable 163 import re 164 gcc_exe = find_executable('gcc') 165 if gcc_exe: 166 out = os.popen(gcc_exe + ' -dumpversion', 'r') 167 out_string = out.read() 168 out.close() 169 result = re.search('(\\d+\\.\\d+(\\.\\d+)*)', out_string) 170 if result: 171 gcc_version = LooseVersion(result.group(1)) 172 else: 173 gcc_version = None 174 else: 175 gcc_version = None 176 ld_exe = find_executable('ld') 177 if ld_exe: 178 out = os.popen(ld_exe + ' -v', 'r') 179 out_string = out.read() 180 out.close() 181 result = re.search('(\\d+\\.\\d+(\\.\\d+)*)', out_string) 182 if result: 183 ld_version = LooseVersion(result.group(1)) 184 else: 185 ld_version = None 186 else: 187 ld_version = None 188 dllwrap_exe = find_executable('dllwrap') 189 if dllwrap_exe: 190 out = os.popen(dllwrap_exe + ' --version', 'r') 191 out_string = out.read() 192 out.close() 193 result = re.search(' (\\d+\\.\\d+(\\.\\d+)*)', out_string) 194 if result: 195 dllwrap_version = LooseVersion(result.group(1)) 196 else: 197 dllwrap_version = None 198 else: 199 dllwrap_version = None 200 return (gcc_version, ld_version, dllwrap_version)