仓库源文站点原文


title: 为Cargo编译的可执行文件增加commit版本号 toc: true cover: 'https://img.paulzzh.com/touhou/random?7' date: 2022-11-17 17:00:19 categories: Rust tags: [Rust, Cargo]

description: 有的时候我们在发布一些Cli工具时,除了明确的版本号之外,还想要添加对应的Git CommitId号;这个功能可以通过 build.rs 脚本实现;

有的时候我们在发布一些Cli工具时,除了明确的版本号之外,还想要添加对应的Git CommitId号;

这个功能可以通过 build.rs 脚本实现;

源代码:

<br/>

<!--more-->

为Cargo编译的可执行文件增加commit版本号

build.rs简要说明

一些项目希望编译第三方的非 Rust 代码,例如 C 依赖库;一些希望链接本地或者基于源码构建的 C 依赖库;还有一些项目需要功能性的工具,例如在构建之前执行一些代码生成的工作等;

此时,可以使用项目根目录下的 build.rs 创建构建脚本;

例如:

build.rs

fn main() {
    // 以下代码告诉 Cargo ,一旦指定的文件 `src/hello.c` 发生了改变,就重新运行当前的构建脚本
    println!("cargo:rerun-if-changed=src/hello.c");
    // 使用 `cc` 来构建一个 C 文件,然后进行静态链接
    cc::Build::new()
        .file("src/hello.c")
        .compile("hello");
}

关于构建脚本的一些使用场景如下:

更详细见:

<br/>

增加Commit版本号

对于在可执行文件中增加commit版本号,我们可以:

例如:

build.rs

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::process::Command;

fn get_git_version() -> String {
    let version = env::var("CARGO_PKG_VERSION").unwrap();

    let child = Command::new("git").args(["describe", "--always"]).output();
    match child {
        Ok(child) => {
            let buf = String::from_utf8(child.stdout).expect("failed to read stdout");
            version + "-" + &buf
        }
        Err(err) => {
            eprintln!("`git describe` err: {}", err);
            version
        }
    }
}

fn main() {
    let version = get_git_version();
    let mut f = File::create(Path::new(&env::var("OUT_DIR").unwrap()).join("VERSION")).unwrap();
    f.write_all(version.trim().as_bytes()).unwrap();
}

上面通过 get_git_version 函数获取到 version 字符串,并最后写入到 ${OUT_DIR}/VERSION 文件中;

get_git_version 函数中:

<br/>

在二进制中读取版本号

上面在编译之前生成了版本号,因此我们可以在代码中读取到这个记录版本号的文件;

例如:

src/main.rs

pub const VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/VERSION"));

fn main() {
    println!("Hello, world on build version: {}", VERSION);
}

上面的 VERSION 常量字符串, 就包含了 $OUT_DIR/VERSION 文件中的内容;

其中:

最终测试结果:

$ cargo run    

Hello, world on build version: 0.1.0-9968d66

<br/>

附录

文章参考:

源代码:

<br/>