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 build 搭配使用(例如,在混合使用 Apple 规则和纯 C++ 的情况下构建)和平台映射。
其他语言
如果您拥有语言规则集,请参阅迁移规则集以添加支持。
背景
引入平台和工具链,使软件项目针对不同架构和交叉编译实现标准化。
这启发了我们发现,语言维护人员已经在通过不兼容的方式临时执行此操作。例如,C++ 规则使用 --cpu
和 --crosstool_top
声明目标 CPU 和工具链。这些方式都无法正确模拟“平台”。这生成了尴尬的错误构建。
Java、Android 和其他语言也为了类似目的而改进自己的标志,所有这些标志都不互操作。这使得跨语言构建变得复杂且复杂。
Bazel 适用于大型、多语言、多平台的项目。这需要对这些概念提供更有原则的支持,包括清晰的标准 API。
需要迁移
升级到新 API 需要执行两项操作:发布 API 和升级规则逻辑以使用它。
第一个已完成,第二个正在进行。这包括确保已定义特定于语言的平台和工具链、语言逻辑会通过新的 API(而不是像 --crosstool_top
之类的旧标志)读取工具链,config_setting
也会对新 API(而不是旧标志)进行选择。
这项工作简单明了,但需要为每种语言分别采取不同的措施,还需要对项目所有者发出公平警告,以测试即将发生的更改。
因此,我们仍在持续进行这项迁移。
目标
当所有项目都使用以下形式构建时,表示迁移已完成:
bazel build //:myproject --platforms=//:myplatform
这意味着:
- 项目规则应选择适合
//:myplatform
的工具链。 - 项目的依赖项需要为
//:myplatform
选择合适的工具链。 //:myplatform
引用CPU
、OS
和其他与语言无关的通用属性的常见声明- 所有相关
select()
均正确匹配//:myplatform
。 //:myplatform
在一个清晰且可访问的位置进行定义:在平台中,如果该平台对于您的项目是唯一的,或者所有使用中的项目都可以找到该平台,则在项目的代码库中
--cpu
、--crosstool_top
和 --fat_apk_cpu
等旧标志将在安全的情况下立即弃用和移除。
最终,这将是配置架构的唯一方式。
迁移项目
如果您使用支持平台的语言进行构建,那么您的 build 应该已经可以使用如下调用:
bazel build //:myproject --platforms=//:myplatform
如需了解确切的详细信息,请参阅状态和语言文档。
如果某语言需要借助标志来启用平台支持,那么您还需要设置该标志。如需了解详情,请参阅状态。
对于要构建的项目,您需要检查以下内容:
//:myplatform
必须存在。通常情况下,项目所有者应负责定义平台,因为不同的项目针对不同的机器。请参阅默认平台。您要使用的工具链必须存在。如果使用的是库存工具链,语言所有者应包含有关如何注册它们的说明。如果要编写自己的自定义工具链,则需要在
WORKSPACE
中或使用--extra_toolchains
注册它们。如果您的 build 混合了支持平台和不支持平台的语言,您可能需要平台映射,以帮助旧版语言支持新的 API。如需了解详情,请参阅平台映射。
如果您仍遇到问题,请联系支持团队。
默认平台
项目所有者应定义明确的平台以描述其要构建的架构。然后,这些事件通过 --platforms
触发。
如果未设置 --platforms
,Bazel 会默认使用代表本地构建机器的 platform
。这是在 @local_config_platform//:host
中自动生成的,因此无需明确定义。它会使用 @platforms
中声明的 constraint_value
映射本地机器的 OS
和 CPU
。
select()
项目可以对 constraint_value
目标执行 select()
操作,但无法完成平台。这是有意为之,因此 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" }
,或使用平台映射在迁移期间支持这两种样式。
迁移规则集
如果您拥有规则集并希望支持平台,则需要:
让规则逻辑使用工具链 API 解析工具链。请参阅 工具链 API (
ctx.toolchains
)。可选:定义一个
--incompatible_enable_platforms_for_my_language
标志,以便规则逻辑在迁移测试期间通过新的 API 或旧标志(如--crosstool_top
)交替解析工具链。定义构成平台组件的相关属性。请参阅常见平台属性
定义标准工具链,并通过规则的注册说明允许用户访问这些工具链(详细信息)。
确保
select()
和配置转换支持平台。这是最大的挑战。对于多语言项目来说,这尤其具有挑战性(如果所有语言都无法读取--platforms
,则可能会失败)。
如果您需要混用不支持平台的规则,则可能需要平台映射来弥合差距。
通用平台属性
OS
和 CPU
等常见的跨语言平台属性应在 @platforms
中声明。这样有助于促进共享、标准化和跨语言兼容性。
规则的专属属性应在规则的代码库中声明。这样,您就可以明确指出您的规则负责的特定概念。
如果您的规则使用自定义用途的操作系统或 CPU,则应在规则的代码库中声明,而非在 @platforms
中声明。
平台映射
平台映射是一种临时 API,可让平台感知逻辑与同一 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_x86_64 --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin_x86_64
--apple_platform_type=macos
//platforms:macos
Bazel 使用这项配置来确保所有设置(包括基于平台和旧版的设置)在整个 build 中保持一致,包括通过转换。
默认情况下,Bazel 会从工作区根目录中的 platform_mappings
文件读取映射。您还可以设置 --platform_mappings=//:my_custom_mapping
。
如需了解详情,请参阅平台映射设计。
API 审核
platform
是 constraint_value
目标的集合:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
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"
)。其提供程序会将这些信息传递给需要使用这些工具进行构建的规则。
工具链声明其目标 (target_compatible_with = ["@platforms//os:linux"]
) 和机器运行 (exec_compatible_with = ["@platforms//os:mac"]
) 的机器的 constraint_value
。
构建 $ bazel build //:myproject --platforms=//:myplatform
时,Bazel 会自动选择可以在构建机器上运行的工具链,并为 //:myplatform
构建二进制文件。这称为“工具链解析”。
可以使用 WORKSPACE
在 register_toolchains
中或通过命令行使用 --extra_toolchains
注册可用工具链集。
如需了解详情,请参阅此处。
问题解答
如需获得有关迁移时间表的常规支持和问题,请与 bazel-discuss 或相应规则的所有者联系。
如需查看关于平台/工具链 API 的设计和演变的讨论,请与 bazel-dev 联系。