如何标记Bazel规则属性以支持Make变量替换?
解决Bazel自定义规则中Make变量替换的问题
核心说明
Bazel没有提供直接标记属性"支持Make变量替换"的配置项,自定义规则需要手动实现变量替换逻辑。你需要通过platform_common.TemplateVariableInfo获取变量映射,再调用ctx.expand_make_variables()方法对目标属性内容进行替换。
你的代码问题分析
你已经正确通过version_rule输出了TemplateVariableInfo,但在_file规则的实现中,直接将原始的content属性写入文件,没有执行变量替换操作,因此$(VERSION)没有被解析。
修改后的代码实现
修改file.bzl
def file(**kwargs): _file(out = "{output_name}.txt".format(**kwargs), **kwargs) def _impl(ctx): # 收集TemplateVariableInfo提供的变量映射 template_vars = {} if ctx.attr.version: var_provider = ctx.attr.version[platform_common.TemplateVariableInfo] template_vars.update(var_provider.variables) # 替换content中的Make变量 expanded_content = ctx.expand_make_variables( "content", # 用于错误提示的属性名标识 ctx.attr.content, template_vars ) output = ctx.outputs.out ctx.actions.write(output = output, content = expanded_content) _file = rule( implementation = _impl, attrs = { "version": attr.label(providers=[platform_common.TemplateVariableInfo]), "output_name": attr.string(mandatory=True), "content": attr.string(), "out": attr.output() }, )
关键修改点
- 收集变量映射:从
version属性指向的规则中提取TemplateVariableInfo里的变量键值对 - 执行变量替换:调用
ctx.expand_make_variables()处理content属性,将$(VERSION)替换为实际值1-2-3-4 - 写入替换后的内容:将处理后的
expanded_content写入输出文件
额外说明
如果需要支持Bazel内置的Make变量(如$(BINDIR)、$(TARGET_CPU)等),可以省略自定义的template_vars参数,ctx.expand_make_variables()会自动使用默认的内置变量集合:
expanded_content = ctx.expand_make_variables("content", ctx.attr.content, {})
内容的提问来源于stack exchange,提问作者Sergey Vlasov
相关产品推荐
相关产品推荐

