libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: Support libtool -no-undefined under GNU/Linux (also *BSD, other G


From: Alexander Dupuy
Subject: PATCH: Support libtool -no-undefined under GNU/Linux (also *BSD, other GNU ld systems)
Date: Thu, 05 Jun 2003 16:56:13 -0400
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030314

On Feb  7, 2001, Mark Mitchell <address@hidden> wrote:
So, it would be really good if libtool would support -no-undefined
usage on GNU/Linux.  If that means working around a GNU linker bug,
isn't that the sort of thing libtool is supposed to do?

In the two year old message (thread) at:
 http://gcc.gnu.org/ml/gcc-patches/2001-02/msg00390.html

Alexandre Oliva <address@hidden> replies:
Yep.  I'm convinced.  I'll gladly accept patches that arrange for
libtool to use, in decreasing order of preference:

`${wl}--no-undefined', if running `$LD --no-undefined -shared -o
conftest -lc' works, otherwise

`${wl}--no-undefined ${wl}--allow-shlib-undefined', if running `$LD
--no-undefined -shared -o conftest -lc' works, otherwise,

empty, if everything else fails.

I'd rather not explicitly link libraries against /lib/ld-linux.so.*,
because this would introduce an unnecessary and possibly incorrect
dependence of the library being created on /lib/ld-linux.so.*.

If nobody beats me to it, I'll probably implement this myself some
day.

While I can't believe that two years later, I might have beaten him to this, the recent libtool-1.5 release still didn't have any support for this useful functionality. I had hacked something similar into libtool-1.4.something, but took this opportunity to do it more cleanly, per Alexandre's spec.

In my previous attempt, I had linked against /lib/ld-linux.so.2, but by actually passing --allow-shlib-undefined to the linker rather than the compiler, I found that wasn't necessary.

Anyhow, for anyone who (still) cares, attached are unidiffs to vanilla libtool 1.5 that implement libtool's -no-undefined option on GNU/Linux and other platforms that use GNU ld (e.g. *BSD variants, although I've only tested on Linux and FreeBSD 4.8).

I needed to add a -pthread flag so that on *BSD libtool could decide whether to add a dependency on -lc_r (to resolve undefined symbols) or just turn off the undefined symbol checking. While this does defeat the checking in the common case, that seemed preferable to creating shared libraries/modules that broke threaded applications. I figured that any application built with -pthread probably uses the extra functions in -lc_r, so adding a dependency there wasn't likely to break anything.

If there's a better solution for this (e.g. a way to add a shared library for resolving symbols without recording it in a NEEDED entry), I'd love to hear about it.

@alex

Index: libtool.m4
===================================================================
RCS file: /src/cvs/libtool/libtool.m4,v
retrieving revision 1.1.1.2
retrieving revision 1.4
diff -u -r1.1.1.2 -r1.4
--- libtool.m4  14 Apr 2003 21:58:23 -0000      1.1.1.2
+++ libtool.m4  31 May 2003 07:06:25 -0000      1.4
@@ -2569,6 +2569,24 @@
 esac
 AC_MSG_RESULT([$enable_shared])
 
+#
+# Check to see whether we can use GNU linker options --no-undefined (possibly
+# with --allow-shlib-undefined) to force failure on undefined references when
+# linking shared modules/libraries.
+#
+if test "$enable_shared" = "yes" -a "$_LT_AC_TAGVAR(allow_undefined_flag, $1)" 
!= "unsupported"; then
+  wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+  AC_LIBTOOL_LINKER_OPTION([if $compiler -shared ${wl}--no-undefined works],
+    _LT_AC_TAGVAR(shared_no_undefined_works, $1),
+    -shared ${wl}--no-undefined,
+    [_LT_AC_TAGVAR(shared_no_undefined_flag_spec, $1)='${wl}--no-undefined'],
+    AC_LIBTOOL_LINKER_OPTION([if adding ${wl}--allow-shlib-undefined does],
+      _LT_AC_TAGVAR(shared_no_undefined_allow_shlib_works, $1),
+      -shared ${wl}--no-undefined ${wl}--allow-shlib-undefined,
+      [_LT_AC_TAGVAR(shared_no_undefined_flag_spec, $1)='${wl}--no-undefined 
${wl}--allow-shlib-undefined'],
+      [_LT_AC_TAGVAR(shared_no_undefined_flag_spec, $1)=]))
+fi
+
 AC_MSG_CHECKING([whether to build static libraries])
 # Make sure either enable_shared or enable_static is yes.
 test "$enable_shared" = yes || enable_static=yes
@@ -2673,6 +2691,7 @@
   # Check if GNU C++ uses GNU ld as the underlying linker, since the
   # archiving commands below assume that GNU ld is being used.
   if test "$with_gnu_ld" = yes; then
+    # FIXME: consider adding $shared_no_undefined_flag_spec here
     _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects 
$libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o 
$lib'
     _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib 
$predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname 
$wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
@@ -3844,6 +3863,7 @@
     _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
     _LT_AC_TAGVAR(allow_undefined_flag, $1) \
     _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(shared_no_undefined_flag_spec, $1) \
     _LT_AC_TAGVAR(export_symbols_cmds, $1) \
     _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
     _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
@@ -3878,7 +3898,7 @@
   done
 
   case $lt_echo in
-  *'\[$]0 --fallback-echo"')
+  *'\[$]0 --fallback-echo"')           # " - for emacs font-lock
     lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 
--fallback-echo"[$]/[$]0 --fallback-echo"/'`
     ;;
   esac
@@ -4142,6 +4162,10 @@
 # Flag that forces no undefined symbols.
 no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
 
+# Flags that force no undefined symbols for shared libraries.
+eval 
shared_no_undefined_flag_spec=\"$lt_[]_LT_AC_TAGVAR(shared_no_undefined_flag_spec,
 $1)\"
+# (eval is needed to expand references to ${wl})
+
 # Commands used to finish a libtool library installation in a directory.
 finish_cmds=$lt_finish_cmds
 
@@ -5094,8 +5118,8 @@
        _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs 
$linker_flags -o $lib'
        wlarc=
       else
-       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file 
$wl$export_symbols -o $lib'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -5113,8 +5137,8 @@
 
 EOF
       elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; 
then
-       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file 
$wl$export_symbols -o $lib'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        _LT_AC_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -5129,8 +5153,8 @@
 
     *)
       if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
-       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs 
$compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file 
$wl$export_symbols -o $lib'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared 
$shared_no_undefined_flag_spec $libobjs $deplibs $compiler_flags ${wl}-soname 
$wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        _LT_AC_TAGVAR(ld_shlibs, $1)=no
       fi
Index: ltmain.in
===================================================================
RCS file: /src/cvs/libtool/ltmain.in,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- ltmain.in   14 Apr 2003 21:58:24 -0000      1.1.1.2
+++ ltmain.in   31 May 2003 07:06:25 -0000      1.2
@@ -876,6 +876,7 @@
     xrpath=
     perm_rpath=
     temp_rpath=
+    pthread=no
     thread_safe=no
     vinfo=
     vinfo_number=no
@@ -1392,6 +1393,16 @@
        continue
        ;;
 
+      -pthread)
+       pthread=yes
+       arg=-pthread
+       linker_flags="$linker_flags $arg"
+       compiler_flags="$compiler_flags $arg"
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+       continue
+       ;;
+
       -thread-safe)
        thread_safe=yes
        continue
@@ -3022,6 +3033,7 @@
            build_libtool_libs=no
            build_old_libs=yes
          fi
+         shared_no_undefined_flag_spec=
        else
          # Don't allow undefined symbols.
          allow_undefined_flag="$no_undefined_flag"
@@ -3114,7 +3126,21 @@
            ;;
          *-*-openbsd* | *-*-freebsd*)
            # Do not include libc due to us having libc/libc_r.
-           test "X$arg" = "X-lc" && continue
+           # (we make an exception if -no-undefined)
+           if test "$build_libtool_need_lc" = "yes"; then
+             if test -n "$shared_no_undefined_flag_spec"; then
+               if test "$pthread" = yes; then
+                 # if you ask for -pthread -no-undefined, you should not be
+                 # upset by a dependency on -lc_r (even if it's unnecessary)
+                 deplibs="$deplibs -lc_r"
+               else
+                 # by principle of least annoyance, rather than creating
+                 # a dependency on non-threaded -lc, just drop -no-undefined
+                 shared_no_undefined_flag_spec=
+                 # :BAD: deplibs="$deplibs -lc"
+               fi
+             fi
+           fi
            ;;
          *)
            # Add libc to deplibs on all other systems if necessary.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]