我的问题相当概念化。我注意到同一架构有不同的软件包,比如x86-64,但适用于不同的操作系统。例如,RPM为同一个x86-64架构的Fedora和OpenSUSE提供了不同的包:http://www.rpmfind.net/linux/rpm2html/search.php?query=wget - 更不用说由YUM和APT(对于Ubuntu)提供的不同包,全部用于x86-64。
我的理解是一个包包含适用于给定CPU体系结构的二进制指令,因此只要CPU具有该体系结构,它就应该能够本地执行这些指令。那么为什么针对不同操作系统为相同架构构建的软件包会有所不同?
答案 0 :(得分:2)
这些包包含需要运行特定Application Binary Interface(ABI)的本机二进制文件。 CPU架构只是ABI的一部分。不同的Linux发行版具有不同的ABI,因此相同的二进制文件可能不是compatible。这就是为什么相同的架构有不同的包,但不同的操作系统。 Linux Standard Base项目旨在标准化Linux发行版的ABI,以便更容易构建可移植的软件包。
答案 1 :(得分:2)
只考虑不同的Linux发行版:
除了针对不同的库版本进行编译(如Hadi所述),包装本身和默认配置文件也可以不同。也许一个发行版需要/etc/wget.conf
,而另一个发行版需要/etc/default/wget.conf
,或者这些文件具有不同的内容。 (如果wget专门有一个全局配置文件,我会忘记;有些软件包肯定会这样做,而不仅仅是像Exim或Apache这样的服务器。)
或者不同的发行版可以启用/禁用不同的编译时选项集。 (传统上在./configure --enable-foo --disable-bar
之前设置make -j4 && make install
)。
对于wget
,选项可能包括要编译的TLS库(OpenSSL与gnutls),而不仅仅是哪个版本。
所以ABI(库版本)很重要,但是还有其他原因可以解释为什么每个发行版都有自己的包。
完全不同的操作系统,如Linux与Windows与OS X,具有不同的可执行文件格式。 ELF vs. PE vs. Mach-O。所有这三种格式都包含x86-64机器代码,但元数据不同。 (操作系统差异意味着您希望机器代码执行不同的操作。
例如,可以使用int open(const char *pathname, int flags, mode_t mode);
系统调用在Linux或OS X(或任何POSIX OS)上打开文件。所以相同的源代码适用于这两个平台,虽然它仍然可以编译为不同的机器代码,或者实际上在这种情况下非常相似的机器代码来调用围绕系统调用的libc包装器(OS X and Linux use the same function calling convention),但是不同的符号名称。 OS X将编译为对_open
的调用,但Linux不会将下划线添加到符号名称,因此动态链接器符号名称将为open
。
open
的模式常量可能不同。例如也许OS X将O_RDWR
定义为4
,但Linux可能将其定义为2
。这将是一个ABI差异:相同的源代码编译到不同的机器代码,程序和库就什么意味着什么达成一致。
但 Windows不是POSIX系统。用于打开文件的WinAPI函数是HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle);
如果你想做最近发明的事情而不是打开/关闭文件,特别是绘制GUI,平台之间的事情就更不相似了,你会使用不同的库。 (或者跨平台GUI库将在不同平台上使用不同的后端。)
OS X和Linux都具有Unix传统(真实或克隆实现),因此低级文件的内容类似。