如何在Bazel构建中生成含构建时间与目标的文件并让输出二进制获取该信息?
在Bazel中为二进制嵌入构建元信息并扩展构建流程
1. 生成包含构建时间、目标的元信息文件
最简单的方式是用Bazel内置的genrule规则,直接利用Bazel提供的预定义变量生成源文件。示例如下:
BUILD文件片段:
genrule( name = "build_info_gen", outs = ["build_info.c"], cmd = """ echo '#include "build_info.h"' > $@ echo 'const char* BUILD_TIMESTAMP = "$(BUILD_TIMESTAMP)";' >> $@ echo 'const char* BUILD_TARGET = "$(TARGET)";' >> $@ """, )
配套头文件build_info.h:
#ifndef BUILD_INFO_H #define BUILD_INFO_H extern const char* BUILD_TIMESTAMP; extern const char* BUILD_TARGET; #endif
这里用到的Bazel预定义变量说明:
BUILD_TIMESTAMP:构建触发时的Unix时间戳(整数格式)TARGET:完整的构建目标路径(比如//my/package:my_binary),如果只需要目标名称可以用TARGET_NAME
2. 将元信息文件嵌入二进制
把生成的build_info.c和你的业务代码一起编译链接即可,示例cc_binary规则:
cc_binary( name = "my_binary", srcs = ["main.c", ":build_info_gen"], hdrs = ["build_info.h"], )
在业务代码中直接引用这些变量:
#include <stdio.h> #include "build_info.h" int main() { printf("构建时间戳:%s\n", BUILD_TIMESTAMP); printf("构建目标:%s\n", BUILD_TARGET); return 0; }
3. 添加自定义构建步骤(复杂场景)
如果需要更灵活的元信息处理(比如生成可读时间格式、添加Bazel版本等),可以用脚本配合genrule实现自定义步骤。
示例Python脚本generate_build_info.py:
import os import time # 从环境变量获取Bazel传递的参数 timestamp = os.environ.get("BUILD_TIMESTAMP") full_target = os.environ.get("TARGET") output_path = os.environ.get("OUTPUT") # 生成可读时间格式 readable_time = time.ctime(int(timestamp)) if timestamp else "未知" # 写入输出文件 with open(output_path, "w") as f: f.write('#include "build_info.h"\n') f.write(f'const char* BUILD_TIMESTAMP = "{timestamp}";\n') f.write(f'const char* BUILD_TARGET = "{full_target}";\n') f.write(f'const char* READABLE_BUILD_TIME = "{readable_time}";\n')
BUILD文件中调用脚本的genrule:
genrule( name = "build_info_gen_py", outs = ["build_info.c"], cmd = "$(PYTHON) $(location generate_build_info.py)", tools = ["generate_build_info.py"], env = { "BUILD_TIMESTAMP": "$(BUILD_TIMESTAMP)", "TARGET": "$(TARGET)", "OUTPUT": "$@", }, )
4. 验证结果
构建并运行二进制:
bazel run //:my_binary
预期输出:
构建时间戳:1718923456 构建目标://:my_binary 可读构建时间:Wed Jun 19 14:37:36 2024
内容的提问来源于stack exchange,提问作者y.selivonchyk
相关产品推荐
相关产品推荐

