Bazel 为建模平台和 工具链。将其与真实项目集成需要 代码所有者、规则维护人员和核心 Bazel 开发者之间密切合作。
本页总结了平台的用途,并展示了如何使用这些平台构建应用。
tl;dr:Bazel 的平台和工具链 API 可用,但无法正常运行
直到所有语言规则、select()
和其他旧版引用
。这项工作仍在进行中。最终,所有 build 都将基于平台。
请阅读下文,了解您的 build 的适用区域。
如需查看更正式的文档,请参阅:
背景
引入了平台和工具链,以实现软件 项目针对不同的机器,并使用合适的语言工具进行构建。
这是相对新近的 Bazel 添加功能。时间是
启发了
观察到语言维护者已经在投放广告中采取了这种做法
临时的、不兼容的方式。例如,C++ 规则使用 --cpu
和 --crosstool_top
来设置 build 的目标 CPU 和 C++ 工具链。这两个模型都不正确
即“平台”历史上尝试这样做的尝试导致了构建尴尬且不准确的构建。
这些标志也不控制 Java 编译,而 Java 编译已经发展出了自己的
与 --java_toolchain
的独立接口。
Bazel 适用于大型、多语言和多平台项目。这个 需要更有条理地支持这些概念,包括清晰明了的 API, 鼓励语言和项目的互操作性。这就是这些新的 API 。
迁移
平台和工具链 API 仅在项目实际使用它们时才有效。这个
项目的规则逻辑、工具链、依赖项和
select()
必须支持它们。这需要谨慎的迁移序列
确保所有项目及其依赖项正常运行。
例如,Bazel 的 C++ 规则支持平台。但 Apple 规则则不然。您的 C++ 项目 可能并不关心 Apple但其他人可能会。因此 为所有 C++ build 全局启用平台尚不安全。
本页的其余部分将介绍此迁移顺序,以及迁移方式和时机
目标
当所有项目都使用以下格式构建时,Bazel 的平台迁移完成:
bazel build //:myproject --platforms=//:myplatform
这意味着:
- 项目使用的规则可以推断出正确的工具链
//:myplatform
。 - 项目的依赖项使用的规则可以推断出正确的工具链
//:myplatform
起。 - 根据您的项目任何项目
//:myplatform
或 项目支持旧版 API(例如--crosstool_top
)。 //:myplatform
参考 [通用声明][通用平台声明]{: .external} 包含CPU
、OS
和其他支持自动跨项目的通用概念 兼容性。- 所有相关项目的
select()
了解//:myplatform
隐含的机器属性。 //:myplatform
在清晰且可重复使用的位置进行定义:在项目的 如果平台是您的项目独有的,则使用 repo;否则为所有项目 其他对象。
实现此目标后,旧 API 将被移除。然后 成为项目选择平台和工具链的标准方式。
我是否应该使用平台?
如果您只想构建或交叉编译项目,则应遵循 项目的官方文档。
如果您是项目、语言或工具链维护人员,您最终会希望 来支持这些新 API是否等待全局迁移完成 或提前选择启用,具体取决于您的具体价值 / 费用需求:
值
- 您可以使用
select()
或选择您关注的属性上的工具链 而不是--cpu
等硬编码标记。例如, 可以支持相同的指令集。 - 更正确的 build。如果您在上述示例中使用
--cpu
执行select()
操作,则: 添加支持相同指令集的新 CPU,即select()
出现故障。但平台上的select()
仍然是准确的。 - 更简单的用户体验。所有项目都了解:
--platforms=//:myplatform
。无需使用多种语言版本 标志。 - 语言设计更简单。所有语言使用相同的 API 来定义 工具链、使用工具链,以及为平台选择正确的工具链。
- 您可在以下位置中跳过目标: 构建和测试阶段(如果它们与目标平台不兼容)。
费用
- 尚不支持平台的依赖项目可能无法自动运行 。
- 使它们正常运行可能需要额外的临时维护。
- 新旧 API 共存需要更仔细的用户指导, 避免混淆
- 常见属性的规范定义,例如
OS
和CPU
仍在发展中,可能需要额外的初始贡献。 - 针对特定语言的工具链的规范定义仍在发展中, 可能需要额外的初始贡献。
API 审核
platform
是一系列
constraint_value
个目标:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
constraint_value
是机器
属性。同一“kind”的值归到一个通用规则下
constraint_setting
:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
toolchain
是 Starlark 规则。其
属性声明语言工具(例如 compiler =
"//mytoolchain:custom_gcc"
)。其提供程序通行证
将这些信息传递给需要使用这些工具构建的规则。
工具链会声明它们可以运行的机器的 constraint_value
目标
(target_compatible_with = ["@platforms//os:linux"]
) 以及他们的工具
运行位置
(exec_compatible_with = ["@platforms//os:mac"]
)。
构建 $ bazel build //:myproject --platforms=//:myplatform
时,Bazel
它会自动选择可以在构建机器上运行的工具链
针对 //:myplatform
的 build 二进制文件。这称为工具链解析。
您可以使用以下命令在 WORKSPACE
中注册这组可用工具链
register_toolchains
或在
和 --extra_toolchains
搭配使用。
如需深入了解,请点击此处。
状态
当前平台支持因语言而异。Bazel 的所有主要规则都是 迁移到平台但此过程需要一些时间。这主要有三个原因:
必须更新规则逻辑,才能从新的工具链中获取工具信息 API (
ctx.toolchains
) 并停止读取旧版设置,例如--cpu
和--crosstool_top
。这种方法相对简单。工具链维护人员必须定义工具链,并使其可供 用户(在 GitHub 代码库和
WORKSPACE
条目中)。 这在技术上很简单,但必须巧妙地组织 保持轻松的用户体验还需要进行平台定义(除非您针对同一台机器构建 运行 Bazel)。通常,项目应定义自己的平台。
您必须迁移现有项目。
select()
秒和 转场效果 已迁移。这是最大的挑战。对于企业来说 多语言项目(如果所有语言都无法读取,则可能会失败--platforms
)。
如果您要设计新的规则集,必须支持 开头。这样,您的规则就会自动与其他 随着平台 API 变得越来越完善, 更加普遍
通用平台属性
各个项目通用的平台属性(例如 OS
和 CPU
)应该
在标准的集中位置声明这样可以鼓励跨项目
和跨语言兼容性
例如,如果 MyApp 在 constraint_value
上有 select()
@myapp//cpus:arm
和 SomeCommonLib 的select()
@commonlib//constraints:arm
,它们会触发其“实验组”模式(具有不兼容的模式)
条件。
全局通用属性在
@platforms
代码库
(因此,上述示例的规范标签是 @platforms//cpu:arm
)。
语言通用属性应在其各自对应的代码库中声明
语言。
默认平台
通常,项目所有者应定义明确的
平台来描述
各种机器的机器类型然后
--platforms
。
如果未设置 --platforms
,则 Bazel 默认使用一个 platform
表示
本地构建机器。这是 @local_config_platform//:host
自动生成的
因此无需明确定义它会映射本地机器的 OS
以及 CPU
(其中声明了 constraint_value
)
@platforms
。
C++
在设置工具链时,Bazel 的 C++ 规则使用平台来选择工具链
--incompatible_enable_cc_toolchain_resolution
(#7260)。
这意味着您可以用以下代码配置 C++ 项目:
bazel build //:my_cpp_project --platforms=//:myplatform
而不是旧版:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...
如果您的项目是纯 C++ 项目,非 C++ 项目并不依赖于该项目,则可以使用
您的select
和
转场效果是兼容的。请参阅
#7260 和
如需更多指导,请参阅配置 C++ 工具链。
此模式默认处于停用状态。这是因为,Apple 项目
仍使用 --cpu
和 --crosstool_top
配置 C++ 依赖项
(示例)。这取决于迁移到平台的 Apple 规则。
Java
Bazel 的 Java 规则使用平台。
这取代了旧版标志 --java_toolchain
、--host_java_toolchain
、
--javabase
和--host_javabase
。
如需了解如何使用配置标志,请参阅 Bazel 和 Java 手册。 如需了解详情,请参阅设计文档。
如果您仍在使用旧版标志,请按照问题 7849 中的迁移流程操作。
Android
在设置工具链时,Bazel 的 Android 规则会使用平台来选择工具链
--incompatible_enable_android_toolchain_resolution
。
默认情况下,此功能处于停用状态。不过,迁移工作正在进行之中。
Apple
Bazel 的 Apple 规则尚不支持用于选择 Apple 工具链的平台。
它们也不支持启用平台的 C++ 依赖项,因为它们使用
旧版 --crosstool_top
来设置 C++ 工具链。在迁移完成之前
可以将 Apple 项目、支持 Platom 的 C++ 和平台
映射
(示例)。
其他语言
如果您要为新语言设计规则,请使用平台 选择语言的工具链。请参阅 工具链文档,获取详细的演示。
select()
项目可以select()
constraint_value
个目标,但尚未完成
平台。这是有意为之,以便 select()
支持尽可能多的
尽可能多地训练机器。包含 ARM
专用源代码的库应支持
所有由 ARM
提供支持的机器,除非有具体理由。
如需选择一个或多个 constraint_value
,请使用以下命令:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
这相当于以往在 --cpu
上进行选择:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
如需了解更多详情,请点击此处。
--cpu
、--crosstool_top
等平台上的 select
无法识别 --platforms
。时间
将项目迁移到平台时,您必须将其转换为
constraint_values
或使用平台映射来支持
在迁移窗口中选择这两种样式
转场效果
Starlark 过渡变更
对构建图的各个部分进行标记如果您的项目使用
设置 --cpu
、--crossstool_top
或其他旧版标志、规则
--platforms
不会看到这些更改。
将项目迁移到平台时,您必须将更改(例如
return { "//command_line_option:cpu": "arm" }
到return {
"//command_line_option:platforms": "//:my_arm_platform" }
或使用平台
映射,以便在迁移过程中同时支持这两种样式
窗口。
当前如何使用平台
如果您只想构建或交叉编译项目,则应遵循 项目的官方文档。取决于语言和项目维护人员 确定与平台集成的方式和时机,以及集成的价值。
如果您是项目、语言或工具链维护人员,但构建 使用平台时,您有三种选择(除了等待 迁移):
翻转“使用平台”标记(如果 one),并进行所需的测试,看看您关注的项目是否 工作内容
如果您关心的项目仍然依赖于
--cpu
和--crosstool_top
,请将这些内容与--platforms
结合使用:bazel build //:my_mixed_project --platforms==//:myplatform --cpu=... --crosstool_top=...
这会有一些维护成本(您必须手动确保设置 匹配)。但在没有反派行为的情况下,这种方法应该有效 过渡。
编写平台映射来同时支持这两种样式,具体做法如下: 将
--cpu
样式的设置映射到相应的平台,反之亦然。
平台映射
平台映射是一种临时 API,可让由平台提供支持的 通过在 build 中弃用后者,旧版驱动的逻辑在同一 build 中共存 窗口。
平台映射是 platform()
到
一组相应的旧版标志(反之亦然)。例如:
platforms:
# Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
//platforms:ios
--cpu=ios_x86_64
--apple_platform_type=ios
flags:
# Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--cpu=ios_x86_64
--apple_platform_type=ios
//platforms:ios
# Maps "--cpu=darwin --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin
--apple_platform_type=macos
//platforms:macos
Bazel 使用此 ID 来保证所有设置,包括基于平台的设置 在整个构建过程中始终适用,包括 过渡。
默认情况下,Bazel 会从platform_mappings
工作区根目录。您还可以设置
--platform_mappings=//:my_custom_mapping
。
请参阅 此处 了解完整详情。
问题
如需获得常规支持或咨询有关迁移时间表的问题,请联系 bazel-discuss@googlegroups.com 或相应规则的所有者
有关平台/工具链 API 的设计和演变的讨论, 联系人 bazel-dev@googlegroups.com.