【问题标题】:Bazel - depend on generated outputsBazel - 取决于生成的输出
【发布时间】:2021-10-24 03:49:35
【问题描述】:

我在 Bazel monorepo 中有一个 yaml 文件,其中包含我想在多种语言中使用的常量。这有点像 protobuffs 的创建和使用方式。

如何在构建时解析这个 yaml 文件并依赖于输出?

例如:

item1: "hello"
item2: "world"
nested:
  nested1: "I'm nested"
  nested2: "I'm also nested"

然后我需要解析这个 yaml 文件,以便它可以用于许多不同的语言(例如,Rust、TypeScript、Python 等)。例如,这是 TypeScript 所需的输出:

export default {
  item1: "hello",
  item2: "world",
  nested: {
    nested1: "I'm nested",
    nested2: "I'm also nested",
  }
}

注意,我不想要读取 yaml 文件并将其转换为对象的 TypeScript 代码。这种转换应该在构建过程中完成。

对于实际的转换,我正在考虑用 Python 编写它,但不是必须的。这意味着 python 也需要在构建时运行。


附:我主要关心功能,所以我对它的完成方式很灵活。我什至可以使用 yaml 之外的其他文件格式。

【问题讨论】:

  • 好像 genrule 只运行终端命令?这意味着如果我使用 Python 脚本(或其他语言)来解析 yaml,它就不会是封闭的。还是我错过了什么?
  • “密封”是什么意思? Genrule 可以将任何标签视为“可执行”,并针对多个源标签之一运行它以生成目标标签。如果您事先不知道目标标签的名称,您可以创建返回 DefaultInfo 的自定义规则(或任何其他 *Info 对象来做任何可能的事情)。只是稍微困难一点。

标签: bazel bazel-rules


【解决方案1】:

感谢@oakad 的帮助,我得以解决。本质上,您可以使用 genrule 创建输出。

因此,假设您有一些目标(如 python setup)来生成名为 parse_config 的输出,您可以这样做:

genrule(
    name = "generated_output",
    srcs = [],
    outs = ["output.txt"],
    cmd = "./$(execpath :parse_config) > $@" % name,
    exec_tools = [":parse_config"],
    visibility = ["//visibility:public"],
)

生成的文件是output.txt。您可以通过//lib/config:generated_output 访问它。

注意,cmd 本质上是将stdout 传送到文件内容中。在 Python 中,这意味着任何打印的内容都会出现在生成的文件中。

【讨论】:

  • 几个挑剔:1) 来自文档:Users are encouraged to prefer exec_tools to tools where this does not cause any issues 2) 使用 $(location ...) is "legacy pre-Starlark behavior and not recommended" pretty sure using $(rootpath ...) 是合适的 docs.bazel.build/versions/main/be/… docs.bazel.build/versions/main/be/…
  • 谢谢!更新了这两件事,它们在我的机器上工作。更新了我的答案,以确保其他人也遵循最佳做法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
相关资源
最近更新 更多