bug#80153: libtool: 2.5.4 - gcc 16 --push-state --as-needed -latomic --pop-state vs. libtool

Jakub Jelinek via bug-libtool via Bug reports for the GNU libtool shared library maintenance tool <[email protected]> Thu, 8 Jan 2026 12:25:41 +0100
Newsgroups gmane.comp.gnu.libtool.bugs
Message-ID <aV-UNUJd0StR6-L3@tucnak>
Hi!

gcc 16 in https://gcc.gnu.org/r16-4315 https://gcc.gnu.org/PR81358 change
added --push-state --as-needed -latomic --pop-state to the collect2/ld
invocation from the gcc/g++ etc. drivers.

Unfortunately libtool.m4 in the loop starting with
  # Parse the compiler output and extract the necessary
  # objects, libraries and library flags.
grabs object files and libraries and -L/-R options from the compiler
driver invocation of the linker and grabs them without these
--push-state --as-needed / --pop-state wrapping options, which are needed
to only link the library in if it is actually needed.
I think on Solaris the pair is -z ignore / -z record instead, but
unfortunately in that case it is less clear if those options are meant to
affect just the single library and so are a property of that library, or
if they have been randomly added e.g. by the user or whatever and affect
instead what comes after it or multiple libraries etc.

Anyway, what we see in gcc, as mentioned in https://gcc.gnu.org/PR123396
is that several shared libraries linked with libtool are then uselessly
linked to libatomic.so:
for i in libstdc++-v3/src/.libs/libstdc++.so.6.*.* libsanitizer/*/.libs/lib*.so.*.* libgcobol/.libs/lib*.so.*.*; do echo $i; ldd -u $i; done
libstdc++-v3/src/.libs/libstdc++.so.6.0.35
Unused direct dependencies:
	/lib64/libatomic.so.1
libsanitizer/asan/.libs/libasan.so.8.0.0
Unused direct dependencies:
	/lib64/libatomic.so.1
libsanitizer/hwasan/.libs/libhwasan.so.0.0.0
Unused direct dependencies:
	/lib64/libm.so.6
	/lib64/libatomic.so.1
libsanitizer/lsan/.libs/liblsan.so.0.0.0
Unused direct dependencies:
	/lib64/libm.so.6
	/lib64/libatomic.so.1
libsanitizer/tsan/.libs/libtsan.so.2.0.0
Unused direct dependencies:
	/lib64/libatomic.so.1
libsanitizer/ubsan/.libs/libubsan.so.1.0.0
Unused direct dependencies:
	/lib64/libm.so.6
	/lib64/libatomic.so.1
libgcobol/.libs/libgcobol.so.2.0.0
Unused direct dependencies:
	/lib64/libatomic.so.1
E.g. for libstdc++-v3, libtool created by configure has
postdep_objects="/home/jakub/src/gcc/obj38/./gcc/crtendS.o /lib/../lib64/crtn.o"
postdeps=" -lgcc_s -latomic -lc -lgcc_s "

I see -latomic in postdeps or postdeps_CXX in other packags, e.g. when
gettext is built with gcc 16, but in that case I actually don't see any
shared library or binary linked uselessly against libatomic.so.1; not really
sure why though.

In https://gcc.gnu.org/pipermail/gcc-patches/2025-December/704644.html
the PR81358 patch author suggested to work around this by filtering
out -latomic from postdeps_CXX, though I think that just means the libraries
will never be linked against libatomic.so.1 rather than only linking against
it on architectures where e.g. some atomics aren't provided by inlined code
and need to fallback to libatomic.so.1.

So, I've been wondering if the libtool.m4
  # Parse the compiler output and extract the necessary
  # objects, libraries and library flags.
couldn't special case at least the --push-state --as-needed options before
-lXXX option and --pop-state after it and in that case put into postdeps_*
var instead of just -lXXX
$_LT_TAGVAR(lt_prog_compiler_wl, $1)--push-state $_LT_TAGVAR(lt_prog_compiler_wl, $1)--as-needed -lXXX $_LT_TAGVAR(lt_prog_compiler_wl, $1)
But I admit I haven't studied in detail in what exactly the postdeps var is
used.

	Jakub