Greg Ward | 7c6395a | 2000-06-21 03:33:03 +0000 | [diff] [blame^] | 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 |