首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理自定义Skylark规则中增量构建的隐式依赖(例如C++包含)

如何处理自定义Skylark规则中增量构建的隐式依赖(例如C++包含)
EN

Stack Overflow用户
提问于 2017-12-06 02:58:31
回答 1查看 1.2K关注 0票数 2

问题

我想知道如何告知bazel声明时未知但在构建时已知的依赖项(即隐式依赖项、动态依赖项,.)。例如,在编译C++源文件时,.cpp源文件将取决于某些头文件,并且在编写构建文件时此信息不可用。它需要在构建时被检索。无论获取信息的解决方案是什么(模拟运行、生成页文件、解析标准输出),都需要在构建时完成,并且需要将信息检索到bazel构建图中。

由于skylark不允许执行I/O操作,例如读取生成的页文件或解析包含依赖项列表的stdout结果,因此我不知道如何处理它。

在隐式依赖项的背后,我正在寻找正确的增量构建。

示例

为了实验这个问题,我创建了一个简单的工具,just_a_tool.exe,它接受一个输入文件,从它读取一个文件列表,并将所有这些文件的内容连接到一个输出文件。

命令行示例:

代码语言:javascript
复制
just_a_tool.exe --input input.txt --depfile dep.d output.txt

D包含所有读取文件的列表。

问题

如果更改test1.txt、test2.txt或test3.txt的内容,bazel就不会重新构建output.txt文件。当然,因为它不知道存在依赖关系。

示例文件

just_a_tool.bzl

代码语言:javascript
复制
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"}
)

构建

代码语言:javascript
复制
load("//tool:just_a_tool.bzl", "jat_convert")

jat_convert(
    name="my_output",
    source=":input.txt"
)

input.txt

代码语言:javascript
复制
test1.txt
test2.txt
test3.txt

目标

对于以下情况,我想做正确和快速的增量构建:

  • 从C++源生成反射数据,此自定义工具的执行取决于我的源文件中包含的头文件。
  • 使用内部工具构建可以包含其他文件的资产文件
  • 在我的着色器上运行一个自定义预处理程序,允许使用#include特性

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2017-12-06 12:18:05

Bazel的扩展语言不支持使用动态输入集创建操作,而这个集合依赖于以前操作的输出。换句话说,自定义规则不能运行操作、读取操作的输出、然后使用这些输入创建操作或更新(或修剪)已经创建的操作的输入集。

相反,我建议在规则中添加属性,用户可以在其中声明源可能包含的文件集。我管这叫“头的宇宙”。您创建的操作依赖于这个用户定义的域,因此操作输入集是完全定义的。当然,这意味着这些操作可能比它们处理的cpp文件所包含的文件更多。

这种方法类似于cc_*规则的工作方式:cc_*.srcs中的文件可以包含同一规则的srcs中的其他文件和依赖项的hdrs中的其他文件,但没有其他文件。因此,srcs + hdrs (直接和传递)依赖项的联合定义了cpp文件可能包含的头文件的范围。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47666091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档