包的主机、构建和目标平台如何定义(相对于依赖关系)?

包的主机、构建和目标平台如何定义(相对于依赖关系)?

https://www.uber.com/blog/bootstrapping-ubers-infrastruct-on-arm64-with-zig/说:

主机是编译二进制文件的机器。目标是将运行二进制文件的机器。在本机编译中,主机和目标是相同的平台(即操作系统、处理器架构和共享库相同)。

https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-dependency-reference说:

依赖关系可以沿三个轴分解:相对于新衍生版本的主机和目标平台,以及它们是否被传播。平台的区别是由交叉编译引起的;请参阅交叉编译以了解每个平台的具体含义。 [1] 但即使不是交叉编译,平台也意味着在运行时或构建时是否需要依赖关系,这一概念在交叉编译之外非常有意义。默认情况下,运行时/构建时的区别只是为了头脑清晰的一个提示,但在设置了 strictDeps 后,即使在本机情况下,它也基本上是强制执行的。

上面提到的具有依赖关系的 PATH 扩展仅根据相关平台进行。该过程仅针对其主机平台与新派生的构建平台匹配的依赖项执行,即在将构建新派生的平台上运行的依赖项。[2] 对于这些依赖项中的每个依赖项,dep/bin(如果存在)将添加到 PATH 环境变量中。

当某些其他可传递(非直接)下游依赖项也需要它作为直接依赖项时,就称该依赖项被传播。 [3]

重要的是要注意依赖关系不一定像以前那样传播,而是按照相应的排序,以便平台规则仍然保持一致为了确定依赖关系传播的确切规则,我们首先为每个依赖关系分配几个三进制数字(-1 表示构建,0 表示主机,1 表示目标)表示其依赖关系类型,该类型捕获其主机和目标平台的情况与依赖派生的主机和目标平台的每个“偏移”。下表总结了可以获得的不同组合:...

第一个引用将包的主机和目标平台定义为构建和运行包的平台。

但读到第二句话时,我无法理解

该过程仅针对其主机平台与新派生的构建平台匹配的依赖项执行,即在将构建新派生的平台上运行的依赖项。

这是否意味着依赖项的主机平台被定义为它们的运行位置?而新派生的构建平台是它的构建位置?

宿主平台和构建平台是同一个概念吗?如果是,为什么第二句话要区分它们?

谢谢。

答案1

假设主机 B(平台类型 A)正在为平台类型 Y 构建软件 X。

现在,B 是构建主机A 将是搭建平台。对于该构建项目的所有子部分都是如此。

软件 X 可以有两种类型的依赖关系:运行时依赖构建时依赖。但构建时依赖项可以进一步分为两个子类:

  • 作为构建过程的一部分需要在构建主机上运行的东西,即源代码预处理器和类似工具。这些需要适合在平台 A 上运行。
  • 将成为软件 X 一部分的事物,例如将静态链接的代码库,或将合并到最终软件包中的数据。如果任何可执行代码属于此类别,则它需要适合在平台 Y 上运行。此子类的某些内容实际上可能与平台无关,例如某些库头文件和其他数据项。

当平台 A 等于平台 Y 时,这两个子类型都可以用相同的方式解析:只需构建依赖树,然后从叶开始向根前进。

但是,当 A 不等于 Y 时,您还需要跟踪每个构建时依赖项属于哪个子类型。

现在,每个构建时依赖项都可能有自己的依赖项。因此,构建者可能会发现,为了为平台 Y 构建软件 X,它首先需要为自己构建一个工具 T...而为了为平台 A 构建工具 T,它首先需要满足它的构建依赖关系,这可能会导致平台 A 的构建工具 T3 链为平台 A 构建另一个工具 T2 ......最终构建软件 X。

构建时依赖项的第二个子类需要交叉构建:如果我们的软件 X 需要静态库 L,那么构建主机将需要首先获取或构建适用于平台类型 Y 的 L 版本。但是库 L可能会有自己的一组构建时依赖项两个子类型的:要为平台 Y 构建库 L,构建主机可能首先必须为自己(平台 A)构建工具 T2,以及将用作库 L 的一部分的库 L2,因此也必须为平台 Y 构建 L2。

自动构建过程必须跟踪所有这些依赖关系,每个迭代到任意深度。理想情况下,它还应该弄清楚,如果需要特定的工具 T 来构建属于整体构建一部分的多个软件组件,则应该只构建一次并保留该工具,直到构建了需要该工具的所有软件组件为止。

因此,自动构建器首先会一一构建构建时依赖项,直到最终可以构建软件 X。每个单独的组件构建操作都会有主机平台一个和一个目标平台A 或 Y 取决于它是构建时依赖项的哪个子类。

一旦软件 X 完全构建完成,它可能会携带一些元数据,这些元数据有效地表示“为平台类型 Y 构建在(平台 A 的)主机 B 上”。换句话说,这个特定的软件 X 构建实例具有构建主机乐队目标平台Y。

搭建平台(A) 此时通常不重要,除非需要追踪仅在特定架构上使用特定工具时才会发生的构建错误。

在软件项目中,编写文档时通常最多只考虑一个交叉构建步骤:主机平台相当于搭建平台:两者都指构建/正在构建/将构建可执行文件的平台,并且目标平台指正在构建的可执行文件将运行的平台。

一旦构建了可执行文件,您就可以停止思考它是如何构建的,而开始思考可以用它做什么。如果可执行文件是交叉编译器,则主机和目标平台术语将在下一步中回收:

  • 构建交叉编译器的平台现在只是一个历史细节,没有特定的名称
  • 新交叉编译器将运行的平台现在称为主机平台
  • 新的交叉编译器将生成可执行文件的平台将是目标平台

我认为对于交叉编译交叉编译器的情况,“最终”目标平台没有一个广泛使用的行业标准术语。

但是 Nixpkgs 构建系统准备好处理交叉编译器的交叉编译情况,所以当你专门谈论 Nixpkgs 时,他们指定了各种平台条款如下:

  • 搭建平台= 构建/构建/将构建正在构建的可执行文件的平台
  • 主机平台= 正在构建的可执行文件将运行的平台
  • 目标平台= 仅适用于生成可执行代码的事物;正在构建的可执行文件最终将为其构建可执行代码的平台;最终目标平台。

相关内容