获取给定 Bazel 目标的特定属性值。

4
我很确定这个问题已经有文档记录了,但是我无法在任何地方找到答案。
如果我有以下内容:
```bazel_rule(
    name = "foo",
    srcs = ["foo.cpp"],
    attr_bar = "bar"
)```

如果我在一个Starlark (.bzl)文件中有对这个规则的引用(//src:foo),我如何查询目标以获取特定属性的值。例如,在此示例中,get_attribute("//src:foo", "attr_bar")应返回"bar"。

1个回答

7
这取决于您是要从 规则还是 特征 中读取属性。

简短回答:

宏无法读取目标的属性(宏大致在构建文件加载时评估,而属性会在稍后的分析时评估)。您可以执行诸如获取所关心的属性并在宏中创建规则 (bazel_rule 在您的示例中),以便宏具有属性值,但这通常很快变得混乱且难以跟踪。

Starlark 规则也无法直接从依赖项读取属性值(当然,它可以读取自己的属性)。您感兴趣的规则 (bazel_rule 在这里) 必须将信息放入 提供程序 中,而 Starlark 规则从其依赖项读取提供程序。

特征可以直接通过 ctx.rule.attr.<attr_name>这里的示例 实现)读取其所评估的规则的属性。


谢谢!背景:我正在使用bazel构建ROS包,它的构建系统有一个名为packageFoo的概念,它声明了一些依赖项,但是任何依赖于Foo的包都需要依赖于这些依赖项。因此,我想创建一个带有参数“deps2”的宏,以便当A依赖于B时,A将B的“deps2”放入自己的“deps”属性中。我在使用属性这个词时很宽泛,我真正需要的只是让A读取B的“deps2”参数。我也尝试过使用规则来实现这一点,但我需要将一个规则包装在另一个规则中,并在包装器内更新ctx.attrs.deps,而这是不可更改的。 - Brian Barnes
这听起来类似于 java_libraryexports 属性:https://docs.bazel.build/versions/master/be/java.html#java_library.exports。你是在使用自己的 Starlark 规则、本地规则还是其他人的规则? - ahumesky
如果您正在使用自己的规则,我们称之为 ros_package,我会添加一个名为 exports(或任何您想要的名称)的属性到 ros_package 中,并在 ros_package 的实现中读取 exports 并将其放入提供程序中,例如 RosInfo。同样,在 ros_package 的实现中,您需要从依赖项中读取 RosInfo 提供程序,读取提供程序中的 exports 并将其添加到规则内的依赖项中。 - ahumesky
非常感谢您的周到回复。我正在使用 rules_foreign_cc,并在该存储库 https://github.com/bazelbuild/rules_foreign_cc/issues/88 下提交了一个FR。 - Brian Barnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接