发行版之间的可执行二进制文件有什么区别吗?

由于所有Linux发行版使用相同的内核,它们的可执行二进制文件之间是否有区别?

如果是的话,主要区别是什么? 或者这意味着我们可以build立一个通用的Linux可执行文件?

所有的Linux发行版都使用相同的二进制格式ELF,但是仍然存在一些差异:

  1. 不同的cpu使用不同的指令集。
  2. 相同的cpu arch可以使用不同的ABI,ABI定义了如何使用寄存器文件,如何调用/返回一个例程。 不同的ABI不能一起工作。
  3. 即使在相同的拱形,相同的ABI,这仍然不意味着我们可以复制一个分布到另一个二进制文件。 由于大多数二进制文件不是静态链接的,所以它们依赖于分发下的库,这意味着不同的分发版本可能会使用不同的版本或不同的库编译配置。

所以如果你想让你的程序运行在所有的发行版上,你可能需要静态链接一个依赖于内核系统调用的版本,即使这样你也只能运行一个指定的版本库。

如果你真的想在任何拱门上运行一个程序,那么你必须编译所有拱门的二进制文件,并使用shell脚本来启动正确的程序。

所有Linux端口(即不同处理器上的Linux内核)都使用ELF作为可执行文件和库的文件格式。 一个特定的ELF二进制文件被标记为可以运行的单个体系结构/操作系统(尽管一些操作系统具有兼容性来运行来自其他操作系统的ELF二进制文件)。

大多数端口都支持旧的a.out格式。 (有些处理器是新的,从来没有任何a.out可执行文件。)

某些端口也支持其他可执行文件格式; 例如,PA-RISC端口支持HP-UX的旧SOM可执行文件,而μcLinux(nonmmu)端口则支持自己的FLAT格式。

Linux也有binfmt_misc ,它允许用户空间注册任意二进制格式的处理程序。 一些发行版利用这个功能可以执行Windows,.NET或Java应用程序 – 它确实还在启动一个解释器,但是它对用户是完全透明的。


Linux on Alpha支持加载英特尔二进制文件,通过em86模拟器运行。

可以为其他体系结构的可执行文件注册binfmt_misc ,并使用qemu-user运行。

理论上,人们可以创建一个新的格式 – 也许在ELF中注册一个新的“架构” – 用于胖二进制文件。 然后内核binfmt加载器将不得不被教导这种新的格式,你不会想错过ld-linux.so动态链接器和整个构建工具链。 对这样的功能一点兴趣也没有,就我所知,没有人在做这样的事情。

几乎所有的Linux程序文件都使用ELF标准。

旧的Unix也使用COFF格式。 在这种格式下,您仍然可以找到昔日的可执行文件。 Linux仍然支持它(我不知道它是否在当前的发行版中编译)。

如果你想创建一个运行所有Linux发行版的程序,你可以考虑使用脚本语言 (比如PythonPerl )或者独立于 Java平台编程语言

用脚本语言编写的程序在执行时被编译,这意味着它们总是被编译来匹配它们被执行的平台,因此应该总是工作(假定库被正确设置)。

另一方面,用Java编写的程序在分发之前进行编译,只要安装了Java VM,就可以在任何Linux发行版上执行。

此外,使用Java编写的Java可以在MS WindowsMac OS等其他操作系统上运行。

许多使用PythonPerl编写的程序也是如此。 但是, PythonPerl程序是否可以在另一个操作系统上工作取决于该程序使用的库以及这些库是否可用于其他操作系统。