为什么构建交叉编译器比构建常规编译器更难?

时间:2009-02-17 17:37:06

标签: compiler-construction cross-platform cross-compiling

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

7 个答案:

答案 0 :(得分:1)

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

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

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

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

在没有帮助代码的情况下构建限制版C2的行为是自举。

答案 1 :(得分:1)

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

在仅为平台B编译代码的平台A上编写编译器原则上不应该比在仅为平台A编译的平台A上编写编译器更难。

答案 2 :(得分:1)

只有在您可能想要交叉编译的情况下,才会构建交叉编译器。有趣的是,汇编器,链接器和调试器也是如此。您需要做的就是记住创建一个显式抽象来表示您对目标机器的了解。

有关设计精良,文档齐全的交叉编译器的示例,请查看lcc。要了解交叉调试器的设计,可以使用conference paperdoctoral dissertation。 代码可以下载;我不确定。

答案 3 :(得分:1)

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

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

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

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

但是,真的,这就是我遇到的一般性问题。

答案 4 :(得分:0)

您是否有可能在查看特定情况,例如“将GCC构建为交叉编译器”,其中“构建”意味着“编译”而不是“编写”?

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

我和你在'创建代码生成器'方面是相同的 - 或者至少受目标处理器体系结构的影响比编译器执行的更多。

并且有明显的情况,交叉编译器比非交叉编译器更容易 。我认为8051托管的C ++编译器无论在什么平台上都会很难实现。

答案 5 :(得分:0)

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

Why can't we create programs cross-platforms these days?

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

[当我回家时我会更新,因为我现在必须离开工作]

答案 6 :(得分:0)

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

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

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

在交叉编译的情况下,交叉编译器,make文件等不能做出这些假设 - 如果他们这样做,他们将链接错误的库。

因此,事实上,开发人员在早期做出了某些假设,而且我们仍然坚持这一点。

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

- 亚当