结合使用带有新glibc和binutils的GCC来为具有较旧sysroot的系统构建软件

时间:2018-11-28 11:25:12

标签: c++ gcc glibc

几个月以来,我一直在问一个问题,而且很长一段时间都无法与Google回答。

背景: 我正在为运行Linux发行版ptxdist的基于arm的控制器交叉编译软件。完整的linux映像是使用针对glibc-2.13和binutils-2.21构建的交叉gcc(4.5.2)构建的。 C ++标准已经很老了,因此我建立了一个支持c ++ 11(gcc 4.8.5)的新工具链。现在,它是针对glibc-2.20和binutils-2.24构建的。我想将新的编译器用于控制器上的应用程序软件(不是完整的映像,而只是一个“主”二进制文件),可以通过程序包管理系统进行更新。

该软件似乎正在运行。我只需要将指向libstdc ++。so.0.19的LD_LIBRARY_PATH设置为二进制文件而不是libstdc ++。so.14。它不接受新的libc,它是libc-2.20而不是libc-2.13。

因此二进制文件使用libstdc ++。so.0.19,而系统的其余部分保持不变。

问题: 为什么这样做有效? 我期望运行此软件有什么风险,无论如何我还是应该这样做? 例如,该二进制文件将来会因为只在目标计算机上获取glibc-2.13而会丢失glibc-2.20的某些功能吗?无法针对glibc-2.13构建gcc-4.8.5。

到目前为止,我阅读的内容取决于ABI内部的更改: Impact on upgrade gcc or binutils

这里说,如果由GCC4.1编译为GCC 4.8,则C代码是兼容的。

谢谢!

2 个答案:

答案 0 :(得分:0)

glibc 2.14引入了memcpy@GLIBC_2.14符号,因此几乎所有针对glibc 2.20编译的软件都无法在glibc 2.13上运行,因为该符号丢失了。理想情况下,您将针对glibc 2.13(而不是glibc 2.20)构建新的GCC。您声称无法针对glibc 2.13构建GCC 4.8.5,但这显然是不正确的。

某些较新的C ++功能将与旧系统libstdc ++一起使用,因为它们完全依赖模板(来自头文件),而libstdc ++中没有新代码。

您还可以研究Red Hat Developer Toolset中的混合链接模型如何工作。它静态链接libstdc ++的较新部分,同时依靠系统libstdc ++来处理较常见的较旧部分。这样,您就可以针对异常之类的东西获得适当的互操作性,而不必在目标上安装较新的libstdc ++。

答案 1 :(得分:0)

好的材料可能在这里:

Multiple glibc libraries on a single host

Glibc vs GCC vs binutils compatibility

我的最终解决方案是:

我将GCC 4.8.5构建为交叉编译器。我无法使用旧版glibc2.13(仅适用于2.20版)来构建它。可能是可行的,但在我看来,它是行不通的。无论如何,这不是问题,因为我也使用sysroot-flag构建了它。编译新软件完全取决于我的旧系统,包括C运行时。我没有与此相关的新C ++标准,但是如果您启用编译器优化,则我会体验到更好的二进制压缩和性能。 关于新的C ++标准,我可以使用-l:libstdc ++。so.6.0.19作为LDDFLAG链接交叉编译器随附的更新的libstdc ++。因此,我只需要在目标上复制旧的libstdc ++之外的其他libstdc ++。 在使用

查看新库使用的符号后

strings libstdc++.so.6.0.19 | grep GLIBC_

您会发现它不依赖于比GLIBC_2.4更新的任何符号。看来我永远也不会遇到缺少符号的问题。 因此,就我而言,我很幸运使用了新的C ++ 11标准,而系统的其余部分没有任何更改。如果引入了新符号,则需要点击我的帖子中的上述链接,这些链接会提供很多信息。但是我永远不会自己尝试。就我而言,在GCC 4.9.4中,libstdc ++。so.6.0.20的符号指向GLIBC_2.17。在与GLIBC_2.13交叉编译时,这可能会给我带来麻烦。