[Distutils] Re: CygwinCCompiler, msvc hack, BCPPCompiler
Rene Liebscher
R.Liebscher@gmx.de
Thu, 29 Jun 2000 18:39:02 +0200
This is a multi-part message in MIME format.
--------------CEAF3E0844BC03C09B03A5C1
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
---- CygwinCCompiler ------------
OK, it should now be better to read. I also included your other changes
(set_executables, build_temp.)
----- msvc hack -----------
I also had a look at this msvc hack in build_ext. I think it is now
possible
to get rid of it. It does several things which could be done in an other
way or shouldn't be done at all.
First, it tries to find a def-file in the source directory if
none is given. I think one should specify this explicitely, who
knows if it is really the right file and moreover it overwrites
any export_symbols given to Extension().
Then it uses the module_name to create an export directive
for the procedure 'init{modulename}'. It is possible to extract
this name from the output filename (see (bcpp|cygwin)compiler.py )
I think this export parameter should be only used if neither a def
file nor a list of symbols is given. (Then you could use your compiler
classes also for non python dll's by specifying [] as export_symbols
list.)
And finally it uses the build_temp path for it implib directive.
We have now this new extra parameter to link_shared_library, so
this is also not a problem.
When I looked at the code of build_ext I found you are not using
export_symbols as parameter to link_shared_object. Also you are not
using any of this export_* values from the Extension class.
This should be changed. But there is one point which is not clear.
There is no parameter at link_shared_object for export_symbols_file.
Either we add this or we change the semantics of the existing
export_symbols a bit.
* export_symbols == None : no export symbols given => add init{module}
* type(export_symbols) == ListType : export all symbols from this list
* type(export_symbols) == StringType : take this as a filename of a def
file
------ bcppcompiler -------------
Which version of Borland C you need to use it?
I tried BC5. It doesn't have a linker named ilink32 (?)
and it doesn't accept some of your parameters
/q for bcc32 and /Gn /q for the linker (tlink32).
Also it is using mypylib, which probably the
stub library for python15.dll . Is this library
somewhere to download or how can I create it?
My BC version doesn't include files if they are
in the source directory
( src/foo.c includes "foo.h" which is really src/foo.h )
so I had to specify this as an include_dir (-Isrc).
If all versions of BC do the same, the directories
of the source files should append to include_dir
in the bcppcompiler class.
Kind regards
Rene Liebscher
--------------CEAF3E0844BC03C09B03A5C1
Content-Type: text/plain; charset=us-ascii; name="cygwinccompiler.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="cygwinccompiler.py"
"""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: cygwinccompiler.py,v 1.1 2000/06/21 03:33:03 gward Exp $"
import os,sys,string
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 is using a unmodified version.
def check_config_h():
""" 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:
# is somewhere a #ifdef __GNUC__ or something similar
string.index(s,"__GNUC__")
except ValueError:
sys.stderr.write ("warning: "+
"Python's config.h doesn't seem to support your compiler.\n")
except IOError:
# if we can't read this file, we cannot say it is wrong
# the compiler will complain later about this file as missing
pass
# This is called when the module is imported, so we make this check only once
check_config_h()
# 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
# dllwrap: specification of entry point is not necessary
self.set_executables(compiler='gcc -O -Wall',
compiler_so='gcc -O -Wall',
linker_exe='gcc',
linker_so='dllwrap --target=i386-cygwin32')
# cygwin and mingw32 need different sets of libraries
self.dll_libraries=[
# cygwin shouldn't need msvcrt,
# but without the dll's will crash
# ( gcc version 2.91.57 )
# perhaps something about initialization
# 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,
build_temp=None):
if libraries == None:
libraries = []
# additional libraries
# the python library is always needed on Windows
# we need the python version without the dot, eg. '15'
libraries = libraries + [
"python%d%d" % ( sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)
] + self.dll_libraries
# name of extension
if not debug:
ext_name = os.path.basename(output_filename)[:-len(".pyd")]
else:
ext_name = os.path.basename(output_filename)[:-len("_d.pyd")]
def_file = os.path.join(build_temp, ext_name + ".def")
#exp_file = os.path.join(build_temp, ext_name + ".exp")
#lib_file = os.path.join(build_temp, 'lib' + ext_name + ".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 we want.)
f = open(def_file,"w")
f.write("EXPORTS\n") # intro
if export_symbols == None:
# export a function "init" + ext_name
f.write("init" + ext_name + "\n")
else:
# if there are more symbols to export write them into f
for sym in export_symbols:
f.write(sym+"\n")
f.close()
if extra_preargs == None:
extra_preargs = []
extra_preargs = extra_preargs + [
#"--verbose",
#"--output-exp",exp_file,
#"--output-lib",lib_file,
"--def",def_file
]
# who wants symbols and a many times larger output file
# should explicitely switch the debug mode on
# otherwise we let dllwrap strip the output file
# (On my machine unstripped_file = stripped_file + 254KB
# 10KB < stripped_file < ??100KB )
if not debug:
extra_preargs = extra_preargs + ["-s"]
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,
build_temp)
# 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.set_executables(compiler='gcc -mno-cygwin -O -Wall',
compiler_so='gcc -mno-cygwin -O -Wall',
linker_exe='gcc -mno-cygwin',
linker_so='dllwrap'
+ ' --target=i386-mingw32'
+ ' --entry _DllMain@12')
# mingw32 doesn't really need 'target' and cygwin too (it seems,
# it is enough to specify a different entry point)
# no additional libraries need
# (only msvcrt, which is already added by CygwinCCompiler)
# __init__ ()
# class Mingw32CCompiler
--------------CEAF3E0844BC03C09B03A5C1--