Fixed Issue 5900: distutils.command.build_ext - Ensure RUNPATH is added to extension modules with RPATH if GNU ld is used

This commit is contained in:
Tarek Ziadé 2009-05-09 08:28:53 +00:00
parent 809e22543f
commit e2be83def8
7 changed files with 163 additions and 8 deletions

View File

@ -125,7 +125,7 @@ class BuildExtTestCase(support.TempdirManager,
dist = Distribution({'name': 'xx'})
cmd = build_ext(dist)
# making sure the suer option is there
# making sure the user option is there
options = [name for name, short, lable in
cmd.user_options]
self.assert_('user' in options)
@ -145,6 +145,7 @@ class BuildExtTestCase(support.TempdirManager,
# see if include_dirs and library_dirs
# were set
self.assert_(lib in cmd.library_dirs)
self.assert_(lib in cmd.rpath)
self.assert_(incl in cmd.include_dirs)
def test_optional_extension(self):

View File

@ -0,0 +1,93 @@
"""Tests for distutils.unixccompiler."""
import sys
import unittest
from distutils import sysconfig
from distutils.unixccompiler import UnixCCompiler
class UnixCCompilerTestCase(unittest.TestCase):
def setUp(self):
self._backup_platform = sys.platform
self._backup_get_config_var = sysconfig.get_config_var
class CompilerWrapper(UnixCCompiler):
def rpath_foo(self):
return self.runtime_library_dir_option('/foo')
self.cc = CompilerWrapper()
def tearDown(self):
sys.platform = self._backup_platform
sysconfig.get_config_var = self._backup_get_config_var
def test_runtime_libdir_option(self):
# not tested under windows
if sys.platform == 'win32':
return
# Issue#5900
#
# Ensure RUNPATH is added to extension modules with RPATH if
# GNU ld is used
# darwin
sys.platform = 'darwin'
self.assertEqual(self.cc.rpath_foo(), '-L/foo')
# hp-ux
sys.platform = 'hp-ux'
self.assertEqual(self.cc.rpath_foo(), '+s -L/foo')
# irix646
sys.platform = 'irix646'
self.assertEqual(self.cc.rpath_foo(), ['-rpath', '/foo'])
# osf1V5
sys.platform = 'osf1V5'
self.assertEqual(self.cc.rpath_foo(), ['-rpath', '/foo'])
# GCC GNULD
sys.platform = 'bar'
def gcv(v):
if v == 'CC':
return 'gcc'
elif v == 'GNULD':
return 'yes'
sysconfig.get_config_var = gcv
self.assertEqual(self.cc.rpath_foo(), '-Wl,--enable-new-dtags,-R/foo')
# GCC non-GNULD
sys.platform = 'bar'
def gcv(v):
if v == 'CC':
return 'gcc'
elif v == 'GNULD':
return 'no'
sysconfig.get_config_var = gcv
self.assertEqual(self.cc.rpath_foo(), '-Wl,-R/foo')
# non-GCC GNULD
sys.platform = 'bar'
def gcv(v):
if v == 'CC':
return 'cc'
elif v == 'GNULD':
return 'yes'
sysconfig.get_config_var = gcv
self.assertEqual(self.cc.rpath_foo(), '-R/foo')
# non-GCC non-GNULD
sys.platform = 'bar'
def gcv(v):
if v == 'CC':
return 'cc'
elif v == 'GNULD':
return 'no'
sysconfig.get_config_var = gcv
self.assertEqual(self.cc.rpath_foo(), '-R/foo')
def test_suite():
return unittest.makeSuite(UnixCCompilerTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")

View File

@ -273,8 +273,9 @@ class UnixCCompiler(CCompiler):
# Linkers on different platforms need different options to
# specify that directories need to be added to the list of
# directories searched for dependencies when a dynamic library
# is sought. GCC has to be told to pass the -R option through
# to the linker, whereas other compilers just know this.
# is sought. GCC on GNU systems (Linux, FreeBSD, ...) has to
# be told to pass the -R option through to the linker, whereas
# other compilers and gcc on other systems just know this.
# Other compilers may need something slightly different. At
# this time, there's no way to determine this information from
# the configuration data stored in the Python installation, so
@ -287,10 +288,23 @@ class UnixCCompiler(CCompiler):
return "+s -L" + dir
elif sys.platform[:7] == "irix646" or sys.platform[:6] == "osf1V5":
return ["-rpath", dir]
elif compiler[:3] == "gcc" or compiler[:3] == "g++":
return "-Wl,-R" + dir
else:
return "-R" + dir
if compiler[:3] == "gcc" or compiler[:3] == "g++":
# gcc on non-GNU systems does not need -Wl, but can
# use it anyway. Since distutils has always passed in
# -Wl whenever gcc was used in the past it is probably
# safest to keep doing so.
if sysconfig.get_config_var("GNULD") == "yes":
# GNU ld needs an extra option to get a RUNPATH
# instead of just an RPATH.
return "-Wl,--enable-new-dtags,-R" + dir
else:
return "-Wl,-R" + dir
else:
# No idea how --enable-new-dtags would be passed on to
# ld if this system was using GNU ld. Don't know if a
# system like this even exists.
return "-R" + dir
def library_option(self, lib):
return "-l" + lib

View File

@ -36,6 +36,8 @@ AR= @AR@
RANLIB= @RANLIB@
SVNVERSION= @SVNVERSION@
GNULD= @GNULD@
# Shell used by make (some versions default to the login shell, which is bad)
SHELL= /bin/sh

View File

@ -285,6 +285,9 @@ Core and Builtins
Library
-------
- Issue #5900: Ensure RUNPATH is added to extension modules with RPATH if GNU
ld is used. Original patch by Floris Bruynooghe.
- Issue #5941: Distutils build_clib command was not working anymore because
of an incomplete costumization of the archiver command. Added ARFLAGS in the
Makefile besides AR and make Distutils use it. Original patch by David

27
configure vendored
View File

@ -695,6 +695,7 @@ LDLIBRARYDIR
INSTSONAME
RUNSHARED
LINKCC
GNULD
RANLIB
AR
ARFLAGS
@ -3998,6 +3999,27 @@ fi
{ echo "$as_me:$LINENO: result: $LINKCC" >&5
echo "${ECHO_T}$LINKCC" >&6; }
# GNULD is set to "yes" if the GNU linker is used. If this goes wrong
# make sure we default having it set to "no": this is used by
# distutils.unixccompiler to know if it should add --enable-new-dtags
# to linker command lines, and failing to detect GNU ld simply results
# in the same bahaviour as before.
{ echo "$as_me:$LINENO: checking for GNU ld" >&5
echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6; }
ac_prog=ld
if test "$GCC" = yes; then
ac_prog=`$CC -print-prog-name=ld`
fi
case `"$ac_prog" -V 2>&1 < /dev/null` in
*GNU*)
GNULD=yes;;
*)
GNULD=no;;
esac
{ echo "$as_me:$LINENO: result: $GNULD" >&5
echo "${ECHO_T}$GNULD" >&6; }
{ echo "$as_me:$LINENO: checking for --enable-shared" >&5
echo $ECHO_N "checking for --enable-shared... $ECHO_C" >&6; }
# Check whether --enable-shared was given.
@ -26042,6 +26064,7 @@ LDLIBRARYDIR!$LDLIBRARYDIR$ac_delim
INSTSONAME!$INSTSONAME$ac_delim
RUNSHARED!$RUNSHARED$ac_delim
LINKCC!$LINKCC$ac_delim
GNULD!$GNULD$ac_delim
RANLIB!$RANLIB$ac_delim
AR!$AR$ac_delim
ARFLAGS!$ARFLAGS$ac_delim
@ -26059,7 +26082,6 @@ SO!$SO$ac_delim
LDSHARED!$LDSHARED$ac_delim
BLDSHARED!$BLDSHARED$ac_delim
CCSHARED!$CCSHARED$ac_delim
LINKFORSHARED!$LINKFORSHARED$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@ -26101,6 +26123,7 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
LINKFORSHARED!$LINKFORSHARED$ac_delim
CFLAGSFORSHARED!$CFLAGSFORSHARED$ac_delim
SHLIBS!$SHLIBS$ac_delim
USE_SIGNAL_MODULE!$USE_SIGNAL_MODULE$ac_delim
@ -26126,7 +26149,7 @@ SRCDIRS!$SRCDIRS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 23; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 24; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -647,6 +647,25 @@ then
fi
AC_MSG_RESULT($LINKCC)
# GNULD is set to "yes" if the GNU linker is used. If this goes wrong
# make sure we default having it set to "no": this is used by
# distutils.unixccompiler to know if it should add --enable-new-dtags
# to linker command lines, and failing to detect GNU ld simply results
# in the same bahaviour as before.
AC_SUBST(GNULD)
AC_MSG_CHECKING(for GNU ld)
ac_prog=ld
if test "$GCC" = yes; then
ac_prog=`$CC -print-prog-name=ld`
fi
case `"$ac_prog" -V 2>&1 < /dev/null` in
*GNU*)
GNULD=yes;;
*)
GNULD=no;;
esac
AC_MSG_RESULT($GNULD)
AC_MSG_CHECKING(for --enable-shared)
AC_ARG_ENABLE(shared,
AC_HELP_STRING(--enable-shared, disable/enable building shared python library))