Bazel中能否根据命令行指定的cpu参数自动推导设置对应host_cpu值
结论
可以实现,你要的等效调用效果完全可以通过Starlark的**配置转换(Configuration Transition)**功能实现,仅需在.bzl和BUILD文件中添加代码即可,不需要修改用户侧的调用逻辑。
实现步骤
1. 编写自定义transition逻辑
新建一个.bzl文件(比如cpu_host_mapping.bzl),添加如下代码:
# 自定义CPU到对应HOST_CPU的映射表,可按需扩展 CPU_TO_HOST_CPU = { "CPU_A": "HOST_CPU_A", "CPU_B": "HOST_CPU_B", } def _map_cpu_to_host_cpu_impl(settings, attr): current_cpu = settings["//command_line_option:cpu"] # 匹配不到映射关系时保留原有host_cpu作为降级逻辑 target_host_cpu = CPU_TO_HOST_CPU.get(current_cpu, settings["//command_line_option:host_cpu"]) return { "//command_line_option:cpu": current_cpu, "//command_line_option:host_cpu": target_host_cpu, } # 定义transition cpu_to_host_cpu_transition = transition( implementation = _map_cpu_to_host_cpu_impl, inputs = ["//command_line_option:cpu", "//command_line_option:host_cpu"], outputs = ["//command_line_option:cpu", "//command_line_option:host_cpu"], ) # 定义包装规则,用于给目标绑定transition def _wrapped_target_impl(ctx): # 透传依赖的所有provider,不影响原有构建逻辑 return [ctx.attr.dep[p] for p in dir(ctx.attr.dep)] wrapped_build_target = rule( implementation = _wrapped_target_impl, attrs = { "dep": attr.label(cfg = cpu_to_host_cpu_transition), # Bazel要求的transition权限声明 "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ), }, )
2. 绑定到构建目标
在需要生效的BUILD文件中引入上面的规则,包装原有构建目标即可:
load("//path/to:cpu_host_mapping.bzl", "wrapped_build_target") # 原有构建目标,无需修改 cc_binary( name = "my_binary", srcs = ["main.c"], ) # 新增包装后的目标 wrapped_build_target( name = "my_binary_auto_host", dep = ":my_binary", )
3. 调用验证
现在执行以下两个命令完全等效:
# 仅传--cpu参数,自动推导host_cpu bazel build --cpu=CPU_A //:my_binary_auto_host
# 手动传两个参数的原有调用 bazel build --cpu=CPU_A --host_cpu=HOST_CPU_A //:my_binary
全局生效方案
如果不需要给每个目标单独包装,可以直接将transition配置为全局生效,在项目的.bazelrc中添加一行:
build --transition=//path/to:cpu_to_host_cpu_transition
配置后所有构建命令都会自动根据传入的--cpu值推导--host_cpu,无需修改任何BUILD文件的目标定义。
内容的提问来源于stack exchange,提问作者Łukasz Maciejewski
相关产品推荐
相关产品推荐

