关于GCC和交叉编译的一般问题

15

最近我在尝试使用GCC进行交叉编译,并发现了一项似乎比较复杂的内容,即工具链。

我不太理解这一点,因为我原本认为GCC可以为大多数常见的架构创建二进制机器代码,而其他真正重要的只是你链接的库和创建的可执行文件类型。

GCC不能自己完成所有这些吗? 通过单个GCC版本的构建,所有适当的库和正确的标志被发送到GCC,我能否生成一个PE可执行文件,用于Windows x86计算机,然后创建一个用于嵌入式Linux MIPS设备的ELF可执行文件,最后再为OSX PowerPC机器创建一个可执行文件? 如果无法做到,请问有人能解释一下如何实现?


LLVM的单一构建更加强大。它可以为多个架构生成代码。 - osgx
请解释您将如何实现此目标,而不需要创建大量单独的跨环境。 - osgx
2个回答

12
使用单个GCC构建,所有适当的库和正确的标志都发送到GCC,我能够为Windows x86机器生成PE可执行文件,然后创建一个嵌入式Linux MIPS设备的ELF可执行文件,最后是OSX PowerPC机器的可执行文件吗?如果不行,有人能解释一下如何实现吗?
不行。单个GCC构建只能生成一个目标架构的目标代码。您需要构建针对Intel x86、MIPS和PowerPC的版本。但是,编译器并不是您唯一需要的工具,尽管您可以通过单个调用GCC将源代码构建为可执行文件。在底层,它还使用汇编器(as)和链接器(ld),这些工具也需要为目标体系结构和平台构建。通常,GCC使用GNU binutils软件包中的这些工具的版本,因此您还需要为目标平台构建它们。
您可以在这里阅读有关构建交叉编译工具链的更多信息。
“我不太理解这一点,因为我认为GCC可以为大多数常见架构创建二进制机器代码。”
这在某种意义上是正确的,因为GCC本身的源代码可以构建成针对各种架构的编译器,但仍需要单独的构建。
关于 -march,它不允许同一版本的GCC在不同平台之间切换。相反,它用于选择可用于同一系列处理器的指令。例如,一些现代x86处理器支持的指令集(如MMX和SSE扩展指令集)在最早的x86处理器上不受支持,因为它们是后来引入的。当您传递 -march 时,GCC会启用该处理器及其前身支持的所有操作码。引用GCC手册的话说:“虽然选择特定的cpu-type将适当地安排那个特定芯片的事情,但编译器不会生成任何在没有使用-march = cpu-type选项的情况下不能在i386上运行的代码。”

这是否意味着GCC源代码具备为所有这些架构生成机器码的能力,但您必须在编译时选择一个且仅一个?此外,现在我对-march=标志的用途感到困惑。 - ArturPhilibin
是的,您必须在编译时选择架构。请参阅我的有关“-march”的编辑。 - Nick Meyer
1
顺便说一下,在同一开发机器上同时存在本地编译器和交叉编译器是完全可行的。如果你在命名和路径方面小心谨慎,甚至可以为不同目标使用多个交叉编译器。 - Nick Meyer
1
“-march”不会阻止gcc生成操作码。它允许gcc生成操作码,否则将不被允许,因为它们在80386/7上不存在。 - R.. GitHub STOP HELPING ICE

2
如果你想尝试交叉编译,而不想自己构建工具链,我建议看看CodeSourcery。他们有一个基于GNU的工具链,他们免费的 "Lite" 版本支持相当多的架构。我已经用它来为Linux/ARM和Android/ARM进行编译。

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