编译程序时,有时候需要在编译时传入一些宏定义,给程序内部使用。
比如将智研流水线构建的版本号,以及编译的时间以编译宏的方式传给程序。
经过研究,暂时发现bazel有两种方式可以实现以上目的,记录如下:
方式一
bazel build //:main --copt=-DBUILD_VERSION="\"${BUILD_VER}\"" --copt=-DBUILD_TIME="\"$(date)\""
BUILD_VER是智研流水线的构建版本号,是一个环境变量。
使用该方式时,可以直接在代码中引用宏BUILD_VERSION和BUILD_TIME。
方式二
bazel build //:main --define VERSION="\\\"${BUILD_VER}\\\"" --define DATE="\\\"$(date)\\\""
使用这种方式,还需要:
cc_binary(
name = "main",
srcs = ["main.c"],
local_defines = [
"VERSION=\"$(VERSION)\"",
"DATE=\"$(DATE)\"",
],
)
然后你就可以在代码中使用宏VERSION和DATE了。
在代码中使用以上两种方式传入的宏
#include <stdio.h>
void show_version() {
printf("Version: [方式1:%s %s | 方式2:%s %s]\n", BUILD_VERSION, BUILD_TIME, VERSION, DATE);
}
int main(int argc, char** argv) {
if (argc > 1 && std::string(argv[1]) == "-v") {
show_version();
_exit(0);
}
...
return 0;
}
注意
- 为了允许日期中的空格,所有转义都是必需的。
请注意,--define DATE="\\\"$(date)\\\""
必须在命令行中提供,并且不能放入.bazelrc
中,因为.bazelrc
的计算不像shell。 - 在bazel 3.7.2版本,使用bazel编译时,代码直接使用"_DATE_" "_TIME_"时,显示出来是redacted,这里经过查阅资料发现是bazel的锅https://stackoverflow.com/questions/59725177/how-do-i-prevent-bazel-from-overriding-the-value-of-builtin-macros-date-and。
参考文献
https://cloud.tencent.com/developer/ask/sof/107481836