当编写依赖于CPU架构的软件时,例如在x86上运行的C代码或在ARM CPU上运行的C代码。通常有两种方法来编译这些代码,要么交叉编译到ARM CPU架构(例如,如果您在x86系统上开发),要么将代码复制到本地arch CPU系统并进行本地编译。
我想知道本机方法与交叉编译方法相比是否有好处?我注意到Fedora ARM团队正在使用一个缓慢/低功耗ARM设备的构建服务器集群来“本机”编译他们的Fedora ARM spin...当然,由Red Hat支持的项目可以访问一些运行x86 CPU的强大构建服务器,这些服务器可以在1/2的时间内完成工作...那么为什么他们选择?交叉编译我的软件是否遗漏了什么?
5条答案
按热度按时间x8goxv8g1#
主要的好处是所有的
./configure
脚本在本地运行时不需要调整。如果你使用的是shadowrootfs,那么你仍然有运行uname
的配置来检测CPU类型等。例如,请参阅this question。pkgconfig
和其他工具试图简化 * 交叉构建 *,但是软件包通常会先在x86上进行 * 本机构建 *,然后在ARM上进行 * 本机构建 。 交叉构建 * 可能会很痛苦,因为每个软件包可能需要单独的调整。最后,如果您正在执行profile guided optimizations并按照Joachim运行 * 测试套件 *,那么在 * 交叉构建 * 环境中几乎不可能做到这一点。
ARM上的编译速度明显快于人类包构建器,读取
configure
,编辑configure
,重新运行配置,编译,链接周期。这也很适合continuous integration策略。各种软件包,尤其是 libraries,可以快速构建/部署/测试。libraries 的测试可能涉及数百个依赖包。Arm *Linux发行版 * 在升级和修补基础库时通常需要对更改进行原型化,该基础库可能有数百个依赖包,至少需要重新测试。由计算机完成的缓慢循环总是比由人工干预的快速编译要好。
dvtswwa32#
不,从技术上讲,在.c -〉.o -〉a.out(或其他)的上下文中进行交叉编译不会遗漏任何内容;交叉编译器会给予你和本机编译器一样的二进制文件(尽管版本不同)
本机构建的“优势”来自编译后测试和管理复杂系统。
1)如果我能在编译后快速运行单元测试,我就能快速找到任何bug/问题,这个周期大概比交叉编译周期短;
2)如果我正在编译一些目标软件,它使用第三方库,那么在本机平台上构建,部署并使用它们来构建我的目标可能会更容易;我不想处理那些交叉编译的构建,因为其中一半的构建过程是由疯狂的猴子编写的,这使得交叉编译变得非常痛苦。
通常情况下,对于大多数事情,人们会尝试获得基本构建并在本机编译其余部分。除非我有一个生病的设置,我的交叉编译器超级快,我在那里保存的时间是值得的,以使其余的事情(如单元测试和依赖项管理)更容易。
至少我是这么想的
fivyi3re3#
本机编译的唯一好处是,您不必将程序转移到目标平台,因为它已经在那里了。
然而,考虑到大多数目标平台与现代x86 PC相比性能严重不足,这并不是一个很大的好处。内存量,更快的CPU,特别是更快的磁盘使PC上的编译时间快了很多倍。以至于本机构建的优势不再是一个真正的优势。
cbeh67ev4#
这在很大程度上取决于编译器。工具链如何处理本机和交叉编译之间的差异。是否只是工具链总是认为它是作为交叉编译器构建的,但构建它的一种方法是让配置脚本自动检测主机,而不是手动操作(并自动设置前缀等)?
不要因为它是一个原生编译器就认为它真的是原生编译器。有很多例子,发行版将其原生编译器(以及内核和其他二进制文件)简化,以便该发行版可以在更广泛的系统上运行。例如,在ARMv 6系统上,您可能正在运行默认为ARMv 4的编译器。
这就引出了一个类似的问题,如果我用一个默认架构构建工具链,然后指定另一个,那么为目标架构构建工具链有什么不同吗?
理想情况下,你会希望一个主要调试的编译器/工具链会给予你相同的结果,无论你是原生的还是交叉编译的,并且独立于默认架构。现在我在一个旧的llvm上看到llvm-gcc在64位主机上运行时,交叉编译到arm会将所有int构建为64位,增加了很多代码,相同的编译器版本,32位主机上的相同源代码将给予不同的结果基本上-m32开关不适用于llvm-gcc(当时),我不知道这是否仍然是这样,因为我切换到clang时做llvm的工作,从来没有回头看llvm-gcc... llvm/例如,clang一直以来都是一个交叉编译器,链接器是唯一一个看起来特定于主机的东西,你可以使用现成的llvm,在任何主机系统上编译任何目标(当然,前提是你的构建没有禁用任何支持的目标)。
sr4lhrrt5#
虽然许多人认为“本地编译”比“交叉编译”更有好处,或者至少没有什么区别,但事实恰恰相反。
对于那些在低层(如linux内核)工作的人来说,他们通常会遭受编译平台周围的复制,以x86和ARM为例,直接的想法是建立ARM编译库,但这是一个坏主意。
二进制有时候是不一样的,例如,
一般来说,较高级别的应用程序可以同时使用,较低级别(硬件相关)的工作建议使用
x86 "cross compile"
,因为它有更好的工具链。无论如何,compile是一个关于GCC Glibc和www.example.com的工作lib.so,如果你熟悉这些,任何一种方式都应该很容易。
PS:下面是源代码