Bazel构建时genrule引用$(BUILD_TAG)未定义的原因及解决方法
报错原因
Bazel解析genrule的cmd字段时,$(xxx)格式的内容会被优先识别为两类变量:一是Bazel内置的占位变量(比如$<指代输入文件、$@指代输出文件),二是你通过规则属性显式声明传入的自定义变量。你使用的$(BUILD_TAG)不属于内置变量,也没有做任何自定义声明,因此构建时会直接抛出未定义错误。
修复方案
根据BUILD_TAG的来源不同,可以选择对应方案:
- 方案1:BUILD_TAG需要从构建时动态传入
你需要开启构建戳功能,通过工作区状态命令传入变量:
- 给genrule添加
stamp = 1属性,同时将cmd中的$(BUILD_TAG)调整为{BUILD_TAG}:
genrule( name = "create_version_pom", srcs = ["pom_template.xml"], outs = ["version_pom.xml"], stamp = 1, cmd = "sed 's/BUILD_TAG/{BUILD_TAG}/g' $< > $@", )
- 构建时通过
--workspace_status_command参数传入BUILD_TAG的值。比如你可以在项目根目录创建status.sh脚本:
#!/bin/bash echo "BUILD_TAG ${1:-dev}"
执行构建命令时指定版本号即可:
chmod +x status.sh bazel build //example:create_version_pom --workspace_status_command="./status.sh v2.3.1"
- 方案2:BUILD_TAG为固定值
直接在BUILD文件中声明变量即可,无需修改构建命令:
genrule( name = "create_version_pom", srcs = ["pom_template.xml"], outs = ["version_pom.xml"], cmd = "sed 's/BUILD_TAG/$(BUILD_TAG)/g' $< > $@", env = {"BUILD_TAG": "v1.0.0"}, # 此处替换为你需要的固定版本号 )
如果不需要复用变量,也可以直接把版本号硬编码到sed命令中,省略env配置。
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

