Search code examples
c++gcclinkerundefined-referencelibstdc++

Old GCC can not automatically find the new version libstdc++?


I'm trying to use the 3rd-party lib, called DocToText, with gcc 4.4.7.

I compiled the program with:

g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext -o example test_doctotext.cpp

In the beginning, it returned libstdc++.so.6: version GLIBCXX_3.4.15 not found

I manually downloaded the newer version, and re-linked, here is the result

[root@mail]~xian# find / -name "libstdc++.so.6"
/lib64/libstdc++.so.6
/usr/lib64/libstdc++.so.6
[root@mail]~xian# strings /lib64/libstdc++.so.6 | grep GLIBCXX_3.4.15
GLIBCXX_3.4.15
[root@mail]~xian# strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX_3.4.15
GLIBCXX_3.4.15

But when I compiled again, it returned:

[root@mail]~xian# g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext -o example test_doctotext.cpp 
./doctotext//libdoctotext.so: undefined reference to `std::__detail::_List_node_base::swap(std::__detail::_List_node_base&, std::__detail::_List_node_base&)@GLIBCXX_3.4.15'
./doctotext//libdoctotext.so: undefined reference to `std::__detail::_List_node_base::_M_transfer(std::__detail::_List_node_base*, std::__detail::_List_node_base*)@GLIBCXX_3.4.15'
./doctotext//libdoctotext.so: undefined reference to `std::__detail::_List_node_base::_M_unhook()@GLIBCXX_3.4.15'
./doctotext//libdoctotext.so: undefined reference to `std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)@GLIBCXX_3.4.15'
collect2: ld returned 1 exit status

I also tried

g++ -I./doctotext/ -L./doctotext/ -L/lib64/ -Wl,-rpath=./doctotext,-rpath=/lib64 -ldoctotext -lstdc++ -o example test_doctotext.cpp

, and I got the same errors (undefined reference).

libdoctotext.so indeed link to /lib64/libstdc++.so.6

[root@mail]~xian# ldd doctotext/libdoctotext.so | grep libstdc++.so.6
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f96c7ab4000)

Fortunately, I found two method to solve this problem:

  1. use newer gcc: I used gcc 9.1.1 (with scl), then g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext -o example test_doctotext.cpp directly works.
  2. specify the path to libstdc++.so.6 with gcc 4.4.7: g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext /lib64/libstdc++.so.6 -o example test_doctotext.cpp

But I'm really curious about why my gcc 4.4.7 can not link to that libstdc++ under the system default path?

Is the version of libstdc++ be tightly coupled to the version of gcc in someway?


Solution

  • Every GCC release is accompanied by its very own libstdc++ release.

    The C++ standard library (and support libraries like libsupc++) often rely on specific implementation details in the compiler, including bugs, and specific changes in behaviour due to defect reports etc. Sometimes even a new GCC release also needs a matching binutils (linker) release, as the way the code is generated changed to use a specific feature only available in the newer linker.

    You can explicitly link it to the system libstdc++ by passing that path to the compiler/linker, but I don't recommend it, as the ABI may have changed in an incompatible way.