Linux C 将版本信息编译进二进制文件中
有时候我们会想要将一些额外的信息写入c程序,如代码版本信息,好进行调试等工作。
一种办法是把版本信息写入源码中,然后通过接口去获取,如以下的c代码:
#define VERSION "v1.0"
void dump_version() {
puts(VERSION);
}
这种方式必须要执行这个文件才能获取到版本号,我下面提供另一个思路,通过内联汇编把版本信息编译到目标的comment区来记录。
先做一个小实验,将以下C代码存为version.c文件:
// version.c
__asm__(".section .comment");
__asm__(".string \"Version: v1.0\"");
使用gcc编译:
gcc -c version.c -o version.o
然后通过readelf命令读取:
readelf -p .comment version.o
结果为:
String dump of section '.comment':
[ 0] Version: v1.0
[ f] GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
使用-Qn命令可以让gcc不编译自身信息(第二段信息)。
将以上过程写成一个脚本,如下:
#!/bin/sh
DATE=$(date +"%Y-%m-%d %H:%M:%S")
HASH=$(git rev-parse HEAD)
TAG=$(git describe --tags)
mkdir -p build
SRC_FILE=build/version.c
TARGET_FILE=build/version.o
(
cat <<EOF
__asm__(".section .comment");
__asm__(".string \"DATE: $DATE\"");
__asm__(".string \"GIT: $HASH $TAG\"");
__asm__(".section .text");
EOF
) >$SRC_FILE
gcc -Qn -c $SRC_FILE -o $TARGET_FILE
然后在Makefile文件中,每次编译前执行一下这个脚本,并在链接的命令中,把build/version.o也加进去,就大功告成了。
其中调用了git命令获取当前仓库的信息,这里也列出了其他的git命令,供参考。
Disqus评论加载中...