似乎genrule只能输出一个Target,而expand_template替换只接受string_dict,我该如何使用genrule的输出来expand_template?
gen.bzl
def _expand_impl(ctx):
ctx.actions.expand_template(
template = ctx.file._template,
output = ctx.outputs.source_file,
substitutions = {
"{version}": ctx.attr.version,
}
)
expand = rule(
implementation = _expand_impl,
attrs = {
"version": attr.string(mandatory = True),
"_template": attr.label(
default = Label("//version:local.go.in"),
allow_single_file = True,
),
},
outputs = {"source_file": "local.go"},
)
已构建
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "templates",
srcs = ["local.go.in"],
)
genrule(
name = "inject",
outs = ["VERSION"],
local = 1,
cmd = "git rev-parse HEAD",
)
load(":gen.bzl", "expand")
expand(
name = "expand",
version = ":inject",
)
go_library(
name = "go_default_library",
srcs = [
"default.go",
":expand", # Keep
],
importpath = "go.megvii-inc.com/brain/data/version",
visibility = ["//visibility:public"],
)
和local.go.in
package version
func init() {
V = "{version}"
}
我希望local.go.in中的{version}可以由git rev-parse HEAD
输出代替。
答案 0 :(得分:0)
这里的问题是substitutions
的{{1}}自变量必须在分析阶段(即运行ctx.actions.expand_template()
的时候)知道,该参数发生在_expand_impl
之前genrule的命令将运行(即在执行阶段)。
有几种方法可以做到这一点。最简单的是做所有事情:
git rev-parse HEAD
这取决于genrule(
name = "gen_local_go",
srcs = ["local.go.in"],
outs = ["local.go"],
local = 1,
cmd = 'sed "s/{VERSION}/$(git rev-parse HEAD)/" "$<" > "$@"',
)
在主机上是否可用,但是可以输入一个文件,修改文本并将其输出到另一个文件的任何其他程序都可以使用。
另一种选择是结合使用--workspace_status_command 这里有更多详细信息: How to run a shell command at analysis time in bazel? 这种方法的优点是它避免了局部风格。