about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2025-03-16 17:44:07 +0100
committerJakub Beránek <berykubik@gmail.com>2025-04-20 09:13:29 +0200
commit1d1f248093289cb9cc2a3ae9b451f47895f2ba7f (patch)
tree9d6cc3d9682b302177fc44d546d0dc473502503a /src/bootstrap
parent082ab9c6d89071f2907cae69d45b06a4a6696004 (diff)
Use `check_path_modifications` for detecting local GCC changes
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/src/core/build_steps/gcc.rs68
-rw-r--r--src/bootstrap/src/core/config/config.rs4
2 files changed, 46 insertions, 26 deletions
diff --git a/src/bootstrap/src/core/build_steps/gcc.rs b/src/bootstrap/src/core/build_steps/gcc.rs
index 48bb5cb8e87..ec7c78da50d 100644
--- a/src/bootstrap/src/core/build_steps/gcc.rs
+++ b/src/bootstrap/src/core/build_steps/gcc.rs
@@ -17,6 +17,7 @@ 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 {
@@ -104,18 +105,30 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<Pa
         eprintln!("GCC CI download is only available for the `x86_64-unknown-linux-gnu` target");
         return None;
     }
-    let sha =
-        detect_gcc_sha(&builder.config, builder.config.rust_info.is_managed_git_subrepository());
-    let root = ci_gcc_root(&builder.config);
-    let gcc_stamp = BuildStamp::new(&root).with_prefix("gcc").add_stamp(&sha);
-    if !gcc_stamp.is_up_to_date() && !builder.config.dry_run() {
-        builder.config.download_ci_gcc(&sha, &root);
-        t!(gcc_stamp.write());
+    let source = detect_gcc_freshness(
+        &builder.config,
+        builder.config.rust_info.is_managed_git_subrepository(),
+    );
+    match source {
+        PathFreshness::LastModifiedUpstream { upstream } => {
+            // Download from upstream CI
+            let root = ci_gcc_root(&builder.config);
+            let gcc_stamp = BuildStamp::new(&root).with_prefix("gcc").add_stamp(&upstream);
+            if !gcc_stamp.is_up_to_date() && !builder.config.dry_run() {
+                builder.config.download_ci_gcc(&upstream, &root);
+                t!(gcc_stamp.write());
+            }
+
+            let libgccjit = root.join("lib").join("libgccjit.so");
+            create_lib_alias(builder, &libgccjit);
+            Some(libgccjit)
+        }
+        PathFreshness::HasLocalModifications { .. } => {
+            // We have local modifications, rebuild GCC.
+            eprintln!("Found local GCC modifications, GCC will *not* be downloaded");
+            None
+        }
     }
-
-    let libgccjit = root.join("lib").join("libgccjit.so");
-    create_lib_alias(builder, &libgccjit);
-    Some(libgccjit)
 }
 
 #[cfg(test)]
@@ -264,31 +277,34 @@ fn ci_gcc_root(config: &crate::Config) -> PathBuf {
     config.out.join(config.build).join("ci-gcc")
 }
 
-/// This retrieves the GCC sha we *want* to use, according to git history.
+/// Detect whether GCC sources have been modified locally or not.
 #[cfg(not(test))]
-fn detect_gcc_sha(config: &crate::Config, is_git: bool) -> String {
-    use build_helper::git::get_closest_merge_commit;
-
-    let gcc_sha = if is_git {
-        get_closest_merge_commit(
-            Some(&config.src),
-            &config.git_config(),
-            &["src/gcc", "src/bootstrap/download-ci-gcc-stamp"],
+fn detect_gcc_freshness(config: &crate::Config, is_git: bool) -> build_helper::git::PathFreshness {
+    use build_helper::git::{PathFreshness, check_path_modifications};
+
+    let freshness = if is_git {
+        Some(
+            check_path_modifications(
+                Some(&config.src),
+                &config.git_config(),
+                &["src/gcc", "src/bootstrap/download-ci-gcc-stamp"],
+                config.ci_env(),
+            )
+            .unwrap(),
         )
-        .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 gcc_sha.is_empty() {
+    let Some(freshness) = freshness else {
         eprintln!("error: could not find commit hash for downloading GCC");
         eprintln!("HELP: maybe your repository history is too shallow?");
         eprintln!("HELP: consider disabling `download-ci-gcc`");
         eprintln!("HELP: or fetch enough history to include one upstream commit");
         panic!();
-    }
+    };
 
-    gcc_sha
+    freshness
 }
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 43b62789536..145badadb95 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -3379,6 +3379,10 @@ impl Config {
             _ => !self.is_system_llvm(target),
         }
     }
+
+    pub fn ci_env(&self) -> CiEnv {
+        if self.is_running_on_ci { CiEnv::GitHubActions } else { CiEnv::None }
+    }
 }
 
 /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options.