Consider editing the original post to replace Unicode Character “
with "
and utilize fenced code blocks so that people can play with the example with ease.
clang -shared -fpic -o libfoo.so foo.cc # libfoo.so does not need libstdc++.so.6
clang -fuse-ld=bfd test.c -L./ -lfoo -Wl,--as-needed -lstdc++ -Wl,--no-as-needed # a.out needs libstdc++.so.6
% readelf -W --dyn-syms tmp/c/libfoo.so | grep _ZSt21ios_base_library_initv
5: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND _ZSt21ios_base_library_initv
I have debugged ld. In binutils-gdb/bfd/elflink.c
, libstdc++.so.6
is considered needed becuase it defines _ZSt21ios_base_library_initv@@GLIBCXX_3.4.32
, which can satisfy libfoo.so
’s unversioned reference.
/* Add symbols from an ELF object file to the linker hash table. */
static bool
elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
{
...
elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class)
(elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
If libfoo.so needs libstdc++.so.6 (clang++ -shared -fpic -o libfoo.so foo.cc
, clang++
instead of clang
to link against libstdc++), a.out
will not need libstdc++.so.6
.
Why does GNU ld care about libfoo.so
’s dependency on libstdc++.so.6
?
I guess this is used as a linker workaround for underlinking problems.
When the missing dependency (libstdc++.so.6
) by a DSO is seen by the executable link, the executable will get the DT_NEEDED
to satisfy the DSO’s requirement, even if itself doesn’t need the dependency.
I think the justification for this special case is low and other linkers should not port this behavior.
I have updated my Explain GNU style linker options | MaskRay to mention GNU ld’s behavior