[Python-checkins] CVS: distutils/distutils bcppcompiler.py,1.6,1.7 ccompiler.py,1.33,1.34 cygwinccompiler.py,1.7,1.8 msvccompiler.py,1.41,1.42 unixccompiler.py,1.31,1.32

Greg Ward python-dev@python.org
Tue, 26 Sep 2000 19:08:17 -0700


Update of /cvsroot/python/distutils/distutils
In directory slayer.i.sourceforge.net:/tmp/cvs-serv16450

Modified Files:
	bcppcompiler.py ccompiler.py cygwinccompiler.py 
	msvccompiler.py unixccompiler.py 
Log Message:
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


Index: bcppcompiler.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/bcppcompiler.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** bcppcompiler.py	2000/09/01 01:28:33	1.6
--- bcppcompiler.py	2000/09/27 02:08:14	1.7
***************
*** 64,68 ****
  
          self.cc = "bcc32.exe"
!         self.link = "ilink32.exe"
          self.lib = "tlib.exe"
  
--- 64,68 ----
  
          self.cc = "bcc32.exe"
!         self.linker = "ilink32.exe"
          self.lib = "tlib.exe"
  
***************
*** 74,77 ****
--- 74,79 ----
          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']
  
  
***************
*** 109,122 ****
                  self.announce ("skipping %s (%s up-to-date)" % (src, obj))
              else:
                  if ext in self._c_extensions:
                      input_opt = ""
                  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))
  
                  # Compiler command line syntax is: "bcc32 [options] file(s)".
--- 111,141 ----
                  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 = ""                              
  
                  output_opt = "-o" + obj
  
                  # Compiler command line syntax is: "bcc32 [options] file(s)".
***************
*** 164,206 ****
      # 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):
  
          # XXX this ignores 'build_temp'!  should follow the lead of
--- 183,200 ----
      # create_static_lib ()
      
      
!     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
***************
*** 214,218 ****
              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)
--- 208,212 ----
              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)
***************
*** 220,257 ****
          if self._need_link (objects, output_filename):
  
!             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)
  
              # 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.
! 
              for l in library_dirs:
                  ld_args.append("/L%s" % os.path.normpath(l)) 
!                 
!             ld_args.extend(objects)     # list of object files
  
              # XXX the command-line syntax for Borland C++ is a bit wonky;
              # certain filenames are jammed together in one big string, but
--- 214,267 ----
          if self._need_link (objects, output_filename):
  
!             # 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:
!                 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
!             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
!             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.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
***************
*** 264,268 ****
              # them.  Arghghh!.  Apparently it works fine as coded...
  
!             # name of dll file
              ld_args.extend([',',output_filename])
              # no map file and start libraries 
--- 274,278 ----
              # them.  Arghghh!.  Apparently it works fine as coded...
  
!             # name of dll/exe file
              ld_args.extend([',',output_filename])
              # no map file and start libraries 
***************
*** 271,275 ****
              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:
--- 281,285 ----
              for lib in libraries:
                  # see if we find it and if there is a bcpp specific lib 
!                 # (xxx_bcpp.lib)
                  libfile = self.find_library_file(library_dirs, lib, debug)
                  if libfile is None:
***************
*** 280,285 ****
--- 290,304 ----
                      # 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:
***************
*** 290,294 ****
              self.mkpath (os.path.dirname (output_filename))
              try:
!                 self.spawn ([self.link] + ld_args)
              except DistutilsExecError, msg:
                  raise LinkError, msg
--- 309,313 ----
              self.mkpath (os.path.dirname (output_filename))
              try:
!                 self.spawn ([self.linker] + ld_args)
              except DistutilsExecError, msg:
                  raise LinkError, msg
***************
*** 296,375 ****
          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)   
-     
- 
      # -- 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
          # and xxx_d.lib is better than xxx.lib if debug is set
          #
!         # The "bcpp_" prefix 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
--- 315,330 ----
          else:
              self.announce ("skipping %s (up-to-date)" % output_filename)
  
!     # link ()
  
      # -- Miscellaneous methods -----------------------------------------
  
  
      def find_library_file (self, dirs, lib, debug=0):
          # List of effective library names to try, in order of preference:
!         # xxx_bcpp.lib is better than xxx.lib
          # and xxx_d.lib is better than xxx.lib if debug is set
          #
!         # 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
***************
*** 391,392 ****
--- 346,375 ----
              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 ()

Index: ccompiler.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/ccompiler.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -r1.33 -r1.34
*** ccompiler.py	2000/08/04 01:31:13	1.33
--- ccompiler.py	2000/09/27 02:08:14	1.34
***************
*** 562,583 ****
      
  
!     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.
  
          'libraries' is a list of libraries to link against.  These are
--- 562,591 ----
      
  
!     # 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
***************
*** 611,617 ****
          Raises LinkError on failure.
          """
!         pass
      
  
      def link_shared_object (self,
                              objects,
--- 619,649 ----
          Raises LinkError on failure.
          """
!         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,
                              objects,
***************
*** 626,639 ****
                              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
  
  
--- 658,668 ----
                              extra_postargs=None,
                              build_temp=None):
!         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)
  
  
***************
*** 648,661 ****
                           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
! 
  
  
--- 677,686 ----
                           extra_preargs=None,
                           extra_postargs=None):
!         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)
  
  
***************
*** 757,760 ****
--- 782,793 ----
          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,

Index: cygwinccompiler.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/cygwinccompiler.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** cygwinccompiler.py	2000/09/01 01:24:31	1.7
--- cygwinccompiler.py	2000/09/27 02:08:14	1.8
***************
*** 40,43 ****
--- 40,44 ----
  #     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
***************
*** 46,51 ****
--- 47,54 ----
  
  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):
***************
*** 88,94 ****
          # dllwrap 2.10.90 is buggy
          if self.ld_version >= "2.10.90": 
!             self.linker = "gcc"
          else:
!             self.linker = "dllwrap"
  
          # Hard-code GCC because that's what this is all about.
--- 91,97 ----
          # dllwrap 2.10.90 is buggy
          if self.ld_version >= "2.10.90": 
!             self.linker_dll = "gcc"
          else:
!             self.linker_dll = "dllwrap"
  
          # Hard-code GCC because that's what this is all about.
***************
*** 98,102 ****
                               linker_exe='gcc -mcygwin',
                               linker_so=('%s -mcygwin -mdll -static' %
!                                         self.linker))
  
          # cygwin and mingw32 need different sets of libraries 
--- 101,105 ----
                               linker_exe='gcc -mcygwin',
                               linker_so=('%s -mcygwin -mdll -static' %
!                                         self.linker_dll))
  
          # cygwin and mingw32 need different sets of libraries 
***************
*** 112,167 ****
      # __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):
          
          # use separate copies, so we can modify the lists
          extra_preargs = copy.copy(extra_preargs or [])
          libraries = copy.copy(libraries 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, 
              # but for this we had to insert some unchanged parts of 
              # UnixCCompiler, and this is not what we want.) 
              def_file = os.path.join(temp_dir, dll_name + ".def")
              contents = [
                  "LIBRARY %s" % os.path.basename(output_filename),
--- 115,220 ----
      # __init__ ()
  
!     # 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)
  
!         # 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),
***************
*** 171,204 ****
              self.execute(write_file, (def_file, contents),
                           "writing %s" % def_file)
  
!         if def_file:
!             if self.linker == "dllwrap":
                  # 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)
                                                   
          # 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 ) 
          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)
          
!     # link_shared_object ()
  
  # class CygwinCCompiler
--- 224,300 ----
              self.execute(write_file, (def_file, contents),
                           "writing %s" % def_file)
+ 
+             # 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.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: 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(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 ()
! 
!     # -- 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
***************
*** 228,232 ****
                               linker_exe='gcc -mno-cygwin',
                               linker_so='%s -mno-cygwin -mdll -static %s' 
!                                         % (self.linker, entry_point))
          # Maybe we should also append -mthreads, but then the finished
          # dlls need another dll (mingwm10.dll see Mingw32 docs)
--- 324,328 ----
                               linker_exe='gcc -mno-cygwin',
                               linker_so='%s -mno-cygwin -mdll -static %s' 
!                                         % (self.linker_dll, entry_point))
          # Maybe we should also append -mthreads, but then the finished
          # dlls need another dll (mingwm10.dll see Mingw32 docs)

Index: msvccompiler.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/msvccompiler.py,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -r1.41 -r1.42
*** msvccompiler.py	2000/09/19 23:56:43	1.41
--- msvccompiler.py	2000/09/27 02:08:14	1.42
***************
*** 206,210 ****
  
              self.cc   = find_exe("cl.exe", version)
!             self.link = find_exe("link.exe", version)
              self.lib  = find_exe("lib.exe", version)
              self.rc   = find_exe("rc.exe", version)     # resource compiler
--- 206,210 ----
  
              self.cc   = find_exe("cl.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
***************
*** 222,226 ****
              # devstudio not found in the registry
              self.cc = "cl.exe"
!             self.link = "link.exe"
              self.lib = "lib.exe"
              self.rc = "rc.exe"
--- 222,226 ----
              # devstudio not found in the registry
              self.cc = "cl.exe"
!             self.linker = "link.exe"
              self.lib = "lib.exe"
              self.rc = "rc.exe"
***************
*** 397,440 ****
      # 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):
- 
          (objects, output_dir) = self._fix_object_args (objects, output_dir)
          (libraries, library_dirs, runtime_library_dirs) = \
--- 397,414 ----
      # create_static_lib ()
      
+     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) = \
***************
*** 453,460 ****
          if self._need_link (objects, output_filename):
  
!             if debug:
!                 ldflags = self.ldflags_shared_debug
              else:
!                 ldflags = self.ldflags_shared
  
              export_opts = []
--- 427,440 ----
          if self._need_link (objects, output_filename):
  
!             if target_desc == CCompiler.EXECUTABLE:
!                 if debug:
!                     ldflags = self.ldflags_shared_debug[1:]
!                 else:
!                     ldflags = self.ldflags_shared[1:]
              else:
!                 if debug:
!                     ldflags = self.ldflags_shared_debug
!                 else:
!                     ldflags = self.ldflags_shared
  
              export_opts = []
***************
*** 470,479 ****
              # 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 extra_preargs:
--- 450,460 ----
              # directory. Since they have different names for debug and release
              # builds, they can go into the same directory.
!             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:
***************
*** 484,488 ****
              self.mkpath (os.path.dirname (output_filename))
              try:
!                 self.spawn ([self.link] + ld_args)
              except DistutilsExecError, msg:
                  raise LinkError, msg
--- 465,469 ----
              self.mkpath (os.path.dirname (output_filename))
              try:
!                 self.spawn ([self.linker] + ld_args)
              except DistutilsExecError, msg:
                  raise LinkError, msg
***************
*** 491,546 ****
              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)   
-     
  
      # -- Miscellaneous methods -----------------------------------------
--- 472,477 ----
              self.announce ("skipping %s (up-to-date)" % output_filename)
  
!     # link ()
  
  
      # -- Miscellaneous methods -----------------------------------------

Index: unixccompiler.py
===================================================================
RCS file: /cvsroot/python/distutils/distutils/unixccompiler.py,v
retrieving revision 1.31
retrieving revision 1.32
diff -C2 -r1.31 -r1.32
*** unixccompiler.py	2000/09/26 01:56:15	1.31
--- unixccompiler.py	2000/09/27 02:08:14	1.32
***************
*** 191,234 ****
  
  
!     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):
- 
          (objects, output_dir) = self._fix_object_args(objects, output_dir)
          (libraries, library_dirs, runtime_library_dirs) = \
--- 191,208 ----
  
  
!     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,299 ****
                  ld_args.extend(extra_postargs)
              self.mkpath(os.path.dirname(output_filename))
-             try:
-                 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
--- 227,235 ----
                  ld_args.extend(extra_postargs)
              self.mkpath(os.path.dirname(output_filename))
              try:
!                 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
***************
*** 301,305 ****
              self.announce("skipping %s (up-to-date)" % output_filename)
  
!     # link_executable ()
  
  
--- 237,241 ----
              self.announce("skipping %s (up-to-date)" % output_filename)
  
!     # link ()