Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 1 | """distutils.cygwinccompiler |
| 2 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 3 | Provides the CygwinCCompiler class, a subclass of UnixCCompiler that |
| 4 | handles the Cygwin port of the GNU C compiler to Windows. It also contains |
| 5 | the Mingw32CCompiler class which handles the mingw32 port of GCC (same as |
| 6 | cygwin in no-cygwin mode). |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 7 | """ |
| 8 | |
| 9 | # created 2000/05/05, Rene Liebscher |
| 10 | |
| 11 | __revision__ = "$Id$" |
| 12 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 13 | import os,sys,string |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 14 | from distutils import sysconfig |
| 15 | from distutils.unixccompiler import UnixCCompiler |
| 16 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 17 | # Because these compilers aren't configured in Python's config.h file by |
| 18 | # default we should at least warn the user if he is using a unmodified |
| 19 | # version. |
| 20 | |
| 21 | def check_config_h(): |
| 22 | """Checks if the GCC compiler is mentioned in config.h. If it is not, |
| 23 | compiling probably doesn't work, so print a warning to stderr. |
| 24 | """ |
| 25 | |
| 26 | # XXX the result of the check should be returned! |
| 27 | |
| 28 | from distutils import sysconfig |
| 29 | import string,sys |
| 30 | try: |
| 31 | # It would probably better to read single lines to search. |
| 32 | # But we do this only once, and it is fast enough |
| 33 | f=open(sysconfig.get_config_h_filename()) |
| 34 | s=f.read() |
| 35 | f.close() |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 36 | try: |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 37 | # is somewhere a #ifdef __GNUC__ or something similar |
| 38 | string.index(s,"__GNUC__") |
| 39 | except ValueError: |
| 40 | sys.stderr.write ("warning: "+ |
| 41 | "Python's config.h doesn't seem to support your compiler.\n") |
| 42 | except IOError: |
| 43 | # if we can't read this file, we cannot say it is wrong |
| 44 | # the compiler will complain later about this file as missing |
| 45 | pass |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 46 | |
| 47 | |
| 48 | # This is called when the module is imported, so we make this check only once |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 49 | # XXX why not make it only when the compiler is needed? |
| 50 | check_config_h() |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 51 | |
| 52 | |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 53 | class CygwinCCompiler (UnixCCompiler): |
| 54 | |
| 55 | compiler_type = 'cygwin' |
| 56 | |
| 57 | def __init__ (self, |
| 58 | verbose=0, |
| 59 | dry_run=0, |
| 60 | force=0): |
| 61 | |
| 62 | UnixCCompiler.__init__ (self, verbose, dry_run, force) |
| 63 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 64 | # Hard-code GCC because that's what this is all about. |
| 65 | # XXX optimization, warnings etc. should be customizable. |
| 66 | self.set_executables(compiler='gcc -O -Wall', |
| 67 | compiler_so='gcc -O -Wall', |
| 68 | linker_exe='gcc', |
| 69 | linker_so='dllwrap --target=i386-cygwin32') |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 70 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 71 | # cygwin and mingw32 need different sets of libraries |
| 72 | self.dll_libraries=[ |
| 73 | # cygwin shouldn't need msvcrt, |
| 74 | # but without the dll's will crash |
| 75 | # ( gcc version 2.91.57 ) |
| 76 | # perhaps something about initialization |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 77 | # mingw32 needs it in all cases |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 78 | "msvcrt" |
| 79 | ] |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 80 | |
| 81 | # __init__ () |
| 82 | |
| 83 | def link_shared_object (self, |
| 84 | objects, |
| 85 | output_filename, |
| 86 | output_dir=None, |
| 87 | libraries=None, |
| 88 | library_dirs=None, |
| 89 | runtime_library_dirs=None, |
| 90 | export_symbols=None, |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 91 | debug=0, |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 92 | extra_preargs=None, |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 93 | extra_postargs=None, |
| 94 | build_temp=None): |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 95 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 96 | if libraries == None: |
| 97 | libraries = [] |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 98 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 99 | # Additional libraries: the python library is always needed on |
| 100 | # Windows we need the python version without the dot, eg. '15' |
| 101 | |
| 102 | pythonlib = ("python%d%d" % |
| 103 | (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) |
| 104 | libraries.append(pythonlib) |
| 105 | libraries.extend(self.dll_libraries) |
| 106 | |
| 107 | # name of extension |
| 108 | |
| 109 | # XXX WRONG WRONG WRONG |
| 110 | # this is NOT the place to make guesses about Python namespaces; |
| 111 | # that MUST be done in build_ext.py |
| 112 | |
| 113 | if not debug: |
| 114 | ext_name = os.path.basename(output_filename)[:-len(".pyd")] |
| 115 | else: |
| 116 | ext_name = os.path.basename(output_filename)[:-len("_d.pyd")] |
| 117 | |
| 118 | def_file = os.path.join(build_temp, ext_name + ".def") |
| 119 | #exp_file = os.path.join(build_temp, ext_name + ".exp") |
| 120 | #lib_file = os.path.join(build_temp, 'lib' + ext_name + ".a") |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 121 | |
| 122 | # Make .def file |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 123 | # (It would probably better to check if we really need this, |
| 124 | # but for this we had to insert some unchanged parts of |
| 125 | # UnixCCompiler, and this is not what we want.) |
| 126 | f = open(def_file,"w") |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 127 | f.write("EXPORTS\n") # intro |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 128 | if export_symbols == None: |
| 129 | # export a function "init" + ext_name |
| 130 | f.write("init" + ext_name + "\n") |
| 131 | else: |
| 132 | # if there are more symbols to export write them into f |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 133 | for sym in export_symbols: |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 134 | f.write(sym+"\n") |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 135 | f.close() |
| 136 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 137 | if extra_preargs == None: |
| 138 | extra_preargs = [] |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 139 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 140 | extra_preargs = extra_preargs + [ |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 141 | #"--verbose", |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 142 | #"--output-exp",exp_file, |
| 143 | #"--output-lib",lib_file, |
| 144 | "--def",def_file |
| 145 | ] |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 146 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 147 | # who wants symbols and a many times larger output file |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 148 | # should explicitely switch the debug mode on |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 149 | # otherwise we let dllwrap strip the output file |
| 150 | # (On my machine unstripped_file = stripped_file + 254KB |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 151 | # 10KB < stripped_file < ??100KB ) |
| 152 | if not debug: |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 153 | extra_preargs = extra_preargs + ["-s"] |
| 154 | |
| 155 | UnixCCompiler.link_shared_object(self, |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 156 | objects, |
| 157 | output_filename, |
| 158 | output_dir, |
| 159 | libraries, |
| 160 | library_dirs, |
| 161 | runtime_library_dirs, |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 162 | None, # export_symbols, we do this with our def-file |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 163 | debug, |
| 164 | extra_preargs, |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 165 | extra_postargs, |
| 166 | build_temp) |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 167 | |
| 168 | # link_shared_object () |
| 169 | |
| 170 | # class CygwinCCompiler |
| 171 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 172 | |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 173 | # the same as cygwin plus some additional parameters |
| 174 | class Mingw32CCompiler (CygwinCCompiler): |
| 175 | |
| 176 | compiler_type = 'mingw32' |
| 177 | |
| 178 | def __init__ (self, |
| 179 | verbose=0, |
| 180 | dry_run=0, |
| 181 | force=0): |
| 182 | |
| 183 | CygwinCCompiler.__init__ (self, verbose, dry_run, force) |
| 184 | |
Greg Ward | f34506a | 2000-06-29 22:57:55 +0000 | [diff] [blame] | 185 | self.set_executables(compiler='gcc -mno-cygwin -O -Wall', |
| 186 | compiler_so='gcc -mno-cygwin -O -Wall', |
| 187 | linker_exe='gcc -mno-cygwin', |
| 188 | linker_so='dllwrap' |
| 189 | + ' --target=i386-mingw32' |
| 190 | + ' --entry _DllMain@12') |
| 191 | # mingw32 doesn't really need 'target' and cygwin too (it seems, |
| 192 | # it is enough to specify a different entry point) |
| 193 | |
Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame] | 194 | # no additional libraries need |
| 195 | # (only msvcrt, which is already added by CygwinCCompiler) |
| 196 | |
| 197 | # __init__ () |
| 198 | |
| 199 | # class Mingw32CCompiler |