将GCC与新的glibc和binutils结合使用,为具有旧sysroot的系统构建软件



几个月以来我一直有一个问题,很长一段时间我都无法用谷歌找到答案。

背景:我正在为运行linux发行版ptxdist的基于arm的控制器交叉编译软件。完整的linux镜像是用一个跨gcc(4.5.2(构建的,它是针对glibc-2.13和binutils-2.221构建的。c++标准已经很旧了,所以我构建了一个新的工具链,支持c++11(gcc 4.8.5(。它现在是针对glibc-2.20和binutils-2.24构建的。我想在控制器上的应用软件中使用新的编译器(不是完整的映像,只是这个"主"二进制文件(,它通过包管理系统更新。

软件似乎在运行。我只需要将LD_LIBRARY_PATH设置为指向二进制文件的libstdc++.so.0.19,而不是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内部的变化:对升级gcc或binutils 的影响

这里有人说,如果由GCC4.1到GCC 4.8构建,C代码是兼容的。

谢谢!

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++。

这方面的好材料可能在这里:

单个主机上的多个glibc库

Glibc与GCC与binutils兼容性

我的最终解决方案是:

我构建了GCC 4.8.5作为一个交叉编译器。我无法用旧的glibc2.13构建它,只能用2.20版本。这可能是可能的,但就我而言,它没有起作用。无论如何,这不是问题,因为我也使用sysroot标志构建了它。编译新软件完全依赖于我的旧系统,包括C Runtime。我没有得到一个新的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进行交叉编译。

最新更新