是否有可能编译一个C / C ++源代码在所有的Linux发行版中执行而无需重新编译?
如果答案是肯定的,我可以使用任何外部(非标准C / C ++)库吗?
我想分发我的二进制应用程序,而不是分发源代码。
不,你不能编译一个可执行文件在所有的Linux发行版中执行。 但是,您可以编译一个可执行文件,该文件可用于大多数人会倾向于关注的分发。
编译32位。 编译您希望支持的最低CPU级别。
构建您自己的glibc版本。 使用--enable-kernel
选项来设置您愿意支持的最低内核版本。
编译你打算使用的所有其他库。 使用glibc版本中的头文件和你选择的CPU /编译器标志。
链接静态。
对于任何你不能静态链接的东西(例如,如果你需要访问系统的默认名称解析或者你需要PAM),你必须设计你自己的帮助程序和API。 释放源代码到助手进程,让他们(或你的安装者)编译它。
在需要支持的所有平台上进行彻底测试。
你可能需要调整一些库,如果他们调用不能使用这个机制的函数。 这包括dlopen
, gethostbyname
, iconv_open
等等。 (这些函数从根本上依赖于动态链接,参见上面的第5步,链接时会得到警告。)
另外,如果您不小心,时区往往会中断,因为您的代码可能不了解系统的区域格式或区域文件位置。 (你将不会收到任何警告,这是行不通的。)
大多数人这样做是建立在最低支持的CPU是Pentium 4,最低支持的内核版本是2.6.0。
装置之间有两个区别。 建筑和图书馆。
对于不同的体系结构有一个二进制文件是不可能的; 有一个尝试在一个文件中有多个二进制文件( fatelf ),但是没有被广泛使用,并且不太可能获得动力。 所以至少你必须为ia32,amd64,arm,…分配二进制文件(尽管amd64发行版的内核已经被编译了,但支持运行ia32代码)
分发包含不同版本的库。 只要API不更改就可以,您可以链接到该库。 有些库确保在主数字中向后兼容(所以GTK2.2应用程序可以在GTK2.30库中正常运行,但反过来也不一定)。 如果你想确定,你必须静态链接到你使用的所有库,除了最基本的库(可能只有libc6
,这是二进制兼容的发行版AFAIK)。 这可以增加二进制文件的大小,也是为什么例如Acrobat Reader是相对较大的下载的原因之一,尽管应用程序本身不是特别丰富的功能。
c ++ ABI有一个过渡期,它在gcc 2.9和3(IIRC)之间有所变化,但是旧的ABI实际上只是在古代的装置上。 这不应该是一个问题,如果你静态链接,这是无关的。
一般没有。
有几个bariers。
不同的架构
而一个32位二进制文件将在x86_64系统上运行,反之亦然。 另外还有很多ARM系统。
内核ABI
内核ABI变化非常缓慢,但它确实发生了变化,因此您不能真正支持所有可能的版本。 请注意,在某些地方,内核2.2仍在使用中。
你可以创建一个静态链接的二进制文件。 这样的二进制文件将包括你的应用程序所依赖的所有库,并将在所有具有相同体系结构和合理类似内核版本的系统上工作。