【问题标题】:Binary compatibility between Linux distributionsLinux 发行版之间的二进制兼容性
【发布时间】:2010-12-18 18:52:54
【问题描述】:

对不起,如果这是一个明显的问题,但我在网络上发现的参考资料非常少......

我正在使用由我们的一位业务合作伙伴用 C 编写的 API,并以 .so 二进制文件的形式提供给我们,基于 Fedora 11 构建。我们一直在使用 Fedora 11 开发机器测试该 API没问题。但是,当我尝试在我们客户的目标平台(恰好是 SuSE Enterprise 10.2)上链接 API 时,我收到“无法识别文件格式”错误。

也是 binutils 包的一部分的命令,例如 objdump 或 nm,给我同样的文件格式错误。 “文件”命令向我展示了:

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 库之间不兼容,问题是代码是针对新版本的 glibc 等编译的,而不是 SuSE 10.2 上可用的。我发布这个问题是因为有一种方法可以在我们合作伙伴的 Fedora 11 平台上编译代码,使其也可以在 SuSE 10.2 上运行。

【问题讨论】:

  • 在同一个架构上? (i386 != amd64)
  • 我应该提到构建平台和目标 SuSE 10.2 平台都是 x86_64。
  • 您可以使用 objdump 或简单地执行 .so 来检查文件格式(是的,这是可能的)。它将是 ELF,因为它是从石器时代开始使用的。如果您有不兼容的 libc 版本,您将收到一条错误消息,其中说明了这一点 - 所以您的猜测很可能是错误的,问题可能是不同的。
  • 实际上,在 SuSE 上运行的 objdump 给了我与链接器相同的“无法识别文件格式”错误。我已经编辑了问题以反映这一点并显示文件和 ldd 命令的输出,它们确实有效。

标签: c linux compiler-construction binary-compatibility


【解决方案1】:

我认为诀窍是在您希望支持的任何平台上使用最古老的内核和 C 库版本构建 linux 风格。在我的工作中,我们构建在 Debian 4 之上,这使我们能够以非官方方式正式支持 Debian 4 及更高版本、RedHat 3、4、5、SuSE 10 以及各种其他发行版(SELinux 等)。

我怀疑通过构建一个不错的新版本 linux,在旧机器上支持人们变得很困难。

(编辑)我应该提到我们使用 Debian 4 附带的默认编译器,我认为它是 GCC 4.1.2。安装较新的编译器版本往往会使兼容性变得更差。

【讨论】:

    【解决方案2】:

    Windows 在不同版本、服务包、已安装的 SDK 和一般 DLL 之间的兼容性方面存在问题(DLL Hell,有人知道吗?)。 Linux 也不能幸免于此类问题。

    我看到的兼容性问题包括:

    • 运行时库更改
    • 链接库更改
    • 内核更改
    • 编译器技术更改(例如:EGCS gcc 前后版本。这可能是您的问题)。
    • 打包程序问题(RPM 与 APT)

    在您的特定情况下,我会让他们在他们的系统上执行“gcc -v”并向您报告 gcc 版本号。将其与您使用的进行比较。

    您可能必须使用该版本的编译器来构建您的一半。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        这只是个人意见,但在 Linux 上以仅二进制形式分发某些内容时,您有几个选择:

        1. 为阳光下的每个发行版构建 .debs 和 .rpms 的范围,并为您错过的任何内容使用标称的“.tar.gz full of binaries”包。第一部分很理想但很麻烦。后一部分将引导您进入第 2 点和第 3 点。

        2. 按照一些人的建议去做,找到你能找到并在那里构建的最古老的发行版。我个人的看法是,这是一种荒谬的想法。见第 3 点。

        3. 分发二进制文件,并尽可能静态链接。特别是对于 libstdc++,这似乎是你的问题。似乎有很多不兼容的 libstdc++ 版本在四处飘荡,这使其成为兼容性的噩梦。如果您不能静态链接,您也可以将 *.so 文件放在二进制文件旁边,并使用 LD_PRELOADLD_LIBRARY_PATH 之类的东西使它们在运行时优先链接。请注意,如果您采用这种方式,您可能必须遵守 LGPL 等,因为您现在正在与您的项目一起分发其他人的工作。

        当然,在 Linux 上以源代码形式分发您的项目始终是首选。 :-)

        【讨论】:

          【解决方案5】:

          如果消息是文件格式无法识别,那么问题很可能是 elmarco 在评论中提到的问题 - 即不同的架构。它可能(我不确定)是动态链接器版本不匹配,但这意味着 .so 文件是使用古老的动态链接器构建的。我不相信 libc 中的任何不兼容性会导致这种情况——它们可能会导致链接失败和运行时问题(后者很少发生),但不会这样。

          【讨论】:

            【解决方案6】:

            我不了解 Suse,但我知道 fedora 喜欢走在最前沿。所以你很可能对库版本是正确的。你为什么不问问看你能不能得到源代码并在你的 Suse 机器上构建它?

            【讨论】:

              猜你喜欢
              • 2011-01-02
              • 1970-01-01
              • 1970-01-01
              • 2013-02-14
              • 1970-01-01
              • 2013-12-09
              • 2020-09-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多