summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarek Ziadé <ziade.tarek@gmail.com>2009-05-09 08:28:53 (GMT)
committerTarek Ziadé <ziade.tarek@gmail.com>2009-05-09 08:28:53 (GMT)
commite2be83def891db39fd4b7b707247740bd28cd811 (patch)
treed13ef17339ecba456175c093d1a70bb9ded07121
parent809e22543f8bafd2df66fbe116ad49bbca5793f3 (diff)
downloadcpython-e2be83def891db39fd4b7b707247740bd28cd811.zip
cpython-e2be83def891db39fd4b7b707247740bd28cd811.tar.gz
cpython-e2be83def891db39fd4b7b707247740bd28cd811.tar.bz2
Fixed Issue 5900: distutils.command.build_ext - Ensure RUNPATH is added to extension modules with RPATH if GNU ld is used
-rw-r--r--Lib/distutils/tests/test_build_ext.py3
-rw-r--r--Lib/distutils/tests/test_unixccompiler.py93
-rw-r--r--Lib/distutils/unixccompiler.py24
-rw-r--r--Makefile.pre.in2
-rw-r--r--Misc/NEWS3
-rwxr-xr-xconfigure27
-rw-r--r--configure.in19
7 files changed, 163 insertions, 8 deletions
diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py
index 9097bee..141c286 100644
--- a/Lib/distutils/tests/test_build_ext.py
+++ b/Lib/distutils/tests/test_build_ext.py
@@ -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):
diff --git a/Lib/distutils/tests/test_unixccompiler.py b/Lib/distutils/tests/test_unixccompiler.py
new file mode 100644
index 0000000..94e9edf
--- /dev/null
+++ b/Lib/distutils/tests/test_unixccompiler.py
@@ -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")
diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py
index 045368a..0b1dc4a 100644
--- a/Lib/distutils/unixccompiler.py
+++ b/Lib/distutils/unixccompiler.py
@@ -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
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 8851216..8f91f88 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -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
diff --git a/Misc/NEWS b/Misc/NEWS
index fa362fd..485920a 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
diff --git a/configure b/configure
index 0379997..910542a 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/configure.in b/configure.in
index 1491417..d2c41a9 100644
--- a/configure.in
+++ b/configure.in
@@ -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))