[Top][All Lists]
[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.
- PATCH: Support libtool -no-undefined under GNU/Linux (also *BSD, other GNU ld systems),
Alexander Dupuy <=