交叉编译或编译Native Arch for CPU Arch

时间:2013-05-06 16:58:16

标签: c arm native cross-compiling

编写依赖于CPU拱的软件时,例如在x86上运行的C代码或在ARM cpus上运行的C代码。通常有两种方法可以编译这些代码,或者交叉编译到ARM CPU arch(例如,如果你在x86系统上开发),或者将代码复制到本机arch cpu系统并进行天真编译。 / p>

我想知道原生方法和交叉编译方法是否有好处?我注意到Fedora ARM团队正在使用慢速/低功耗ARM设备的构建服务器集群来“天真地”编译他们的Fedora ARM旋转......当然,由Red Hat支持的项目可以访问运行x86 cpu的一些强大的构建服务器这可以在1/2的时间内完成工作......为什么他们选择呢?我是否通过交叉编译我的软件而错过了什么?

5 个答案:

答案 0 :(得分:4)

主要好处是在本机运行时不需要调整所有./configure脚本。如果您使用阴影 rootfs ,那么您仍然有运行uname的配置来检测CPU类型等。例如,请参阅this questionpkgconfig和其他工具尝试简化交叉构建,但软件包通常首先在 x86 上获得 native-building ,然后可能 ARM 上的 native-building 交叉构建可能会很痛苦,因为每个软件包可能需要单独调整。

最后,如果您按profile guided optimizations 执行Joachim并运行测试套件 ,则几乎不可能在交叉构建环境。

ARM 上的编译速度明显快于人类软件包构建器,阅读configure,编辑configure,重新运行configure,编译,链接循环。

这也适用于continuous integration策略。可以快速构建/部署/测试各种软件包,尤其是的测试可能涉及数百个依赖包。在升级和修补基础库时,Arm Linux distrubutions 通常需要进行原型更改,这些库可能具有数百个依赖包,至少需要重新测试。计算机完成的慢速循环总是优于快速编译,然后是人工干预。

答案 1 :(得分:2)

本地编译的唯一好处是您不必将程序转移到目标平台,因为它已经存在。

然而,当考虑到大多数目标平台与现代x86 PC相比功能不足时,这并不是一个很大的好处。内存量,更快的CPU以及更快的磁盘使得PC上的编译时间快了许多倍。因此,本土建筑的优势不再具有优势了。

答案 2 :(得分:2)

从技术上讲,你不会在.c - >的背景下通过交叉编译错过任何东西。 .o - > a.out(或其他);交叉编译器将为您提供与本机编译器相同的二进制文件(尽管版本等)

本地构建的“优势”来自后编译测试和管理复杂系统。

1)如果我可以在编译后快速运行单元测试,我可以快速解决任何错误/问题,周期可能比交叉编译周期短;

2)如果我正在编译一些具有它使用的第三方库的目标软件,那么在本机平台上构建,部署然后使用它们构建我的目标可能会更容易;我不想处理那些交叉编译的构建,因为其中有一半是由疯狂的猴子编写的构建过程,这使得交叉编译它们很痛苦。

通常对于大多数事情,人们会尝试进入基础构建并本地编译其余部分。除非我有一个生病的设置,我的交叉编译器是快速超级恶劣的,我节省的时间是值得的设置,使其余的事情(如单元测试和依赖管理)更容易。

至少那些是我的想法

答案 3 :(得分:1)

这在很大程度上取决于编译器。工具链如何处理本机编译和交叉编译之间的区别。仅仅是工具链的情况总是认为它是作为交叉编译器构建的,但构建它的一种方法是让configure脚本自动检测主机而不是手动执行(并自动设置前缀等) )?

不要以为只是因为它是一个本机编译器而构建它真的是原生的。在许多情况下,发行版愚弄了他们的本机编译器(以及内核和其他二进制文件),以便该发行版在更广泛的系统上运行。在ARMv6系统上,您可能正在运行默认为ARMv4的编译器。

如果我使用一个默认体系结构构建工具链,然后指定另一个与构建目标体系结构的工具链不同的那个问题,那么就会遇到类似的问题吗?

理想情况下,无论您是本机还是交叉编译且独立于默认架构,您都希望大多数调试的编译器/工具链能够提供相同的结果。现在我在旧的llvm上看到llvm-gcc在64位主机上运行时,交叉编译到arm将构建所有的int,因为64位为代码增加了很多,相同的编译器版本,32位的相同源代码主机会给出不同的结果(32位整数)。基本上-m32开关不适用于llvm-gcc(当时),我不知道是否仍然如此,因为我在做llvm工作时切换到clang并且从不回头看llvm-gcc ... llvm / clang例如,主要是一个交叉编译器,链接器是唯一看起来是特定于主机的东西,你可以采用现成的llvm并为任何主机系统上的任何目标进行编译(前提是你的构建没有禁用任何目标)当然支持的目标)。

答案 4 :(得分:1)

尽管许多人认为“本地编译”的好处更多或至少与“交叉编译”相比没有区别,但事实恰恰相反。

对于在较低级别(即linux内核)上工作的人们,他们通常会遭受围绕编译平台的复制的困扰。以x86和ARM为例,直接的想法是建立ARM编译基础,但这不是一个好主意。

例如,有时二进制不一样

# diff hello_x86.ko hello_arm.ko
Binary files hello_x86.ko and hello_arm.ko differ
# diff hello_x86_objdump.txt hello_arm_objdump.txt
2c8
< hello_x86.ko:     file format elf64-littleaarch64
---
> hello_arm.ko:     file format elf64-littleaarch64
26,27c26,27
<    8: 91000000        add     x0, x0, #0x0
<    c: 910003fd        mov     x29, sp
---
>    8: 910003fd        mov     x29, sp
>    c: 91000000        add     x0, x0, #0x0

通常较高级别的应用程序可以同时使用,较低级别(与硬件相关的)工作建议使用x86 "cross compile",因为它具有更好的工具链。

无论如何,编译是关于GCC Glibc和lib.so的作品,如果熟悉它们,那么任一种方法都应该很容易。