#21 ell fails to link with slibtool (no dlopen)
Closed 3 years ago by midipix. Opened 3 years ago by rossburton.

Building ell with slibtool fails:

/usr/src/debug/ell/0.33-r0/build/../ell-0.33/ell/plugin.c:68: undefined reference to `dlclose'

Of note is that slibtool is passing no-undefined to the linker, whereas libtool does not. Neither are actually passing -ldl, which you'd think would be needed.

If this is intentional then feel free to close.


The core link commands for both libtool and slibtool:

aarch64-poky-linux-libtool: link: aarch64-poky-linux-gcc
-mcpu=neoverse-n1+crc+crypto -fstack-protector-strong  -D_FORTIFY_SOURCE=2
-Wformat -Wformat-security -Werror=format-security
--sysroot=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0/recipe-sysroot
-shared  -fPIC -DPIC  ell/.libs/util.o ell/.libs/test.o ell/.libs/strv.o
ell/.libs/utf8.o ell/.libs/queue.o ell/.libs/hashmap.o ell/.libs/string.o
ell/.libs/settings.o ell/.libs/main.o ell/.libs/idle.o ell/.libs/signal.o
ell/.libs/timeout.o ell/.libs/io.o ell/.libs/ringbuf.o ell/.libs/log.o
ell/.libs/plugin.o ell/.libs/checksum.o ell/.libs/netlink.o ell/.libs/genl.o
ell/.libs/rtnl.o ell/.libs/dbus.o ell/.libs/dbus-message.o ell/.libs/dbus-util.o
ell/.libs/dbus-service.o ell/.libs/dbus-client.o ell/.libs/dbus-name-cache.o
ell/.libs/dbus-filter.o ell/.libs/gvariant-util.o ell/.libs/siphash.o
ell/.libs/hwdb.o ell/.libs/cipher.o ell/.libs/random.o ell/.libs/uintset.o
ell/.libs/base64.o ell/.libs/pem.o ell/.libs/tls.o ell/.libs/tls-record.o
ell/.libs/tls-extensions.o ell/.libs/tls-suites.o ell/.libs/uuid.o
ell/.libs/key.o ell/.libs/pkcs5.o ell/.libs/file.o ell/.libs/dir.o
ell/.libs/net.o ell/.libs/dhcp.o ell/.libs/dhcp-transport.o
ell/.libs/dhcp-lease.o ell/.libs/dhcp6.o ell/.libs/dhcp6-transport.o
ell/.libs/dhcp6-lease.o ell/.libs/cert.o ell/.libs/ecc-external.o
ell/.libs/ecc.o ell/.libs/ecdh.o ell/.libs/time.o ell/.libs/gpio.o
ell/.libs/path.o    -mcpu=neoverse-n1+crc+crypto -fstack-protector-strong
--sysroot=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0/recipe-sysroot
-O2 -g -Wl,--version-script=../ell-0.33/ell/ell.sym -Wl,-O1 -Wl,--hash-style=gnu
-Wl,--as-needed -Wl,-z -Wl,relro -Wl,-z -Wl,now   -Wl,-soname -Wl,libell.so.0 -o
ell/.libs/libell.so.0.0.2
slibtool: link: aarch64-poky-linux-gcc ell/.libs/util.o ell/.libs/test.o
ell/.libs/strv.o ell/.libs/utf8.o ell/.libs/queue.o ell/.libs/hashmap.o
ell/.libs/string.o ell/.libs/settings.o ell/.libs/main.o ell/.libs/idle.o
ell/.libs/signal.o ell/.libs/timeout.o ell/.libs/io.o ell/.libs/ringbuf.o
ell/.libs/log.o ell/.libs/plugin.o ell/.libs/checksum.o ell/.libs/netlink.o
ell/.libs/genl.o ell/.libs/rtnl.o ell/.libs/dbus.o ell/.libs/dbus-message.o
ell/.libs/dbus-util.o ell/.libs/dbus-service.o ell/.libs/dbus-client.o
ell/.libs/dbus-name-cache.o ell/.libs/dbus-filter.o ell/.libs/gvariant-util.o
ell/.libs/siphash.o ell/.libs/hwdb.o ell/.libs/cipher.o ell/.libs/random.o
ell/.libs/uintset.o ell/.libs/base64.o ell/.libs/pem.o ell/.libs/tls.o
ell/.libs/tls-record.o ell/.libs/tls-extensions.o ell/.libs/tls-suites.o
ell/.libs/uuid.o ell/.libs/key.o ell/.libs/pkcs5.o ell/.libs/file.o
ell/.libs/dir.o ell/.libs/net.o ell/.libs/dhcp.o ell/.libs/dhcp-transport.o
ell/.libs/dhcp-lease.o ell/.libs/dhcp6.o ell/.libs/dhcp6-transport.o
ell/.libs/dhcp6-lease.o ell/.libs/cert.o ell/.libs/ecc-external.o
ell/.libs/ecc.o ell/.libs/ecdh.o ell/.libs/time.o ell/.libs/gpio.o
ell/.libs/path.o -mcpu=neoverse-n1+crc+crypto -fstack-protector-strong
-D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security
--sysroot=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0/recipe-sysroot
-fvisibility=hidden -DUNITDIR="../ell-0.33/unit/" -DCERTDIR="./unit/" -O2 -pipe
-g -feliminate-unused-debug-types
-fmacro-prefix-map=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0=/usr/src/debug/ell/0.33-r0
-fdebug-prefix-map=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0=/usr/src/debug/ell/0.33-r0
-fdebug-prefix-map=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0/recipe-sysroot=
-fdebug-prefix-map=/home/ross/Yocto/build/tmp/work/neoversen1-poky-linux/ell/0.33-r0/recipe-sysroot-native=
-Wl,--version-script=../ell-0.33/ell/ell.sym -Wl,-O1 -Wl,--hash-style=gnu
-Wl,--as-needed -Wl,-z,relro,-z,now -shared -fPIC -Wl,--no-undefined -Wl,-soname
-Wl,libell.so.0 -o ell/.libs/libell.so.0.0.2

(I also see that slibtool is passing CPPFLAGS to the linker)

What is ell? Can you please link to their upstream source?

Thanks, confirmed here too.

slibtool: 2c4e5f9
libtool: 2.4.6
libell: https://git.kernel.org/pub/scm/libs/ell/ell.git/commit/?id=c156b921accae7d556f5d4166d02c0204cd50f56

rdlibtool: link: ln -s /dev/null ell/.libs/libell.a.disabled
rdlibtool: link: clang ell/.libs/util.o ell/.libs/test.o ell/.libs/strv.o ell/.libs/utf8.o ell/.libs/queue.o ell/.libs/hashmap.o ell/.libs/string.o ell/.libs/settings.o ell/.libs/main.o ell/.libs/idle.o ell/.libs/signal.o ell/.libs/timeout.o ell/.libs/io.o ell/.libs/ringbuf.o ell/.libs/log.o ell/.libs/plugin.o ell/.libs/checksum.o ell/.libs/netlink.o ell/.libs/genl.o ell/.libs/rtnl.o ell/.libs/dbus.o ell/.libs/dbus-message.o ell/.libs/dbus-util.o ell/.libs/dbus-service.o ell/.libs/dbus-client.o ell/.libs/dbus-name-cache.o ell/.libs/dbus-filter.o ell/.libs/gvariant-util.o ell/.libs/siphash.o ell/.libs/hwdb.o ell/.libs/cipher.o ell/.libs/random.o ell/.libs/uintset.o ell/.libs/base64.o ell/.libs/pem.o ell/.libs/tls.o ell/.libs/tls-record.o ell/.libs/tls-extensions.o ell/.libs/tls-suites.o ell/.libs/uuid.o ell/.libs/key.o ell/.libs/pkcs5.o ell/.libs/file.o ell/.libs/dir.o ell/.libs/net.o ell/.libs/dhcp.o ell/.libs/dhcp-transport.o ell/.libs/dhcp-lease.o ell/.libs/dhcp6.o ell/.libs/dhcp6-transport.o ell/.libs/dhcp6-lease.o ell/.libs/cert.o ell/.libs/ecc-external.o ell/.libs/ecc.o ell/.libs/ecdh.o ell/.libs/time.o ell/.libs/gpio.o ell/.libs/path.o -fvisibility=hidden -DUNITDIR="./unit/" -DCERTDIR="./unit/" -Wall -O2 -fsigned-char -fno-exceptions -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -Wl,--version-script=./ell/ell.sym -shared -fPIC -Wl,--no-undefined -Wl,-soname -Wl,libell.so.0 -o ell/.libs/libell.so.0.0.2
/usr/bin/ld: ell/.libs/plugin.o: in function `l_plugin_load':
plugin.c:(.text+0x1a4): undefined reference to `dlclose'
/usr/bin/ld: plugin.c:(.text+0x1c6): undefined reference to `dlopen'
/usr/bin/ld: plugin.c:(.text+0x1d9): undefined reference to `dlsym'
/usr/bin/ld: plugin.c:(.text+0x20a): undefined reference to `dlerror'
/usr/bin/ld: ell/.libs/plugin.o: in function `plugin_destroy':
plugin.c:(.text+0x2f2): undefined reference to `dlclose'
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
rdlibtool: exec error upon slbt_exec_link_create_library(), line 1446: (see child process error messages).
rdlibtool: < returned to > slbt_exec_link(), line 1836.
make[1]: *** [Makefile:1416: ell/libell.la] Error 2
make: *** [Makefile:1233: all] Error 2
~

Reproduction:
1. autoreconf -fi
2. ./configure
3. make

slibtool log: http://slackless.raccoons.tech/logs/libell-slibtool-1.log
libtool log: http://slackless.raccoons.tech/logs/libell-libtool.log

Maybe because -dlopen is a no-op currently. See 05ca7ea.

I can't decide if this is a ell bug that libtool hides (fails to link to libdl, doesn't pass flags to make that an error) or slibtool (warns for undefined by default instead of opt-in).

I think this is because slibtool sees -Wl,--no-undefined while libtool doesn't. The libtool link command will fail in the same way if its added.

Also I think libell is abusing AM_CFLAGS which contains the CPPFLAGS and libtool silently swallows them while slibtool does not.

It will build with slibtool using this patch, I am not sure if this is correct.

diff --git a/Makefile.am b/Makefile.am
index 4eb20c6..b58e9fc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,8 +138,7 @@ ell_libell_la_SOURCES = $(linux_headers) \
            ell/gpio.c \
            ell/path.c

-ell_libell_la_LDFLAGS = -no-undefined \
-           -Wl,--version-script=$(top_srcdir)/ell/ell.sym \
+ell_libell_la_LDFLAGS = -Wl,--version-script=$(top_srcdir)/ell/ell.sym \
            -version-info $(ELL_CURRENT):$(ELL_REVISION):$(ELL_AGE)

 ell_libell_la_DEPENDENCIES = ell/ell.sym

libtool seems to swallow the -no-undefined for the relevant linker command.

@rossburton For future reference its much more useful to share the log output from rdlibtool instead of rlibtool or slibtool so that we can see the more verbose debug output.

For example:

export MAKEFLAGS='LIBTOOL=rdlibtool V=1'

Where V=1 is verbose output for make(1).

I can't decide if this is a ell bug that libtool hides (fails to link to libdl, doesn't pass flags to make that an error) or slibtool (warns for undefined by default instead of opt-in).

That actually is not the case: slibtool never adds -Wl,--no-undefined out of own initiative, however a documented difference between slibtool and gnu libtool is that slibtool does respect -no-undefined, while with gnu libtool that switch appears to be a no-op. The slibtool policy to respect -no-undefined has in fact helped discover several bugs (missing -lfoo arguments) in third-party projects.

As @orbea has noted earlier, -no-undefined does come form ell's Makefile rules.

It will build with slibtool using this patch, I am not sure if this is correct.<

I'd say the above patch is very incorrect:‑P

More specifically, since ell seems to be referring to dlopen(3) then they simply need to add the -ldl directive to ell_libell_la_LDFLAGS.

Here is the correct patch for libell. This should be upstreamed for them.

diff --git a/Makefile.am b/Makefile.am
index 4eb20c6..35c9374 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,7 +138,7 @@ ell_libell_la_SOURCES = $(linux_headers) \
            ell/gpio.c \
            ell/path.c

-ell_libell_la_LDFLAGS = -no-undefined \
+ell_libell_la_LDFLAGS = -no-undefined -ldl \
            -Wl,--version-script=$(top_srcdir)/ell/ell.sym \
            -version-info $(ELL_CURRENT):$(ELL_REVISION):$(ELL_AGE)

Perfect, that indeed is the correct solution.

Metadata Update from @midipix:
- Issue status updated to: Closed (was: Open)

3 years ago

Here is another patch that was linked to me on #ell @ freenode. This problem apparently is also exposed when linked with gold.

diff --git a/Makefile.am b/Makefile.am
index d115360..bd276eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -215,7 +215,7 @@ unit_test_io_LDADD = ell/libell-private.la
 unit_test_ringbuf_LDADD = ell/libell-private.la

 unit_test_plugin_LDFLAGS = -Wl,-export-dynamic
-unit_test_plugin_LDADD = ell/libell-private.la -ldl
+unit_test_plugin_LDADD = ell/libell-private.la

 unit_test_checksum_LDADD = ell/libell-private.la

diff --git a/configure.ac b/configure.ac
index 5a962ac..487bff6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,7 +106,7 @@ AC_CHECK_FUNC(timerfd_create, dummy=yes,
 AC_CHECK_FUNC(epoll_create, dummy=yes,
            AC_MSG_ERROR(epoll support is required))

-AC_CHECK_LIB(dl, dlopen, dummy=yes,
+AC_SEARCH_LIBS(dlopen, dl, dummy=yes,
            AC_MSG_ERROR(dynamic linking loader is required))

 AC_CHECK_HEADERS(linux/types.h linux/if_alg.h)
diff --git a/ell/ell.pc.in b/ell/ell.pc.in
index 4fc933b..65ea88e 100644
--- a/ell/ell.pc.in
+++ b/ell/ell.pc.in
@@ -6,5 +6,5 @@ includedir=@includedir@
 Name: ELL
 Description: Embedded Linux library
 Version: @VERSION@
-Libs: -L${libdir} -lell -ldl
+Libs: -L${libdir} -lell @LIBS@
 Cflags: -I${includedir}
-- 
2.17.1

https://lists.01.org/hyperkitty/list/ell@lists.01.org/thread/J24VXJEFNOZU637T3MJQOO7QPV72UK6X/#FIFLSUALSOUWGG3MYJATF6X33WS2N

Login to comment on this ticket.

Metadata