在Linux下确定二进制兼容性

6
什么是确定预编译二进制文件依赖关系的最佳方法(特别是关于glibc和libstdc++符号和版本),然后确保目标系统已安装这些依赖项?
我有一个限制,即不能提供源代码在每台机器上进行编译(雇主限制),因此“在每台机器上编译以确保兼容性”的事实上的回应不适用。我也不希望提供静态编译的二进制文件 -> 这似乎非常像用锤子打开鸡蛋的情况。
我考虑了许多方法,大致上集中在通过使用命令来确定我的可执行文件/库所需的符号/库,例如 ldd -v </path/executable> 或 objdump -x </path/executable> | grep UND 然后在目标系统上运行某个命令来检查是否提供了这些符号、库和版本(不太确定如何执行此步骤?)。 然后会进行一些模式或符号匹配,以确保正确的版本或更高版本存在。
话虽如此,我觉得这已经在很大程度上为我完成了,我正在遭受...“知识差距?”的困扰,不知道它当前是如何实现的。
对于如何继续的想法/建议有什么想法吗?
我应该补充说,这是为了在各种Linux发行版上安装我的软件 - 特别是定制的集群 - 这些发行版可能不遵守分发指南或标准化的打包方法。目标是实现无缝安装。
我希望在安装时实现二进制兼容性,而不是在后续运行时,这可能由于用户权限不足而发生依赖关系。
此外,由于我没有访问所有第三方库的源代码并进行安装(专门的数学/工程库),因此编码中的解决方案效果不佳。我想我可以编写一个测试特定符号(&版本)是否存在的二进制文件,但这个二进制文件本身将具有兼容性问题。
我认为我的解决方案必须是针对旧库进行编译(如上所述),并将其安装以及使用LSB检查器(看起来很有前途)。

可能是重复问题:https://dev59.com/HW855IYBdhLWcg3wj1QS - oakad
GNU头文件与glibc和stdc++相关联,已定义适当的版本宏。实际上,对于stdc++,您可以依赖于gcc版本,它们总是一起发布的。 - oakad
我正在使用的一些库是由第三方提供的,因此我无法访问它们的源代码以内部检查版本宏。 - John
2个回答

4

GNU库(glibc和libstdc++)支持一种称为符号版本控制的机制。首先,这些库会导出由动态链接器使用的特殊符号,以解析适当的符号版本(在libstdc++中为CXXABI_*和GLIBCXX_*,在glibc中为GLIBC_*)。一个简单的脚本如下:

nm -D libc.so.6 | grep " A "

将返回版本符号列表,可以进一步使用shell来确定最大支持的libc接口版本(对于libstdc++也是同样的方法)。从C语言代码中,可以使用dlvsym()函数来完成相同的操作(首先将库dlopen()打开,然后检查是否可以使用dlvsym()查找到需要的符号的某个最小版本)。
在运行时获取glibc版本的其他选项包括gnu_get_libc_version()和confstr()库调用。
然而,正确使用版本化接口的方法是编写显式链接到特定glibc/libstdc++库版本的代码。例如,链接到GLIBC_2.10接口版本的代码预期可与任何新于2.10的glibc版本(包括所有2.18及以上版本)配合使用。虽然可以在每个符号基础上启用版本控制(使用".symver"汇编器/linker指令),但更合理的方法是使用旧版本(最小支持的)的工具链设置chroot环境并针对其编译项目(它将无缝地运行任何遇到的新版本)。

1
使用Linux应用检查器工具([1], [2], [3])检查您的应用程序与各种Linux发行版的二进制兼容性。您还可以通过此工具检查与自定义发行版的兼容性。

enter image description here


这不是我的自定义发行版。在我的经验中,每次我遇到 Linux 群集时,系统管理员都以各种非标准的方式进行了自定义。其中一个常见的表现形式是他们喜欢安装软件的位置。我将 /opt 指定为默认值(我相信这是 LSB 指定的),但我发现有 50% 的安装程序更喜欢其他地方。 - John

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接