40

如果我在我的机器上编译一个 C++ 程序,然后在另一个(使用旧软件)上运行它,我会得到:/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found.

事实上,在我的系统上 glibc 是更新的(我得到了 gcc-libs 4.5.1: libstdc++.so.6.0.14)并且strings /usr/lib/libstdc++.so.6 | grep GLIBCXXGLIBCXX_3.4to打印GLIBCXX_3.4.14。相反,在另一个系统上,它只打印到GLIBCXX_3.4.8(我得到了 libstdc++.so.6.0.8)。

所以我有几个问题:

  1. 为什么我的链接器将 C++ 二进制文件链接到 libstdc++ 版本GLIBCXX_3.4.9而不是GLIBCXX_3.4.14?

  2. 如果我根据 libstdc++ 版本编译我的二进制文件,GLIBCXX_3.4我猜它几乎可以在任何地方运行。这是否意味着任何类型的问题?(例如:它会使用旧的——因此更糟糕的——算法实现吗?)

  3. 相反,如果我将我的程序与我的 libstdc++静态链接,我猜它会在任何地方运行;当然,二进制文件会更大(~1MB),还有其他优点/缺点吗?

  4. 我可以强制链接器将我的二进制文件链接到给定版本的 libstdc++ 吗?

4

3 回答 3

39

使用readelf -aobjdump -x来检查 ELF 文件,而不是strings.

实际上,所有 GLIBCXX_* 版本并不适用于整个库,而是适用于每个符号(符号版本控制,请参阅DSO-howto)。所以你可以有例如:std::char_traits<wchar_t>::eq@@GLIBCXX_3.4.5std::ios_base::Init::~Init()@@GLIBCXX_3.4在同一个库文件上。

您的程序需要 GLIBCXX_3.4.9 的事实可能意味着它已与已在 GLIBCXX_3.4.9 上引入/已更改语义的符号链接。

于 2010-11-09T13:04:27.307 回答
1
  1. 系统上安装的库版本。您可以手动构建 glibc 版本 3.4.14 并链接到它
  2. 那要看。也许以后的版本修复了一些问题。您的程序的用户必须链接到您的程序所需的版本
  3. 内存使用率更高
  4. 是的,将正确的参数传递给链接器。如果您需要特定版本的库,那么最好下载它,手动构建它,然后链接到它。

编辑

我只记得静态链接库会增加内存使用量。

于 2010-11-09T12:44:43.710 回答
-1

在我看来,如果您的二进制文件不使用较新 GLIBCXX 版本的新功能,那么它们将不会与该版本链接。所以你的二进制文件与 GLBCXX 3.4.9 链接,必须至少有一个符号从中导出,并且没有任何符号从高于 3.4.9 的版本导出。

于 2016-06-01T02:33:59.517 回答