我的 Linux 二进制文件可以在所有发行版上运行吗?

我的 Linux 二进制文件可以在所有发行版上运行吗?

我找到了一个很好的 Delphi 替代 IDE,名为 Lazarus。但我没有什么问题要问程序员。

会不会静态链接Linux 二进制文件适用于所有 Linux 发行版吗?也就是说,我构建它的 Linux 发行版并不重要,它可以在 Debian / ArchLinux / Ubuntu / OpenSUSE / ... 等等上运行?

根据我的研究结果,真的只有 32 位与 64 位重要吗?我想在发布之前确定一下。

答案1

这个答案首先是为了更普遍的问题“我的二进制文件可以在所有发行版上运行”而写的,但它在后半部分解决了静态链接的二进制文件。


对于任何比静态链接的 hello world 更复杂的东西,答案是可能没有
无需在发行版 X 上进行测试,假设答案X 不可以。

如果您想以二进制形式发布软件,请限制自己

  • 适用于您的软件使用领域的一些流行发行版(桌面、服务器、嵌入式……)

  • 每个的最新一两个版本

否则你最终会得到数百个各种大小、版本和年龄的发行版(十年前的发行版仍在使用支持的)。

测试一下。只是一些关于否则会出现什么问题的提示:

  • 您所需的工具/库的包在不同发行版甚至同一发行版的不同版本中命名不同

  • 您需要的库太新或太旧(版本错误)。不要仅仅因为您的程序可以链接就假设它与正确的库链接。

  • 相同的库(磁盘上的文件)在不同的发行版上有不同的名称,导致无法链接

  • 64 位上的 32 位:可能未安装 32 位环境,或者某些非必需的 32 位库被移至 32on64 环境之外的额外包中,因此对于这种情况,您有一个额外的依赖项。

  • Shell:不要假定您的 Bash 版本。甚至不要假设 Bash。

  • 工具:不要假设任何地方都存在一些非 POSIX 命令行工具。

  • 工具:不要仅仅因为发行版的 GNU 版本可以识别该工具即可识别某个选项。

  • 内核接口:不要/proc仅仅因为文件在您的计算机上存在/具有结构就假定文件的存在或结构

  • Java:您真的确定您的程序可以在 SLES 附带的 IBM JRE 上运行而不进行测试吗?

奖金:

  • 指令集:在您的计算机上编译的二进制文件不能在较旧的硬件上运行。

静态链接(或者:将您需要的所有库与您的软件捆绑在一起)解决方案?即使技术上可行,相关成本也可能很高。不幸的是,答案也可能是否定的。

  • 安全性:您将更新库的责任从软件的用户转移到您自己身上。

  • 大小和复杂性:只是为了好玩尝试构建一个静态链接的 GUI 程序。

  • 互操作性:如果您的软件是任何类型的“插件”,您就依赖于调用您的软件。

  • 库设计:如果您将程序静态链接到 GNU libc 并使用名称服务(getpwnam()等),则最终会动态链接到 libc 的 NSS(名称服务开关)。

  • 库设计:与程序静态链接的库使用数据文件或其他资源(例如时区或区域设置)。


由于上述所有原因,测试是必不可少的。

  • 熟悉 KVM 或其他虚拟化技术,并拥有您计划支持的每个发行版的 VM。在每台虚拟机上测试您的软件。

  • 使用这些发行版的最小安装。

  • 创建具有受限指令集(例如无 SSE 4)的 VM。

  • 仅静态链接或捆绑:检查您的二进制文件,ldd看看它们是否真正静态链接/仅使用捆绑的库。

  • 仅静态链接或捆绑:创建一个空目录并将您的软件复制到其中。chroot进入该目录并运行您的软件。

答案2

答案是这取决于。,但在大多数情况下,是的,只要操作系统上安装了必要的库即可。

一般来说,大多数主要发行版(例如您提到的发行版)都有其包管理工具,用于安装社区维护的应用程序版本。这会处理应用程序需要的任何先决条件包。如果您在没有包管理器的情况下安装它,则需要您确保所有必需的包和库都安装到操作系统上。最好在文档中包含这些必备应用程序的列表。

答案3

先说蹩脚的答案:这取决于

如果您要发布二进制文件,请假定答案为“否”,除非您要分发全部它的库曾经涉及它(从头开始,这很烦人,除非您提供一个真正独立的庞大系统)或静态链接等效项。

...但是巫师和金钱,还有金钱巫师...

IBM 有一些“通用的 Unixish”安装程序,它们在我尝试过的任何地方都能工作,这让我感到震惊:来自几代内核的几种 Linux、OpenSolaris(或现在的任何名称)、Solaris 和 BSD。但它们很大。而他们提供的东西同样巨大。不会以这种方式发布精巧的小型赛车程序,只有您期望从 IBM 获得的大型企业类型的东西。

就仅停留在 Linux 上,但在大多数 Linuxdom 上运行良好而言,这似乎可以以二进制形式实现,正如您从某些供应商处看到的各种“for Linux(通用)”类型的二进制安装程序所证明的那样。一些聊天、浏览器、游戏、元安装程序等都是通过这种方式发布的,但总是由大型供应商发布,他们可以花时间来做好这件事。他们可以说“for Linux”并且普遍相信它会起作用,这有点令人惊讶,但事实似乎确实如此。

但...

我使用构建实用程序将我的软件作为源代码进行分发。我在 C、Erlang、Python、Guile 等中执行此操作。这给了我一个很多关于它是否运行的灵活性更大,并且编写一个构建脚本来确保构建时存在正确的东西比确保运行时一切都就位要容易得多。一旦存在,如果您分发源代码,那么为您的程序编写自动更新程序就很简单了:源代码通常比包含所有 deps 和其他疯狂内容的二进制文件小得多。使用这种方法,我在 Unices(有时是 Windows,但这有点麻烦)上可靠地部署时没有遇到太多麻烦。

玩够了,武装自己!

当你像 srsly srs 一样认真地想要顺利融入 Linux 世界时,你就会分发 C 源代码或者转向完全托管的环境,使用已经预先构建的令人愉悦的语言。例如,如果您正在编写 Python 代码,您可以检查版本并了解您的 CPython 版本适用于哪个版本,并且通常期望给定的 Linux 上存在一些兼容版本(这比广泛的 C 库更容易检查/您可能正在使用的版本)。 Erlang、Guile、Python、Perl、CL 等都是非常此类部署的简单目标,其中许多都有一个中央存储库,例如 CPAN 或 pip(或其他),用户可以在需要时运行命令来自行拉取签名源,并且知道事情通常会按您的预期运行。

[附录:1。即使 Haskell 通常也可以通过 Cabal 实现这一点——尽管我在生产环境中这样做会持谨慎态度。 2. Erlang 有完全不同的“发布”部署策略,可以保证您的代码带有完整的环境。 3. Python在虚拟环境方面更进一步;并非所有运行时都能为您提供那么多帮助。]

关于 Linux 上的托管环境的最后一点太棒了。而且,作为奖励,它允许您定义更通用的依赖项,自动解决它们,而无需您付出额外的努力,不需要为每个发行版编写一个包,您可以不再关心系统是 32 位还是 64 位(一般来说,无论如何)。

相关内容