]> granicus.if.org Git - python/commitdiff
Patch from Rene Liebscher. Some ugly changes, but supposedly this makes
authorGreg Ward <gward@python.net>
Wed, 2 Aug 2000 01:03:23 +0000 (01:03 +0000)
committerGreg Ward <gward@python.net>
Wed, 2 Aug 2000 01:03:23 +0000 (01:03 +0000)
it so BCPPCompiler actually works, so I'm provisionally accepting it
-- ugly and working is better than not working!  Major changes:
  - normalize paths (apparently BC++ doesn't like slashes)
  - overhauled how we search for and specify libraries on the linker
    command-line
  - hacked up 'find_library_file()' so it knows about "debug" library
    naming convention as well as "bcpp_xxx.lib" -- the question is,
    is this a well-established and sensible convention?
Also:
  - change to use 'util.write_file()' to write the .def file

Lib/distutils/bcppcompiler.py

index 6c9ac827c1c4d1566860fa09c6cd7c42d3a47ac8..7daa597b75fbd711c0a1447cc02a4dfede7eefee 100644 (file)
@@ -11,17 +11,6 @@ for the Borland C++ compiler.
 # someone should sit down and factor out the common code as
 # WindowsCCompiler!  --GPW
 
-# XXX Lyle reports that this doesn't quite work yet:
-# """...but this is what I've got so far. The compile step works fine but
-# when it runs the link step I get an "out of memory" failure.  Since
-# spawn() echoes the command it's trying to spawn, I can type the link line
-# verbatim at the DOS prompt and it links the Windows DLL correctly -- so
-# the syntax is correct. There's just some weird interaction going on when
-# it tries to "spawn" the link process from within the setup.py script. I'm
-# not really sure how to debug this one right off-hand; obviously there's
-# nothing wrong with the "spawn()" function since it's working properly for
-# the compile stage."""
-
 __revision__ = "$Id$"
 
 
@@ -31,6 +20,7 @@ from distutils.errors import \
      CompileError, LibError, LinkError
 from distutils.ccompiler import \
      CCompiler, gen_preprocess_options, gen_lib_options
+from distutils.file_util import write_file
 
 
 class BCPPCompiler(CCompiler) :
@@ -123,14 +113,15 @@ class BCPPCompiler(CCompiler) :
                 elif ext in self._cpp_extensions:
                     input_opt = "-P"
 
+                src = os.path.normpath(src)
+                obj = os.path.normpath(obj)
+                
                 output_opt = "-o" + obj
-
-                self.mkpath (os.path.dirname (obj))
+                self.mkpath(os.path.dirname(obj))
 
                 # Compiler command line syntax is: "bcc32 [options] file(s)".
                 # Note that the source file names must appear at the end of
                 # the command line.
-
                 try:
                     self.spawn ([self.cc] + compile_opts + pp_opts +
                                 [input_opt, output_opt] +
@@ -212,6 +203,9 @@ class BCPPCompiler(CCompiler) :
                             extra_postargs=None,
                             build_temp=None):
 
+        # XXX this ignores 'build_temp'!  should follow the lead of
+        # msvccompiler.py
+
         (objects, output_dir) = self._fix_object_args (objects, output_dir)
         (libraries, library_dirs, runtime_library_dirs) = \
             self._fix_lib_args (libraries, library_dirs, runtime_library_dirs)
@@ -226,33 +220,63 @@ class BCPPCompiler(CCompiler) :
         if self._need_link (objects, output_filename):
 
             if debug:
-                ldflags = self.ldflags_shared_debug
+                ld_args = self.ldflags_shared_debug[:]
             else:
-                ldflags = self.ldflags_shared
+                ld_args = self.ldflags_shared[:]
 
+            # Borland C++ has problems with '/' in paths
+            objects = map(os.path.normpath, objects)
             startup_obj = 'c0d32'
+            objects.insert(0, startup_obj)
 
-            libraries.append ('mypylib')
+            # either exchange python15.lib in the python libs directory against
+            # a Borland-like one, or create one with name bcpp_python15.lib 
+            # there and remove the pragmas from config.h  
+            #libraries.append ('mypylib')            
             libraries.append ('import32')
             libraries.append ('cw32mt')
 
             # Create a temporary exports file for use by the linker
             head, tail = os.path.split (output_filename)
             modname, ext = os.path.splitext (tail)
-            def_file = os.path.join (build_temp, '%s.def' % modname)
-            f = open (def_file, 'w')
-            f.write ('EXPORTS\n')
+            temp_dir = os.path.dirname(objects[0]) # preserve tree structure
+            def_file = os.path.join (temp_dir, '%s.def' % modname)
+            contents = ['EXPORTS']
             for sym in (export_symbols or []):
-                f.write ('  %s=_%s\n' % (sym, sym))
-
-            ld_args = ldflags + [startup_obj] + objects + \
-                [',%s,,' % output_filename] + \
-                libraries + [',' + def_file]
+                contents.append('  %s=_%s' % (sym, sym))
+            self.execute(write_file, (def_file, contents),
+                         "writing %s" % def_file)
+
+            # Start building command line flags and options.
+
+            for l in library_dirs:
+                ld_args.append("/L%s" % os.path.normpath(l)) 
+                
+            ld_args.extend(objects)     # list of object files
+
+            # name of dll file
+            ld_args.extend([',',output_filename])
+            # no map file and start libraries 
+            ld_args.extend([',', ','])
+
+            for lib in libraries:
+                # see if we find it and if there is a bcpp specific lib 
+                # (bcpp_xxx.lib)
+                libfile = self.find_library_file(library_dirs, lib, debug)
+                if libfile is None:
+                    ld_args.append(lib)
+                    # probably a BCPP internal library -- don't warn
+                    #    self.warn('library %s not found.' % lib)
+                else:
+                    # full name which prefers bcpp_xxx.lib over xxx.lib
+                    ld_args.append(libfile)
+            # def file for export symbols
+            ld_args.extend([',',def_file])
             
             if extra_preargs:
                 ld_args[:0] = extra_preargs
             if extra_postargs:
-                ld_args.extend (extra_postargs)
+                ld_args.extend(extra_postargs)
 
             self.mkpath (os.path.dirname (output_filename))
             try:
@@ -325,15 +349,32 @@ class BCPPCompiler(CCompiler) :
 
     def runtime_library_dir_option (self, dir):
         raise DistutilsPlatformError, \
-              "don't know how to set runtime library search path for MSVC++"
+              ("don't know how to set runtime library search path "
+               "for Borland C++")
 
     def library_option (self, lib):
         return self.library_filename (lib)
 
 
-    def find_library_file (self, dirs, lib):
-
+    def find_library_file (self, dirs, lib, debug=0):
+        # find library file
+        # bcpp_xxx.lib is better than xxx.lib
+        # and xxx_d.lib is better than xxx.lib if debug is set
         for dir in dirs:
+            if debug:
+                libfile = os.path.join (
+                    dir, self.library_filename ("bcpp_" + lib + "_d"))
+                if os.path.exists (libfile):
+                    return libfile
+            libfile = os.path.join (
+                dir, self.library_filename ("bcpp_" + lib))
+            if os.path.exists (libfile):
+                return libfile
+            if debug:
+                libfile = os.path.join (
+                    dir, self.library_filename(lib + '_d'))
+                if os.path.exists (libfile):
+                    return libfile
             libfile = os.path.join (dir, self.library_filename (lib))
             if os.path.exists (libfile):
                 return libfile