【问题标题】:Old GCC can not automatically find the new version libstdc++?老的GCC不能自动找到新版本的libstdc++?
【发布时间】:2020-11-10 09:32:58
【问题描述】:

我正在尝试将名为 DocToText 的第 3 方库与 gcc 4.4.7 一起使用。

我编译了这个程序:

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

一开始,它返回libstdc++.so.6: version GLIBCXX_3.4.15 not found

我手动下载了较新的版本,并重新链接,这是结果

[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

但是当我再次编译时,它返回了:

[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

我也试过

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

,我得到了同样的错误(未定义的引用)。

libdoctotext.so 确实链接到 /lib64/libstdc++.so.6

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

幸运的是,我找到了两种方法来解决这个问题:

  1. 使用较新的 gcc: 我用的是 gcc 9.1.1(带 scl),然后g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext -o example test_doctotext.cpp 直接工作。
  2. 使用 gcc 4.4.7 指定 libstdc++.so.6 的路径: g++ -I./doctotext/ -L./doctotext/ -Wl,-rpath=./doctotext -ldoctotext /lib64/libstdc++.so.6 -o example test_doctotext.cpp

但是我真的很好奇为什么我的gcc 4.4.7不能链接到系统默认路径下的那个libstdc++?

libstdc++ 的版本是否以某种方式与 gcc 的版本紧密耦合?

================================================ =================================

最终,我发现 gcc 会使用

[root@mail]/usr/lib64# find / -name "libstdc++.so"
/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/32/libstdc++.so
/opt/rh/devtoolset-9/root/usr/lib/gcc/x86_64-redhat-linux/9/libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/32/libstdc++.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libstdc++.so
[root@mail]/usr/lib64# ll /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libstdc++.so
lrwxrwxrwx. 1 root root 37 Aug 21 15:22 /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libstdc++.so -> ../../../../lib64/libstdc++.so.6.0.13

6.0.13 没有 GLIBCXX_3.4.15

我将它重新链接到 libstdc++.so.6.0.17,问题已解决

【问题讨论】:

  • 为什么有这么古老的 GCC 版本?
  • @tadman 我的服务器使用 Centos6 和 gcc 4.4.7,由于某些原因我无法同时升级它们...
  • 随着时间的推移,旧的东西只会出现越来越多的问题。您最终将不得不升级或永远坚持相同的构建。由于是 2020 年,您有很多方法可以解决此问题,例如使用容器,而不必手动调整服务器。
  • 如果您真的需要构建一些链接到旧库的东西,最好在 VM 或安装了一个且只有一个版本的 GCC 的容器中进行。

标签: c++ gcc linker undefined-reference libstdc++


【解决方案1】:

每个 GCC 版本都伴随着它自己的 libstdc++ 版本。

C++ 标准库(以及像 libsupc++ 这样的支持库)通常依赖于编译器中的特定实现细节,包括错误,以及由于缺陷报告等导致的特定行为变化。 有时,即使是新的 GCC 版本也需要匹配的 binutils(链接器)版本,因为生成代码的方式已更改为使用仅在较新的链接器中可用的特定功能。

您可以通过将该路径传递给编译器/链接器,将其显式链接到系统 libstdc++,但我不建议这样做,因为 ABI 可能以不兼容的方式更改。

【讨论】:

  • '-L/lib64 -lstdc++' 不也是一种显式链接的方式吗?为什么它不起作用,而 '/lib64/libstdc++.so.6' 起作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
相关资源
最近更新 更多