英文:
How do I wrap all files from a Bazel filegroup into a directory?
问题
如何将`filegroup`中的所有文件放入一个名为`test-data`的目录中,并创建一个新的目标?
我的使用情况是,在test-data/BUILD.bazel文件中有一个名为`render-test-files`的`filegroup`,但测试运行器希望将文件放在一个名为`test-data`的目录中。
```bzl
filegroup(
name = "render-test-files",
srcs = glob([
"integration/**",
"tests/**",
"linux-gcc8-release/**",
"expectations/platform-all/**",
"ignores/**",
], allow_empty = False)
visibility = [
"//render-test:__subpackages__",
],
)
我无法使用genrule
,因为它要求将所有输出文件明确列出。
<details>
<summary>英文:</summary>
How can I wrap all files of a `filegroup` in a directory and create a new target out of that?
My use case is that I have a filegroup inside test-data/BUILD.bazel but the test runner expects the files inside a directory called `test-data`.
```bzl
filegroup(
name = "render-test-files",
srcs = glob([
"integration/**",
"tests/**",
"linux-gcc8-release/**",
"expectations/platform-all/**",
"ignores/**",
], allow_empty = False)
visibility = [
"//render-test:__subpackages__",
],
)
I cannot use a genrule
because it requires all output files to be listed explicitly.
答案1
得分: 1
要将文件收集到一个目录并将其视为构建产物,您可以编写一个自定义规则,使用declare_directory
操作返回TreeArtifact
。在一个非常朴素/简单的形式中(不可移植,不检查源文件是否包含任何文件,...),可以像这样:
def _impl(ctx):
outdir = ctx.actions.declare_directory("{}.dir".format(ctx.attr.name))
args = ctx.actions.args()
args.add(outdir.path)
args.add_all(ctx.files.srcs)
ctx.actions.run_shell(
outputs = [outdir],
inputs = ctx.files.srcs,
arguments = [args],
command = """
outdir="$1";
shift;
cp "$@" "${outdir}"
"""
)
return [
DefaultInfo(files = depset([outdir])),
]
dirrule = rule(
_impl,
attrs = {
"srcs": attr.label_list(
allow_files = True,
mandatory = True,
),
},
)
然后可以在BUILD
文件中使用它,mydir
现在是包含file0[12]
副本的目录:
load(":dirrule.bzl", "dirrule")
dirrule(
name = "mydir",
srcs = [
"//myfiles:file01",
"//myfiles:file02",
],
)
我个人更愿意尝试调整接收工具以实际处理输入列表...或者如果不可能(超出我的控制),可能更愿意在已经采取的自定义规则中包装其使用(调用),该规则将接受该列表并以期望的形状填充树(最好是符号链接,即使工具没有太大问题)。
英文:
To collect files into a directory and have that considered a build artifact, you can write a custom rule returning TreeArtifact
using declare_directory
action. In a very naive/trivial form (not portable, not checking if sources contain any files, ...) something like:
def _impl(ctx):
outdir = ctx.actions.declare_directory("{}.dir".format(ctx.attr.name))
args = ctx.actions.args()
args.add(outdir.path)
args.add_all(ctx.files.srcs)
ctx.actions.run_shell(
outputs = [outdir],
inputs = ctx.files.srcs,
arguments = [args],
command = """
outdir="$1";
shift;
cp "$@" "${outdir}"
""",
)
return [
DefaultInfo(files = depset([outdir])),
]
dirrule = rule(
_impl,
attrs = {
"srcs": attr.label_list(
allow_files = True,
mandatory = True,
),
},
)
Which could then be used in a BUILD
file with mydir
now being directory containing copies of file0[12]
:
load(":dirrule.bzl", "dirrule")
dirrule(
name = "mydir",
srcs = [
"//myfiles:file01",
"//myfiles:file02",
],
)
I would personally rather try to adapt the receiving tool to actually handle list of inputs... or if impossible (beyond my control), probably rather wrap its use (call) from (I presume already the case anyways) custom rule which would take that list and populate the tree (preferably symlink even if the tool isn't way broken) in shape it expects.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论