@@ -12,13 +12,12 @@ use std::fs;
12
12
use std:: path:: { Path , PathBuf } ;
13
13
use std:: sync:: OnceLock ;
14
14
15
- use build_helper:: ci:: CiEnv ;
16
-
17
15
use crate :: core:: builder:: { Builder , Cargo , Kind , RunConfig , ShouldRun , Step } ;
18
16
use crate :: core:: config:: TargetSelection ;
19
17
use crate :: utils:: build_stamp:: { BuildStamp , generate_smart_stamp_hash} ;
20
18
use crate :: utils:: exec:: command;
21
19
use crate :: utils:: helpers:: { self , t} ;
20
+ use build_helper:: ci:: CiEnv ;
22
21
23
22
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
24
23
pub struct Gcc {
@@ -106,18 +105,30 @@ fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<Pa
106
105
eprintln ! ( "GCC CI download is only available for the `x86_64-unknown-linux-gnu` target" ) ;
107
106
return None ;
108
107
}
109
- let sha =
110
- detect_gcc_sha ( & builder. config , builder. config . rust_info . is_managed_git_subrepository ( ) ) ;
111
- let root = ci_gcc_root ( & builder. config ) ;
112
- let gcc_stamp = BuildStamp :: new ( & root) . with_prefix ( "gcc" ) . add_stamp ( & sha) ;
113
- if !gcc_stamp. is_up_to_date ( ) && !builder. config . dry_run ( ) {
114
- builder. config . download_ci_gcc ( & sha, & root) ;
115
- t ! ( gcc_stamp. write( ) ) ;
108
+ let source = detect_gcc_freshness (
109
+ & builder. config ,
110
+ builder. config . rust_info . is_managed_git_subrepository ( ) ,
111
+ ) ;
112
+ match source {
113
+ PathFreshness :: LastModifiedUpstream { upstream } => {
114
+ // Download from upstream CI
115
+ let root = ci_gcc_root ( & builder. config ) ;
116
+ let gcc_stamp = BuildStamp :: new ( & root) . with_prefix ( "gcc" ) . add_stamp ( & upstream) ;
117
+ if !gcc_stamp. is_up_to_date ( ) && !builder. config . dry_run ( ) {
118
+ builder. config . download_ci_gcc ( & upstream, & root) ;
119
+ t ! ( gcc_stamp. write( ) ) ;
120
+ }
121
+
122
+ let libgccjit = root. join ( "lib" ) . join ( "libgccjit.so" ) ;
123
+ create_lib_alias ( builder, & libgccjit) ;
124
+ Some ( libgccjit)
125
+ }
126
+ PathFreshness :: HasLocalModifications { .. } => {
127
+ // We have local modifications, rebuild GCC.
128
+ eprintln ! ( "Found local GCC modifications, GCC will *not* be downloaded" ) ;
129
+ None
130
+ }
116
131
}
117
-
118
- let libgccjit = root. join ( "lib" ) . join ( "libgccjit.so" ) ;
119
- create_lib_alias ( builder, & libgccjit) ;
120
- Some ( libgccjit)
121
132
}
122
133
123
134
#[ cfg( test) ]
@@ -266,31 +277,34 @@ fn ci_gcc_root(config: &crate::Config) -> PathBuf {
266
277
config. out . join ( config. build ) . join ( "ci-gcc" )
267
278
}
268
279
269
- /// This retrieves the GCC sha we *want* to use, according to git history .
280
+ /// Detect whether GCC sources have been modified locally or not .
270
281
#[ cfg( not( test) ) ]
271
- fn detect_gcc_sha ( config : & crate :: Config , is_git : bool ) -> String {
272
- use build_helper:: git:: get_closest_merge_commit;
273
-
274
- let gcc_sha = if is_git {
275
- get_closest_merge_commit (
276
- Some ( & config. src ) ,
277
- & config. git_config ( ) ,
278
- & [ config. src . join ( "src/gcc" ) , config. src . join ( "src/bootstrap/download-ci-gcc-stamp" ) ] ,
282
+ fn detect_gcc_freshness ( config : & crate :: Config , is_git : bool ) -> build_helper:: git:: PathFreshness {
283
+ use build_helper:: git:: { PathFreshness , check_path_modifications} ;
284
+
285
+ let freshness = if is_git {
286
+ Some (
287
+ check_path_modifications (
288
+ Some ( & config. src ) ,
289
+ & config. git_config ( ) ,
290
+ & [ "src/gcc" , "src/bootstrap/download-ci-gcc-stamp" ] ,
291
+ CiEnv :: current ( ) ,
292
+ )
293
+ . unwrap ( ) ,
279
294
)
280
- . unwrap ( )
281
295
} else if let Some ( info) = crate :: utils:: channel:: read_commit_info_file ( & config. src ) {
282
- info. sha . trim ( ) . to_owned ( )
296
+ Some ( PathFreshness :: LastModifiedUpstream { upstream : info. sha . trim ( ) . to_owned ( ) } )
283
297
} else {
284
- "" . to_owned ( )
298
+ None
285
299
} ;
286
300
287
- if gcc_sha . is_empty ( ) {
301
+ let Some ( freshness ) = freshness else {
288
302
eprintln ! ( "error: could not find commit hash for downloading GCC" ) ;
289
303
eprintln ! ( "HELP: maybe your repository history is too shallow?" ) ;
290
304
eprintln ! ( "HELP: consider disabling `download-ci-gcc`" ) ;
291
305
eprintln ! ( "HELP: or fetch enough history to include one upstream commit" ) ;
292
306
panic ! ( ) ;
293
- }
307
+ } ;
294
308
295
- gcc_sha
309
+ freshness
296
310
}
0 commit comments