]> granicus.if.org Git - python/commitdiff
Fixed Issue 5900: distutils.command.build_ext - Ensure RUNPATH is added to extension...
authorTarek Ziadé <ziade.tarek@gmail.com>
Sat, 9 May 2009 08:28:53 +0000 (08:28 +0000)
committerTarek Ziadé <ziade.tarek@gmail.com>
Sat, 9 May 2009 08:28:53 +0000 (08:28 +0000)
Lib/distutils/tests/test_build_ext.py
Lib/distutils/tests/test_unixccompiler.py [new file with mode: 0644]
Lib/distutils/unixccompiler.py
Makefile.pre.in
Misc/NEWS
configure
configure.in

index 9097bee2e45c43b69dfe85f2d3c42e6c6e7f20d5..141c2869b59587072226f827add874dcee9d8db3 100644 (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):
diff --git a/Lib/distutils/tests/test_unixccompiler.py b/Lib/distutils/tests/test_unixccompiler.py
new file mode 100644 (file)
index 0000000..94e9edf
--- /dev/null
@@ -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")
index 045368a925d7204b5d7a6fc2129be47789dd080f..0b1dc4af7d33aa714f287f5336017bc4c7ae3d6d 100644 (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
index 88512164215aeab3bef2af35ff781e46265412fd..8f91f88485b46945a12a33d0edc206a67ada3c19 100644 (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
 
index fa362fd929b458aa7fdc5cde11069bbd2ebede14..485920a5c43c628c103929bbe61f71222ebe1d2c 100644 (file)
--- 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
index 0379997ca979e8eb5495ba821e8b1eb874718d38..910542ae67982ff3f22fab41c3f11b7f67f8362c 100755 (executable)
--- 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
index 1491417ea0191942df8189f22bb4ac0f9d0c2cfa..d2c41a9141e17a714ded796204088b8a74906878 100644 (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))