Bazel 如何在规则的默认参数值中包含当前工作区名称?

Bazel 如何在规则的默认参数值中包含当前工作区名称?,bazel,Bazel,假设我有一条规则: blah = rule( attrs = { "foo": attr.string(default = "@HELP@"), }, ) 我希望foo的默认值包含调用规则的工作区的名称。我怎样才能做到这一点 (注意:一种可接受的方法是在值中保留一个占位符,并在规则使用该属性时替换它,但我也不知道如何在那里获取当前工作区。我能找到的最接近的是ctx.label.workspace\u root,但对于“main”来说,该占位符是空的工作空间,例如

假设我有一条规则:

blah = rule(
    attrs = {
        "foo": attr.string(default = "@HELP@"),
    },
)
我希望
foo
的默认值包含调用规则的工作区的名称。我怎样才能做到这一点

(注意:一种可接受的方法是在值中保留一个占位符,并在规则使用该属性时替换它,但我也不知道如何在那里获取当前工作区。我能找到的最接近的是
ctx.label.workspace\u root
,但对于“main”来说,该占位符是空的工作空间,例如用于其他事物的
外部/foo

ctx.workspace\u name
未给出正确答案。例如,如果我打印(“%s”->“%s”(ctx.label.workspace\u root,ctx.workspace\u name)),我会得到如下结果:

'externals/foo' -> 'main'
'externals/bar' -> 'main'

…这是错误的;这些应该是'foo'和'bar',而不是'main'('main'是我的主/根工作区)。请注意,这些上下文中的标签是例如@foo/:foo,因此Bazel显然知道正确的工作区名称。

您可以使用占位符属性,然后在实现中使用

def _impl(ctx):
  print("ws: %s" % ctx.workspace_name)

blah = rule(
    implementation = _impl,
)

就获得工作区名称而言,这似乎是次优的,但似乎也可行:

def _workspace(ctx):
    """Compute name of current workspace."""

    # Check for meaningful workspace_root
    workspace = ctx.label.workspace_root.split("/")[-1]
    if len(workspace):
        return workspace

    # If workspace_root is empty, assume we are the root workspace
    return ctx.workspace_name

根据Kristina在原始问题中的回答和评论,这可以用来替换参数值中的占位符。

否,这在主工作区以外的地方给出了错误的答案。(见更新的问题)哦,说得好。它实际上应该在将来给出正确的结果(一旦出现),但在此之前,您只能使用黑客脚本(抱歉)。