为Rust二进制文件添加版本信息

623次阅读  |  发布于1年以前

我们想在Rust二进制文件中添加版本信息,像这样:

如何添加这些信息?让我们想一下。简单地说,我们可以将这些信息作为静态变量写在配置文件中。

static version: String = "v0.1.0";
static commit: String = "78848d8b84b60c9592d41970a9db99a37e8d2e9e";
static date: String = "2023-10-14T06:00:20Z";

当然,这是可行的。但这有点愚蠢,每次当我们做一个新的版本时都需要手动更新配置。

我们能在运行building时生成它吗?然后我们只需要创建一个新标签,编译器就会自动处理这些信息。听起来不错。但是,怎么做呢?

Cargo支持build脚本,在根目录下创建build.rs文件,它可以为Cargo构建进度做一些集成。Rust宏env!在编译时将某些环境变量导出到程序中。

let version = env!("CARGO_PKG_VERSION");

也许我们可以用这两个功能来实现我们想要的,让我们试一试。

首先是version,从Cargo.toml中读取版本信息:

static VERSION: &'static str = env!("CARGO_PKG_VERSION");

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

编译和运行它:

Hello, world!
version: 0.1.0

接下来,让我们尝试使用build.rs去设置更多的信息。在项目根目录下创建build.rs文件,写入如下代码:

// build.rs
fn main() {
    println!("cargo:rustc-env=GIT_VERSION={}", "v0.1.0");
    println!("cargo:rustc-env=GIT_COMMIT={}", "78848d8b84b60c9592d41970a9db99a37e8d2e9e");
    println!("cargo:rustc-env=GIT_DATE={}", "2023-10-14T06:00:20Z");
}

在src/main.rs中使用这些环境变量:

static VERSION: &'static str = env!("GIT_VERSION");
static COMMIT: &'static str = env!("GIT_COMMIT");
static DATE: &'static str = env!("GIT_DATE");

fn main() {
    println!("Hello, world!");
    println!("version: {}", VERSION);
    println!("commit: {}", COMMIT);
    println!("date: {}", DATE);
}

编译和运行它:

Hello, world!
version: v0.1.0
commit: 78848d8b84b60c9592d41970a9db99a37e8d2e9e
date: 2023-02-19T20:20:20Z

接下来,让我们尝试使用build.rs读取git信息。

首先,让我们创建一个新的git标签:

git tag -a v0.1.2 -m 'new version'

然后,编写build.rs:

// build.rs
use chrono::{DateTime, Utc};
use std::process::Command;

fn main() {
    let output = Command::new("git")
        .args(["describe", "--tags", "--abbrev=0"])
        .output()
        .unwrap();
    let git_tag = String::from_utf8(output.stdout).unwrap();
    println!("cargo:rustc-env=GIT_VERSION={}", git_tag);

    let output = Command::new("git")
        .args(["rev-parse", "HEAD"])
        .output()
        .unwrap();
    let git_commit = String::from_utf8(output.stdout).unwrap();
    println!("cargo:rustc-env=GIT_COMMIT={}", git_commit);

    let now: DateTime<Utc> = Utc::now();
    let build_date = now.to_rfc3339();
    println!("cargo:rustc-env=GIT_DATE={}", build_date);
}

我们需要chrono格式化日期,所以,我们需要把它添加到Cargo.toml:

[build-dependencies]
chrono = "0.4.23"

编译和运行它:

Hello, world!
version: 
commit: HEAD
date: 2023-10-14T06:00:50.180122+00:00

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8