我正在经历Linux 从头开始 11.0 书。在三.构建 LFS 交叉工具链和临时工具,ii。工具链技术说明,有一点关于加拿大交叉交叉编译的内容。我不明白为什么需要 3 个阶段和 3 台机器才能达到最终结果。文本假设我们从计算机 A 和一个在 A 上运行并为 A 生成二进制文件的编译器开始。那么为什么我们不直接使用该编译器来构建一个在 C 上运行并为 C 构建二进制文件的编译器呢?为什么会有这么多麻烦,先构建一个在 A 上运行但为 B 构建的编译器,然后构建一个在 B 上运行但为 C 构建的编译器,最后构建在 C 上运行并为 C 构建的编译器?
我还在维基百科上找到了一篇关于它的文章 -https://en.wikipedia.org/wiki/Cross_compiler。
答案1
描述的场景是这样的
- 机器A速度慢并且有编译器
- 机器 B 速度快,但没有编译器
- 机器 C 是目标,但速度很慢,并且没有编译器
您可以在 A 上构建 C 的所有二进制文件,但这会花费很长时间,因为机器 A 速度很慢。
作者认为,花少量时间在 A 上交叉编译 B 的编译器是值得的。然后,可以使用快速机器 B 来交叉编译慢速机器 C 的所有必需的二进制文件,从而减少总体时间避免在 A 或 C 上编译。
最后一步,在 C 上为 C 构建编译器,只是消除对机器 B 的依赖。虽然速度很慢,但机器 C 现在可以直接编译偶尔的程序本身。
答案2
首先,计算机 C 并不是可以实际编译的东西。它可能是嵌入式设备,甚至只是您不想设置进行编译的生产机器。
所以你就有了这样一台“nix”机器。您需要能够对其进行交叉编译。
你拥有的是一台构建机器。这是 B。它是一台足够快、足够强大的机器,但它没有编译器。它甚至没有为 B 构建的编译器,更不用说为 C 构建的编译器了。你想用它来为 C 构建东西。
你怎么得到它?好吧,您与拥有 B 编译器的人交谈,最好是直接交叉编译到 C 的编译器。然后将其下载到 B,并使用它为您的定制系统 C 进行交叉编译。
他们从哪里获得 B 的编译器?他们的系统很可能与 B 不同。他们如何开始?
他们真正需要的是一个系统 A,以及一个为 A 编译程序的编译器。
现在,已经安装在 A 上的这个编译器可能无法构建交叉编译器。它只是某种语言的编译器(比如C)是由供应商或其他东西提供的。
您需要的是一个可以为 B 编译二进制文件的交叉编译器。为此,首先您使用 A 到 A 编译器(您的“供应商”编译器),并编译一个支持交叉编译到 B 的编译器。
接下来,你那编译器,然后你让它编译一个从 B 编译到 C 的交叉编译器。
然后你分发那B 到 C 编译器给拥有计算机 B 和 C 的人。
...
现在,这是(并且曾经是)一个现实世界的问题。您有一台带有供应商编译器的 microsoft windows 计算机,或者一台 Solaris unix 计算机,或者一台 macOS 计算机。在所有情况下,您都可以轻松获得编译器,但不能轻松获得交叉编译器。这些供应商对为您提供交叉编译器兴趣不大。
您没有向您提供工具的每个人都拥有的计算机(B 和 C)。因此,您可以从“锁定”的系统 A 引导到能够构建和分发全套预构建工具以供用户下载的程度。
“硬”要求是计算机A有一个编译器,可以编译B到C的交叉编译器;其中编译器的执行指令集和编译器的目标指令集对于A来说都是外来的。
答案3
罗艾玛的回答描述了LFS提出的逻辑。我不相信 LFS 对三路“加拿大十字”编译给出了很好的解释。
假设机器 A 为机器 B 生成一个编译器,该编译器为机器 C 进行编译:
由于机器 C 的限制,B 和 C 通常是不同的(是)。举个例子,开发人员可能想要为机器 C 编译代码,但 C 的功能非常有限小型计算机公司或嵌入式设备,并且由于 CPU 和内存限制而无法轻松运行其自己的编译器。因此,开发人员使用功能更强大的桌面(机器 B)来编译 C。
A 和 B 最常见的是不同的,但这并不是因为资源限制。更常见的原因通常是编译编译器本身的开发人员与编译 C 最终代码的开发人员不同。他们通常不在同一组织中。
例子
获取ubuntu包gcc-arm-linux-gnueabihf。这是由 Ubuntu 核心开发人员维护的。任何希望在另一台机器(例如 AMD64 机器)上编译 ARM 程序的人都可以下载该软件包。也就是说,任何人都可以将其安装到 B 上来编译 C,而 Ubuntu Core 开发人员无法控制机器的 B 和 C。
现在 Ubuntu Core 开发人员编译 gcc-arm-linux-gnueabihf 以在 amd64、arm64 和 i386 上运行。他们不想要或不需要三台构建机器来构建它的所有三个版本。那是因为机器a能与机器 B 和 C 的架构不同。