【问题标题】:How to reveal all the explicit bazel targets packed into a macro如何显示打包到宏中的所有显式 bazel 目标
【发布时间】:2021-05-26 13:38:46
【问题描述】:

我正在诊断一些 codegen,它由一些由自定义 bazel 规则支持的 bazel 宏支持。

#projX/BUILD
macro_foo(
    name = "foo_data"
    ...
)

py_binary(
    name = "client_foo_data",
    deps = [":foo_data"]
    ...
)

如果我构建原始宏目标,代码生成实际上不会执行。如果我构建一个反向依赖于foo_data 的目标,代码生成会执行。

bazel build //projX:foo_data # doesn't trigger codegen
bazel build //projY:client_foo_data # does codegen

如何找出给定目标的所有不同目标名称?我怀疑我需要构建其中一种特定的变体来满足 codegen 的需求;某种 bazel 查询或在宏下解包目标的东西应该可以解决问题。


VScode Codelens 构建/测试链接

除了直接适用之外,在 VSCode 中,它用于装饰我的宏和其他扩展到多个 bazel 目标的东西,我可以单击链接来启动构建或测试(一些升级对我来说失去了这个功能,我过去常常依靠它来找到这些目标变体)。这就是他们所谓的 codelens 功能

CodeLens 链接在 BUILD 文件中,只需单击目标即可直接启动构建或测试

https://github.com/bazelbuild/vscode-bazel#features

您可以在这里看到注释“另一个快捷方式” https://kig.re/2020/03/21/building-intellij-bazel-plugin.html

了解 bazel 插件用于发现从给定目标展开的所有特定目标变体的机制应该指向正确的方向。如果围绕这个细节有一些概念/词汇/术语,知道这也将有助于理解正在发生的事情。

【问题讨论】:

  • 我应该注意从 codlens 部分到达这里的任何其他人,它实际上是您的 bazel 扩展设置中的配置。我的在某些时候未选中,因此我在不知不觉中禁用了该功能。

标签: bazel


【解决方案1】:

bazel query --output=build //projX:all 将在宏和全局扩展后打印出该包中的所有目标。它具有每个目标的宏扩展堆栈跟踪的 cmets,包括宏定义的文件名和行号。

//projX:allwildcard 的形式,它指定了package 中的所有目标。宏只能在单个包中生成目标,因此将始终包含从该宏调用生成的所有目标。

【讨论】:

    【解决方案2】:

    所以我发现了 vscode 插件使用的查询,他们基本上是在使用一种规则查询

      const queryResult = await new BazelQuery(
        bazelExecutable,
        workspace,
        `kind(rule, ${pkg}:all)`,
        [],
      ).queryTargets();
    

    https://github.com/bazelbuild/vscode-bazel/blob/12c20773c5bbbdbbd30cc393c414622059c05537/src/bazel/bazel_utils.ts#L45-L50

    为了得到我想要的结果,我运行了以下命令...

    bazel query 'kind(rule, //projX:all)' | grep foo_data
    

    暴露了我们在规则中使用的所有“后缀”变体,例如

    //projX:foo_data_variant1
    //projX:foo_data_variant2
    //projX:foo_data_variant3
    ...
    //projX:foo_data
    

    all 技巧是关键,如果我只使用目标名称运行命令,我只会得到那个:-(

    bazel query 'kind(rule, //projX:foo_data)'
    //projX:foo_data
    

    旁注

    在我参与的项目的用例中,欺骗的是传递给宏的“基本名称”实际上用作宏中的目标。所以我遭受的谬误是认为因为一个宏有一个名称参数,该宏本身就是一个目标,它不是,而且给宏的名称很可能被传递给一些实际的 bazel 规则目标不应与宏混淆,即使它们共享一个通用名称。一个是成为实际标签一部分的名称,另一个只是宏/函数的参数。

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2022-06-15
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-19
      相关资源
      最近更新 更多