bug#54726: when linking a shared library on Linux, libtool 2.4.6 ignores libfoo.so arguments
Nicolas Boulenguez <[email protected]> Tue, 5 Apr 2022 12:50:59 +0200
| Newsgroups | gmane.comp.gnu.libtool.bugs |
|---|---|
| Message-ID | <YkwfE+ADs54LpIHz@pegase> |
Hello.
When linking a shared library or a program against a (locally built, not
installed) foo library, it is recommended to prefer
dir/libfoo.so
over
-Ldir -lfoo
which only adds complexity and unwanted ambiguity (for example,
/usr/lib/libfoo.{a,so} may silently be selected if dir/libfoo.so is
unexpectedly missing).
Libtool recognizes such options when linking a program, but ignores
them when linking a shared library.
The attached reproducer
* builds with -Ldir -lfoo in order to ensure that the sources are
correct
* demonstrates the link failure with a direct path
* builds with the attached patch applied and a direct path
Just in case it helps, the original bug report is here:
Bug-Debian: https://bugs.debian.org/960469
Thanks.
_______________________________________________
Bug-libtool mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-libtool
draft960469.diff
(text/x-diff, 1.1 KB)
Description: allow dir/libfoo.so as argument when linking a shared library This already works for programs, and is actually recommended for uninstalled yet libraries instead of the more ambiguous -Ldir -lfoo. Bug-Debian: https://bugs.debian.org/960469 Author: Nicolas Boulenguez <[email protected]> --- a/build-aux/ltmain.in +++ b/build-aux/ltmain.in @@ -5517,6 +5517,13 @@ continue ;; + *.so) + # An explicit path to a shared library. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + *.la) # A libtool-controlled library. @@ -5871,6 +5878,16 @@ func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; + *.so) + # FIXME: linkmode=prog copies .so arguments without this stanza. Duplicate code? + if test lib = "$linkmode"; then + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + elif test prog != "$linkmode"; then + func_warning "shared library '$deplib' ignored for archive/object" + fi + continue + ;; *.$libext) if test conv = "$pass"; then deplibs="$deplib $deplibs"
reproducer
(text/plain, 1.9 KB)
#!/bin/sh
# Demonstrate the issue and check the fix.
# Tested with GNU libtool 2.4.6 on Debian 5.10/GNU Linux x86_64.
fix=draft960469.diff
tmpdir=reproducer_temporary_directory
set -C -e -f -u -v
mkdir $tmpdir
cd $tmpdir
recreate_template() {
find . -mindepth 1 -delete
cat > hello.c <<EOF
#include <stdio.h>
void hello (void) {
printf ("If you are reading this, all probably went OK.\n");
}
EOF
cat > redirect.c <<EOF
void hello (void);
void redirect (void) {
hello ();
}
EOF
cat > main.c <<EOF
void redirect (void);
int main (void) {
redirect ();
return 0;
}
EOF
cat > configure.ac <<EOF
AC_INIT([foo], [0.0.0])
AC_CONFIG_MACRO_DIRS([m4])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
EOF
cat > Makefile.am <<EOF
ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = main
main_SOURCES = main.c
main_LDADD = libredirect.la
main_LDFLAGS = -Wl,-rpath-link=.
lib_LTLIBRARIES = libredirect.la
libredirect_la_SOURCES = redirect.c
# For unrelated reasons, libhello is unable to use libtool.
libhello.so: CFLAGS += -fPIC
libhello.so: hello.o
\$(LINK.c) -shared -o \$@ \$^
EOF
}
# Pass --no-undefined to the linker so that the bug is reported soon.
# Without it, libtool would fail later when trying to link main.o.
export LDFLAGS=-Wl,--no-undefined
# Traditional way (-L. -l:libhello.so). Should succeed.
recreate_template
echo 'libredirect_la_LIBADD = -L. -l:libhello.so' >> Makefile.am
echo 'EXTRA_libredirect_la_DEPENDENCIES = libhello.so' >> Makefile.am
autoreconf -i
./configure
make
LD_LIBRARY_PATH=. ./main
# Recommended way (libhello.so). Currently fails.
recreate_template
echo 'libredirect_la_LIBADD = libhello.so' >> Makefile.am
autoreconf -i
./configure
! make
# Recommended way, with libtool patched. Should succeed.
recreate_template
echo 'libredirect_la_LIBADD = libhello.so' >> Makefile.am
autoreconf -i
./configure
patch -p2 libtool ../$fix
make
LD_LIBRARY_PATH=. ./main