Hello there! I'm using automake+libtool for building C++ code and hitting a
peculiar issue with 3rd-party libraries. It comes up when a library is
built with one version of GCC and then the application is built with a
newer compler.

So, given the following wrapper lib that pulls libzmq:

noinst_LTLIBRARIES += libnsevent.la
nodist_libnsevent_la_SOURCES = libs/nsevent/wrapper.cpp
libnsevent_la_LIBADD = -lzmq

Libtool results in the following g++ invocation when linking the
application:

 /opt/gcc-11/bin/g++ -std=c++17 -Wl,-rpath -Wl,/opt/gcc-11/lib64 -Wl,-rpath
-Wl,/opt/3p/lib -o ns_conn_test
libs/netsvc/test/ns_conn_test/src/cpp/NsConnTest.o  -L/opt/3p/lib
./.libs/libnsevent.a /opt/3p/lib/libzmq.so
/opt/gcc-9/lib/../lib64/libstdc++.so /opt/gcc-11/lib/../lib64/libstdc++.so
-lpthread -lrt -ldl -lm -lz -Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath
-Wl,/opt/gcc-9/lib/../lib64 -Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64
-Wl,-rpath -Wl,/opt/3p/lib -Wl,-rpath -Wl,/opt/gcc-9/lib/../lib64
-Wl,-rpath -Wl,/opt/gcc-11/lib/../lib64

It looks like GCC9 references come from libzmq:

$ ldd /opt/3p/lib/libzmq.so | grep libstd
        libstdc++.so.6 => /opt/gcc-9/lib/../lib64/libstdc++.so.6
(0x00007f95f8d9f000)

Obviously the 3rd-party library was built a while ago with GCC9. At the
time it was linked to the compiler's runtime... but now the main
application has moved to GCC11 and I'm linking to the runtime that is
correct right now.

It looks like automake/libtool try to be helpful and check the library's
dependencies... but that gets in the way as the new libstdc++ is a strict
superset of the old one. They maintain ABI compatibility and so scenarios
like these are supported.

Is there a way to suppress dependency tracking for the 3rd-party libraries?
I wish Libtool/automake was not trying to be smart and simply passed
"-lzmq" directly to the linker. Yet instead, the actual .so file is
discovered and then its libstdc++.so is linked. This is just wrong for the
scenario at hand.

Thanks in advance,
Oleg.

Reply via email to