我想指定 bazel 的输入文件,其名称类似于
ContextFinder$5.class
。
考虑以下 bazel BUILD 文件:
package(<redacted>)
filegroup(
name = "class_overrides",
srcs = [
"ContextFinder$$1.class",
"ContextFinder$$2.class",
"ContextFinder$$3.class",
"ContextFinder$$4.class",
"ContextFinder$$5.class",
"ContextFinder.class"
],
)
当我尝试构建包含此内容的目标时,我收到错误消息:
missing input file...ContextFinder$$1.class
。
如果我不将
$
加倍,则会收到以下错误:
in cmd attribute of genrule rule <redacted>
'$1' syntax is not supported; use '$(1)' instead for "Make" variables, or escape the '$' as '$$' if you intended this for the shell
是否可以指定带有
$
的输入文件名?
这里的问题是
filegroup
不做变量替换,而 cmd
的 genrule
做。
我假设你有一个像这样使用
genrule
的 $(SRCS)
:
genrule(
name = "gen",
srcs = [":class_overrides"],
outs = ["out"],
cmd = "echo $(SRCS) > $@",
)
filegroup(
name = "class_overrides",
srcs = [
"ContextFinder$1.class",
...
],
)
srcs
的filegroup
需要真实的文件名(ContextFinder$1.class
),然后$(SRCS)
的cmd
中的genrule
被替换(echo $(SRCS) > $@
-> echo ContextFinder$1.class > output.txt
),并且使变量替换找到$1
,没有机会逃避这一点。
一种解决方法是避免指定包含
$
的名称,例如类似于 cmd = "echo *.class > $@"
,因为 *.class
将在执行时由 shell 扩展,而不是在 genrule 的 bazel 分析期间扩展。
另一种选择是不使用 genrule 并编写一个小型 Starlark 规则来满足您的需要。一个简单的例子是:
defs.bzl
:
def _generate_overrides_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name + ".out")
files = depset(transitive = [l.files for l in ctx.attr.srcs])
ctx.actions.write(
output = out,
content = "\n".join([f.path for f in files.to_list()]),
)
return DefaultInfo(files = depset([out]))
generate_overrides = rule(
implementation = _generate_overrides_impl,
attrs = {
"srcs": attr.label_list(),
},
)
BUILD.bazel
:
load(":defs.bzl", "generate_overrides")
generate_overrides(
name = "generate_overrides",
srcs = [":class_overrides"],
)
filegroup(
name = "class_overrides",
srcs = [
"ContextFinder$1.class",
...
],
)
$ bazel build generate_overrides
INFO: Analyzed target //:generate_overrides (1 packages loaded, 7 targets configured).
INFO: Found 1 target...
Target //:generate_overrides up-to-date:
bazel-bin/generate_overrides.out
INFO: Elapsed time: 0.084s, Critical Path: 0.00s
INFO: 2 processes: 2 internal.
INFO: Build completed successfully, 2 total actions
$ cat bazel-bin/generate_overrides.out
ContextFinder$1.class
ContextFinder$2.class
ContextFinder$3.class
ContextFinder$4.class
ContextFinder$5.class
但这取决于您需要做什么。