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
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 @@
         # 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 @@
         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 @@
             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 @@
 
     # 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 @@
         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 @@
             # 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 @@
                 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 @@
 
             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 @@
             # 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 ()