menu XUJINKAI 的个人主页
create settings
home
主页
list
全部博文
  • Collection
  • About
  • assistant_photo
    个人项目
    person
    关于

    Linux C 将版本信息编译进二进制文件中

    Tags: 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评论加载中。。。