我想知道如何通知bazel关于在声明时未知的依赖关系,但在构建时知道(a.k.a隐式依赖关系,动态依赖关系......)。例如,在编译C ++源代码时,.cpp源文件将依赖于某些头文件,并且在编写BUILD文件时此信息不可用。它需要在构建时检索。无论获取信息的解决方案是什么(干运行,生成depfile,解析stdout),都需要在构建时完成,并且需要将信息检索到bazel构建图。
由于skylark不允许执行I / O,例如读取生成的depfile或解析包含依赖项列表的stdout结果,我不知道如何处理它。
在隐式依赖项后面,我正在寻找正确的增量构建。
为了试验这个问题,我创建了一个简单的工具just_a_tool.exe
,它接受一个输入文件,从中读取文件列表,并将所有这些文件的内容连接到输出文件。
命令行示例:
just_a_tool.exe --input input.txt --depfile dep.d output.txt
dep.d包含所有读取文件的列表。
如果我更改了test1.txt,test2.txt或test3.txt的内容,则bazel不会重建output.txt文件。当然,因为它不知道存在依赖性。
just_a_tool.bzl
def _impl(ctx):
exec_path = "C:/Code/JustATool/just_a_tool.exe"
for f in ctx.attr.source.files:
source_path = f.path
output_path = ctx.outputs.out.path
dep_file = ctx.actions.declare_file("dep.d")
args = ["--input", source_path, "--dep_file", dep_file.path, output_path]
ctx.actions.run(
outputs=[ctx.outputs.out, dep_file],
executable=exec_path,
inputs=ctx.attr.source.files,
arguments=args
)
jat_convert = rule(
implementation = _impl,
attrs = {
"source" : attr.label(mandatory=True, allow_files=True, single_file=True)
},
outputs = {"out": "%{name}.txt"}
)
BUILD
load("//tool:just_a_tool.bzl", "jat_convert")
jat_convert(
name="my_output",
source=":input.txt"
)
input.txt中
test1.txt
test2.txt
test3.txt
我希望针对以下情况进行正确且快速的增量构建:
谢谢!
答案 0 :(得分:0)
Bazel的扩展语言不支持使用动态输入集创建动作,其中此集取决于上一个动作的输出。换句话说,自定义规则无法运行操作,读取操作的输出,然后使用这些输入创建操作或更新(或修剪已设置的)已创建操作的输入。
相反,我建议在您的规则中添加属性,用户可以在其中声明源可能包含的文件集。我把它称为“标题的宇宙”。您创建的操作取决于此用户定义的Universe,因此完全定义了操作输入集。当然,这意味着这些操作可能依赖于比他们处理的cpp文件更多的文件,包括。
此方法类似于cc_*
规则的工作方式:cc_*.srcs
中的文件可以包含同一规则的srcs
中的其他文件以及hdrs
个依赖项中的文件, 但没有别的。因此,srcs
+ hdrs
(直接和传递)依赖关系的并集定义了cpp文件可能包含的头文件的范围。