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:
Greg Ward 2000-08-02 01:03:23 +00:00
parent bb56190422
commit c58c517741
1 changed files with 69 additions and 28 deletions

View File

@ -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