@@ -947,7 +947,14 @@ impl Config {
947
947
) ;
948
948
}
949
949
950
- config. download_rustc_commit = config. download_ci_rustc_commit (
950
+ config. download_rustc_commit = download_ci_rustc_commit (
951
+ & config. stage0_metadata ,
952
+ config. path_modification_cache . clone ( ) ,
953
+ & config. src ,
954
+ config. is_running_on_ci ,
955
+ & config. exec_ctx ,
956
+ & config. rust_info ,
957
+ & config. host_target ,
951
958
rust_download_rustc,
952
959
debug_assertions_requested,
953
960
config. llvm_assertions ,
@@ -2340,3 +2347,123 @@ pub fn check_stage0_version(
2340
2347
) ) ;
2341
2348
}
2342
2349
}
2350
+
2351
+ pub fn download_ci_rustc_commit (
2352
+ stage0_metadata : & build_helper:: stage0_parser:: Stage0 ,
2353
+ path_modification_cache : Arc < Mutex < HashMap < Vec < & ' static str > , PathFreshness > > > ,
2354
+ src : & Path ,
2355
+ is_running_on_ci : bool ,
2356
+ exec_ctx : & ExecutionContext ,
2357
+ rust_info : & channel:: GitInfo ,
2358
+ host_target : & TargetSelection ,
2359
+ download_rustc : Option < StringOrBool > ,
2360
+ debug_assertions_requested : bool ,
2361
+ llvm_assertions : bool ,
2362
+ ) -> Option < String > {
2363
+ if !is_download_ci_available ( & host_target. triple , llvm_assertions) {
2364
+ return None ;
2365
+ }
2366
+
2367
+ // If `download-rustc` is not set, default to rebuilding.
2368
+ let if_unchanged = match download_rustc {
2369
+ // Globally default `download-rustc` to `false`, because some contributors don't use
2370
+ // profiles for reasons such as:
2371
+ // - They need to seamlessly switch between compiler/library work.
2372
+ // - They don't want to use compiler profile because they need to override too many
2373
+ // things and it's easier to not use a profile.
2374
+ None | Some ( StringOrBool :: Bool ( false ) ) => return None ,
2375
+ Some ( StringOrBool :: Bool ( true ) ) => false ,
2376
+ Some ( StringOrBool :: String ( s) ) if s == "if-unchanged" => {
2377
+ if !rust_info. is_managed_git_subrepository ( ) {
2378
+ println ! (
2379
+ "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources."
2380
+ ) ;
2381
+ crate :: exit!( 1 ) ;
2382
+ }
2383
+
2384
+ true
2385
+ }
2386
+ Some ( StringOrBool :: String ( other) ) => {
2387
+ panic ! ( "unrecognized option for download-rustc: {other}" )
2388
+ }
2389
+ } ;
2390
+
2391
+ let commit = if rust_info. is_managed_git_subrepository ( ) {
2392
+ // Look for a version to compare to based on the current commit.
2393
+ // Only commits merged by bors will have CI artifacts.
2394
+ let freshness = check_path_modifications_ (
2395
+ stage0_metadata,
2396
+ src,
2397
+ path_modification_cache,
2398
+ RUSTC_IF_UNCHANGED_ALLOWED_PATHS ,
2399
+ ) ;
2400
+ exec_ctx. verbose ( || {
2401
+ eprintln ! ( "rustc freshness: {freshness:?}" ) ;
2402
+ } ) ;
2403
+ match freshness {
2404
+ PathFreshness :: LastModifiedUpstream { upstream } => upstream,
2405
+ PathFreshness :: HasLocalModifications { upstream } => {
2406
+ if if_unchanged {
2407
+ return None ;
2408
+ }
2409
+
2410
+ if is_running_on_ci {
2411
+ eprintln ! ( "CI rustc commit matches with HEAD and we are in CI." ) ;
2412
+ eprintln ! (
2413
+ "`rustc.download-ci` functionality will be skipped as artifacts are not available."
2414
+ ) ;
2415
+ return None ;
2416
+ }
2417
+
2418
+ upstream
2419
+ }
2420
+ PathFreshness :: MissingUpstream => {
2421
+ eprintln ! ( "No upstream commit found" ) ;
2422
+ return None ;
2423
+ }
2424
+ }
2425
+ } else {
2426
+ channel:: read_commit_info_file ( src)
2427
+ . map ( |info| info. sha . trim ( ) . to_owned ( ) )
2428
+ . expect ( "git-commit-info is missing in the project root" )
2429
+ } ;
2430
+
2431
+ if debug_assertions_requested {
2432
+ eprintln ! (
2433
+ "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \
2434
+ rustc is not currently built with debug assertions."
2435
+ ) ;
2436
+ return None ;
2437
+ }
2438
+
2439
+ Some ( commit)
2440
+ }
2441
+
2442
+ pub fn check_path_modifications_ (
2443
+ stage0_metadata : & build_helper:: stage0_parser:: Stage0 ,
2444
+ src : & Path ,
2445
+ path_modification_cache : Arc < Mutex < HashMap < Vec < & ' static str > , PathFreshness > > > ,
2446
+ paths : & [ & ' static str ] ,
2447
+ ) -> PathFreshness {
2448
+ // Checking path modifications through git can be relatively expensive (>100ms).
2449
+ // We do not assume that the sources would change during bootstrap's execution,
2450
+ // so we can cache the results here.
2451
+ // Note that we do not use a static variable for the cache, because it would cause problems
2452
+ // in tests that create separate `Config` instsances.
2453
+ path_modification_cache
2454
+ . lock ( )
2455
+ . unwrap ( )
2456
+ . entry ( paths. to_vec ( ) )
2457
+ . or_insert_with ( || {
2458
+ check_path_modifications ( src, & git_config ( stage0_metadata) , paths, CiEnv :: current ( ) )
2459
+ . unwrap ( )
2460
+ } )
2461
+ . clone ( )
2462
+ }
2463
+
2464
+ pub fn git_config ( stage0_metadata : & build_helper:: stage0_parser:: Stage0 ) -> GitConfig < ' _ > {
2465
+ GitConfig {
2466
+ nightly_branch : & stage0_metadata. config . nightly_branch ,
2467
+ git_merge_commit_email : & stage0_metadata. config . git_merge_commit_email ,
2468
+ }
2469
+ }
0 commit comments