You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bazel的$(locations)中结合.format()拼接目标标签?

问题:Bazel genrule中如何结合$(locations)与字符串格式化获取目标文件路径

问题描述

我需要在Bazel的genrule的cmd中,根据传入的变量templateName组装目标标签(最终要得到//project/test:fileList),再用$(locations)获取该目标下的文件列表。直接写$(locations //project/test:fileList)一切正常,但尝试在$(locations)内部用'//project/test:{}'.format(templateName)组装标签时,抛出错误:

invalid label in $(locations) expression: invalid package name '"//project/test': package names may not contain '//' path separators

显然是变量templateName在字符串内部无法被正确解析,请问该如何正确结合$(locations)与.format()?

原代码示例

def test_genrule(templateName):
    native.genrule(
        name = "example",
        srcs = "//project/test:{}.format(templateName)",
        outs = result,
        cmd = ["$(execpath //project/tools:tool)"] +
              "$(locations '//project/test:{}'.format(templateName))",
        tools = ["//project/tools:tool"]
    )

解决方案

核心问题是你把Python的字符串格式化操作放到了Bazel的$(locations)表达式内部,导致Bazel先解析$(locations)内容,而非先执行Python的格式化逻辑。正确做法是先在Python层面组装好完整的目标标签,再传入$(locations)。

修正后的代码如下:

def test_genrule(templateName):
    # 先在Python层面生成完整的目标标签
    target_label = "//project/test:{}".format(templateName)
    native.genrule(
        name = "example",
        srcs = [target_label],
        outs = result,
        cmd = "$(execpath //project/tools:tool) $(locations {})".format(target_label),
        tools = ["//project/tools:tool"]
    )

关键修正点:

  • 提前用Python的.format()生成完整目标标签,存入target_label变量
  • 将target_label作为元素传入srcs列表(原代码中src应为srcs,且需是列表类型)
  • 在cmd中,把$(locations {})作为模板,用.format(target_label)填充完整标签,让Bazel最终解析到正确的$(locations //project/test:fileList)表达式

另外需注意原代码的语法错误:

  • src应为srcs,Bazel genrule的srcs接受列表类型
  • 字符串引号未闭合、cmd行末尾缺失逗号
  • cmd无需用列表拼接,直接字符串格式化更简洁

内容的提问来源于stack exchange,提问作者Ventu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 03:23:22