【问题标题】:Having two dependent actions in a single rule在单个规则中有两个依赖操作
【发布时间】:2021-11-30 15:00:25
【问题描述】:

编辑:下面的示例确实有效,我误解了编译器给我的输出。答案可能对某些人仍然有帮助。

是否有办法让规则中的操作生成一个文件,供同一规则中的后续操作使用?

例如:

def _example_rule_impl(ctx):
  thefile = ctx.actions.declare_file("required_file.json")

  ctx.actions.write(
    output = thefile,
    content = "CONTENT",
  )

  args = ctx.actions.args()
  args.add("--config", thefile)

  ctx.actions.run(
    inputs = ctx.files.srcs + ctx.files.deps + [thefile],
    outputs = outs,
    arguments = [args],
    progress_message = "Compiling...",
    executable = ctx.executable._compiler,
  )

这样做的主要问题似乎是,所有操作输出似乎都写入了 bazel-out,但运行操作需要将生成的文件写入 execroot 中的 srcs 和 deps 文件旁边才能正常工作.有没有办法将操作写入 execroot 或者这不是正确的方法?

【问题讨论】:

    标签: bazel bazel-rules


    【解决方案1】:

    将其他操作的输出作为输入的操作是一种非常典型的做法,基本上应该按照您的设置工作。 Bazel 负责处理输入和输出文件,例如,在 linux 上使用大量符号链接、在沙箱中挂载东西、上传和下载文件以进行远程执行等。

    https://docs.bazel.build/versions/main/output_directories.html

    另外,关于这一行:

    inputs = ctx.files.srcs + ctx.files.deps + [thefile],
    

    根据您的需要,出于性能原因,您可能希望使用 depset。见https://docs.bazel.build/versions/main/skylark/depsets.html 尤其是最后https://docs.bazel.build/versions/main/skylark/depsets.html#performance

    【讨论】:

    • 谢谢!事实证明它一直有效,我只是误解了编译器给我的错误。关于 depset:我正在使用一个,但在试图找到问题时摆脱了它。但是,我不确定我是否正确使用它。我会把所有文件都放在一个despet中吗?输入 = depset(ctx.files.srcs + ctx.files.deps + [thefile])?或者我是否为它们中的每一个创建一个 depset 并将它们添加到彼此的传递依赖关系中?
    • 这取决于您的规则的结构。 Depset 主要用于避免目标之间的数据结构中的二次内存使用/连接。例如。 foo(name="a", deps=["b"]) foo(name="b", deps=["c"]) foo(name="c", deps=["d"]) 没有 depset如果 foo 使用列表,则可能导致 [a, b, c, d], [b, c, d], [c, d], [d]。但是,如果您没有在 inputs 的构建图的“层”中聚合类似的元素,那么您不一定需要 depset。
    猜你喜欢
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    相关资源
    最近更新 更多