@@ -199,16 +199,6 @@ impl Step for Std {
199199
200200 builder. require_submodule ( "library/stdarch" , None ) ;
201201
202- // Profiler information requires LLVM's compiler-rt
203- if builder. config . profiler {
204- builder. require_submodule (
205- "src/llvm-project" ,
206- Some (
207- "The `build.profiler` config option requires `compiler-rt` sources from LLVM." ,
208- ) ,
209- ) ;
210- }
211-
212202 let mut target_deps = builder. ensure ( StartupObjects { compiler, target } ) ;
213203
214204 let compiler_to_use = builder. compiler_for ( compiler. stage , compiler. host , target) ;
@@ -466,15 +456,51 @@ pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> {
466456 }
467457}
468458
459+ /// Tries to find LLVM's `compiler-rt` source directory, for building `library/profiler_builtins`.
460+ ///
461+ /// Normally it lives in the `src/llvm-project` submodule, but if that submodule
462+ /// is absent and we have downloaded a copy of CI LLVM, then we try to use the
463+ /// `compiler-rt` sources from there instead, which lets us avoid checking out
464+ /// the LLVM submodule.
465+ fn compiler_rt_for_profiler ( builder : & Builder < ' _ > ) -> PathBuf {
466+ // If the LLVM submodule is already active, just update it and use that.
467+ builder. update_existing_submodule ( "src/llvm-project" ) ;
468+ let submodule_compiler_rt = builder. src . join ( "src/llvm-project/compiler-rt" ) ;
469+ if submodule_compiler_rt. exists ( ) {
470+ return submodule_compiler_rt;
471+ }
472+
473+ // Try to use `compiler-rt` sources from downloaded CI LLVM, if possible.
474+ if builder. config . llvm_from_ci {
475+ let ci_llvm_compiler_rt = builder. config . ci_llvm_root ( ) . join ( "compiler-rt" ) ;
476+ if ci_llvm_compiler_rt. exists ( ) {
477+ return ci_llvm_compiler_rt;
478+ }
479+ }
480+
481+ // Otherwise, fall back to requiring the LLVM submodule.
482+ builder. require_submodule ( "src/llvm-project" , {
483+ Some ( "The `build.profiler` config option requires `compiler-rt` sources from LLVM." )
484+ } ) ;
485+ submodule_compiler_rt
486+ }
487+
469488/// Configure cargo to compile the standard library, adding appropriate env vars
470489/// and such.
471490pub fn std_cargo ( builder : & Builder < ' _ > , target : TargetSelection , stage : u32 , cargo : & mut Cargo ) {
472491 if let Some ( target) = env:: var_os ( "MACOSX_STD_DEPLOYMENT_TARGET" ) {
473492 cargo. env ( "MACOSX_DEPLOYMENT_TARGET" , target) ;
474493 }
475494
495+ // Paths needed by `library/profiler_builtins/build.rs`.
476496 if let Some ( path) = builder. config . profiler_path ( target) {
477497 cargo. env ( "LLVM_PROFILER_RT_LIB" , path) ;
498+ } else if builder. config . profiler_enabled ( target) {
499+ let compiler_rt = compiler_rt_for_profiler ( builder) ;
500+ // Currently this is separate from the env var used by `compiler_builtins`
501+ // (below) so that adding support for CI LLVM here doesn't risk breaking
502+ // the compiler builtins. But they could be unified if desired.
503+ cargo. env ( "RUST_COMPILER_RT_FOR_PROFILER" , compiler_rt) ;
478504 }
479505
480506 // Determine if we're going to compile in optimized C intrinsics to
@@ -507,8 +533,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
507533 ) ;
508534 let compiler_builtins_root = builder. src . join ( "src/llvm-project/compiler-rt" ) ;
509535 assert ! ( compiler_builtins_root. exists( ) ) ;
510- // Note that `libprofiler_builtins/build.rs` also computes this so if
511- // you're changing something here please also change that.
536+ // The path to `compiler-rt` is also used by `profiler_builtins` (above),
537+ // so if you're changing something here please also change that as appropriate .
512538 cargo. env ( "RUST_COMPILER_RT_ROOT" , & compiler_builtins_root) ;
513539 " compiler-builtins-c"
514540 } else {
0 commit comments