Mac OSX 10.6编译器:32位与64位的困惑经历

9

我对OSX 10.6雪豹自带的gcc编译器感到困惑,主要是因为我缺乏64位环境方面的经验。

$ cat >foo.c
main() {}
$ gcc foo.c -o foo
$ file foo
foo: Mach-O 64-bit executable x86_64
$ lipo -detailed_info foo
input file foo is not a fat file
Non-fat file: foo is architecture: x86_64

然而,我的架构被视为Intel i386类型(我拥有最新的Intel Core2双核MacBook之一)。
$ arch
i386

编译器的目标是i686-apple-darwin10。

$ gcc --version 
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646)

当然,如果我编译32位,就会得到一个32位的可执行文件。
$ gcc -m32 foo.c -o foo
$ file foo
foo: Mach-O executable i386

但是我不明白大局。编译器的默认设置是生成x86_64可执行文件,即使我的arch说我有一个32位机器(为什么?Core2是64位);即使(我猜)我正在运行32位内核;即使我有一个针对i686-apple-darwin平台的编译器。为什么?它们如何运行?我应该编译64位还是32位?
这个问题是由于我尝试在Mac上编译gcc 4.2.3引起的,但我遇到了一堆问题,其中gmp、mpfr和libiberty在某些情况下被编译为x86_64。我应该编译所有的x86_64吗?如果是这样,目标是什么(我猜不是i686-apple-darwin10)?
感谢您的帮助。

1
顺便问一下,"lipo"和"fat file"之间有什么让人摇头的双关语吗? - Stefano Borini
我无法想象那会是无意的。 - Cajunluke
显然,顺便说一句,如果你想构建gcc,你应该使用MacPorts,或者至少看看他们是如何做的。同时也可以参考http://hpc.sourceforge.net/ - LaC
4个回答

15

在Snow Leopard上的默认编译器是gcc4.2,其默认架构是x86_64。构建Mac软件的典型方法是分别构建多个体系结构的软件,然后使用lipo将结果合并。(lipo仅将单一体系结构文件编译为多体系结构文件,或从多体系结构文件中剥离体系结构。正如您所发现的,它对单一体系结构文件没有用处。)

编译器的位数与任何事情都无关。您可以使用64位编译器构建32位二进制文件,反之亦然。(您认为的编译器的“目标”实际上是其可执行文件,这是不同的。)

内核的位数与任何事情都无关。您可以在启动32位内核时构建和运行64位二进制文件,反之亦然。

重要的是在链接时,您是否具有适当的架构以供链接。您无法将32位版本与64位二进制文件进行链接,反之亦然。因此,重要的是查看链接库的架构是什么,确保它们是连贯的,然后构建与您链接库相同架构的二进制文件,以便您可以链接到您拥有的库。


我现在看到的问题是我的mpfr和gmp库是为x86_64编译的,但当我编译gcc时,它无法链接,因为显然编译器构建了一个i386-apple-darwin10.0.0编译器,它无法链接到我的库“ld:警告:/blabla/libmpfr.dylib,文件不符合所需的架构。我现在正在尝试使用--build/target/host作为i686-apple-darwin10编译gcc。祈祷一切顺利,但很明显我无法出于某种原因创建兼容的对象。 - Stefano Borini
没有机会。由于某种原因,编译编译器总是产生大量的i386内容,这当然无法与x86_64 gmp和mpfr库链接。我真的很困惑。 - Stefano Borini
你需要构建你的编译器以支持-arch x86_64来链接你的gmp和mpfr库,或者获取这些库的i386版本。 - cdespinosa
我遇到了类似的问题,GMP在x86_64上构建正确,但其他库(Nettle、GnuTLS)默认为i386。Nettle开发人员收到了很多这方面的投诉,并确定问题出在config.guess上。看起来,由于Leopard和Snow Leopard默认启动32位内核,即使在64位处理器上也是如此,因此它默认为i386,在此情况下,GMP和其他库执行更具体的处理器检查,因此检测到它们支持64位。我将尝试提交使用sysctl -n hw.cpu64bit_capable或类似方法的config.guess补丁。 - morgant

2

i686-apple-darwin10.0.0包含一个x86_64文件夹,大多数版本的autotools都无法理解。换句话说,在Snow Leopard上,我会说gcc编译器不幸地简直就是个笑话。为什么要将32位和64位库捆绑到i686-apple-darwin10.0.0中,这超出了我的理解。

$ ls /usr/lib/gcc
i686-apple-darwin10 powerpc-apple-darwin10

您需要修改所有的autotools配置文件,以处理在*86-darwin目录中进行查找,然后查找64位库。

与您的系统一样,我的Mac mini也说它是i386,尽管显然使用的是64位平台,这是另一个错误,因为它分发的是64位硬件。

$arch
i386

1

苹果工具链支持多种架构。如果你想创建一个包含x86和x86_64代码的fat二进制文件,那么你需要向gcc传递参数-arch i386 -arch x86_64。编译器将会一次为两个平台编译您的代码。

在CFLAGS中添加-arch i386 -arch x86_64可以让您一次编译gmp、mpfr等多种架构的库。以这种方式构建libusb对我很有效。


0

这个回答是错误的,但请查看下面的评论

真正的问题是......你怎么得到了一个32位的OSX版本?我不知道Snow Leopard有32位版本,因为苹果的所有Intel芯片都支持x86_64架构,包括Core 2或者Xeon。

哦,而且Snow Leopard只适用于Intel芯片。

编辑:显然Snow Leopard以32位模式启动。


那一定是为了兼容性的原因。 - Powerlord
6
Snow Leopard可以在32位Intel机器上运行32位系统软件和应用程序,在64位Intel机器上运行64位系统软件和32位、64位应用程序。Snow Leopard桌面版启动32位内核是为了保持kext和驱动程序的兼容性,但所有用户空间都是64位的。Mac OS X Server启动64位内核。Core 2 Duo是一台64位机器。请尝试使用$ sysctl hw.cpu64bit_capable或sysctl hw.optional.x86_64来验证您是否拥有64位CPU。在Leopard和Snow Leopard中,arch命令将始终显示i386作为Intel硬件的架构。 - cdespinosa
5
我会保留这个回答,但我认为对它的评论可能会对其他用户有用。 - Powerlord
苹果公司在一些电脑中也配备了Core 1 Duo和Solo处理器,当然这些处理器是32位的。 - Coxy
@coxymla:参考资料呢?我相当确定即使是Mac Mini也是从Core 2 Solo和Duo(分别为两个型号)开始的。 - Powerlord
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接