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 ()
diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py
index ce3f2be..9794906 100644
--- a/Lib/distutils/ccompiler.py
+++ b/Lib/distutils/ccompiler.py
@@ -561,24 +561,32 @@
         pass
     
 
-    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):
-        """Link a bunch of stuff together to create a shared library file.
-        Similar semantics to 'create_static_lib()', with the addition of
-        other libraries to link against and directories to search for them.
-        Also, of course, the type and name of the generated file will
-        almost certainly be different, as will the program used to create
-        it.
+    # values for target_desc parameter in link()
+    SHARED_OBJECT = "shared_object"
+    SHARED_LIBRARY = "shared_library"
+    EXECUTABLE = "executable"
+
+    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):
+        """Link a bunch of stuff together to create an executable or
+        shared library file.
+
+        The "bunch of stuff" consists of the list of object files supplied
+        as 'objects'.  'output_filename' should be a filename.  If
+        'output_dir' is supplied, 'output_filename' is relative to it
+        (i.e. 'output_filename' can provide directory components if
+        needed).
 
         'libraries' is a list of libraries to link against.  These are
         library names, not filenames, since they're translated into
@@ -610,7 +618,31 @@
 
         Raises LinkError on failure.
         """
-        pass
+        raise NotImplementedError
+
+    
+    # old methods, rewritten to use the new link() method.
+
+    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.warn("link_shared_lib(..) is deprecated, please "
+                  "use link(CCompiler.SHARED_LIBRARY, ...) instead")
+        self.link(CCompiler.SHARED_LIBRARY, objects, 
+                  self.library_filename(output_libname, lib_type='shared'),
+                  output_dir,
+                  libraries, library_dirs, runtime_library_dirs,
+                  export_symbols, debug,
+                  extra_preargs, extra_postargs, build_temp)
     
 
     def link_shared_object (self,
@@ -625,16 +657,13 @@
                             extra_preargs=None,
                             extra_postargs=None,
                             build_temp=None):
-        """Link a bunch of stuff together to create a shared object file.
-        Much like 'link_shared_lib()', except the output filename is
-        explicitly supplied as 'output_filename'.  If 'output_dir' is
-        supplied, 'output_filename' is relative to it
-        (i.e. 'output_filename' can provide directory components if
-        needed).
-
-        Raises LinkError on failure.
-        """
-        pass
+        self.warn("link_shared_object(...) is deprecated, please "
+                  "use link(CCompiler.SHARED_OBJECT,...) instead.")
+        self.link(CCompiler.SHARED_OBJECT, objects,
+                  output_filename, output_dir,
+                  libraries, library_dirs, runtime_library_dirs,
+                  export_symbols, debug,
+                  extra_preargs, extra_postargs, build_temp)
 
 
     def link_executable (self,
@@ -647,16 +676,12 @@
                          debug=0,
                          extra_preargs=None,
                          extra_postargs=None):
-        """Link a bunch of stuff together to create a binary executable
-        file.  The "bunch of stuff" is as for 'link_shared_lib()'.
-        'output_progname' should be the base name of the executable
-        program--e.g. on Unix the same as the output filename, but on
-        DOS/Windows ".exe" will be appended.
-
-        Raises LinkError on failure.
-        """
-        pass
-
+        self.warn("link_executable(...) is deprecated, please "
+                  "use link(CCompiler.EXECUTABLE,...) instead.")
+        self.link (CCompiler.EXECUTABLE, objects, 
+                   self.executable_filename(output_progname), output_dir,
+                   libraries, library_dirs, runtime_library_dirs, None, 
+                   debug, extra_preargs, extra_postargs, None)
 
 
     # -- Miscellaneous methods -----------------------------------------
@@ -756,6 +781,14 @@
             basename = os.path.basename (basename)
         return os.path.join (output_dir, basename + self.shared_lib_extension)
 
+    def executable_filename (self,
+                                basename,
+                                strip_dir=0,
+                                output_dir=''):
+        if output_dir is None: output_dir = ''
+        if strip_dir:
+            basename = os.path.basename (basename)
+        return os.path.join(output_dir, basename + (self.exe_extension or ''))
 
     def library_filename (self,
                           libname,
diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py
index f547d54..5b06d3d 100644
--- a/Lib/distutils/cygwinccompiler.py
+++ b/Lib/distutils/cygwinccompiler.py
@@ -39,14 +39,17 @@
 #     By specifying -static we force ld to link against the import libraries, 
 #     this is windows standard and there are normally not the necessary symbols 
 #     in the dlls.
+#   *** only the version of June 2000 shows these problems 
 
 # created 2000/05/05, Rene Liebscher
 
 __revision__ = "$Id$"
 
 import os,sys,copy
+from distutils.ccompiler import gen_preprocess_options, gen_lib_options
 from distutils.unixccompiler import UnixCCompiler
 from distutils.file_util import write_file
+from distutils.errors import DistutilsExecError, CompileError, UnknownFileError
 
 class CygwinCCompiler (UnixCCompiler):
 
@@ -87,9 +90,9 @@
         # same as the rest of binutils ( also ld )
         # dllwrap 2.10.90 is buggy
         if self.ld_version >= "2.10.90": 
-            self.linker = "gcc"
+            self.linker_dll = "gcc"
         else:
-            self.linker = "dllwrap"
+            self.linker_dll = "dllwrap"
 
         # Hard-code GCC because that's what this is all about.
         # XXX optimization, warnings etc. should be customizable.
@@ -97,7 +100,7 @@
                              compiler_so='gcc -mcygwin -mdll -O -Wall',
                              linker_exe='gcc -mcygwin',
                              linker_so=('%s -mcygwin -mdll -static' %
-                                        self.linker))
+                                        self.linker_dll))
 
         # cygwin and mingw32 need different sets of libraries 
         if self.gcc_version == "2.91.57":
@@ -111,58 +114,108 @@
         
     # __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):
+    # not much different of the compile method in UnixCCompiler,
+    # but we have to insert some lines in the middle of it, so
+    # we put here a adapted version of it.
+    # (If we would call compile() in the base class, it would do some 
+    # initializations a second time, this is why all is done here.)
+    def compile (self,
+                 sources,
+                 output_dir=None,
+                 macros=None,
+                 include_dirs=None,
+                 debug=0,
+                 extra_preargs=None,
+                 extra_postargs=None):
+
+        (output_dir, macros, include_dirs) = \
+            self._fix_compile_args (output_dir, macros, include_dirs)
+        (objects, skip_sources) = self._prep_compile (sources, output_dir)
+
+        # Figure out the options for the compiler command line.
+        pp_opts = gen_preprocess_options (macros, include_dirs)
+        cc_args = pp_opts + ['-c']
+        if debug:
+            cc_args[:0] = ['-g']
+        if extra_preargs:
+            cc_args[:0] = extra_preargs
+        if extra_postargs is None:
+            extra_postargs = []
+
+        # Compile all source files that weren't eliminated by
+        # '_prep_compile()'.        
+        for i in range (len (sources)):
+            src = sources[i] ; obj = objects[i]
+            ext = (os.path.splitext (src))[1]
+            if skip_sources[src]:
+                self.announce ("skipping %s (%s up-to-date)" % (src, obj))
+            else:
+                self.mkpath (os.path.dirname (obj))
+                if ext == '.rc' or ext == '.res':
+                    # gcc needs '.res' and '.rc' compiled to object files !!!
+                    try:
+                        self.spawn (["windres","-i",src,"-o",obj])
+                    except DistutilsExecError, msg:
+                        raise CompileError, msg
+                else: # for other files use the C-compiler 
+                    try:
+                        self.spawn (self.compiler_so + cc_args +
+                                [src, '-o', obj] +
+                                extra_postargs)
+                    except DistutilsExecError, msg:
+                        raise CompileError, msg
+
+        # Return *all* object filenames, not just the ones we just built.
+        return objects
+
+    # compile ()
+
+
+    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):
         
         # use separate copies, so we can modify the lists
         extra_preargs = copy.copy(extra_preargs or [])
         libraries = copy.copy(libraries or [])
-        
+        objects = copy.copy(objects or [])
+                
         # Additional libraries
         libraries.extend(self.dll_libraries)
-        
-        # we want to put some files in the same directory as the 
-        # object files are, build_temp doesn't help much
 
-        # where are the object files
-        temp_dir = os.path.dirname(objects[0])
-
-        # name of dll to give the helper files (def, lib, exp) the same name
-        (dll_name, dll_extension) = os.path.splitext(
-            os.path.basename(output_filename))
-
-        # generate the filenames for these files
-        def_file = None # this will be done later, if necessary
-        exp_file = os.path.join(temp_dir, dll_name + ".exp")
-        lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
-
-        #extra_preargs.append("--verbose")
-        if self.linker == "dllwrap":
-            extra_preargs.extend([#"--output-exp",exp_file,
-                                  "--output-lib",lib_file,
-                                 ])
-        else:
-            # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
-            extra_preargs.extend([#"-Wl,--out-implib,%s" % lib_file,
-                                 ])
-       
-        #  check what we got in export_symbols
-        if export_symbols is not None:
-            # Make .def file
-            # (It would probably better to check if we really need this, 
+        # handle export symbols by creating a def-file
+        # with executables this only works with gcc/ld as linker
+        if ((export_symbols is not None) and
+            (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
+            # (The linker doesn't do anything if output is up-to-date.
+            # So 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.) 
+
+            # we want to put some files in the same directory as the 
+            # object files are, build_temp doesn't help much
+            # where are the object files
+            temp_dir = os.path.dirname(objects[0])
+            # name of dll to give the helper files the same base name
+            (dll_name, dll_extension) = os.path.splitext(
+                os.path.basename(output_filename))
+
+            # generate the filenames for these files
             def_file = os.path.join(temp_dir, dll_name + ".def")
+            exp_file = os.path.join(temp_dir, dll_name + ".exp")
+            lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a")
+       
+            # Generate .def file
             contents = [
                 "LIBRARY %s" % os.path.basename(output_filename),
                 "EXPORTS"]
@@ -171,35 +224,78 @@
             self.execute(write_file, (def_file, contents),
                          "writing %s" % def_file)
 
-        if def_file:
-            if self.linker == "dllwrap":
+            # next add options for def-file and to creating import libraries
+
+            # dllwrap uses different options than gcc/ld
+            if self.linker_dll == "dllwrap":
+                extra_preargs.extend([#"--output-exp",exp_file,
+                                       "--output-lib",lib_file,
+                                     ])
                 # for dllwrap we have to use a special option
-                extra_preargs.append("--def")
-            # for gcc/ld it is specified as any other object file    
-            extra_preargs.append(def_file)
+                extra_preargs.extend(["--def", def_file])
+            # we use gcc/ld here and can be sure ld is >= 2.9.10
+            else:
+                # doesn't work: bfd_close build\...\libfoo.a: Invalid operation
+                #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file])
+                # for gcc/ld the def-file is specified as any other object files    
+                objects.append(def_file)
+
+        #end: if ((export_symbols is not None) and
+        #        (target_desc <> self.EXECUTABLE or self.linker_dll == "gcc")):
                                                  
         # who wants symbols and a many times larger output file
         # should explicitly switch the debug mode on 
         # otherwise we let dllwrap/ld strip the output file
-        # (On my machine unstripped_file = stripped_file + 254KB
-        #   10KB < stripped_file < ??100KB ) 
+        # (On my machine: 10KB < stripped_file < ??100KB 
+        #   unstripped_file = stripped_file + XXX KB
+        #  ( XXX=254 for a typical python extension)) 
         if not debug: 
             extra_preargs.append("-s") 
         
-        UnixCCompiler.link_shared_object(self,
-                            objects,
-                            output_filename,
-                            output_dir,
-                            libraries,
-                            library_dirs,
-                            runtime_library_dirs,
-                            None, # export_symbols, we do this in our def-file
-                            debug,
-                            extra_preargs,
-                            extra_postargs,
-                            build_temp)
+        UnixCCompiler.link(self,
+                           target_desc,
+                           objects,
+                           output_filename,
+                           output_dir,
+                           libraries,
+                           library_dirs,
+                           runtime_library_dirs,
+                           None, # export_symbols, we do this in our def-file
+                           debug,
+                           extra_preargs,
+                           extra_postargs,
+                           build_temp)
         
-    # link_shared_object ()
+    # link ()
+
+    # -- Miscellaneous methods -----------------------------------------
+
+    # 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' or ext == '.rc':
+                # these need to be compiled to object files
+                obj_names.append (os.path.join (output_dir, 
+                                            base + ext + self.obj_extension))
+            else:
+                obj_names.append (os.path.join (output_dir,
+                                            base + self.obj_extension))
+        return obj_names
+
+    # object_filenames ()
 
 # class CygwinCCompiler
 
@@ -227,7 +323,7 @@
                              compiler_so='gcc -mno-cygwin -mdll -O -Wall',
                              linker_exe='gcc -mno-cygwin',
                              linker_so='%s -mno-cygwin -mdll -static %s' 
-                                        % (self.linker, entry_point))
+                                        % (self.linker_dll, entry_point))
         # Maybe we should also append -mthreads, but then the finished
         # dlls need another dll (mingwm10.dll see Mingw32 docs)
         # (-mthreads: Support thread-safe exception handling on `Mingw32')       
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
index ea58a79..0325b48 100644
--- a/Lib/distutils/msvccompiler.py
+++ b/Lib/distutils/msvccompiler.py
@@ -205,7 +205,7 @@
             version = versions[0]  # highest version
 
             self.cc   = find_exe("cl.exe", version)
-            self.link = find_exe("link.exe", version)
+            self.linker = find_exe("link.exe", version)
             self.lib  = find_exe("lib.exe", version)
             self.rc   = find_exe("rc.exe", version)     # resource compiler
             self.mc   = find_exe("mc.exe", version)     # message compiler
@@ -221,7 +221,7 @@
         else:
             # devstudio not found in the registry
             self.cc = "cl.exe"
-            self.link = "link.exe"
+            self.linker = "link.exe"
             self.lib = "lib.exe"
             self.rc = "rc.exe"
             self.mc = "mc.exe"
@@ -396,45 +396,19 @@
 
     # 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):
 
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         (libraries, library_dirs, runtime_library_dirs) = \
@@ -452,10 +426,16 @@
 
         if self._need_link (objects, output_filename):
 
-            if debug:
-                ldflags = self.ldflags_shared_debug
+            if target_desc == CCompiler.EXECUTABLE:
+                if debug:
+                    ldflags = self.ldflags_shared_debug[1:]
+                else:
+                    ldflags = self.ldflags_shared[1:]
             else:
-                ldflags = self.ldflags_shared
+                if debug:
+                    ldflags = self.ldflags_shared_debug
+                else:
+                    ldflags = self.ldflags_shared
 
             export_opts = []
             for sym in (export_symbols or []):
@@ -469,12 +449,13 @@
             # needed! Make sure they are generated in the temporary build
             # directory. Since they have different names for debug and release
             # builds, they can go into the same directory.
-            (dll_name, dll_ext) = os.path.splitext(
-                os.path.basename(output_filename))
-            implib_file = os.path.join(
-                os.path.dirname(objects[0]),
-                self.library_filename(dll_name))
-            ld_args.append ('/IMPLIB:' + implib_file)
+            if export_symbols is not None:
+                (dll_name, dll_ext) = os.path.splitext(
+                    os.path.basename(output_filename))
+                implib_file = os.path.join(
+                    os.path.dirname(objects[0]),
+                    self.library_filename(dll_name))
+                ld_args.append ('/IMPLIB:' + implib_file)
 
             if extra_preargs:
                 ld_args[:0] = extra_preargs
@@ -483,66 +464,16 @@
 
             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 ()
+    # link ()
 
 
-    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)   
-    
-
     # -- Miscellaneous methods -----------------------------------------
     # These are all used by the 'gen_lib_options() function, in
     # ccompiler.py.
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index ff0341a..f7eb93a 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -190,45 +190,19 @@
     # 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.library_filename(output_libname, lib_type='shared'),
-            output_dir,
-            libraries,
-            library_dirs,
-            runtime_library_dirs,
-            export_symbols,
-            debug,
-            extra_preargs,
-            extra_postargs,
-            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):
 
         (objects, output_dir) = self._fix_object_args(objects, output_dir)
         (libraries, library_dirs, runtime_library_dirs) = \
@@ -253,54 +227,16 @@
                 ld_args.extend(extra_postargs)
             self.mkpath(os.path.dirname(output_filename))
             try:
-                self.spawn(self.linker_so + ld_args)
+                if target_desc == CCompiler.EXECUTABLE:    
+                    self.spawn(self.linker_exe + ld_args)
+                else:
+                    self.spawn(self.linker_so + 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)
-
-        lib_opts = gen_lib_options(self,
-                                   library_dirs, runtime_library_dirs,
-                                   libraries)
-        output_filename = output_progname # Unix-ism!
-        if output_dir is not None:
-            output_filename = os.path.join(output_dir, output_filename)
-
-        if self._need_link(objects, output_filename):
-            ld_args = objects + self.objects + lib_opts + ['-o', output_filename]
-            if debug:
-                ld_args[:0] = ['-g']
-            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.linker_exe + ld_args)
-            except DistutilsExecError, msg:
-                raise LinkError, msg
-        else:
-            self.announce("skipping %s (up-to-date)" % output_filename)
-
-    # link_executable ()
+    # link ()
 
 
     # -- Miscellaneous methods -----------------------------------------