【问题标题】:Is it possible to compile a C/C++ source code that executes in all Linux distributions without recompilation?是否可以编译在所有 Linux 发行版中执行而无需重新编译的 C/C++ 源代码?
【发布时间】:2011-09-18 11:27:45
【问题描述】:

是否可以编译在所有 Linux 发行版中执行的 C/C++ 源代码而无需重新编译?

如果答案是肯定的,我可以使用任何外部(非标准 C/C++)库吗?

我想分发我的二进制应用程序而不是分发源代码。

【问题讨论】:

  • 当你说“所有 Linux 发行版”时,你在看多远?
  • @jancha - 即使使用静态链接的程序仍然存在问题,例如系统调用的变化
  • 所以如果一个人想要通用的东西,那么 java 就是解决方案之一。
  • @jancha:如果您提供源文件和 Makefile,您应该能够在大多数发行版上构建,只要您将自己限制在 C 和 C++ 标准中定义的操作。 Linux 发行版通常自带 gcc。

标签: c++ c linux


【解决方案1】:

不,您不能编译在所有 Linux 发行版中执行的可执行文件。但是,您可以编译一个适用于人们倾向于关心的大多数发行版的可执行文件。

  1. 编译 32 位。编译为您愿意支持的最低 CPU 级别。

  2. 构建您自己的 glibc 版本。使用--enable-kernel 选项设置您愿意支持的最低内核版本。

  3. 编译您计划自己使用的所有其他库。使用 glibc 构建中的标头和您选择的 CPU/编译器标志。

  4. 静态链接。

  5. 对于无法静态链接的任何内容(例如,如果您需要访问系统的默认名称解析或需要 PAM),您必须设计自己的帮助进程和 API。将源代码发布到帮助程序进程并让他们(或您的安装程序)编译它。

  6. 在您需要支持的所有平台上进行彻底测试。

如果某些库调用了无法使用此机制的函数,您可能需要调整它们。这包括dlopengethostbynameiconv_open 等等。 (这些类型的函数基本上依赖于动态链接。参见上面的第 5 步。链接这些函数时会收到警告。)

此外,如果您不小心,时区往往会中断,因为您的代码可能无法理解系统的区域格式或区域文件位置。 (您不会收到这些警告。它只是行不通。)

大多数这样做的人都在构建时使用最低支持的 CPU 是 Pentium 4,最低支持的内核版本是 2.6.0。

【讨论】:

  • 这个答案已经过时了几年。您现在可以分发 64 位版本。您不需要静态链接——您可以包含共享库。而且您可能不需要编译自己的 glibc 版本。现在,典型的最低 CPU 是任何支持 64 位的 CPU,并且典型的最低支持内核版本更高。
  • 如何使用目标机器上可能不存在的共享库?除非您实际上将共享库与您的二进制文件一起分发 - 这会破坏目的
  • @AaronMcDaid 我建议静态链接。 (或者至少,我在 2011 年左右做过。)见上面的 4 和 5。
  • 噢!我没有注意到您是同一个人-您正在评论自己的答案。所以我假设你不同意答案,而不仅仅是更新它。我猜您的观点 (3) 和 (5) 基本上是说我们需要将所有必要的软件捆绑在一起以分发给用户。但它不需要静态链接在一起
【解决方案2】:

安装之间有两个不同之处。架构和库。

  1. 不可能直接为不同的架构使用一个二进制文件;曾尝试在一个文件中包含多个拱门的二进制文件 (fatelf),但它没有被广泛使用,也不太可能获得动力。因此,至少您必须为 ia32、amd64、arm、... 分发单独的二进制文件(不过,如果不是所有 amd64 发行版都已编译内核并支持运行 ia32 代码)

  2. 发行版包含不同版本的库。只要 API 不变,您就可以链接到该库。一些库确保主要编号内的基本向后兼容性(因此 GTK2.2 应用程序可以与 GTK2.30 库一起正常运行,但不一定反之亦然)。如果你想确定,你必须静态链接你使用的所有库,除了最基本的库(可能只有libc6,这是二进制兼容的跨发行版 AFAIK)。这可以增加二进制文件的大小,这也是原因之一。 Acrobat Reader 的下载量相对较大,虽然应用程序本身的功能并不特别丰富。

  3. c++ ABI 有一个过渡期,在 gcc 2.9 和 3 (IIRC) 之间发生了变化,但旧的 ABI 实际上只是在古老的安装上。这对您来说应该不再是问题,如果您静态链接,无论如何都无关紧要。

【讨论】:

    【解决方案3】:

    一般不会。

    有几个障碍。

    不同的架构

    虽然 32 位二进制文​​件可以在 x86_64 系统上运行,但反之则不行。另外还有很多 ARM 系统。

    内核 ABI

    内核 ABI 变化非常缓慢,但确实会发生变化,因此您不能真正支持所有可能的版本。请注意,在某些地方,内核 2.2 仍在使用中。

    您可以做的是创建一个静态链接的二进制文件。此类二进制文件将包含您的应用所依赖的所有库,并且可以在具有相同架构和相当相似内核版本的所有系统上运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 2010-10-24
      • 2012-08-11
      相关资源
      最近更新 更多