about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2025-03-21 22:23:37 +0100
committerJakub Beránek <berykubik@gmail.com>2025-04-20 09:13:55 +0200
commit0396f0e522c07fc208dc4244b752ef571d6ce7d2 (patch)
treedb2f9381497a31e7dca516ca97a18080796d2997
parent1d1f248093289cb9cc2a3ae9b451f47895f2ba7f (diff)
downloadrust-0396f0e522c07fc208dc4244b752ef571d6ce7d2.tar.gz
rust-0396f0e522c07fc208dc4244b752ef571d6ce7d2.zip
Use `check_path_modifications` for detecting local LLVM changes
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs29
-rw-r--r--src/bootstrap/src/core/config/config.rs19
-rw-r--r--src/bootstrap/src/core/download.rs9
-rw-r--r--src/build_helper/src/git.rs5
-rw-r--r--src/build_helper/src/git/tests.rs5
6 files changed, 50 insertions, 20 deletions
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index ec7c78da50d..867874fc7cc 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -17,7 +17,6 @@ use crate::core::config::TargetSelection;
 use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
 use crate::utils::exec::command;
 use crate::utils::helpers::{self, t};
-use build_helper::git::PathFreshness;
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Gcc {
@@ -97,6 +96,8 @@ pub enum GccBuildStatus {
 /// Returns a path to the libgccjit.so file.
 #[cfg(not(test))]
 fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<PathBuf> {
+    use build_helper::git::PathFreshness;
+
     // Try to download GCC from CI if configured and available
     if !matches!(builder.config.gcc_ci_mode, crate::core::config::GccCiMode::DownloadFromCi) {
         return None;
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 6f6839ad15b..6e695ee1e7c 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -14,7 +14,7 @@ use std::path::{Path, PathBuf};
 use std::sync::OnceLock;
 use std::{env, fs};
 
-use build_helper::git::get_closest_merge_commit;
+use build_helper::git::{PathFreshness, check_path_modifications};
 #[cfg(feature = "tracing")]
 use tracing::instrument;
 
@@ -181,26 +181,33 @@ pub const LLVM_INVALIDATION_PATHS: &[&str] = &[
     "src/version",
 ];
 
-/// This retrieves the LLVM sha we *want* to use, according to git history.
-pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
-    let llvm_sha = if is_git {
-        get_closest_merge_commit(Some(&config.src), &config.git_config(), LLVM_INVALIDATION_PATHS)
-            .unwrap()
+/// Detect whether LLVM sources have been modified locally or not.
+pub(crate) fn detect_llvm_freshness(config: &Config, is_git: bool) -> PathFreshness {
+    let freshness = if is_git {
+        Some(
+            check_path_modifications(
+                Some(&config.src),
+                &config.git_config(),
+                LLVM_INVALIDATION_PATHS,
+                config.ci_env(),
+            )
+            .unwrap(),
+        )
     } else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) {
-        info.sha.trim().to_owned()
+        Some(PathFreshness::LastModifiedUpstream { upstream: info.sha.trim().to_owned() })
     } else {
-        "".to_owned()
+        None
     };
 
-    if llvm_sha.is_empty() {
+    let Some(freshness) = freshness else {
         eprintln!("error: could not find commit hash for downloading LLVM");
         eprintln!("HELP: maybe your repository history is too shallow?");
         eprintln!("HELP: consider disabling `download-ci-llvm`");
         eprintln!("HELP: or fetch enough history to include one upstream commit");
         panic!();
-    }
+    };
 
-    llvm_sha
+    freshness
 }
 
 /// Returns whether the CI-found LLVM is currently usable.
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 145badadb95..20062e5f9bc 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -16,7 +16,9 @@ use std::{cmp, env, fs};
 
 use build_helper::ci::CiEnv;
 use build_helper::exit;
-use build_helper::git::{GitConfig, get_closest_merge_commit, output_result};
+use build_helper::git::{
+    GitConfig, PathFreshness, check_path_modifications, get_closest_merge_commit, output_result,
+};
 use serde::{Deserialize, Deserializer};
 use serde_derive::Deserialize;
 #[cfg(feature = "tracing")]
@@ -3264,9 +3266,7 @@ impl Config {
             self.update_submodule("src/llvm-project");
 
             // Check for untracked changes in `src/llvm-project` and other important places.
-            let has_changes = self
-                .last_modified_commit(LLVM_INVALIDATION_PATHS, "download-ci-llvm", true)
-                .is_none();
+            let has_changes = self.has_changes_from_upstream(LLVM_INVALIDATION_PATHS);
 
             // Return false if there are untracked changes, otherwise check if CI LLVM is available.
             if has_changes { false } else { llvm::is_ci_llvm_available_for_target(self, asserts) }
@@ -3297,6 +3297,17 @@ impl Config {
         }
     }
 
+    /// Returns true if any of the `paths` have been modified locally.
+    fn has_changes_from_upstream(&self, paths: &[&str]) -> bool {
+        let freshness =
+            check_path_modifications(Some(&self.src), &self.git_config(), paths, CiEnv::current())
+                .unwrap();
+        match freshness {
+            PathFreshness::LastModifiedUpstream { .. } => false,
+            PathFreshness::HasLocalModifications { .. } => true,
+        }
+    }
+
     /// Returns the last commit in which any of `modified_paths` were changed,
     /// or `None` if there are untracked changes in the working directory and `if_unchanged` is true.
     pub fn last_modified_commit(
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 4e4b948a8fd..3c9cfead5a9 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -720,8 +720,9 @@ download-rustc = false
     #[cfg(not(test))]
     pub(crate) fn maybe_download_ci_llvm(&self) {
         use build_helper::exit;
+        use build_helper::git::PathFreshness;
 
-        use crate::core::build_steps::llvm::detect_llvm_sha;
+        use crate::core::build_steps::llvm::detect_llvm_freshness;
         use crate::core::config::check_incompatible_options_for_ci_llvm;
 
         if !self.llvm_from_ci {
@@ -729,7 +730,11 @@ download-rustc = false
         }
 
         let llvm_root = self.ci_llvm_root();
-        let llvm_sha = detect_llvm_sha(self, self.rust_info.is_managed_git_subrepository());
+        let llvm_sha =
+            match detect_llvm_freshness(self, self.rust_info.is_managed_git_subrepository()) {
+                PathFreshness::LastModifiedUpstream { upstream } => upstream,
+                PathFreshness::HasLocalModifications { upstream } => upstream,
+            };
         let stamp_key = format!("{}{}", llvm_sha, self.llvm_assertions);
         let llvm_stamp = BuildStamp::new(&llvm_root).with_prefix("llvm").add_stamp(stamp_key);
         if !llvm_stamp.is_up_to_date() && !self.dry_run() {
diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs
index e1e7319b9aa..fce3a8eca9b 100644
--- a/src/build_helper/src/git.rs
+++ b/src/build_helper/src/git.rs
@@ -261,6 +261,11 @@ pub fn check_path_modifications(
         upstream_sha
     };
 
+    // For local environments, we want to find out if something has changed
+    // from the latest upstream commit.
+    // However, that should be equivalent to checking if something has changed
+    // from the latest upstream commit *that modified `target_paths`*, and
+    // with this approach we do not need to invoke git an additional time.
     if has_changed_since(git_dir, &upstream_sha, target_paths) {
         Ok(PathFreshness::HasLocalModifications { upstream: upstream_sha })
     } else {
diff --git a/src/build_helper/src/git/tests.rs b/src/build_helper/src/git/tests.rs
index cdf50e14218..cc502f08387 100644
--- a/src/build_helper/src/git/tests.rs
+++ b/src/build_helper/src/git/tests.rs
@@ -1,9 +1,10 @@
-use crate::ci::CiEnv;
-use crate::git::{GitConfig, PathFreshness, check_path_modifications};
 use std::ffi::OsStr;
 use std::fs::OpenOptions;
 use std::process::Command;
 
+use crate::ci::CiEnv;
+use crate::git::{GitConfig, PathFreshness, check_path_modifications};
+
 #[test]
 fn test_pr_ci_unchanged_anywhere() {
     git_test(|ctx| {