我有一个bazel genrule,它运行自定义工具来处理某些输入文件集并生成输出。问题在于自定义工具每次运行都会花费很长时间,但是并非输入文件集的每项更改都与自定义工具的输出有关。为了检测更改是否重要,我有另一个脚本可以解析输入内容,并在自定义工具的输出将有所不同时迅速提供信息。
我无法在Bazel中实现上述功能。我要实现的方式如下
INPUT_FILES --------> [RULE1] --------> OUTPUT
| ^
| |
| |
--------------> [RULE2]
RULE2's
输出应决定是否运行RULE1
。但是当它必须运行时,INPUT_FILES
应该可以使用RULE1
。因此,在执行RULE2's
时,基本上只应将RULE1
的输出用于高速缓存命中/未命中的计算,而应该忽略INPUT_FILES
。有没有办法做到这一点?
编辑:
我尝试了一些实验,并且在禁用沙箱的情况下执行RULE1
和RULE2
时可以实现此目的。这样一来,RULE2
可以访问RULE1
的输入而无需明确列出它们。这似乎很麻烦,但是如果有一种方法可以为规则共享一个沙箱,而不是在没有沙箱的情况下执行两个沙漏,那可能很好。
答案 0 :(得分:1)
我不知道执行您所描述的方法的方法,但是还有其他一些策略可能对您有用。 (我认为还有一个复杂之处,就是RULE2
无法访问INPUT_FILES
的先前状态,因此它没有什么可比较的,可以看到输入)。
一种策略是处理输入文件,以便删除所有无关紧要的部分,并且RULE1
中运行时间很长的工具只会看到“重要”的东西。当然,这完全取决于您的工具和规则所执行的操作,但它可能会起作用。
作为一个简单的示例,您可以使用一个工具从代码中删除注释(以保留行号的方式),然后编译器操作只会看到仅代码文件。因此,如果您对注释进行更改,则编译器的输入是相同的,并且bazel会跳过该操作。
这类似于bazel为使Java规则的构建更具增量性所做的工作。有一个工具可以从Java源代码生成“标头jar”,该工具仅包含类接口,而上游规则则只能看到标头jar。这样,只有对类的接口进行更改才能使上游规则重新运行,而对注释或方法实现的更改则不会。