如何在linux上编译以与所有发行版共享?

时间:2010-05-04 10:38:47

标签: php linux cross-platform

我在Fedora Core 12上编译了一个PHP扩展,但当我将它发送给使用CentOS的人时,他们会收到错误:“ELF文件OS ABI无效”

我不确定是什么原因导致此运行文件提供以下信息: ELF 64位LSB共享对象,AMD x86-64,版本1(GNU / Linux),未剥离

加载正常的扩展程序从文件中提供以下内容: ELF 64位LSB共享对象,AMD x86-64,版本1(SYSV),未剥离

所以我觉得我需要为某些发行版生成一个SYSV类型的文件,而不是GNU / LINUX文件,不知道如何。有什么指针吗?

我也应该静态链接吗?

3 个答案:

答案 0 :(得分:8)

语句:“ELF文件操作系统ABI无效”,表示Application Binary Interface在使用的二进制文件之间不兼容(即一个人试图混合主机和目标二进制文件,可能不按预期工作)。 e_ident[EI_OSABI]标头的ELF字节包含操作系统/ ABI标识。您的Fedora系统将此设置为ELFOSABI_LINUX3),而您朋友的CentOS系统将其设置为ELFOSABI_SYSVELFOSABI_NONE0)。

可能能够编译FreeBSD brandelf实用程序(brandelf.c)并使用它将OSABI设置为ELFOSABI_SYSVbrandelf -f 0 <file>或{{1 }}

我不知道在编译/链接时指定此值的任何gcc标志。我相信你的Fedora系统上gcc使用的binutils版本负责将OSABI设置为Linux。我的理解是,如果brandelf -t SVR4 <file>符号在输出文件中结束,链接器仅指定ABI(有关STT_GNU_IFUNC的详细信息,请参阅ifunc.txt http://groups.google.com/group/generic-abi}。


readelf(1)命令可用于检索和显示存储在ELF标题(STT_GNU_IFUNC)中的ABI信息。


similar question也可能会引起关注。

答案 1 :(得分:1)

编译的目标文件通常不会在不同的Linux发行版之间传输良好。不同的发行版通常对库有不同的策略,存储它们的方式,它们的加载方式。

它们之间存在很多差异(是的,甚至在Fedora和RedHat / CentOS中也是如此)。他们可能会在各个级别(内核,PHP,库位置)为组件提供自己的补丁。如果他们使用的是分发PHP软件包,那么分发可能会更好地整合到他们的系统中。

您可能遇到的主要问题是该发行版使用了不同的库/编译器设置。检查他的计算机上有哪些verision gcc,并将其与您的计算机上的内容进行比较。 (Fedora 12有比CentOS更新的库)。这就是您的问题所在。

另一个可能的问题是您的二进制文件很好,但它与它使用的所有库不兼容。我不确定是否有一种很好的方法来解决这个问题而不编译目标分布(或变量)。您可以使用lld <file>命令查看每个共享对象/可执行文件使用的库。

此外,错误ELF file OS ABI invalid之前是否有任何输出?我看到它被引用的大多数地方都有更多的信息。

答案 2 :(得分:-1)

您的朋友很可能没有运行64位系统。 ELF是Linux可执行文件的标准格式,但32位系统无法运行64位可执行文件。

从您的朋友那里获取uname -a的输出。如果输出不包含“x86_64”,那么他就是32位版本的CentOS。

如果是这样,您需要设置交叉编译环境或用于编译32位二进制文​​件的虚拟机,或者只是向您的朋友提供源代码,以便他自己编译。