【问题标题】:GLIBCXX versionsGLIBCXX 版本
【发布时间】:2011-05-07 05:29:05
【问题描述】:

如果我在我的机器上编译一个 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.4 打印到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++ 吗?

【问题讨论】:

  • 您应该使用objdump 来检查库,而不是strings

标签: c++ linux portability glibc


【解决方案1】:
  1. 您系统上安装的库版本。你可以 手动构建 glibc 版本 3.4.14 并链接到它
  2. 这取决于。也许以后的版本修复了一些问题。您的程序的用户必须链接到您的程序所需的版本
  3. 内存使用率较高
  4. 是的,将正确的参数传递给链接器。如果您需要特定版本的库,那么最好下载它,手动构建它,然后链接到它。

编辑

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

【讨论】:

  • @Ignacio Vazquez-Abrams 所以,我得到了 4 分中的 2 分。对于 1),我猜它缺少 glibc 的依赖项。如果3不正确,我想我生活在无知中。那么,如何纠正这两个呢?
  • 1 我不确定,但图书馆确实有GLIBCXX_3.4.14 在其中,只是出于某种原因没有使用它。对于 3,请考虑无法更新库的影响。
  • 如果你静态链接库,那么你不需要更新它。所有的符号都在那里。更新应用程序更糟糕,因为它会变得更大
  • 1.我只安装了 libstdc++.so.6.0.14。除了ninjalj的回答是给出不同的解释...... 4.什么是正确的参数?
  • 与链接其他静态库相同——链接时作为参数传递。 network-theory.co.uk/docs/gccintro/gccintro_25.html
【解决方案2】:

使用readelf -aobjdump -x 优先于strings 检查ELF 文件。

实际上,所有 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 上引入/已更改语义的符号链接。

【讨论】:

  • 如果你有 C++ 代码,c++filt 也会很有帮助。例如:readelf -aW | c++filt
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-15
    • 2017-08-23
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多