基于平台构建
https://docs.bazel.build/versions/4.0.0/platforms-intro.html
Bazel 对 platforms和 toolchains 的模型化有着复杂的支持。将这些整合到项目中需要项目和第三方库拥有者,规则维护者 和 bazel 的核心开发者 之间互相协调合作。
这个页面总结了 platfomes 的使用参数,让您以最小的成本理解相关概念。
简而言之:核心的 api 是可用的,但是规则和仓库的迁移正在进行中。者意味着你可以在你的项目的中使用 platforms 和 toolchains,但你需要明确的将它们添加到你的项目中。
更多信息参见:
背景
platforms 和 toolchains 是用于规范为不同类型的计算机构建编译不同语言的项目所需要的工具。
这是 Bazel 相对较新的功能。这个灵感来源于语言的维护者以零时且不兼容的方式执行一些操作。例如,对于 C++ 规则 使用 --cpu
和 --crosstool_top
设置目标 CPU 和 C++ toolchains。这些都不是正确的规范化的 platform。以前使用这些,不可避免的导致了不准确的构建 API。甚至于 java toolchains,已经演变出了独立的 --java_toolchain
。
Bazle 的目标是在大小,多语言,多平台的项目上脱颖而出。这要求对这些概念有更原则的支持,包括清楚的不区分项目和语言的API。这是新 platform 和 toolchain apis 的实现目标。
迁移
这些 API 还不足以支持所有的平台。我们还必须淘汰旧的 apis。这并非易事,因为所有的语言,工具链,依赖和 select() 都需要支持新的apis。为了保证项目正确,这些需求需要有序的进行迁移。
例如,Bazel 的 c++ 规则已经支持 platforms,但是 android rules 还没有。你的 c++ 项目可能不关心 android。但是其他人有需要。所以platforms对 c++ 构建还不是完全安全的。
该页面的其余部分描述了此迁移顺序,以及适应方式和时间。
目标
当所有的项目使用以下构建方式,Bazel 项目就迁移完成了。
bazel build //:myproject --platforms=//:myplatform
这意味着:
- 你项目使用的规则,可以从
//:platform
推断出正确的toolchains
- 你的项目依赖所使用的规则能够从
//:myplatform
推断出正确的toolchains
- 所有依赖于你的项目,要么支持
//:myplatform
,要么支持传统 API 像--crosstool_top
-
//:myplatform
指的是CPU
,OS
和其他支持自动跨项目的的概念 - 所有使用
select()
的项目默认可以获取//:myplatform
- 如果需要定义项目的专属 platforms ,则
//:myplatform
应该定义在清晰易获取的地方,或者是其他所有可能使用此平台的位置。
一旦这个目标实现,我们将会移除旧的 API 并且使该方法称为选择 platforms 和 toolchains 的唯一方法。
我应该使用 platforms 吗
如果你只想跨平台的构建项目,你应该参照项目的官方指导。
如果你是项目,语言或者工具链的maintainer,你最终应该支持新的 api。至于等到全部迁移完成还是提前取决于您的 收益 / 成本。
收益
- 你可以使用
selet()
或者其他你想要的配置来选择 toolchains,而不是用类似--cpu
的硬编码。例如,很多 cpu 支持相同的指令集。 - 更正确的构建。如果你在
select()
中使用--cpu
,然后添加了一种支持同样指令集的架构,select()
对于新cpu是无法识别的。但是select()
在 platforms 上依然正确。 - 更简单的用户体验。所有的项目都理解
--platforms=//:myplatform
。不需要在命令行中为不同的语言指定不同的参数。 - 更简单的语言设计。所有的语言使用通用的 api 为 platform 定义,使用和选择正确 toolchains。
- Targets 能够在构建和测试阶段跳过,如果它们和目标平台不兼容。
成本
- 你无法自动使用那些不使用 platforms 的独立项目
- 让它们能够使用需要额外的零时维护工作
- 新旧 api 的共存需要更仔细的用户指南以避免混淆
- 像
OS
和CPU
这样更多通用属性的定义仍然在不断发展,并且可能需要额外的初始投入。 - 用于特定语言的工具链仍然在不断发展,并且可能需要额外的初始投入。