summaryrefslogtreecommitdiffstats
path: root/Lib/distutils/bcppcompiler.py
diff options
context:
space:
mode:
authorGreg Ward <gward@python.net>2000-09-27 02:08:14 (GMT)
committerGreg Ward <gward@python.net>2000-09-27 02:08:14 (GMT)
commit4240648a9dffd4b8858c7314bce0c2b0af830b06 (patch)
treebe2f38413bf4f1706820da190443e7999535a07d /Lib/distutils/bcppcompiler.py
parent3ad4e74870e661566392cba0a12b0dc286b59fa7 (diff)
downloadcpython-4240648a9dffd4b8858c7314bce0c2b0af830b06.zip
cpython-4240648a9dffd4b8858c7314bce0c2b0af830b06.tar.gz
cpython-4240648a9dffd4b8858c7314bce0c2b0af830b06.tar.bz2
Big patch from Rene Liebscher to simplify the CCompiler API and
implementations. Details: * replace 'link_shared_object()', 'link_shared_lib()', and 'link_executable()' with 'link()', which is (roughly) the union of the three methods it replaces * in all implementation classes (UnixCCompiler, MSVCCompiler, etc.), ditch the old 'link_*()' methods and replace them with 'link()' * in the abstract base class (CCompiler), add the old 'link_*()' methods as wrappers around the new 'link()' (they also print a warning of the deprecated interface) Also increases consistency between MSVCCompiler and BCPPCompiler, hopefully to make it easier to factor out the mythical WindowsCCompiler class. Details: * use 'self.linker' instead of 'self.link' * add ability to compile resource files to BCPPCompiler * added (redundant?) 'object_filename()' method to BCPPCompiler * only generate a .def file if 'export_symbols' defined
Diffstat (limited to 'Lib/distutils/bcppcompiler.py')
-rw-r--r--Lib/distutils/bcppcompiler.py263
1 files changed, 123 insertions, 140 deletions
diff --git a/Lib/distutils/bcppcompiler.py b/Lib/distutils/bcppcompiler.py
index 2b73b12..bb9557f 100644
--- a/Lib/distutils/bcppcompiler.py
+++ b/Lib/distutils/bcppcompiler.py
@@ -63,7 +63,7 @@ class BCPPCompiler(CCompiler) :
# indicate their installation locations.
self.cc = "bcc32.exe"
- self.link = "ilink32.exe"
+ self.linker = "ilink32.exe"
self.lib = "tlib.exe"
self.preprocess_options = None
@@ -73,6 +73,8 @@ class BCPPCompiler(CCompiler) :
self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x']
self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x']
self.ldflags_static = []
+ self.ldflags_exe = ['/Gn', '/q', '/x']
+ self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r']
# -- Worker methods ------------------------------------------------
@@ -108,16 +110,33 @@ class BCPPCompiler(CCompiler) :
if skip_sources[src]:
self.announce ("skipping %s (%s up-to-date)" % (src, obj))
else:
+ src = os.path.normpath(src)
+ obj = os.path.normpath(obj)
+ self.mkpath(os.path.dirname(obj))
+
+ if ext == '.res':
+ # This is already a binary file -- skip it.
+ continue # the 'for' loop
+ if ext == '.rc':
+ # This needs to be compiled to a .res file -- do it now.
+ try:
+ self.spawn (["brcc32", "-fo", obj, src])
+ except DistutilsExecError, msg:
+ raise CompileError, msg
+ continue # the 'for' loop
+
+ # The next two are both for the real compiler.
if ext in self._c_extensions:
input_opt = ""
elif ext in self._cpp_extensions:
input_opt = "-P"
+ else:
+ # Unknown file type -- no extra options. The compiler
+ # will probably fail, but let it just in case this is a
+ # file the compiler recognizes even if we don't.
+ input_opt = ""
- src = os.path.normpath(src)
- obj = os.path.normpath(obj)
-
output_opt = "-o" + 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
@@ -163,45 +182,20 @@ class BCPPCompiler(CCompiler) :
# create_static_lib ()
-
- def link_shared_lib (self,
- objects,
- output_libname,
- 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):
-
- self.link_shared_object (objects,
- self.shared_library_name(output_libname),
- output_dir=output_dir,
- libraries=libraries,
- library_dirs=library_dirs,
- runtime_library_dirs=runtime_library_dirs,
- export_symbols=export_symbols,
- debug=debug,
- extra_preargs=extra_preargs,
- extra_postargs=extra_postargs,
- build_temp=build_temp)
-
- 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):
+ def link (self,
+ target_desc,
+ 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):
# XXX this ignores 'build_temp'! should follow the lead of
# msvccompiler.py
@@ -213,45 +207,61 @@ class BCPPCompiler(CCompiler) :
if runtime_library_dirs:
self.warn ("I don't know what to do with 'runtime_library_dirs': "
+ str (runtime_library_dirs))
-
+
if output_dir is not None:
output_filename = os.path.join (output_dir, output_filename)
if self._need_link (objects, output_filename):
- if debug:
- ld_args = self.ldflags_shared_debug[:]
+ # Figure out linker args based on type of target.
+ if target_desc == CCompiler.EXECUTABLE:
+ startup_obj = 'c0w32'
+ if debug:
+ ld_args = self.ldflags_exe_debug[:]
+ else:
+ ld_args = self.ldflags_exe[:]
else:
- ld_args = self.ldflags_shared[:]
+ startup_obj = 'c0d32'
+ if debug:
+ ld_args = self.ldflags_shared_debug[:]
+ else:
+ ld_args = self.ldflags_shared[:]
+
# Create a temporary exports file for use by the linker
- head, tail = os.path.split (output_filename)
- modname, ext = os.path.splitext (tail)
- 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 []):
- contents.append(' %s=_%s' % (sym, sym))
- self.execute(write_file, (def_file, contents),
- "writing %s" % def_file)
+ if export_symbols is None:
+ def_file = ''
+ else:
+ head, tail = os.path.split (output_filename)
+ modname, ext = os.path.splitext (tail)
+ 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 []):
+ contents.append(' %s=_%s' % (sym, sym))
+ self.execute(write_file, (def_file, contents),
+ "writing %s" % def_file)
# Borland C++ has problems with '/' in paths
- objects = map(os.path.normpath, objects)
- startup_obj = 'c0d32'
- objects.insert(0, startup_obj)
-
- # 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 ('import32')
- libraries.append ('cw32mt')
-
- # Start building command line flags and options.
-
+ objects2 = map(os.path.normpath, objects)
+ # split objects in .obj and .res files
+ # Borland C++ needs them at different positions in the command line
+ objects = [startup_obj]
+ resources = []
+ for file in objects2:
+ (base, ext) = os.path.splitext(os.path.normcase(file))
+ if ext == '.res':
+ resources.append(file)
+ else:
+ objects.append(file)
+
+
for l in library_dirs:
ld_args.append("/L%s" % os.path.normpath(l))
-
- ld_args.extend(objects) # list of object files
+ ld_args.append("/L.") # we sometimes use relative paths
+
+ # list of object files
+ ld_args.extend(objects)
# XXX the command-line syntax for Borland C++ is a bit wonky;
# certain filenames are jammed together in one big string, but
@@ -263,14 +273,14 @@ class BCPPCompiler(CCompiler) :
# because 'spawn()' would quote any filenames with spaces in
# them. Arghghh!. Apparently it works fine as coded...
- # name of dll file
+ # name of dll/exe file
ld_args.extend([',',output_filename])
# no map file and start libraries
ld_args.append(',,')
for lib in libraries:
# see if we find it and if there is a bcpp specific lib
- # (bcpp_xxx.lib)
+ # (xxx_bcpp.lib)
libfile = self.find_library_file(library_dirs, lib, debug)
if libfile is None:
ld_args.append(lib)
@@ -279,8 +289,17 @@ class BCPPCompiler(CCompiler) :
else:
# full name which prefers bcpp_xxx.lib over xxx.lib
ld_args.append(libfile)
+
+ # some default libraries
+ ld_args.append ('import32')
+ ld_args.append ('cw32mt')
+
# def file for export symbols
ld_args.extend([',',def_file])
+ # add resource files
+ ld_args.append(',')
+ ld_args.extend(resources)
+
if extra_preargs:
ld_args[:0] = extra_preargs
@@ -289,88 +308,24 @@ class BCPPCompiler(CCompiler) :
self.mkpath (os.path.dirname (output_filename))
try:
- self.spawn ([self.link] + ld_args)
+ self.spawn ([self.linker] + ld_args)
except DistutilsExecError, msg:
raise LinkError, msg
else:
self.announce ("skipping %s (up-to-date)" % output_filename)
- # link_shared_object ()
-
-
- def link_executable (self,
- objects,
- output_progname,
- output_dir=None,
- libraries=None,
- library_dirs=None,
- runtime_library_dirs=None,
- debug=0,
- extra_preargs=None,
- extra_postargs=None):
-
- (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)
-
- if runtime_library_dirs:
- self.warn ("I don't know what to do with 'runtime_library_dirs': "
- + str (runtime_library_dirs))
-
- lib_opts = gen_lib_options (self,
- library_dirs, runtime_library_dirs,
- libraries)
- output_filename = output_progname + self.exe_extension
- if output_dir is not None:
- output_filename = os.path.join (output_dir, output_filename)
-
- if self._need_link (objects, output_filename):
-
- if debug:
- ldflags = self.ldflags_shared_debug[1:]
- else:
- ldflags = self.ldflags_shared[1:]
-
- ld_args = ldflags + lib_opts + \
- objects + ['/OUT:' + output_filename]
-
- if extra_preargs:
- ld_args[:0] = extra_preargs
- if extra_postargs:
- ld_args.extend (extra_postargs)
-
- self.mkpath (os.path.dirname (output_filename))
- try:
- self.spawn ([self.link] + ld_args)
- except DistutilsExecError, msg:
- raise LinkError, msg
- else:
- self.announce ("skipping %s (up-to-date)" % output_filename)
-
+ # link ()
# -- Miscellaneous methods -----------------------------------------
- # These are all used by the 'gen_lib_options() function, in
- # ccompiler.py.
-
- def library_dir_option (self, dir):
- return "-L" + dir
-
- def runtime_library_dir_option (self, dir):
- raise DistutilsPlatformError, \
- ("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, debug=0):
# List of effective library names to try, in order of preference:
- # bcpp_xxx.lib is better than xxx.lib
+ # xxx_bcpp.lib is better than xxx.lib
# and xxx_d.lib is better than xxx.lib if debug is set
#
- # The "bcpp_" prefix is to handle a Python installation for people
+ # The "_bcpp" suffix is to handle a Python installation for people
# with multiple compilers (primarily Distutils hackers, I suspect
# ;-). The idea is they'd have one static library for each
# compiler they care about, since (almost?) every Windows compiler
@@ -390,3 +345,31 @@ class BCPPCompiler(CCompiler) :
# Oops, didn't find it in *any* of 'dirs'
return None
+ # overwrite the one from CCompiler to support rc and res-files
+ def object_filenames (self,
+ source_filenames,
+ strip_dir=0,
+ output_dir=''):
+ if output_dir is None: output_dir = ''
+ obj_names = []
+ for src_name in source_filenames:
+ # use normcase to make sure '.rc' is really '.rc' and not '.RC'
+ (base, ext) = os.path.splitext (os.path.normcase(src_name))
+ if ext not in (self.src_extensions + ['.rc','.res']):
+ raise UnknownFileError, \
+ "unknown file type '%s' (from '%s')" % \
+ (ext, src_name)
+ if strip_dir:
+ base = os.path.basename (base)
+ if ext == '.res':
+ # these can go unchanged
+ obj_names.append (os.path.join (output_dir, base + ext))
+ elif ext == '.rc':
+ # these need to be compiled to .res-files
+ obj_names.append (os.path.join (output_dir, base + '.res'))
+ else:
+ obj_names.append (os.path.join (output_dir,
+ base + self.obj_extension))
+ return obj_names
+
+ # object_filenames ()