Bug report: debug builds on msvc compiler don't specify *_d.lib a s link sources
In ccompiler, you have this code in gen_lib_options: for lib in libraries: (lib_dir, lib_name) = os.path.split (lib) if lib_dir: lib_file = compiler.find_library_file ([lib_dir], lib_name) if lib_file: lib_opts.append (lib_file) else: compiler.warn ("no library file corresponding to " "'%s' found (skipping)" % lib) else: lib_opts.append (compiler.library_option (lib)) Note that you aren't passing "debug" to compiler.find_library_file, so the debug libraries will never get used. Also note that msvccompiler doesn't provide for passing the debug flag to library_option, so it doesn't do the proper name mangling (adding _d) for the library name. I'm guessing you'll need to make gen_lib_options get passed the debug flag, and then make it pass that flag on to the compiler methods. No clue what to do for non-vc++ compilers (or even if they need debug flags). Enjoy, Mike
In ccompiler, you have this code in gen_lib_options:
for lib in libraries: (lib_dir, lib_name) = os.path.split (lib) if lib_dir: lib_file = compiler.find_library_file ([lib_dir], lib_name) if lib_file: lib_opts.append (lib_file) else: compiler.warn ("no library file corresponding to " "'%s' found (skipping)" % lib) else: lib_opts.append (compiler.library_option (lib))
Note that you aren't passing "debug" to compiler.find_library_file, so the debug libraries will never get used. Also note that msvccompiler doesn't provide for passing the debug flag to library_option, so it doesn't do the proper name mangling (adding _d) for the library name. I'm guessing you'll need to make gen_lib_options get passed the debug flag, and then make it pass that flag on to the compiler methods. No clue what to do for non-vc++ compilers (or even if they need debug flags).
You are completely right: MSVCCompiler links with the wrong library on debug builds. I just tried and noticed that python15.lib is explicitely passed to the linker (for both debug and release builds) although this is completely unneccessary for MSVC, since the python import library is already set with in pragma in Python.h. Maybe you should try one of the older code snapshots (for a certain definition of 'old')... Thomas
Thomas Heller wrote:
In ccompiler, you have this code in gen_lib_options:
for lib in libraries: (lib_dir, lib_name) = os.path.split (lib) if lib_dir: lib_file = compiler.find_library_file ([lib_dir], lib_name) if lib_file: lib_opts.append (lib_file) else: compiler.warn ("no library file corresponding to " "'%s' found (skipping)" % lib) else: lib_opts.append (compiler.library_option (lib))
Note that you aren't passing "debug" to compiler.find_library_file, so the debug libraries will never get used. Also note that msvccompiler doesn't provide for passing the debug flag to library_option, so it doesn't do the proper name mangling (adding _d) for the library name. I'm guessing you'll need to make gen_lib_options get passed the debug flag, and then make it pass that flag on to the compiler methods. No clue what to do for non-vc++ compilers (or even if they need debug flags).
BorlandCCompiler doesn't use gen_lib_options() and handles debug libraries correct. It uses its own find_library_file() which uses python15_d.lib (or python15_d_bcpp.lib) if it exists. MSVCCompiler has also its own find_library_file() method which works the same way. The only problem is that gen_lib_option() calls it without the debug parameter. I made the changes you describe above in a patch (gen_lib_options.patch). The only problem is now, it is not tested by me because I'm currently 20 km away from my msvccompiler-distutils-test-machine.
You are completely right: MSVCCompiler links with the wrong library on debug builds.
I just tried and noticed that python15.lib is explicitely passed to the linker (for both debug and release builds) although this is completely unneccessary for MSVC, since the python import library is already set with in pragma in Python.h.
Explicitely passing 'python15' as library should not be problem if gen_lib_options() works correct. (You would name a library twice (pragma and explicit) for MSVC, but on the other side 'build_ext' doesn't need to know about special compiler classes.) kind regards Rene Liebscher diff -BurN --exclude=*.pyc --minimal distutils/distutils/ccompiler.py distutils.patched/distutils/ccompiler.py --- distutils/distutils/ccompiler.py Wed Sep 27 11:26:08 2000 +++ distutils.patched/distutils/ccompiler.py Fri Sep 29 13:11:54 2000 @@ -969,7 +969,11 @@ # gen_preprocess_options () -def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries): +def gen_lib_options (compiler, + library_dirs, + runtime_library_dirs, + libraries, + debug=0): """Generate linker options for searching library directories and linking with specific libraries. 'libraries' and 'library_dirs' are, respectively, lists of library names (not filenames!) and search @@ -993,7 +997,7 @@ for lib in libraries: (lib_dir, lib_name) = os.path.split (lib) if lib_dir: - lib_file = compiler.find_library_file ([lib_dir], lib_name) + lib_file = compiler.find_library_file ([lib_dir], lib_name, debug) if lib_file: lib_opts.append (lib_file) else: diff -BurN --exclude=*.pyc --minimal distutils/distutils/command/build_ext.py distutils.patched/distutils/command/build_ext.py --- distutils/distutils/command/build_ext.py Fri Sep 29 10:24:57 2000 +++ distutils.patched/distutils/command/build_ext.py Fri Sep 29 13:16:08 2000 @@ -568,8 +568,8 @@ if sys.platform == "win32" and \ not isinstance(self.compiler, MSVCCompiler): template = "python%d%d" - if self.debug: - template = template + '_d' + #if self.debug: + # template = template + '_d' pythonlib = (template % (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) # don't extend ext.libraries, it may be shared with other diff -BurN --exclude=*.pyc --minimal distutils/distutils/msvccompiler.py distutils.patched/distutils/msvccompiler.py --- distutils/distutils/msvccompiler.py Wed Sep 27 11:26:10 2000 +++ distutils.patched/distutils/msvccompiler.py Fri Sep 29 13:12:34 2000 @@ -420,7 +420,7 @@ lib_opts = gen_lib_options (self, library_dirs, runtime_library_dirs, - libraries) + libraries, debug) if output_dir is not None: output_filename = os.path.join (output_dir, output_filename)
BorlandCCompiler doesn't use gen_lib_options() and handles debug libraries correct. It uses its own find_library_file() which uses python15_d.lib (or python15_d_bcpp.lib) if it exists. MSVCCompiler has also its own find_library_file() method which works the same way. The only problem is that gen_lib_option() calls it without the debug parameter.
Your patch does not work for MSVC: msvccompiler->link() is called with libraries = [..., 'python15'] This calls gen_lib_options() in ccompiler, this calls msvccompiler->library_option() this calls msvccompiler->library_filename('python15'), which is implemented in the CCompiler superclass, and this returns 'python15.lib' EVEN IF debug is set. Bang!
I made the changes you describe above in a patch (gen_lib_options.patch). The only problem is now, it is not tested by me because I'm currently 20 km away from my msvccompiler-distutils-test-machine.
You can test all compilers without having them by something like setup.py build_ext [-g] -n --compiler=[bcpp|msvc|...] (note the -n flag) and looking at the output. Nice feature! BTW: I already have checked in my patches (with the special casing of MSVCCompiler in build_ext removed again). Maybe this is not the right way to do it, but it works. I tested it with several distributions: Numerical-15.3 (from sourceforge), ExtensionClass-2.2.1 and ZODB-2.2.1 (distutilized by akuchling), PyXML-0.5.5.1 from xml-sig, LinkChecker-1.2.5 (sourceforge). in debug and release builds. Maybe I did it not the nicest way, but they work, and currently I'm more worried about the python 2.0 (and distutils 1.0) release schedule than anything else. Hopefully you (and maybe others) can also test the CVS version even more. Thomas
Thomas Heller wrote:
BorlandCCompiler doesn't use gen_lib_options() and handles debug libraries correct. It uses its own find_library_file() which uses python15_d.lib (or python15_d_bcpp.lib) if it exists. MSVCCompiler has also its own find_library_file() method which works the same way. The only problem is that gen_lib_option() calls it without the debug parameter.
Your patch does not work for MSVC:
msvccompiler->link() is called with libraries = [..., 'python15'] This calls gen_lib_options() in ccompiler, this calls msvccompiler->library_option() this calls msvccompiler->library_filename('python15'), which is implemented in the CCompiler superclass, and this returns 'python15.lib' EVEN IF debug is set. Bang!
I see, there is a second path in gen_lib_options() which uses library_option(). So we have now another candidate for a debug parameter. Good to know, I think, the problem will then have to be fixed after the release of Distutils 1.0. Rene
participants (3)
-
Mike Fletcher
-
Rene Liebscher
-
Thomas Heller