在Bazel规则中,如何从缓存命中/未命中检测中排除某些输入文件

时间:2018-11-08 15:51:13

标签: bazel

我有一个bazel genrule,它运行自定义工具来处理某些输入文件集并生成输出。问题在于自定义工具每次运行都会花费很长时间,但是并非输入文件集的每项更改都与自定义工具的输出有关。为了检测更改是否重要,我有另一个脚本可以解析输入内容,并在自定义工具的输出将有所不同时迅速提供信息。

我无法在Bazel中实现上述功能。我要实现的方式如下

INPUT_FILES --------> [RULE1] --------> OUTPUT
     |                   ^
     |                   |
     |                   |
      --------------> [RULE2]

RULE2's输出应决定是否运行RULE1。但是当它必须运行时,INPUT_FILES应该可以使用RULE1。因此,在执行RULE2's时,基本上只应将RULE1的输出用于高速缓存命中/未命中的计算,而应该忽略INPUT_FILES。有没有办法做到这一点?

编辑: 我尝试了一些实验,并且在禁用沙箱的情况下执行RULE1RULE2时可以实现此目的。这样一来,RULE2可以访问RULE1的输入而无需明确列出它们。这似乎很麻烦,但是如果有一种方法可以为规则共享一个沙箱,而不是在没有沙箱的情况下执行两个沙漏,那可能很好。

1 个答案:

答案 0 :(得分:1)

我不知道执行您所描述的方法的方法,但是还有其他一些策略可能对您有用。 (我认为还有一个复杂之处,就是RULE2无法访问INPUT_FILES的先前状态,因此它没有什么可比较的,可以看到输入)。

一种策略是处理输入文件,以便删除所有无关紧要的部分,并且RULE1中运行时间很长的工具只会看到“重要”的东西。当然,这完全取决于您的工具和规则所执行的操作,但它可能会起作用。

作为一个简单的示例,您可以使用一个工具从代码中删除注释(以保留行号的方式),然后编译器操作只会看到仅代码文件。因此,如果您对注释进行更改,则编译器的输入是相同的,并且bazel会跳过该操作。

这类似于bazel为使Java规则的构建更具增量性所做的工作。有一个工具可以从Java源代码生成“标头jar”,该工具仅包含类接口,而上游规则则只能看到标头jar。这样,只有对类的接口进行更改才能使上游规则重新运行,而对注释或方法实现的更改则不会。