如何在Bazel中向genrule传递build setting配置?
使用Starlark Build Settings配置Genrule(替代action_env/--define)
问题背景
我有一个简单的genrule:
genrule( name = "fruit", outs = [ "fruit.txt" ], cmd = "echo \"apple\" > $@", )
想从外部配置输出的内容。用action_env可以实现:
genrule( name = "fruit", outs = [ "fruit.txt" ], cmd = "echo \"$$FRUIT\" > $@", )
执行命令:
bazel build --action_env=FRUIT=banana //:fruit
但action_env会影响所有规则,还不利于缓存。另外还有--define选项,但官方文档说明:
--define是自定义标志的替代遗留语法(例如--define foo=bar)。它可以通过values属性(values = {"define": "foo=bar"})或define_values属性(define_values = {"foo": "bar"})表示。--define仅为向后兼容而支持,尽可能优先使用Starlark build settings。
所以想改用build settings,但不清楚怎么把值传入genrule,期望的效果类似如下伪代码:
# 示例伪代码 config_setting( name = "fruit", ) genrule( name = "fruit", outs = [ "fruit.txt" ], cmd = "echo \"$(value :fruit)\" > $@", )
正确实现步骤
1. 定义Build Setting
首先用string_flag定义一个可从命令行传入的build setting,可以放在单独的.bzl文件(比如fruit_settings.bzl)中,也可以直接写在BUILD文件里:
# fruit_settings.bzl string_flag( name = "fruit_name", build_setting_default = "apple", # 设置默认值 visibility = ["//visibility:public"], # 确保genrule能访问到这个设置 )
2. 在Genrule中引用Build Setting
在BUILD文件中加载这个build setting,然后在cmd里用$(value <build_setting_target>)语法引用它的值:
load("//:fruit_settings.bzl", "fruit_name") genrule( name = "fruit", outs = ["fruit.txt"], cmd = "echo \"$(value :fruit_name)\" > $@", )
3. 命令行传入自定义值
执行构建时,通过--//:fruit_name=<你的值>的方式传入自定义内容:
bazel build --//:fruit_name=banana //:fruit
优势说明
- 作用范围可控:仅会影响引用了该build setting的规则,不会全局干扰其他规则
- 缓存友好:Bazel会将build setting的值纳入缓存键,不同配置值会生成独立的缓存条目
- 符合官方规范:使用现代Starlark配置方式,而非遗留的
--define语法
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

