From 0a3b65446831170a93f3c4659a6b273213aacb97 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Fri, 6 Mar 2026 16:32:55 -0500 Subject: [PATCH 1/4] deps: Replace vergen with a new support crate --- Cargo.lock | 23 +++++++-------------- Cargo.toml | 2 +- openhcl/build_info/Cargo.toml | 2 +- openhcl/build_info/build.rs | 2 +- openhcl/build_info/src/lib.rs | 4 ++-- openhcl/underhill_crash/Cargo.toml | 2 +- openhcl/underhill_crash/build.rs | 2 +- openhcl/underhill_crash/src/lib.rs | 2 +- openhcl/underhill_init/Cargo.toml | 2 +- openhcl/underhill_init/build.rs | 2 +- openhcl/underhill_init/src/lib.rs | 4 ++-- support/build_rs_git_info/Cargo.toml | 10 ++++++++++ support/build_rs_git_info/src/lib.rs | 30 ++++++++++++++++++++++++++++ 13 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 support/build_rs_git_info/Cargo.toml create mode 100644 support/build_rs_git_info/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cb57afded0..b813477f68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,10 +401,14 @@ dependencies = [ name = "build_info" version = "0.0.0" dependencies = [ + "build_rs_git_info", "inspect", - "vergen", ] +[[package]] +name = "build_rs_git_info" +version = "0.0.0" + [[package]] name = "build_rs_guest_arch" version = "0.0.0" @@ -7575,7 +7579,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -8352,6 +8355,7 @@ name = "underhill_crash" version = "0.0.0" dependencies = [ "anyhow", + "build_rs_git_info", "fs-err", "futures", "get_protocol", @@ -8362,7 +8366,6 @@ dependencies = [ "tracing", "tracing-subscriber", "underhill_confidentiality", - "vergen", "vmbus_async", "vmbus_user_channel", "zerocopy", @@ -8400,13 +8403,13 @@ name = "underhill_init" version = "0.0.0" dependencies = [ "anyhow", + "build_rs_git_info", "fs-err", "kmsg_defs", "libc", "log", "nix 0.30.1", "underhill_confidentiality", - "vergen", "walkdir", ] @@ -8590,18 +8593,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vergen" -version = "8.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" -dependencies = [ - "anyhow", - "cfg-if", - "rustversion", - "time", -] - [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 735c7b45fa..91059cabad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -95,6 +95,7 @@ pipette_protocol = { path = "petri/pipette_protocol" } # support crates address_filter = { path = "support/address_filter" } +build_rs_git_info = { path = "support/build_rs_git_info" } arc_cyclic_builder = { path = "support/arc_cyclic_builder" } atomic_ringbuf = { path = "support/atomic_ringbuf" } cache_topology = { path = "support/cache_topology" } @@ -553,7 +554,6 @@ typed-path = "0.11" uefi = "0.35.0" unicycle = "0.10.2" urlencoding = "2.1.3" -vergen = "8.2" vfio-bindings = "0.4.0" walkdir = "2.3" wchar = "0.11" diff --git a/openhcl/build_info/Cargo.toml b/openhcl/build_info/Cargo.toml index 395fdeb7cf..7f302ce17f 100644 --- a/openhcl/build_info/Cargo.toml +++ b/openhcl/build_info/Cargo.toml @@ -10,7 +10,7 @@ rust-version.workspace = true inspect.workspace = true [build-dependencies] -vergen = { workspace = true, features = ["git", "gitcl"] } +build_rs_git_info.workspace = true [lints] workspace = true diff --git a/openhcl/build_info/build.rs b/openhcl/build_info/build.rs index 5a6d24149e..53bb245921 100644 --- a/openhcl/build_info/build.rs +++ b/openhcl/build_info/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - vergen::EmitBuilder::builder().all_git().emit().unwrap(); + build_rs_git_info::emit_git_info(); } diff --git a/openhcl/build_info/src/lib.rs b/openhcl/build_info/src/lib.rs index 7c0868d411..66596b7094 100644 --- a/openhcl/build_info/src/lib.rs +++ b/openhcl/build_info/src/lib.rs @@ -31,12 +31,12 @@ impl BuildInfo { // structure to be closer to PODs. Self { crate_name: env!("CARGO_PKG_NAME"), - revision: if let Some(r) = option_env!("VERGEN_GIT_SHA") { + revision: if let Some(r) = option_env!("BUILD_GIT_SHA") { r } else { "" }, - branch: if let Some(b) = option_env!("VERGEN_GIT_BRANCH") { + branch: if let Some(b) = option_env!("BUILD_GIT_BRANCH") { b } else { "" diff --git a/openhcl/underhill_crash/Cargo.toml b/openhcl/underhill_crash/Cargo.toml index 12f436e189..18f456effa 100644 --- a/openhcl/underhill_crash/Cargo.toml +++ b/openhcl/underhill_crash/Cargo.toml @@ -24,7 +24,7 @@ tracing-subscriber.workspace = true zerocopy.workspace = true [build-dependencies] -vergen = { workspace = true, features = ["git", "gitcl"] } +build_rs_git_info.workspace = true [lints] workspace = true diff --git a/openhcl/underhill_crash/build.rs b/openhcl/underhill_crash/build.rs index 5a6d24149e..53bb245921 100644 --- a/openhcl/underhill_crash/build.rs +++ b/openhcl/underhill_crash/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - vergen::EmitBuilder::builder().all_git().emit().unwrap(); + build_rs_git_info::emit_git_info(); } diff --git a/openhcl/underhill_crash/src/lib.rs b/openhcl/underhill_crash/src/lib.rs index 8a0e46b42a..402eb32f55 100644 --- a/openhcl/underhill_crash/src/lib.rs +++ b/openhcl/underhill_crash/src/lib.rs @@ -283,7 +283,7 @@ pub fn main() -> ! { let os_version = OsVersionInfo::new(); - let crate_revision = option_env!("VERGEN_GIT_SHA").unwrap_or("UNKNOWN_REVISION"); + let crate_revision = option_env!("BUILD_GIT_SHA").unwrap_or("UNKNOWN_REVISION"); let openhcl_version = option_env!("OPENHCL_VERSION").unwrap_or("UNKNOWN_VERSION"); let os_version_major = os_version.major(); diff --git a/openhcl/underhill_init/Cargo.toml b/openhcl/underhill_init/Cargo.toml index 8162fb32ab..d24da48313 100644 --- a/openhcl/underhill_init/Cargo.toml +++ b/openhcl/underhill_init/Cargo.toml @@ -19,7 +19,7 @@ nix = { workspace = true, features = ["ioctl"] } walkdir.workspace = true [build-dependencies] -vergen = { workspace = true, features = ["git", "gitcl"] } +build_rs_git_info.workspace = true [lints] workspace = true diff --git a/openhcl/underhill_init/build.rs b/openhcl/underhill_init/build.rs index 5a6d24149e..53bb245921 100644 --- a/openhcl/underhill_init/build.rs +++ b/openhcl/underhill_init/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - vergen::EmitBuilder::builder().all_git().emit().unwrap(); + build_rs_git_info::emit_git_info(); } diff --git a/openhcl/underhill_init/src/lib.rs b/openhcl/underhill_init/src/lib.rs index 0530183f90..0c29aa7eca 100644 --- a/openhcl/underhill_init/src/lib.rs +++ b/openhcl/underhill_init/src/lib.rs @@ -436,8 +436,8 @@ fn do_main() -> anyhow::Result<()> { log::info!( "Initial process: crate_name={}, crate_revision={}, crate_branch={}", env!("CARGO_PKG_NAME"), - option_env!("VERGEN_GIT_SHA").unwrap_or("UNKNOWN_REVISION"), - option_env!("VERGEN_GIT_BRANCH").unwrap_or("UNKNOWN_BRANCH"), + option_env!("BUILD_GIT_SHA").unwrap_or("UNKNOWN_REVISION"), + option_env!("BUILD_GIT_BRANCH").unwrap_or("UNKNOWN_BRANCH"), ); let stat_files = [ diff --git a/support/build_rs_git_info/Cargo.toml b/support/build_rs_git_info/Cargo.toml new file mode 100644 index 0000000000..1c723151df --- /dev/null +++ b/support/build_rs_git_info/Cargo.toml @@ -0,0 +1,10 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +[package] +name = "build_rs_git_info" +edition.workspace = true +rust-version.workspace = true + +[lints] +workspace = true diff --git a/support/build_rs_git_info/src/lib.rs b/support/build_rs_git_info/src/lib.rs new file mode 100644 index 0000000000..0fd4ffad06 --- /dev/null +++ b/support/build_rs_git_info/src/lib.rs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Build-script helper that emits `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` +//! cargo environment variables by invoking the `git` CLI. + +use std::process::Command; + +fn git_output(args: &[&str]) -> Option { + Command::new("git") + .args(args) + .output() + .ok() + .filter(|o| o.status.success()) + .and_then(|o| String::from_utf8(o.stdout).ok()) + .map(|s| s.trim().to_owned()) +} + +/// Emit `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` as `cargo:rustc-env` +/// variables so they are available via `env!()` / `option_env!()` in the +/// consuming crate. +pub fn emit_git_info() { + println!("cargo:rerun-if-changed=.git/HEAD"); + if let Some(sha) = git_output(&["rev-parse", "HEAD"]) { + println!("cargo:rustc-env=BUILD_GIT_SHA={sha}"); + } + if let Some(branch) = git_output(&["rev-parse", "--abbrev-ref", "HEAD"]) { + println!("cargo:rustc-env=BUILD_GIT_BRANCH={branch}"); + } +} From 58e5ded62603b9059a020492c56b91b1fec82e14 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Fri, 6 Mar 2026 16:38:35 -0500 Subject: [PATCH 2/4] Better errors --- Cargo.lock | 3 +++ openhcl/build_info/build.rs | 2 +- openhcl/underhill_crash/build.rs | 2 +- openhcl/underhill_init/build.rs | 2 +- support/build_rs_git_info/Cargo.toml | 3 +++ support/build_rs_git_info/src/lib.rs | 39 +++++++++++++++++----------- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b813477f68..dfd3278645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -408,6 +408,9 @@ dependencies = [ [[package]] name = "build_rs_git_info" version = "0.0.0" +dependencies = [ + "anyhow", +] [[package]] name = "build_rs_guest_arch" diff --git a/openhcl/build_info/build.rs b/openhcl/build_info/build.rs index 53bb245921..bf72c2b98e 100644 --- a/openhcl/build_info/build.rs +++ b/openhcl/build_info/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - build_rs_git_info::emit_git_info(); + build_rs_git_info::emit_git_info().unwrap(); } diff --git a/openhcl/underhill_crash/build.rs b/openhcl/underhill_crash/build.rs index 53bb245921..bf72c2b98e 100644 --- a/openhcl/underhill_crash/build.rs +++ b/openhcl/underhill_crash/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - build_rs_git_info::emit_git_info(); + build_rs_git_info::emit_git_info().unwrap(); } diff --git a/openhcl/underhill_init/build.rs b/openhcl/underhill_init/build.rs index 53bb245921..bf72c2b98e 100644 --- a/openhcl/underhill_init/build.rs +++ b/openhcl/underhill_init/build.rs @@ -4,5 +4,5 @@ #![expect(missing_docs)] fn main() { - build_rs_git_info::emit_git_info(); + build_rs_git_info::emit_git_info().unwrap(); } diff --git a/support/build_rs_git_info/Cargo.toml b/support/build_rs_git_info/Cargo.toml index 1c723151df..b95d1a0d5e 100644 --- a/support/build_rs_git_info/Cargo.toml +++ b/support/build_rs_git_info/Cargo.toml @@ -6,5 +6,8 @@ name = "build_rs_git_info" edition.workspace = true rust-version.workspace = true +[dependencies] +anyhow.workspace = true + [lints] workspace = true diff --git a/support/build_rs_git_info/src/lib.rs b/support/build_rs_git_info/src/lib.rs index 0fd4ffad06..7a7afd9e1f 100644 --- a/support/build_rs_git_info/src/lib.rs +++ b/support/build_rs_git_info/src/lib.rs @@ -4,27 +4,36 @@ //! Build-script helper that emits `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` //! cargo environment variables by invoking the `git` CLI. +use anyhow::Ok; use std::process::Command; -fn git_output(args: &[&str]) -> Option { - Command::new("git") - .args(args) - .output() - .ok() - .filter(|o| o.status.success()) - .and_then(|o| String::from_utf8(o.stdout).ok()) - .map(|s| s.trim().to_owned()) +fn git_output(args: &[&str]) -> anyhow::Result { + let output = Command::new("git").args(args).output()?; + + if !output.status.success() { + anyhow::bail!( + "git {:?} failed with code {:?}: {}", + args, + output.status.code(), + String::from_utf8_lossy(&output.stderr) + ); + } + + let output = String::from_utf8(output.stdout).unwrap().trim().to_owned(); + Ok(output) } /// Emit `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` as `cargo:rustc-env` /// variables so they are available via `env!()` / `option_env!()` in the /// consuming crate. -pub fn emit_git_info() { +pub fn emit_git_info() -> anyhow::Result<()> { println!("cargo:rerun-if-changed=.git/HEAD"); - if let Some(sha) = git_output(&["rev-parse", "HEAD"]) { - println!("cargo:rustc-env=BUILD_GIT_SHA={sha}"); - } - if let Some(branch) = git_output(&["rev-parse", "--abbrev-ref", "HEAD"]) { - println!("cargo:rustc-env=BUILD_GIT_BRANCH={branch}"); - } + + let sha = git_output(&["rev-parse", "HEAD"])?; + let branch = git_output(&["rev-parse", "--abbrev-ref", "HEAD"])?; + + println!("cargo:rustc-env=BUILD_GIT_SHA={sha}"); + println!("cargo:rustc-env=BUILD_GIT_BRANCH={branch}"); + + Ok(()) } From e16cb7faca1556aadff0eb131da3b6b135965684 Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Mon, 9 Mar 2026 13:07:23 -0400 Subject: [PATCH 3/4] cleanup --- support/build_rs_git_info/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/support/build_rs_git_info/src/lib.rs b/support/build_rs_git_info/src/lib.rs index 7a7afd9e1f..5a5e313fe7 100644 --- a/support/build_rs_git_info/src/lib.rs +++ b/support/build_rs_git_info/src/lib.rs @@ -4,7 +4,6 @@ //! Build-script helper that emits `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` //! cargo environment variables by invoking the `git` CLI. -use anyhow::Ok; use std::process::Command; fn git_output(args: &[&str]) -> anyhow::Result { From c432f7dfa82b64e055f7ba793108fdb7f735e55c Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Mon, 9 Mar 2026 13:22:31 -0400 Subject: [PATCH 4/4] Fix rerun on changed --- support/build_rs_git_info/src/lib.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/support/build_rs_git_info/src/lib.rs b/support/build_rs_git_info/src/lib.rs index 5a5e313fe7..8a856f158f 100644 --- a/support/build_rs_git_info/src/lib.rs +++ b/support/build_rs_git_info/src/lib.rs @@ -22,11 +22,25 @@ fn git_output(args: &[&str]) -> anyhow::Result { Ok(output) } -/// Emit `BUILD_GIT_SHA` and `BUILD_GIT_BRANCH` as `cargo:rustc-env` -/// variables so they are available via `env!()` / `option_env!()` in the -/// consuming crate. +fn git_path(args: &[&str]) -> anyhow::Result { + let output = git_output(args)?; + Ok(std::path::absolute(&output)?) +} + +/// Emit git information as `cargo:rustc-env` variables so they are available via +/// `env!()` / `option_env!()` in the consuming crate. pub fn emit_git_info() -> anyhow::Result<()> { - println!("cargo:rerun-if-changed=.git/HEAD"); + // Always rerun when HEAD changes (e.g. branch switch). + let head_path = git_path(&["rev-parse", "--git-path", "HEAD"])?; + println!("cargo:rerun-if-changed={}", head_path.display()); + + // If HEAD is a symbolic ref (i.e. points at a branch), also watch the + // branch ref file so we rebuild when new commits land on that branch. + if let Ok(head_ref) = git_output(&["symbolic-ref", "HEAD"]) { + // e.g. refs/heads/main → .git/refs/heads/main (or the worktree equivalent) + let ref_path = git_path(&["rev-parse", "--git-path", &head_ref])?; + println!("cargo:rerun-if-changed={}", ref_path.display()); + } let sha = git_output(&["rev-parse", "HEAD"])?; let branch = git_output(&["rev-parse", "--abbrev-ref", "HEAD"])?;