问题
我想知道如何告知bazel声明时未知但在构建时已知的依赖项(即隐式依赖项、动态依赖项,.)。例如,在编译C++源文件时,.cpp源文件将取决于某些头文件,并且在编写构建文件时此信息不可用。它需要在构建时被检索。无论获取信息的解决方案是什么(模拟运行、生成页文件、解析标准输出),都需要在构建时完成,并且需要将信息检索到bazel构建图中。
由于skylark不允许执行I/O操作,例如读取生成的页文件或解析包含依赖项列表的stdout结果,因此我不知道如何处理它。
在隐式依赖项的背后,我正在寻找正确的增量构建。
示例
为了实验这个问题,我创建了一个简单的工具,just_a_tool.exe,它接受一个输入文件,从它读取一个文件列表,并将所有这些文件的内容连接到一个输出文件。
命令行示例:
just_a_tool.exe --input input.txt --depfile dep.d output.txtD包含所有读取文件的列表。
问题
如果更改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"}
)构建
load("//tool:just_a_tool.bzl", "jat_convert")
jat_convert(
name="my_output",
source=":input.txt"
)input.txt
test1.txt
test2.txt
test3.txt目标
对于以下情况,我想做正确和快速的增量构建:
谢谢!
发布于 2017-12-06 12:18:05
Bazel的扩展语言不支持使用动态输入集创建操作,而这个集合依赖于以前操作的输出。换句话说,自定义规则不能运行操作、读取操作的输出、然后使用这些输入创建操作或更新(或修剪)已经创建的操作的输入集。
相反,我建议在规则中添加属性,用户可以在其中声明源可能包含的文件集。我管这叫“头的宇宙”。您创建的操作依赖于这个用户定义的域,因此操作输入集是完全定义的。当然,这意味着这些操作可能比它们处理的cpp文件所包含的文件更多。
这种方法类似于cc_*规则的工作方式:cc_*.srcs中的文件可以包含同一规则的srcs中的其他文件和依赖项的hdrs中的其他文件,但没有其他文件。因此,srcs + hdrs (直接和传递)依赖项的联合定义了cpp文件可能包含的头文件的范围。
https://stackoverflow.com/questions/47666091
复制相似问题