为何Bazel传递$(Version)而非Version变量的实际值?
问题原因
Bazel 默认不会自动展开 go_binary 规则的 x_defs 属性中的 Make 变量(即 $(Version)),导致编译时直接将字符串 $(Version) 赋值给了 main.Version 变量,而非预期的命令行传入值。
解决方案
方案一:直接通过命令行传递版本号(最简方式)
无需修改 BUILD 文件,仅调整 Makefile 中的构建命令,用 --x_defs 参数直接指定版本变量:
@bazelisk build --x_defs=main.Version=1.9 //...
BUILD 文件可保留原结构(也可移除 x_defs 中 Version 相关配置,命令行参数会覆盖文件配置):
go_binary( name = "api", embed = [":api_lib"], visibility = ["//visibility:public"], )
方案二:自定义宏实现变量复用(适合多规则场景)
如果需要在多个构建规则中复用版本变量,或必须通过 --define 传递参数,可通过自定义 Bazel 宏处理变量展开:
- 在项目目录下创建
go_version.bzl文件:
load("@io_bazel_rules_go//go:def.bzl", "go_binary") def go_binary_with_version(name, version_package, **kwargs): x_defs = kwargs.pop("x_defs", {}) x_defs[f"{version_package}.Version"] = "$(Version)" go_binary( name = name, x_defs = x_defs, **kwargs )
- 修改 BUILD 文件,使用自定义宏替换原生
go_binary:
load(":go_version.bzl", "go_binary_with_version") go_binary_with_version( name = "api", embed = [":api_lib"], visibility = ["//visibility:public"], version_package = "main", )
- 保持原 Makefile 命令不变:
@bazelisk build --define Version=1.9 //...
完成上述配置后,重新构建并运行二进制文件,版本号即可正确输出为 1.9。
内容的提问来源于stack exchange,提问作者Amine Hadid
相关产品推荐
相关产品推荐

