summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTarek Ziadé <ziade.tarek@gmail.com>2009-05-09 08:28:53 +0000
committerTarek Ziadé <ziade.tarek@gmail.com>2009-05-09 08:28:53 +0000
commite2be83def891db39fd4b7b707247740bd28cd811 (patch)
treed13ef17339ecba456175c093d1a70bb9ded07121
parent809e22543f8bafd2df66fbe116ad49bbca5793f3 (diff)
downloadcpython-git-e2be83def891db39fd4b7b707247740bd28cd811.tar.gz
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 9097bee2e4..141c2869b5 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 0000000000..94e9edfc09
--- /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 045368a925..0b1dc4af7d 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 8851216421..8f91f88485 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 fa362fd929..485920a5c4 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 0379997ca9..910542ae67 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 1491417ea0..d2c41a9141 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))