Linux发行版之间的二进制兼容性

5
抱歉如果这是一个显而易见的问题,但我在网络上找到的参考资料令人惊讶地少...
我正在使用由我们的商业合作伙伴编写并以.so二进制文件的形式提供给我们的C API,在Fedora 11上构建。我们已经在Fedora 11开发机上测试了API,没有任何问题。然而,当我尝试在客户的目标平台(恰好是SuSE Enterprise 10.2)上链接该API时,我会收到“文件格式不被识别”的错误。
与binutils软件包一起提供的命令,例如objdump或nm,也会给我相同的文件格式错误。 “file”命令显示:
ELF 64-bit LSB shared object, AMD x86-64, version 1 (SYSV), not stripped

而且"ldd"命令显示:

ldd: warning: you do not have execution permission for `./libuscuavactivity.so.1.1'
./libuscuavactivity.so.1.1: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./libuscuavactivity.so.1.1)
[dependent library list]

我猜测这是由于两个平台上的C库不兼容造成的问题,问题在于代码编译时使用了比SuSE 10.2提供的glibc版本更新的版本等。我发布这个问题,希望有办法在我们合作伙伴的Fedora 11平台上编译代码,以便它也能在SuSE 10.2上运行。


2
在相同的架构上吗?(i386!= amd64) - elmarco
我应该提到构建平台和目标 SuSE 10.2 平台都是 x86_64。 - gareth_bowles
你可以使用objdump检查文件格式,或者直接执行.so文件(是的,这是可能的)。它将是ELF格式,因为自石器时代以来就一直在使用。如果您有不兼容的libc版本,则会收到错误消息,其中明确说明了这一点 - 因此,您的猜测很可能是错误的,问题可能是其他原因引起的。 - Gunther Piez
实际上,在SuSE上运行objdump会给我同样的“文件格式不被识别”的错误,就像链接器一样。我已经编辑了问题以反映这一点,并展示了文件和ldd命令的输出,它们可以正常工作。 - gareth_bowles
6个回答

3

Windows在不同版本、服务包、安装SDK以及DLL等方面存在兼容性问题( DLL Hell,有人听说过吗?)。Linux也同样存在这些问题。

我见过的兼容性问题包括:

  • 运行时库变更
  • 链接库变更
  • 内核变更
  • 编译器技术变更(例如:EGCS GCC的先前和后续版本。这可能是您的问题所在)。
  • 打包工具问题(RPM vs. APT)

就你的情况而言,我建议他们在其系统上执行“gcc-v”并向您报告gcc版本号。将其与您正在使用的版本进行比较。

您可能需要获得该编译器版本来构建您的代码。


3
我认为诀窍在于建立在一种具有最古老内核和C库版本的Linux平台上,以支持您希望支持的所有平台。在我的工作中,我们基于Debian 4构建,这使我们能够正式支持Debian 4及以上、RedHat 3、4、5、SuSE 10以及其他各种发行版(如SELinux等)。
我怀疑如果建立在一个新的Linux版本上,就会难以支持旧机器上的人。
(编辑)我应该提到我们使用Debian 4默认附带的编译器,我认为它是GCC 4.1.2。安装更新的编译器版本往往会使兼容性变得更差。

3
您可以使用 Linux Application Checker 工具 ([1], [2], [3]) 来解决 Linux 发行版之间的应用兼容性问题。它将检查您的文件格式和所有依赖库。它支持几乎所有流行的 Linux 发行版,包括所有版本的 SuSE 和 Fedora。

enter image description here


2
这只是个人意见,但在Linux上以二进制形式分发东西时,你有几个选择:
  1. 为每个发行版构建所有的.debs和.rpms,对于你错过的任何内容,提供名为".tar.gz完整二进制文件"的包。第一部分理想但繁琐。后者将使你转向点2和3。
  2. 像一些人建议的那样,找到你能找到的最旧的发行版并在那里构建。我个人认为这是一个有点荒谬的想法。请参见第3点。
  3. 分发二进制文件,并在尽可能多的地方静态链接。特别是对于libstdc++,这似乎是你在这里遇到的问题。似乎有很多不兼容的libstdc++版本在流传,这使得它成为一个兼容性噩梦。如果你无法静态链接,你也可以将*.so文件与你的二进制文件放在一起,并使用像LD_PRELOADLD_LIBRARY_PATH这样的东西,在运行时优先链接它们。请注意,如果你选择这条路,你可能需要遵守LGPL等许可证,因为你现在正在与你的项目一起分发其他人的作品。
当然,在Linux上以源代码形式分发你的项目总是首选。 :-)

1
如果出现文件格式无法识别的消息,则问题很可能是elmarco在评论中提到的问题之一——即不同的架构。这可能(我不确定)是动态链接器版本不匹配,但这意味着.so文件是使用古老的动态链接器构建的。我不认为libc中的任何不兼容性都会导致这种情况——它们可能会导致链接失败和运行时问题(后者非常罕见),但不会导致这种情况。

0

我不了解Suse,但我知道Fedora喜欢保持在最前沿。所以你可能是对的关于库版本的问题。为什么不问问看是否可以获取源代码并在您的Suse机器上构建它呢?


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