【问题标题】:How do I find what libraries need to be installed on a client linux machine if I compile a binary with a newer version of gcc?如果我使用较新版本的 gcc 编译二进制文件,如何找到需要在客户端 linux 机器上安装的库?
【发布时间】:2015-10-06 10:23:29
【问题描述】:

假设我有一个用 gcc 4.4.x 版本编译的 C++ 二进制文件,它用于客户端 linux 机器。

如果我想升级我的编译器以使用更新的编译器,比如 4.9.3(因为我想使用 C++11):

需要在客户端上升级哪些东西才能运行这个新的二进制文件? (例如 .so 库) 以及如何发现这一点?

【问题讨论】:

  • 即使您提供了自己的 libstdc++.so 版本以实现兼容性,您仍然可能需要一个版本太高而无法由仍在使用 GCC 3.4 的系统提供的 glibc 版本。
  • 通常分发存储库对此很宝贵:apt-get install X,dnf install X,为您计算和安装依赖项。
  • 好的,3.4.6 就是一个例子,可能是错误的。我会更新这个问题。例如,假设它当前是 4.4.x?

标签: c++ linux c++11 gcc


【解决方案1】:

需要在客户端上升级哪些东西才能运行这个新的二进制文件?

您需要为您的应用程序提供两个共享库:libgcc_slibstdc++。详情请见https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html

如果您使用$ORIGIN 链接,您可以将这些库与您的可执行文件放在同一目录中。详情请见https://stackoverflow.com/a/4742034/412080

如何发现这一点?

在您的可执行文件上运行 lddreadelf -d 以查看它们需要哪些库。

【讨论】:

    【解决方案2】:

    我从您提到 GCC 3.4 的事实猜测您的客户端系统正在运行 RedHat/CentOS/Scientific Linux 4,它太老了,甚至 Red Hat ended support for it three years ago。如果您正在运行任何较新的版本,那么您将能够利用Developer Toolsets,其中包括修改后的 GCC 版本,它将标准库的较新部分静态链接到您的二进制文件中,这样它就可以在没有更新的旧系统上运行glibc/libstdc++ 运行时。

    【讨论】:

    • 好的,3.4.6 就是一个例子,可能是错误的。我会更新这个问题。例如,假设它当前是 4.4.x?
    【解决方案3】:

    有两种测试共享库兼容性的机制:

    1. SONAME:链接器用来引用库的库的规范名称。您可以使用ldd 命令查询每个 ELF 对象(可执行文件或库)所需的库列表,您需要对每个引用的库递归地执行此操作以获得所需库的完整列表。

      李>
    2. 符号版本信息。这是一个额外的约束,它允许通过为使用的每个符号引入版本要求来向现有库添加功能——仅使用已存在多年的符号的程序将需要比使用新功能的程序更低的库最低版本。

    这两个都需要满足才能让程序运行。

    Linux 发行版的典型方法是保留 SONAME 到包名称的映射(因为可以同时安装多个不同版本的 SONAME),以及一个表这些被引入的包修订版本的符号。适合您的发行版的包开发工具应该能够创建与您的程序要求相匹配的依赖规范列表;如果他们因为符号未知而未能这样做,则很可能该版本不支持该发行版。

    【讨论】:

      【解决方案4】:

      另一种方法是静态链接除libc(以及libmlibdl,如果您使用它们)以外的所有库(特别是libstdc++);那么生成的 ELF 可执行文件仅取决于 libc;但是,使用足够古老的内核或 libc(在目标机器上),即使这样也可能无法工作......

      详情请阅读Drepper的论文:How To Write Shared Libraries

      【讨论】:

        猜你喜欢
        • 2010-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-13
        • 2020-05-10
        相关资源
        最近更新 更多