编译一个在所有Linux发行版中执行而不重新编译的C/ c++源代码是否可能?
Is it possible to compile a C/C++ source code that executes in all Linux distributions without recompilation?
是否有可能编译在所有Linux发行版中执行的C/c++源代码而不重新编译?
如果答案是肯定的,我可以使用任何外部(非标准C/c++)库吗?
我想分发我的二进制应用程序,而不是分发源代码。
不,您不能编译在所有Linux发行版中执行的可执行文件。然而,你可以编译一个可执行文件,它可以在大多数人们会关心的发行版上工作。
-
编译32位。编译您愿意支持的最低CPU级别
-
构建自己的glibc版本。使用
--enable-kernel
选项设置您愿意支持的最小内核版本 -
编译您计划自己使用的所有其他库。
使用你的glibc编译头和你选择的CPU/编译器标志。 静态链接。
对于无法静态链接到的任何内容(例如,如果需要访问系统的默认名称解析或需要PAM),则必须设计自己的helper进程和API。将源代码释放给辅助进程,让它们(或您的安装程序)编译。
在你需要支持的所有平台上进行彻底的测试。
你可能需要调整一些库,如果它们调用的函数不能使用这种机制。包括dlopen
、gethostbyname
、iconv_open
等。(这些功能基本上依赖于动态链接。参见上面的第5步。当你链接这些时,你会得到一个警告。)
另外,如果不小心,时区可能会中断,因为您的代码可能不理解系统的区域格式或区域文件位置。(你不会得到这些警告。它就是不工作。)
大多数这样做的人都是在最低支持的CPU是Pentium 4和最低支持的内核版本是2.6.0的情况下构建的。
不同的安装有两个不同之处。建筑与图书馆。
-
为不同的体系结构使用一个二进制文件是不可能的;曾经有人尝试在一个文件(fatelf)中包含多个arch的二进制文件,但它没有被广泛使用,也不太可能获得动力。所以至少你必须为ia32、amd64、arm等分发单独的二进制文件。(大多数(如果不是全部)amd64发行版的内核编译支持运行ia32代码)
-
发行版包含不同版本的库。只要API没有改变,你就可以链接到那个库。一些库确保在主要编号内的二进制向后兼容性(因此GTK2.2应用程序将与GTK2.30库运行良好,但不一定反之亦然)。如果你想要确保,你必须静态地链接你使用的所有库,除了最基本的库(可能只有
libc6
,它在发行版之间是二进制兼容的)。这可能会增加二进制文件的大小,这也是为什么例如Acrobat Reader的下载量相对较大的原因之一,尽管应用程序本身的功能并不特别丰富。 -
c++ ABI有一个过渡时期,它在gcc 2.9和3 (IIRC)之间发生了变化,但是旧的ABI实际上只适用于旧的安装。这应该不再是一个问题,如果你静态链接,它是无关的。
一般不
有几个障碍。
不同的体系结构
32位二进制文件可以在x86_64系统上运行,反之则不能。另外还有很多ARM系统。
内核ABI内核ABI变化非常缓慢,但它确实在变化,因此您不能真正支持所有可能的版本。请注意,在某些地方内核2.2仍在使用。
你能做的就是创建一个静态链接的二进制文件。这样的二进制文件将包含应用程序所依赖的所有库,并且它将在具有相同架构和合理相似内核版本的所有系统上工作。
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 如何编译:Mac上的Synergy(2017年的新工具链)
- 如何编译和运行一个新的 C++ Actor 框架项目?
- C++编译新的警告过滤器
- 每次都构建(make)lib,只有在lib较新时才重新编译项目
- 如何创建指向派生类的新指针,该派生类在C++编译时未知
- 如何在不退出和失去断点的情况下重新加载重新编译的二进制文件
- 在编译时将整数和分数部分宏组合成一个新的宏或双精度
- C++运算符新重载、编译错误
- 在新OSX上编译旧碳应用
- 为什么G 5.4不能编译此编译时质数代码
- 代码块在尝试编译或创建新文件时出现"An assertion failed!"错误
- 在新的Visual Studio项目中包含任何Eigen 3.3.1文件将无法编译
- RCpp:如何在不重新启动R的情况下重新加载重新编译的C++代码
- 新安装的MinGW问题与编译和可执行文件
- 为什么要编译?(编译是否忽略未包含的 h 文件?
- 高级C和C++编译:无法编译书中提到的示例程序
- 在不同的编译单元中使用不同的编译标志编译相同的头
- 在cygwin中编译新的mingw二进制文件
- 使用boost库编译预编译头文件需要很长时间