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

Compiler construction 为什么构建交叉编译器比构建常规编译器更难?,compiler-construction,cross-platform,cross-compiling,Compiler Construction,Cross Platform,Cross Compiling,我所读到的一切似乎都暗示,构建交叉编译器比构建针对其运行平台的编译器要困难得多。这是真的吗?若然,原因为何?似乎为任意平台生成汇编代码和系统调用不应该比为编译器运行的平台生成此类代码和系统调用更难,但也许我只是太天真了。您是否可能正在研究一个特定的案例,如“将GCC构建为交叉编译器”,“建筑”是指“编译”而不是“写作”吗 这可能会更困难,因为围绕库的问题-对于交叉编译器,您需要针对目标平台的库。对于“本机”(即非交叉)编译器,显然已经有了目标库 在“创建代码生成器”方面,我与您的观点相同,或者至

我所读到的一切似乎都暗示,构建交叉编译器比构建针对其运行平台的编译器要困难得多。这是真的吗?若然,原因为何?似乎为任意平台生成汇编代码和系统调用不应该比为编译器运行的平台生成此类代码和系统调用更难,但也许我只是太天真了。

您是否可能正在研究一个特定的案例,如“将GCC构建为交叉编译器”,“建筑”是指“编译”而不是“写作”吗

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

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


在某些情况下,交叉编译器比非交叉编译器容易得多。我认为一个8051托管C++编译器将是非常困难的,无论它所指向的平台是什么。

< P>这不一定是困难的,但是它可以依赖于编译器体系结构。 编译器不仅仅是将源代码翻译成asm和系统调用。它还将预先存在的助手代码集成到生成的文件中。这是一段代码,包括启动代码、函数前导、可内联的C api部分等

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

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


构建C2的有限版本,而不使用帮助程序代码,这是一个引导过程。

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

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


[我回家后会更新,因为我现在必须离开工作岗位]

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

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

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

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

在正常情况下,所有库都位于特定位置,并由该系统上的所有应用程序使用。所有构建机制和软件都假定库的位置。make文件、编译器等依赖于这样一种想法,即它们可以到达特定的位置并找到所需的内容

然而,在交叉编译的情况下,交叉编译器、make文件等不能做出这些假设——如果他们这样做,就会链接到错误的库

因此,这实际上归结为一个事实,即开发人员在早期就做出了某些假设,我们对此深信不疑

在构建根文件系统时,这会变得更加困难,因为unix只知道一个根文件系统。当您构建另一个根文件系统时,您必须创建一个特殊的环境,允许您在不影响实际根文件系统的情况下操作它


-Adam

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

有关设计良好、文档完整的交叉编译器的示例,请查看。要了解交叉调试器的设计,请参阅和。
代码可以下载;我不确定。

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

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

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

  • 测试可能有点烦人。您必须有两个系统,以及将程序从一个系统传输到另一个系统的方法


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

这是有缺陷的逻辑,因为它不是逻辑,因为它以“我想”开头。没有解释为什么多目标编译器也更难。我认为这很明显。。。您需要多个二进制程序,每个目标一个。您还需要确保在内部表示数据的方式不仅适用于一个指令集,而且可能适用于多个非常不同的指令集