Bazel 对多架构和 交叉编译构建的平台和 工具链建模提供了完善的支持。
本页总结了此支持的状态。
另请参阅:
状态
C++
当设置
--incompatible_enable_cc_toolchain_resolution 时,C++ 规则会使用平台来选择工具链。
这意味着您可以使用以下内容配置 C++ 项目:
bazel build //:my_cpp_project --platforms=//:myplatform而不是旧版:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...此功能将在 Bazel 7.0 中默认启用 (#7260)。
如需使用平台测试 C++ 项目,请参阅 迁移项目和 配置 C++ 工具链。
Java
Java 规则使用平台来选择工具链。
这取代了旧版标志 --java_toolchain、--host_java_toolchain、
--javabase 和 --host_javabase。
如需了解详情,请参阅 Java 和 Bazel。
Android
当设置
--incompatible_enable_android_toolchain_resolution 时,Android 规则会使用平台来选择工具链。
这意味着您可以使用以下内容配置 Android 项目:
bazel build //:my_android_project --android_platforms=//:my_android_platform而不是使用旧版标志(如 --android_crosstool_top、--android_cpu、
和 --fat_apk_cpu)。
此功能将在 Bazel 7.0 中默认启用 (#16285)。
如需使用平台测试 Android 项目,请参阅 迁移项目。
Apple
Apple 规则不支持平台,并且尚未安排 支持。
您仍然可以将平台 API 与 Apple 构建搭配使用(例如,当使用 Apple 规则和纯 C++ 的混合构建时),并使用 平台 映射。
其他语言
如果您拥有语言规则集,请参阅迁移规则集以添加 支持。
背景
平台和工具链的引入是为了标准化软件 项目如何以不同的架构为目标并进行交叉编译。
此举的灵感源于语言维护人员已在以临时、不兼容的方式执行此操作的观察结果。例如,C++ 规则使用 --cpu 和
--crosstool_top 来声明目标 CPU 和工具链。这两者都无法正确地对“平台”进行建模。这会生成不恰当且不正确的构建。
Java、Android 和其他语言出于类似目的而开发了自己的标志, 但这些标志彼此之间互不兼容。这使得跨语言构建 变得令人困惑且复杂。
Bazel 适用于大型、多语言、多平台项目。这 需要对这些概念提供更具原则性的支持,包括明确的 标准 API。
需要迁移
升级到新 API 需要两项工作:发布 API 和升级 规则逻辑以使用该 API。
第一项工作已完成,但第二项工作仍在进行中。这包括确保定义特定于语言的平台和工具链、语言逻辑通过新 API(而不是旧标志(如 --crosstool_top))读取工具链,以及 config_setting 通过新 API(而不是旧标志)进行选择。
这项工作很简单,但每种语言都需要单独完成, 并且需要向项目所有者发出公平警告,以便针对即将发生的变化进行测试。
这就是这是一项持续迁移的原因。
目标
当所有项目都使用以下形式进行构建时,此迁移即完成:
bazel build //:myproject --platforms=//:myplatform这意味着:
- 项目的规则为
//:myplatform选择正确的工具链。 - 项目的依赖项为
//:myplatform选择正确的工具链。 //:myplatform引用 常见声明 的CPU、OS和其他通用、与语言无关的属性- 所有相关的
select()s 均正确匹配//:myplatform。 //:myplatform在清晰、易于访问的位置定义:如果平台是项目独有的,则在项目的 代码库中定义;或者在所有 使用项目都可以找到的某个常见位置定义
一旦安全,旧标志(如 --cpu、--crosstool_top 和 --fat_apk_cpu)将被
废弃并移除。
最终,这将是配置架构的唯一方式。
迁移项目
如果您使用支持平台的语言进行构建,则构建应已 适用于以下调用:
bazel build //:myproject --platforms=//:myplatform如需了解确切详情,请参阅状态和语言的文档。
如果某种语言需要使用标志来启用平台支持,您还需要设置 该标志。如需了解详情,请参阅状态。
如需构建项目,您需要检查以下内容:
//:myplatform必须存在。通常,项目所有者负责定义平台,因为不同的项目以不同的机器为目标。 请参阅默认平台。您要使用的工具链必须存在。如果使用库存工具链, 语言所有者应提供有关如何注册这些工具链的说明。如果 编写自己的自定义工具链,您需要注册这些工具链,将其添加到您的
MODULE.bazel文件中或使用--extra_toolchains。如果您的构建混合使用了支持和不支持平台的语言,您可能 需要平台映射来帮助旧版语言使用新 API。 如需了解详情,请参阅平台映射。
如果您仍然遇到问题,请寻求支持。
默认平台
项目所有者应定义明确的
平台,以描述他们要构建的架构
。然后,使用 --platforms 触发这些平台。
如果未设置 --platforms,Bazel 默认使用表示
本地构建机器的 platform。这是在 @platforms//host(别名为
@bazel_tools//tools:host_platform)
自动生成的,因此无需明确定义。它使用在
@platforms中声明的constraint_values 映射本地机器的OS
和CPU。
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",
},
)
点击此处可了解更多详情。
select 针对 --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" },或者使用 平台
映射 在迁移期间同时支持这两种样式。
窗口。
迁移规则集
如果您拥有规则集并希望支持平台,则需要:
让规则逻辑使用工具链 API 解析工具链。请参阅 工具链 API (
ctx.toolchains)。可选:定义
--incompatible_enable_platforms_for_my_language标志,以便 规则逻辑在迁移测试期间通过新 API 或旧标志 (如--crosstool_top)交替解析工具链。定义构成平台组件的相关属性。请参阅 常见平台属性
定义标准工具链,并通过您的 规则注册说明(详情)让用户可以访问这些工具链
确保
select()s 和 配置转换 支持平台。这是 最大的挑战。对于多语言项目来说,这尤其具有挑战性 (如果所有语言都无法读取--platforms,则可能会失败)。
如果您需要与不支持平台的规则混合使用,则可能需要 平台映射来弥合差距。
常见平台属性
应在 @platforms 中声明常见、跨语言的平台属性(如 OS 和 CPU)。这有助于共享、标准化和跨语言兼容性。
规则独有的属性应在规则的代码库中声明。这样,您就可以清楚地掌握规则负责的特定概念的所有权。
如果规则使用自定义用途的操作系统或 CPU,则应在规则的
代码库(而不是
@platforms)中声明这些操作系统或 CPU。
平台映射
平台映射是一种临时 API,可让平台感知逻辑与 同一构建中的旧版逻辑混合使用。这是一种简单工具,仅用于 消除不同迁移时间范围的不兼容性。
平台映射是指 platform() 到
相应的一组旧版标志的映射,反之亦然。例如:
platforms:
# Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
//platforms:ios
--ios_multi_cpus=x86_64
--apple_platform_type=ios
flags:
# Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--ios_multi_cpus=x86_64
--apple_platform_type=ios
//platforms:ios
# Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin_x86_64
--apple_platform_type=macos
//platforms:macos
Bazel 使用此功能来保证所有设置(基于平台的设置和 旧版设置)在整个构建过程中(包括通过 转换)保持一致。
默认情况下,Bazel 从 platform_mappings 文件读取映射,该文件位于您的
工作区根目录中。您还可以设置
--platform_mappings=//:my_custom_mapping。
如需了解详情,请参阅平台映射设计。
API 审核
platform 是
constraint_value 目标的集合:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
A constraint_value 是机器
属性。相同“类型”的值分组在常见的
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 构建二进制文件的工具链。这称为工具链解析。
可用工具链集可以使用 register_toolchains 在 MODULE.bazel 文件中注册,也可以使用 --extra_toolchains 在命令行中注册。
如需了解详情,请点击此处。
问题
如需获得一般支持以及有关迁移时间表的问题,请与 bazel-discuss或相应规则的所有者联系。
如需讨论平台/工具链 API 的设计和演变, 请与 bazel-dev 联系。