blob: cc2ed5db667c9cfbd2be174530ae4ac7be37dafa [file] [log] [blame]
"""distutils.cygwinccompiler
Contains the CygwinCCompiler class, a subclass of UnixCCompiler that handles
the Gnu Win32 C compiler.
It also contains the Mingw32CCompiler class which handles the mingw32 compiler
(same as cygwin in no-cygwin mode.)
"""
# created 2000/05/05, Rene Liebscher
__revision__ = "$Id$"
import os,sys,string,tempfile
from distutils import sysconfig
from distutils.unixccompiler import UnixCCompiler
# Because these compilers aren't configured in Python's config.h file by default
# we should at least warn the user if he used this unmodified version.
def check_if_config_h_is_gcc_ready():
""" checks, if the gcc-compiler is mentioned in config.h
if it is not, compiling probably doesn't work """
from distutils import sysconfig
import string,sys
try:
# It would probably better to read single lines to search.
# But we do this only once, and it is fast enough
f=open(sysconfig.get_config_h_filename())
s=f.read()
f.close()
try:
string.index(s,"__GNUC__") # is somewhere a #ifdef __GNUC__ or something similar
except:
sys.stderr.write ("warning: Python's config.h doesn't seem to support your compiler.\n")
except: # unspecific error => ignore
pass
# This is called when the module is imported, so we make this check only once
check_if_config_h_is_gcc_ready()
# XXX Things not currently handled:
# * see UnixCCompiler
class CygwinCCompiler (UnixCCompiler):
compiler_type = 'cygwin'
def __init__ (self,
verbose=0,
dry_run=0,
force=0):
UnixCCompiler.__init__ (self, verbose, dry_run, force)
# our compiler uses other names
self.cc='gcc'
self.ld_shared='dllwrap'
self.ldflags_shared=[]
# some variables to manage the differences between cygwin and mingw32
self.dllwrap_options=["--target=i386-cygwin32"]
# specification of entry point is not necessary
self.dll_additional_libraries=[
# cygwin shouldn't need msvcrt, but without the dll's will crash
# perhaps something about initialization (Python uses it, too)
# mingw32 needs it in all cases
"msvcrt"
]
# __init__ ()
def link_shared_object (self,
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):
if libraries==None:
libraries=[]
python_library=["python"+str(sys.hexversion>>24)+str((sys.hexversion>>16)&0xff)]
libraries=libraries+python_library+self.dll_additional_libraries
# if you don't need the def-file afterwards, it is
# better to use for it tempfile.mktemp() as its name
# (unix-style compilers don't like backslashes in filenames)
win_dll_def_file=string.replace(tempfile.mktemp(),"\\","/")
#win_dll_def_file=output_filename[:-len(self.shared_lib_extension)]+".def"
#win_dll_exp_file=output_filename[:-len(self.shared_lib_extension)]+".exp"
#win_dll_lib_file=output_filename[:-len(self.shared_lib_extension)]+".a"
# Make .def file
# (It would probably better to check if we really need this, but for this we had to
# insert some unchanged parts of UnixCCompiler, and this is not what I want.)
f=open(win_dll_def_file,"w")
f.write("EXPORTS\n") # intro
# always export a function "init"+module_name
if not debug:
f.write("init"+os.path.basename(output_filename)[:-len(self.shared_lib_extension)]+"\n")
else: # in debug mode outfile_name is something like XXXXX_d.pyd
f.write("init"+os.path.basename(output_filename)[:-(len(self.shared_lib_extension)+2)]+"\n")
# if there are more symbols to export
# insert code here to write them in f
if export_symbols!=None:
for sym in export_symbols:
f.write(sym+"\n")
f.close()
if extra_preargs==None:
extra_preargs=[]
extra_preargs=extra_preargs+[
#"--verbose",
#"--output-exp",win_dll_exp_file,
#"--output-lib",win_dll_lib_file,
"--def",win_dll_def_file
]+ self.dllwrap_options
# who wants symbols and a many times greater output file
# should explicitely switch the debug mode on
# otherwise we let dllwrap strip the outputfile
# (On my machine unstripped_file=stripped_file+254KB
# 10KB < stripped_file < ??100KB )
if not debug:
extra_preargs=extra_preargs+["-s"]
try:
UnixCCompiler.link_shared_object(self,
objects,
output_filename,
output_dir,
libraries,
library_dirs,
runtime_library_dirs,
None, # export_symbols, we do this with our def-file
debug,
extra_preargs,
extra_postargs)
finally:
# we don't need the def-file anymore
os.remove(win_dll_def_file)
# link_shared_object ()
# class CygwinCCompiler
# the same as cygwin plus some additional parameters
class Mingw32CCompiler (CygwinCCompiler):
compiler_type = 'mingw32'
def __init__ (self,
verbose=0,
dry_run=0,
force=0):
CygwinCCompiler.__init__ (self, verbose, dry_run, force)
self.ccflags = self.ccflags + ["-mno-cygwin"]
self.dllwrap_options=[
# mingw32 doesn't really need 'target'
# and cygwin too (it seems, it is enough
# to specify a different entry point)
#"--target=i386-mingw32",
"--entry","_DllMain@12"
]
# no additional libraries need
# (only msvcrt, which is already added by CygwinCCompiler)
# __init__ ()
# class Mingw32CCompiler