From bd752e9920285566d4d0b9e453109e7c3b5283e1 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 30 Apr 2024 10:44:27 +0200 Subject: [PATCH] add support for reading git-commit-info --- build.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/build.rs b/build.rs index 186e8151d65..9b1e2662eaf 100644 --- a/build.rs +++ b/build.rs @@ -80,6 +80,37 @@ fn commit_info_from_git() -> Option { }) } +// The rustc source tarball is meant to contain all the source code to build an exact copy of the +// toolchain, but it doesn't include the git repository itself. It wouldn't thus be possible to +// populate the version information with the commit hash and the commit date. +// +// To work around this, the rustc build process obtains the git information when creating the +// source tarball and writes it to the `git-commit-info` file. The build process actually creates +// at least *two* of those files, one for Rust as a whole (in the root of the tarball) and one +// specifically for Cargo (in src/tools/cargo). This function loads that file. +// +// The file is a newline-separated list of full commit hash, short commit hash, and commit date. +fn commit_info_from_rustc_source_tarball() -> Option { + let path = Path::new("git-commit-info"); + if !path.exists() { + return None; + } + + // Dependency tracking is a nice to have for this (git doesn't do it), so if the path is not + // valid UTF-8 just avoid doing it rather than erroring out. + if let Some(utf8) = path.to_str() { + println!("cargo:rerun-if-changed={utf8}"); + } + + let content = std::fs::read_to_string(&path).ok()?; + let mut parts = content.split('\n').map(|s| s.to_string()); + Some(CommitInfo { + hash: parts.next()?, + short_hash: parts.next()?, + date: parts.next()?, + }) +} + fn commit_info() { // Var set by bootstrap whenever omit-git-hash is enabled in rust-lang/rust's config.toml. println!("cargo:rerun-if-env-changed=CFG_OMIT_GIT_HASH"); @@ -89,7 +120,7 @@ fn commit_info() { return; } - let Some(git) = commit_info_from_git() else { + let Some(git) = commit_info_from_git().or_else(commit_info_from_rustc_source_tarball) else { return; };