English 中文(简体)
在Rust方案中纳入装饰物
原标题:Include git commit hash as string into Rust program

我在盖特存放处主办一个Rust项目,我希望将其印刷成一些指挥部。 我如何将这一版本纳入该方案? 我认为,建筑文字可以确定环境变量,在汇编项目本身时可以使用这些变量,但并不可行:

<>strong>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");
   |   
                                        ^^^^^^^^^^^^^^^^

是否有办法在汇编时间通过这些数据? 如果没有环境变量,我如何在建筑文字与源代码之间沟通? 我只能想到向某些档案撰写数据,但我认为,这个案件过于熟练。

最佳回答

我只能想到向某些档案撰写数据,但我认为,这个案件过于熟练。

That s unfortunate, because that is the only way of doing it. Environment variables can t work because changes to the environment can t "leak" into other, non-child processes.

简而言之,请can<>em>指示货物界定有条件的汇编旗帜,但这些旗帜强大,足以显示舱面......?

The details of generating code from a build script is detailed in the code generation section of the Cargo documentation.


*** 我指的是,除非你觉得自己喜欢将散射线打成160个混凝土旗,然后在正在汇编的来文方中重新评估,但那怕是<>更<>

问题回答

Since Rust 1.19 (cargo 0.20.0), thanks to https://github.com/rust-lang/cargo/pull/3929, you can now define a compile-time environment variable (env!(…)) for rustc and rustdoc via:

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

So OP s program can be written as:

// 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或以下的话,你仍然不能使用。

无需任何build.rs逻辑或习俗 cr,就很容易做到这一点。 你简单地将目前的电 g直接通过到作为环境变量的建筑指挥系统,并在你的节目中将其改为option_env!(“PROJECT_VERSION”),并加上一个env! (“CARGO_PKG_VERSION”falls。 这些宏观变量在build 时间时为环境变量。

实例如下:

fn main() {
    let version = option_env!("PROJECT_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"));
    println!("This binary was built from {}", version);
}

当你制定方案并想要准确的货仓,例如,在您的 CI/CD配置中,你先用<条码>PROJECT_VERSION=$(git rev-parse --short HEAD)确定货物指挥。 和<代码> (但还有<条码>建造<>条/条码>等工程):

% PROJECT_VERSION=$(git rev-parse --short HEAD) cargo run
This binary was built from 6ca63b2

个人选择$(git打字) over $(git rev-parse),因为前者更具描述性(使用cargo Building,现在仅作改动):

% PROJECT_VERSION=$(git describe) cargo build 
% ./target/debug/your-program
This binary was built from v0.3.0-15-g6ca63b2    # or just  v0.3.0  if current commit is tagged with that

由于你有<代码>CARGO_PKG_VERSION的背后,您的民主选举学会仍能为你建立这些档案。 同样,为了发展,你可以绕过<>PROJECT_VERSION。 在此情况下,将使用以下文本:

% cargo run
This binary was built from 0.3.0

Uh. (I do not recommend this in production or in testing or in public code or even in private code but I mean, it kinda does the job?)

const REF: &str = include_str!("../.git/HEAD");
const REF_MASTER: &str = include_str!("../.git/refs/heads/master");

// (elsewhere)
if REF == "ref: refs/heads/master" { REF_MASTER } else { REF }

(除非你重新制定某种法典,否则不会使用。) 指出,这是100%未经过测试的。





相关问题
Creating an alias for a variable

I have the following code in Rust (which will not compile but illustrates what I am after). For readability purposes, I would like to refer the same string with two different names so that the name of ...

Rust Visual Studio Code code completion not working

I m trying to learn Rust and installed the Rust extension for VSCode. But I m not seeing auto-completions for any syntax. I d like to call .trim() on String but I get no completion for it. I read that ...

热门标签