|
| 1 | +"""distutils.cygwinccompiler |
| 2 | +
|
| 3 | +Contains the CygwinCCompiler class, a subclass of UnixCCompiler that handles |
| 4 | +the Gnu Win32 C compiler. |
| 5 | +It also contains the Mingw32CCompiler class which handles the mingw32 compiler |
| 6 | +(same as cygwin in no-cygwin mode.) |
| 7 | +
|
| 8 | +""" |
| 9 | + |
| 10 | +# created 2000/05/05, Rene Liebscher |
| 11 | + |
| 12 | +__revision__ = "$Id$" |
| 13 | + |
| 14 | +import os,sys,string,tempfile |
| 15 | +from distutils import sysconfig |
| 16 | +from distutils.unixccompiler import UnixCCompiler |
| 17 | + |
| 18 | +# Because these compilers aren't configured in Python's config.h file by default |
| 19 | +# we should at least warn the user if he used this unmodified version. |
| 20 | +def check_if_config_h_is_gcc_ready(): |
| 21 | + """ checks, if the gcc-compiler is mentioned in config.h |
| 22 | + if it is not, compiling probably doesn't work """ |
| 23 | + from distutils import sysconfig |
| 24 | + import string,sys |
| 25 | + try: |
| 26 | + # It would probably better to read single lines to search. |
| 27 | + # But we do this only once, and it is fast enough |
| 28 | + f=open(sysconfig.get_config_h_filename()) |
| 29 | + s=f.read() |
| 30 | + f.close() |
| 31 | + try: |
| 32 | + string.index(s,"__GNUC__") # is somewhere a #ifdef __GNUC__ or something similar |
| 33 | + except: |
| 34 | + sys.stderr.write ("warning: Python's config.h doesn't seem to support your compiler.\n") |
| 35 | + except: # unspecific error => ignore |
| 36 | + pass |
| 37 | + |
| 38 | + |
| 39 | +# This is called when the module is imported, so we make this check only once |
| 40 | +check_if_config_h_is_gcc_ready() |
| 41 | + |
| 42 | + |
| 43 | +# XXX Things not currently handled: |
| 44 | +# * see UnixCCompiler |
| 45 | + |
| 46 | +class CygwinCCompiler (UnixCCompiler): |
| 47 | + |
| 48 | + compiler_type = 'cygwin' |
| 49 | + |
| 50 | + def __init__ (self, |
| 51 | + verbose=0, |
| 52 | + dry_run=0, |
| 53 | + force=0): |
| 54 | + |
| 55 | + UnixCCompiler.__init__ (self, verbose, dry_run, force) |
| 56 | + |
| 57 | + # our compiler uses other names |
| 58 | + self.cc='gcc' |
| 59 | + self.ld_shared='dllwrap' |
| 60 | + self.ldflags_shared=[] |
| 61 | + |
| 62 | + # some variables to manage the differences between cygwin and mingw32 |
| 63 | + self.dllwrap_options=["--target=i386-cygwin32"] |
| 64 | + # specification of entry point is not necessary |
| 65 | + |
| 66 | + self.dll_additional_libraries=[ |
| 67 | + # cygwin shouldn't need msvcrt, but without the dll's will crash |
| 68 | + # perhaps something about initialization (Python uses it, too) |
| 69 | + # mingw32 needs it in all cases |
| 70 | + "msvcrt" |
| 71 | + ] |
| 72 | + |
| 73 | + # __init__ () |
| 74 | + |
| 75 | + def link_shared_object (self, |
| 76 | + objects, |
| 77 | + output_filename, |
| 78 | + output_dir=None, |
| 79 | + libraries=None, |
| 80 | + library_dirs=None, |
| 81 | + runtime_library_dirs=None, |
| 82 | + export_symbols=None, |
| 83 | + debug=0, |
| 84 | + extra_preargs=None, |
| 85 | + extra_postargs=None): |
| 86 | + |
| 87 | + if libraries==None: |
| 88 | + libraries=[] |
| 89 | + |
| 90 | + python_library=["python"+str(sys.hexversion>>24)+str((sys.hexversion>>16)&0xff)] |
| 91 | + libraries=libraries+python_library+self.dll_additional_libraries |
| 92 | + |
| 93 | + # if you don't need the def-file afterwards, it is |
| 94 | + # better to use for it tempfile.mktemp() as its name |
| 95 | + # (unix-style compilers don't like backslashes in filenames) |
| 96 | + win_dll_def_file=string.replace(tempfile.mktemp(),"\\","/") |
| 97 | + #win_dll_def_file=output_filename[:-len(self.shared_lib_extension)]+".def" |
| 98 | + #win_dll_exp_file=output_filename[:-len(self.shared_lib_extension)]+".exp" |
| 99 | + #win_dll_lib_file=output_filename[:-len(self.shared_lib_extension)]+".a" |
| 100 | + |
| 101 | + # Make .def file |
| 102 | + # (It would probably better to check if we really need this, but for this we had to |
| 103 | + # insert some unchanged parts of UnixCCompiler, and this is not what I want.) |
| 104 | + f=open(win_dll_def_file,"w") |
| 105 | + f.write("EXPORTS\n") # intro |
| 106 | + # always export a function "init"+module_name |
| 107 | + if not debug: |
| 108 | + f.write("init"+os.path.basename(output_filename)[:-len(self.shared_lib_extension)]+"\n") |
| 109 | + else: # in debug mode outfile_name is something like XXXXX_d.pyd |
| 110 | + f.write("init"+os.path.basename(output_filename)[:-(len(self.shared_lib_extension)+2)]+"\n") |
| 111 | + # if there are more symbols to export |
| 112 | + # insert code here to write them in f |
| 113 | + if export_symbols!=None: |
| 114 | + for sym in export_symbols: |
| 115 | + f.write(sym+"\n") |
| 116 | + f.close() |
| 117 | + |
| 118 | + if extra_preargs==None: |
| 119 | + extra_preargs=[] |
| 120 | + |
| 121 | + extra_preargs=extra_preargs+[ |
| 122 | + #"--verbose", |
| 123 | + #"--output-exp",win_dll_exp_file, |
| 124 | + #"--output-lib",win_dll_lib_file, |
| 125 | + "--def",win_dll_def_file |
| 126 | + ]+ self.dllwrap_options |
| 127 | + |
| 128 | + # who wants symbols and a many times greater output file |
| 129 | + # should explicitely switch the debug mode on |
| 130 | + # otherwise we let dllwrap strip the outputfile |
| 131 | + # (On my machine unstripped_file=stripped_file+254KB |
| 132 | + # 10KB < stripped_file < ??100KB ) |
| 133 | + if not debug: |
| 134 | + extra_preargs=extra_preargs+["-s"] |
| 135 | + |
| 136 | + try: |
| 137 | + UnixCCompiler.link_shared_object(self, |
| 138 | + objects, |
| 139 | + output_filename, |
| 140 | + output_dir, |
| 141 | + libraries, |
| 142 | + library_dirs, |
| 143 | + runtime_library_dirs, |
| 144 | + None, # export_symbols, we do this with our def-file |
| 145 | + debug, |
| 146 | + extra_preargs, |
| 147 | + extra_postargs) |
| 148 | + finally: |
| 149 | + # we don't need the def-file anymore |
| 150 | + os.remove(win_dll_def_file) |
| 151 | + |
| 152 | + # link_shared_object () |
| 153 | + |
| 154 | +# class CygwinCCompiler |
| 155 | + |
| 156 | +# the same as cygwin plus some additional parameters |
| 157 | +class Mingw32CCompiler (CygwinCCompiler): |
| 158 | + |
| 159 | + compiler_type = 'mingw32' |
| 160 | + |
| 161 | + def __init__ (self, |
| 162 | + verbose=0, |
| 163 | + dry_run=0, |
| 164 | + force=0): |
| 165 | + |
| 166 | + CygwinCCompiler.__init__ (self, verbose, dry_run, force) |
| 167 | + |
| 168 | + self.ccflags = self.ccflags + ["-mno-cygwin"] |
| 169 | + self.dllwrap_options=[ |
| 170 | + # mingw32 doesn't really need 'target' |
| 171 | + # and cygwin too (it seems, it is enough |
| 172 | + # to specify a different entry point) |
| 173 | + #"--target=i386-mingw32", |
| 174 | + "--entry","_DllMain@12" |
| 175 | + ] |
| 176 | + # no additional libraries need |
| 177 | + # (only msvcrt, which is already added by CygwinCCompiler) |
| 178 | + |
| 179 | + # __init__ () |
| 180 | + |
| 181 | +# class Mingw32CCompiler |
0 commit comments