Patch from Rene Liebscher. Some ugly changes, but supposedly this makes
it so BCPPCompiler actually works, so I'm provisionally accepting it -- ugly and working is better than not working! Major changes: - normalize paths (apparently BC++ doesn't like slashes) - overhauled how we search for and specify libraries on the linker command-line - hacked up 'find_library_file()' so it knows about "debug" library naming convention as well as "bcpp_xxx.lib" -- the question is, is this a well-established and sensible convention? Also: - change to use 'util.write_file()' to write the .def file
This commit is contained in:
parent
bb56190422
commit
c58c517741
|
@ -11,17 +11,6 @@ for the Borland C++ compiler.
|
|||
# someone should sit down and factor out the common code as
|
||||
# WindowsCCompiler! --GPW
|
||||
|
||||
# XXX Lyle reports that this doesn't quite work yet:
|
||||
# """...but this is what I've got so far. The compile step works fine but
|
||||
# when it runs the link step I get an "out of memory" failure. Since
|
||||
# spawn() echoes the command it's trying to spawn, I can type the link line
|
||||
# verbatim at the DOS prompt and it links the Windows DLL correctly -- so
|
||||
# the syntax is correct. There's just some weird interaction going on when
|
||||
# it tries to "spawn" the link process from within the setup.py script. I'm
|
||||
# not really sure how to debug this one right off-hand; obviously there's
|
||||
# nothing wrong with the "spawn()" function since it's working properly for
|
||||
# the compile stage."""
|
||||
|
||||
__revision__ = "$Id$"
|
||||
|
||||
|
||||
|
@ -31,6 +20,7 @@ from distutils.errors import \
|
|||
CompileError, LibError, LinkError
|
||||
from distutils.ccompiler import \
|
||||
CCompiler, gen_preprocess_options, gen_lib_options
|
||||
from distutils.file_util import write_file
|
||||
|
||||
|
||||
class BCPPCompiler(CCompiler) :
|
||||
|
@ -123,14 +113,15 @@ class BCPPCompiler(CCompiler) :
|
|||
elif ext in self._cpp_extensions:
|
||||
input_opt = "-P"
|
||||
|
||||
src = os.path.normpath(src)
|
||||
obj = os.path.normpath(obj)
|
||||
|
||||
output_opt = "-o" + obj
|
||||
|
||||
self.mkpath (os.path.dirname (obj))
|
||||
self.mkpath(os.path.dirname(obj))
|
||||
|
||||
# Compiler command line syntax is: "bcc32 [options] file(s)".
|
||||
# Note that the source file names must appear at the end of
|
||||
# the command line.
|
||||
|
||||
try:
|
||||
self.spawn ([self.cc] + compile_opts + pp_opts +
|
||||
[input_opt, output_opt] +
|
||||
|
@ -212,6 +203,9 @@ class BCPPCompiler(CCompiler) :
|
|||
extra_postargs=None,
|
||||
build_temp=None):
|
||||
|
||||
# XXX this ignores 'build_temp'! should follow the lead of
|
||||
# msvccompiler.py
|
||||
|
||||
(objects, output_dir) = self._fix_object_args (objects, output_dir)
|
||||
(libraries, library_dirs, runtime_library_dirs) = \
|
||||
self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
|
||||
|
@ -226,33 +220,63 @@ class BCPPCompiler(CCompiler) :
|
|||
if self._need_link (objects, output_filename):
|
||||
|
||||
if debug:
|
||||
ldflags = self.ldflags_shared_debug
|
||||
ld_args = self.ldflags_shared_debug[:]
|
||||
else:
|
||||
ldflags = self.ldflags_shared
|
||||
ld_args = self.ldflags_shared[:]
|
||||
|
||||
# Borland C++ has problems with '/' in paths
|
||||
objects = map(os.path.normpath, objects)
|
||||
startup_obj = 'c0d32'
|
||||
objects.insert(0, startup_obj)
|
||||
|
||||
libraries.append ('mypylib')
|
||||
# either exchange python15.lib in the python libs directory against
|
||||
# a Borland-like one, or create one with name bcpp_python15.lib
|
||||
# there and remove the pragmas from config.h
|
||||
#libraries.append ('mypylib')
|
||||
libraries.append ('import32')
|
||||
libraries.append ('cw32mt')
|
||||
|
||||
# Create a temporary exports file for use by the linker
|
||||
head, tail = os.path.split (output_filename)
|
||||
modname, ext = os.path.splitext (tail)
|
||||
def_file = os.path.join (build_temp, '%s.def' % modname)
|
||||
f = open (def_file, 'w')
|
||||
f.write ('EXPORTS\n')
|
||||
temp_dir = os.path.dirname(objects[0]) # preserve tree structure
|
||||
def_file = os.path.join (temp_dir, '%s.def' % modname)
|
||||
contents = ['EXPORTS']
|
||||
for sym in (export_symbols or []):
|
||||
f.write (' %s=_%s\n' % (sym, sym))
|
||||
contents.append(' %s=_%s' % (sym, sym))
|
||||
self.execute(write_file, (def_file, contents),
|
||||
"writing %s" % def_file)
|
||||
|
||||
ld_args = ldflags + [startup_obj] + objects + \
|
||||
[',%s,,' % output_filename] + \
|
||||
libraries + [',' + def_file]
|
||||
# Start building command line flags and options.
|
||||
|
||||
for l in library_dirs:
|
||||
ld_args.append("/L%s" % os.path.normpath(l))
|
||||
|
||||
ld_args.extend(objects) # list of object files
|
||||
|
||||
# name of dll file
|
||||
ld_args.extend([',',output_filename])
|
||||
# no map file and start libraries
|
||||
ld_args.extend([',', ','])
|
||||
|
||||
for lib in libraries:
|
||||
# see if we find it and if there is a bcpp specific lib
|
||||
# (bcpp_xxx.lib)
|
||||
libfile = self.find_library_file(library_dirs, lib, debug)
|
||||
if libfile is None:
|
||||
ld_args.append(lib)
|
||||
# probably a BCPP internal library -- don't warn
|
||||
# self.warn('library %s not found.' % lib)
|
||||
else:
|
||||
# full name which prefers bcpp_xxx.lib over xxx.lib
|
||||
ld_args.append(libfile)
|
||||
# def file for export symbols
|
||||
ld_args.extend([',',def_file])
|
||||
|
||||
if extra_preargs:
|
||||
ld_args[:0] = extra_preargs
|
||||
if extra_postargs:
|
||||
ld_args.extend (extra_postargs)
|
||||
ld_args.extend(extra_postargs)
|
||||
|
||||
self.mkpath (os.path.dirname (output_filename))
|
||||
try:
|
||||
|
@ -325,15 +349,32 @@ class BCPPCompiler(CCompiler) :
|
|||
|
||||
def runtime_library_dir_option (self, dir):
|
||||
raise DistutilsPlatformError, \
|
||||
"don't know how to set runtime library search path for MSVC++"
|
||||
("don't know how to set runtime library search path "
|
||||
"for Borland C++")
|
||||
|
||||
def library_option (self, lib):
|
||||
return self.library_filename (lib)
|
||||
|
||||
|
||||
def find_library_file (self, dirs, lib):
|
||||
|
||||
def find_library_file (self, dirs, lib, debug=0):
|
||||
# find library file
|
||||
# bcpp_xxx.lib is better than xxx.lib
|
||||
# and xxx_d.lib is better than xxx.lib if debug is set
|
||||
for dir in dirs:
|
||||
if debug:
|
||||
libfile = os.path.join (
|
||||
dir, self.library_filename ("bcpp_" + lib + "_d"))
|
||||
if os.path.exists (libfile):
|
||||
return libfile
|
||||
libfile = os.path.join (
|
||||
dir, self.library_filename ("bcpp_" + lib))
|
||||
if os.path.exists (libfile):
|
||||
return libfile
|
||||
if debug:
|
||||
libfile = os.path.join (
|
||||
dir, self.library_filename(lib + '_d'))
|
||||
if os.path.exists (libfile):
|
||||
return libfile
|
||||
libfile = os.path.join (dir, self.library_filename (lib))
|
||||
if os.path.exists (libfile):
|
||||
return libfile
|
||||
|
|
Loading…
Reference in New Issue