澄清“./configure”选项“--build”,“--host”和“--target”

4
脚本./configure接受选项--build、--host和--target。阅读了一些帖子和文章后,我仍然不清楚这些选项究竟是什么以及包含哪些软件。
以下是GNU网站上关于这三个术语的摘录:
有三个系统名称是构建知道的:您正在构建的机器(build)、您要构建的机器(host)以及GCC将生成代码的机器(target)。在配置GCC时,您使用--build=、--host=和--target=来指定这些内容。
应避免仅指定主机而不指定构建,因为configure可能会(并曾经)假设您指定的主机也是构建,但这可能不是真实情况。
当使用“building on”或“building for”这一术语时,他们到底指的是什么?从我阅读的帖子中,似乎“building on”是指用于编译调试器或编译器的系统,而主机是运行调试器或编译器的系统。
我在this article中遇到的一个例子让我对“build”正在“构建”的内容感到困惑:
  • build:一台powerpc编译机,你将在上面进行所有的编译工作
  • host:一台x86笔记本电脑,你将在现场使用它来调试这些设备
  • target:多个带有MIPS处理器的嵌入式设备,你的代码将在这些设备上运行

由于PowerPC正在为MIPS设备进行编译,这是否意味着它既是主机也是构建主机?这是否还意味着运行调试软件的系统也归类为主机系统?

根据this article中用户的评论,提到:

  • build = 我将编译编译器的地方
  • host = 编译器将要运行的地方
  • target = 编译器将要生成的代码

这是否意味着运行编译器、链接器和调试工具的系统可以被归类为“主机”?那么“构建”的软件包括什么?

以下是GNU网站上另一个片段:

如果构建、主机和目标都相同,则称为本地。如果构建和主机相同但目标不同,则称为交叉编译。如果构建、主机和目标都不同,则称为加拿大(出于与加拿大政党和当时参与构建的人的背景相关的模糊原因)。如果主机和目标相同,但构建不同,则使用交叉编译器为不同系统构建本地。有些人称之为主机-x-主机、交叉本地或交叉构建本地。如果构建和目标相同,但主机不同,则使用交叉编译器构建交叉编译器,以生成在您正在构建的计算机上运行的代码。这很少见,因此没有通用的描述方式。有一个提议称之为交叉回编。
  • 本地 - 我的 x86_64 机器是我的本地计算机,我在上面运行和测试我的程序。编译器/链接器(gcc)是在安装操作系统时编译和安装的,我使用 gcc 编译我的代码,并在同一台机器上本地运行。
  • 交叉 - 如果我使用同一台 x86_64 机器编译 MIPS 设备的代码,则现在它是交叉编译。x86_64 机器是主机/构建机,MIPS 设备是目标机。
  • 加拿大式 - 发布了新版本的 GCC,我决定使用另一台机器(PowerPC2)来编译和测试新的编译器。任何未来的编译器编译都将在此处完成,并在成功测试后部署到我的 x86_64 上。因此,PowerPC2 现在是构建机,X86_64 系统是主机,MIPS 设备是目标机。
  • 交叉编译器 - 我们将保持 PowerPC2 作为构建系统,但现在我在同一台 x86_64 主机上编译和运行代码。
  • 最后一种设置相当奇怪,它确实表示“没有通用的方法来描述构建和目标相同,但主机不同的情况”。为什么要以这种方式设置系统?
1个回答

2
这并不是针对“普通”软件的复杂问题:您需要一个构建系统(用于编译软件)和一个主机系统(用于运行软件)。通常情况下,这两个系统是相同的(您在自己的系统上生产软件以供自己使用),但有时它们不同,通常是因为主机系统不适合编译软件,例如嵌入式设备,或者当主机系统尚未提供时。这种设置——在一个系统(类型)上编译软件,但在另一个系统(类型)上运行——称为交叉编译。
如果您编译编译器,则会涉及到第三个系统,因为您构建的编译器可能是交叉编译器。您正在构建的编译器将生成代码的系统称为目标系统。通常情况下,构建和主机系统将是相同的——您的新编译器将在您正在构建它的计算机上运行,这显然非常适合编译软件——但有时它们不同;在这种情况下,您正在构建一个编译器(构建),该编译器将在另一个系统(主机)上运行,在那里它将为另一个系统(目标)生成代码。

这篇文章描述了一个类似的场景,但是针对的是被分为两部分的调试器。其中一部分是运行在被调试设备上的服务器,另一部分是运行在连接到嵌入式设备的x86笔记本电脑上的gdb客户端。

现在,调试器就像反编译器一样,与编译器相似,它理解某种体系结构的机器代码。与编译器一样,不需要所有调试器的部分都在被调试的机器上运行;我们可以有一个“交叉调试器”,有一个主机(它在哪里运行)和一个目标(它所理解的体系结构)。这就是这里的情况。这里有:

  • gdbserver在被调试的嵌入式设备上运行
  • 并且gdb客户端在连接到嵌入式设备的服务器的“真实机器”上运行。

对于调试器的两个部分,目标都是MIPS嵌入式设备,即使它们不生成代码,而是解释代码。

对于gdb的客户端而言,构建、主机和目标系统都是不同的:它是在PowerPC上构建的,由x86托管,并针对理解MIPS嵌入式系统架构的系统进行了定位。对于gdb的服务器而言,主机和目标系统是相同的(因为它运行在MIPS嵌入式设备上,理解其架构)。
因为主机和目标系统是相同的,所以我们对服务器进行了经典的交叉编译;只需要定义"host"即可,因为如果没有明确指定,则"target"默认为"host"。

关于PowerPC的示例,PowerPC将是构建和主机,x86_64是调试器的目标,而MIPS设备是实际软件运行的目标。这样正确吗?此外,我使用的GCC程序是交叉编译器,因为我可以指定其他机器的选项。 - supmethods
我认为你想在PowerPC上构建一个gcc,该gcc将在x86_64上运行,并在那里生成MIPS软件?这将是build=PowerPC,host=x86_64,target=MIPS。是的,您需要使用交叉gcc构建交叉gcc。(我认为您需要为所有3个平台获取binutils。) - Peter - Reinstate Monica
我在这篇文章的PowerPC示例中提到了stackoverflow.com/questions/5139403/…,调试器已经作为主机包含在他的示例中。我编辑了我的帖子并在“我的理解”部分将其更改为PowerPC2,以便在讨论中更清晰。其他用户的示例仍然是PowerPC。 - supmethods
@supmethods 看我的编辑...我试图解释gdb服务器/客户端场景。 - Peter - Reinstate Monica
谢谢,这确实解决了问题。GDB客户端是加拿大十字编译:工具正在构建的系统和工具将运行的系统不同。此外,它是针对第三个系统即GDB服务器进行定位的。 - supmethods

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