rust - 将 git commit hash 作为字符串包含到 Rust 程序中

标签 rust rust-cargo

我在 git 存储库中托管了一个 Rust 项目,我想让它在某些命令上打印版本。如何将版本包含到程序中?我认为构建脚本可以设置编译项目本身时可以使用的环境变量,但它不起作用:

build.rs:

use std::env;

fn get_git_hash() -> Option<String> {
    use std::process::Command;

    let branch = Command::new("git")
                         .arg("rev-parse")
                         .arg("--abbrev-ref")
                         .arg("HEAD")
                         .output();
    if let Ok(branch_output) = branch {
        let branch_string = String::from_utf8_lossy(&branch_output.stdout);
        let commit = Command::new("git")
                             .arg("rev-parse")
                             .arg("--verify")
                             .arg("HEAD")
                             .output();
        if let Ok(commit_output) = commit {
            let commit_string = String::from_utf8_lossy(&commit_output.stdout);

            return Some(format!("{}, {}",
                        branch_string.lines().next().unwrap_or(""),
                        commit_string.lines().next().unwrap_or("")))
        } else {
            panic!("Can not get git commit: {}", commit_output.unwrap_err());
        }
    } else {
        panic!("Can not get git branch: {}", branch.unwrap_err());
    }
    None
}

fn main() {
    if let Some(git) = get_git_hash() {
        env::set_var("GIT_HASH", git);
    }
}

src/main.rs:

pub const GIT_HASH: &'static str = env!("GIT_HASH");

fm main() {
    println!("Git hash: {}", GIT_HASH);
}

错误信息:

error: environment variable `GIT_HASH` not defined
  --> src/main.rs:10:25
   |
10 | pub const GIT_HASH: &'static str = env!("GIT_HASH");
   |   
                                        ^^^^^^^^^^^^^^^^

有没有办法在编译时传递这些数据?如果不使用环境变量,我如何在构建脚本和源代码之间进行通信?我只能考虑将数据写入某个文件,但我认为这对于这种情况来说太过分了。

最佳答案

自 Rust 1.19(cargo 0.20.0)以来,感谢 https://github.com/rust-lang/cargo/pull/3929 ,您现在可以通过以下方式为 rustcrustdoc 定义编译时环境变量 (env!(…)):

println!("cargo:rustc-env=KEY=value");

所以OP的程序可以写成:

// build.rs
use std::process::Command;
fn main() {
    // note: add error checking yourself.
    let output = Command::new("git").args(&["rev-parse", "HEAD"]).output().unwrap();
    let git_hash = String::from_utf8(output.stdout).unwrap();
    println!("cargo:rustc-env=GIT_HASH={}", git_hash);
}
// main.rs
fn main() {
    println!("{}", env!("GIT_HASH"));
    // output something like:
    // 7480b50f3c75eeed88323ec6a718d7baac76290d
}

请注意,如果您仍想支持 1.18 或更低版本,您仍然无法使用此功能。

关于rust - 将 git commit hash 作为字符串包含到 Rust 程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43753491/

相关文章:

rust - 如何在连接器上配置多态的 hyper 0.11.x 客户端变量?

rust - 无法在已实现的方法中序列化结构,因为 "the trait ` serde::Serialize` 未针对 `Self` 实现“

rust - cargo 生成在 Ubuntu 20.04 上安装失败

rust - 无法在 MacOS 上编译简单的 Rust 程序

rust - 递归构建迭代器会导致 "recursive opaque type"错误

rust - 在 Rust 中使用 unwrap_or_else 进行错误处理

windows - 如何在 Windows 中的 Warp 等服务器应用程序上隐藏终端 shell?

testing - 为集成测试和基准测试共享实用程序函数的惯用方法是什么?

rust - 交叉编译 [no_std] 代码 - 未找到 libcore 和 compiler_builtins

rust - 我如何使用 Cargo 将库构建为 rlib 和 dylib 但内容不同?