9

我读过的所有内容似乎都暗示构建交叉编译器比构建针对其运行平台的编译器要困难得多。这是真的?如果是这样,为什么?似乎为任意平台生成汇编代码和系统调用不应该比为编译器运行的平台生成这样的代码和系统调用更难,但也许我只是天真。

4

7 回答 7

3

这不一定更难,但它可能取决于编译器架构。

编译器不仅将源代码翻译成 asm 和系统调用。它还将预先存在的帮助代码集成到生成的文件中。这是代码包括启动代码、函数前导码、可以内联的部分 C api 等。

在平台 A 上构建的平台 A 的普通编译器 C1 中,原始编译器 C0 可以直接构建 C1 及其帮助代码(对于 A,因为 C0 以 A 为目标)。

在平台 A 上构建的平台 B 的交叉编译器 C2 中,原始编译器 C0 必须首先构建一个不需要帮助代码的特殊版本的 C2 (因为帮助代码是针对 B,而 C0 针对 A),然后它必须运行 C2 来生成帮助代码。根据编译器的不同,它可能必须生成包含帮助程序代码的第二个 C2 版本。

在没有帮助代码的情况下构建 C2 的受限版本的行为是引导。

于 2009-02-17T17:52:11.237 回答
3

以下是我在使用 GCC 交叉编译时遇到的一些问题:

  • 您必须在主机系统(即 sysroot)上存在来自目标系统的一些系统文件才能链接。

  • 有些语言要求在编译时而不是在运行时评估事物;此外,一些优化导致在编译时评估将(在未优化的情况下)在运行时评估的东西。当目标具有主机系统上不存在的数字类型时,在编译时和运行时情况下获得相同的答案可能会很棘手。

  • 测试可能会更烦人。您必须拥有两个系统,以及一种将程序从一个转移到另一个的方法。

不过,实际上,这就是我遇到的一般问题。

于 2009-08-05T19:26:26.573 回答
2

“构建交叉编译器比构建针对其运行平台的编译器要困难得多。”

由于库的构建和访问方式而存在问题。

在正常情况下,所有库都位于特定位置,并由该系统上的所有应用程序使用。所有构建机制和软件都假定库的位置。make 文件、编译器等取决于他们可以去特定地点并找到所需内容的想法。

但是,在交叉编译的情况下,交叉编译器、make 文件等无法做出这些假设——如果他们这样做,它们将链接错误的库。

所以这真的归结为开发人员在早期做出了某些假设的事实,而我们坚持这一点。

构建根文件系统时会变得更难,因为 unix 只知道一个根文件系统。当您构建另一个根文件系统时,您必须创建一个特殊的环境,允许您在不影响真正的根文件系统的情况下对其进行操作。

-亚当

于 2009-02-17T17:55:53.457 回答
1

您是否有可能正在查看诸如“将 GCC 构建为交叉编译器”之类的特定案例,其中“构建”的意思是“编译”而不是“编写”?

由于库周围的问题,这可能会更难 - 对于交叉编译器,您需要目标平台的库。对于“本机”(即非交叉)编译器,您显然已经有了目标库。

我与您在“创建代码生成器”方面相同 - 或者至少受目标处理器体系结构的影响比受编译器执行位置的影响更大。

在某些情况下,交叉编译器比非交叉编译器容易得多。我认为一个 8051 托管的 C++ 编译器将是艰苦的工作,无论它针对什么平台。

于 2009-02-17T17:50:00.540 回答
1

许多交叉编译器有多个目标。我认为总的来说,多目标编译器比单目标编译器要困难得多,并且所有多目标编译器都是定义交叉编译器。因此,许多交叉编译器比非交叉编译器复杂得多。

在平台 A 上编写一个只为平台 B 编译代码的编译器,原则上不应该比在平台 A 上编写一个只为平台 A 编译的编译器难。

于 2009-02-17T17:55:05.003 回答
1

只有当您从未想到您可能想要交叉编译时,构建交叉编译器才是困难的。有趣的是,汇编器、链接器和调试器也是如此。您需要做的就是记住创建一个明确的抽象来表示您对目标机器的了解。

有关设计良好、文档完善的交叉编译器的示例,请查看lcc。要了解交叉调试器的设计,请参阅会议论文博士论文。该代码可能是可下载的;我不知道。

于 2009-02-20T05:01:00.003 回答
0

以下问题的答案可能会帮助您理解为什么这会很困难。

为什么我们现在不能创建跨平台的程序?

我觉得这一切都归结为不同的操作系统以不同的方式调用本机 IO。要构建一个独立于平台的编译器,您将必须准确了解所有细节是如何工作的,并且基本上构建一个操作系统。

[我回家后会更新,因为我现在要下班了]

于 2009-02-17T17:54:35.490 回答