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

13

我看到的所有资料似乎都在暗示构建一个交叉编译器比构建一个针对运行平台的编译器要难得多。这是真的吗?如果是,为什么会这样?似乎对于任意平台生成汇编代码和系统调用并不比为编译器运行的平台生成这样的代码和系统调用更难,但也许我只是天真了。


你所说的“building”,是指“编程”还是“编译”? - flodin
1
很有趣知道你读了什么。这是错误的 :-) - Norman Ramsey
@dsimcha 不,这并不显著更难,尽管根据常识可能会稍微更难,但我仍然不太明白你想问什么。 - Sapphire_Brick
7个回答

3
这并不一定很难,但取决于编译器架构。
编译器不仅将源代码转换为汇编和系统调用。它还将现有的“辅助代码”集成到生成的文件中。这些代码包括启动代码、函数序言、可以内联的C API的部分等。
在普通编译器C1平台A上建立在平台A上时,原始编译器C0可以直接构建C1及其帮助程序代码(对于A,因为C0针对A)。
在交叉编译器C2平台B上建立在平台A上时,原始编译器C0必须首先构建一个特殊版本的C2,该版本不需要帮助程序代码(因为帮助程序代码是针对B的,而C0则针对A),然后它必须运行C2以生成帮助程序代码。根据编译器的不同,它可能还必须生成第二个包含帮助程序代码的C2版本。
构建没有帮助程序代码的C2的有限版本的过程就是引导过程。

3
以下是我在使用GCC交叉编译时遇到的一些问题:
  • 为了进行链接,你必须在主机系统上拥有一些目标系统的系统文件(即sysroot)。

  • 某些语言要求在编译时而不是运行时评估某些内容;此外,某些优化会导致在编译时评估那些在未经优化的情况下将在运行时评估的内容。当目标具有主机系统上不存在的数值类型时,在编译时和运行时获得相同的答案可能会比较棘手。

  • 测试可能会更加麻烦。你需要两个系统,并且需要一种将程序从一个系统传输到另一个系统的方法。

但总的来说,这就是我遇到的一般性问题。


2
建立一个交叉编译器比针对其所在平台的编译器要困难得多。这个问题存在是因为库的构建和访问方式不同。在正常情况下,所有库都位于特定位置,并由该系统上所有应用程序使用。所有构建机制和软件都假定库的位置。make文件、编译器等都依赖于它们能够到达特定位置并找到所需内容的想法。但在交叉编译的情况下,交叉编译器、make文件等不能做出这些假设,否则它们将链接错误的库。因此,这实际上归结为开发人员早期做出了某些假设,而我们被束缚于此。当您构建根文件系统时,它会变得更加困难,因为Unix只知道一个根文件系统。当您构建另一个根文件系统时,您必须创建一个特殊环境,使您能够在不影响真正的根文件系统的情况下操纵它。

1

你是否在看一个特定的案例,比如“将GCC作为交叉编译器构建”,其中“构建”意味着“编译”,而不是“编写”?

这可能更困难,因为涉及到库的问题 - 对于交叉编译器,您需要针对目标平台的库。对于“本地”(即非交叉)编译器,您显然已经拥有目标库。

我同意您关于“创建代码生成器”的方面是相同的观点 - 或者至少更受目标处理器架构的影响,而不是编译器执行的位置。

而且,有明显的情况下,交叉编译器比非交叉编译器更容易。我认为,在8051托管的C++编译器上,无论它针对哪个平台,都会很费力。


1
许多交叉编译器具有多个目标。我认为,通常来说,多目标编译器比单目标编译器要难得多,而所有多目标编译器都是跨编译器。因此,许多交叉编译器比非交叉编译器要复杂得多。
在平台A上编写一个仅为平台B编译代码的编译器,从原理上讲并不比为平台A编写仅为平台A编译的编译器更难。

这个逻辑是有缺陷的,因为它并不是真正的逻辑,而是以“我认为”开始的。同时也没有解释为什么一个多目标编译器更加困难。 - Henry B
1
我认为这是非常明显的...你需要多个二进制转换器,每个目标一个。你还需要确保你在内部以一种方式表示数据,不仅适用于一个指令集,而且可能适用于多个非常不同的指令集。 - patros
一个针对另一个平台的编译器只需要处理一个平台,即它所针对的那个平台。 - Potatoswatter

1
构建交叉编译器只有在你意识到可能需要进行交叉编译时才会变得困难。同样,汇编器、链接器和调试器也是如此。你所需要做的就是记住创建一个明确的抽象来表示你对目标机器的了解。
如果想要查看一个设计非常良好、文档齐全的交叉编译器示例,请查看lcc。如果想要阅读关于交叉调试器设计的文章,可以参考conference paperdoctoral dissertation。代码可能可供下载,但我不确定。

0

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

为什么现在无法跨平台创建程序?

我觉得这归结于不同操作系统以不同方式调用本地IO。要构建一个平台无关的编译器,您将需要精确了解所有细节,并基本上构建一个操作系统。

(我现在要离开工作,回家后会更新)


我不同意这个观点。如果我有一个可移植的编译器,比如说 ANSI-C,我可以在任何有 ANSI-C 编译器的平台上轻松编译它。IO 如何影响它,与构建操作系统有什么关系? - patros
除非你在谈论链接/归档,但那是另一个完全不同的问题。 - patros

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