编译一个在所有Linux发行版中执行而不重新编译的C/ c++源代码是否可能?

Is it possible to compile a C/C++ source code that executes in all Linux distributions without recompilation?

本文关键字:编译 新编译 源代码 是否 c++ 执行 一个 Linux      更新时间:2023-10-16

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

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

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

不,您不能编译在所有Linux发行版中执行的可执行文件。然而,你可以编译一个可执行文件,它可以在大多数人们会关心的发行版上工作。

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

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

  3. 编译您计划自己使用的所有其他库。

  4. 使用你的glibc编译头和你选择的CPU/编译器标志。
  5. 静态链接。

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

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

你可能需要调整一些库,如果它们调用的函数不能使用这种机制。包括dlopengethostbynameiconv_open等。(这些功能基本上依赖于动态链接。参见上面的第5步。当你链接这些时,你会得到一个警告。)

另外,如果不小心,时区可能会中断,因为您的代码可能不理解系统的区域格式或区域文件位置。(你不会得到这些警告。它就是不工作。)

大多数这样做的人都是在最低支持的CPU是Pentium 4和最低支持的内核版本是2.6.0的情况下构建的。

不同的安装有两个不同之处。建筑与图书馆。

  1. 为不同的体系结构使用一个二进制文件是不可能的;曾经有人尝试在一个文件(fatelf)中包含多个arch的二进制文件,但它没有被广泛使用,也不太可能获得动力。所以至少你必须为ia32、amd64、arm等分发单独的二进制文件。(大多数(如果不是全部)amd64发行版的内核编译支持运行ia32代码)

  2. 发行版包含不同版本的库。只要API没有改变,你就可以链接到那个库。一些库确保在主要编号内的二进制向后兼容性(因此GTK2.2应用程序将与GTK2.30库运行良好,但不一定反之亦然)。如果你想要确保,你必须静态地链接你使用的所有库,除了最基本的库(可能只有libc6,它在发行版之间是二进制兼容的)。这可能会增加二进制文件的大小,这也是为什么例如Acrobat Reader的下载量相对较大的原因之一,尽管应用程序本身的功能并不特别丰富。

  3. c++ ABI有一个过渡时期,它在gcc 2.9和3 (IIRC)之间发生了变化,但是旧的ABI实际上只适用于旧的安装。这应该不再是一个问题,如果你静态链接,它是无关的。

一般不

有几个障碍。

不同的体系结构

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

内核ABI

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

你能做的就是创建一个静态链接的二进制文件。这样的二进制文件将包含应用程序所依赖的所有库,并且它将在具有相同架构和合理相似内核版本的所有系统上工作。