@@ -18,7 +18,7 @@ use serde_derive::Deserialize;
1818#[ cfg( feature = "tracing" ) ]
1919use tracing:: { instrument, span} ;
2020
21- use crate :: core:: build_steps:: gcc:: { Gcc , add_cg_gcc_cargo_flags} ;
21+ use crate :: core:: build_steps:: gcc:: { Gcc , GccOutput , add_cg_gcc_cargo_flags} ;
2222use crate :: core:: build_steps:: tool:: { RustcPrivateCompilers , SourceType , copy_lld_artifacts} ;
2323use crate :: core:: build_steps:: { dist, llvm} ;
2424use crate :: core:: builder;
@@ -1543,13 +1543,22 @@ impl Step for RustcLink {
15431543 }
15441544}
15451545
1546+ /// Output of the `compile::GccCodegenBackend` step.
1547+ /// It includes the path to the libgccjit library on which this backend depends.
1548+ #[ derive( Clone ) ]
1549+ pub struct GccCodegenBackendOutput {
1550+ stamp : BuildStamp ,
1551+ gcc : GccOutput ,
1552+ }
1553+
15461554#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
15471555pub struct GccCodegenBackend {
15481556 compilers : RustcPrivateCompilers ,
15491557}
15501558
15511559impl Step for GccCodegenBackend {
1552- type Output = BuildStamp ;
1560+ type Output = GccCodegenBackendOutput ;
1561+
15531562 const ONLY_HOSTS : bool = true ;
15541563
15551564 fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
@@ -1584,6 +1593,8 @@ impl Step for GccCodegenBackend {
15841593 & CodegenBackendKind :: Gcc ,
15851594 ) ;
15861595
1596+ let gcc = builder. ensure ( Gcc { target } ) ;
1597+
15871598 if builder. config . keep_stage . contains ( & build_compiler. stage ) {
15881599 trace ! ( "`keep-stage` requested" ) ;
15891600 builder. info (
@@ -1592,7 +1603,7 @@ impl Step for GccCodegenBackend {
15921603 ) ;
15931604 // Codegen backends are linked separately from this step today, so we don't do
15941605 // anything here.
1595- return stamp;
1606+ return GccCodegenBackendOutput { stamp, gcc } ;
15961607 }
15971608
15981609 let mut cargo = builder:: Cargo :: new (
@@ -1606,13 +1617,16 @@ impl Step for GccCodegenBackend {
16061617 cargo. arg ( "--manifest-path" ) . arg ( builder. src . join ( "compiler/rustc_codegen_gcc/Cargo.toml" ) ) ;
16071618 rustc_cargo_env ( builder, & mut cargo, target) ;
16081619
1609- let gcc = builder. ensure ( Gcc { target } ) ;
16101620 add_cg_gcc_cargo_flags ( & mut cargo, & gcc) ;
16111621
16121622 let _guard =
16131623 builder. msg ( Kind :: Build , "codegen backend gcc" , Mode :: Codegen , build_compiler, target) ;
16141624 let files = run_cargo ( builder, cargo, vec ! [ ] , & stamp, vec ! [ ] , false , false ) ;
1615- write_codegen_backend_stamp ( stamp, files, builder. config . dry_run ( ) )
1625+
1626+ GccCodegenBackendOutput {
1627+ stamp : write_codegen_backend_stamp ( stamp, files, builder. config . dry_run ( ) ) ,
1628+ gcc,
1629+ }
16161630 }
16171631
16181632 fn metadata ( & self ) -> Option < StepMetadata > {
@@ -2191,53 +2205,6 @@ impl Step for Assemble {
21912205 ) ;
21922206 build_compiler. stage = actual_stage;
21932207
2194- let mut codegen_backend_stamps = vec ! [ ] ;
2195- {
2196- #[ cfg( feature = "tracing" ) ]
2197- let _codegen_backend_span =
2198- span ! ( tracing:: Level :: DEBUG , "building requested codegen backends" ) . entered ( ) ;
2199-
2200- for backend in builder. config . enabled_codegen_backends ( target_compiler. host ) {
2201- // FIXME: this is a horrible hack used to make `x check` work when other codegen
2202- // backends are enabled.
2203- // `x check` will check stage 1 rustc, which copies its rmetas to the stage0 sysroot.
2204- // Then it checks codegen backends, which correctly use these rmetas.
2205- // Then it needs to check std, but for that it needs to build stage 1 rustc.
2206- // This copies the build rmetas into the stage0 sysroot, effectively poisoning it,
2207- // because we then have both check and build rmetas in the same sysroot.
2208- // That would be fine on its own. However, when another codegen backend is enabled,
2209- // then building stage 1 rustc implies also building stage 1 codegen backend (even if
2210- // it isn't used for anything). And since that tries to use the poisoned
2211- // rmetas, it fails to build.
2212- // We don't actually need to build rustc-private codegen backends for checking std,
2213- // so instead we skip that.
2214- // Note: this would be also an issue for other rustc-private tools, but that is "solved"
2215- // by check::Std being last in the list of checked things (see
2216- // `Builder::get_step_descriptions`).
2217- if builder. kind == Kind :: Check && builder. top_stage == 1 {
2218- continue ;
2219- }
2220-
2221- let prepare_compilers = || {
2222- RustcPrivateCompilers :: from_build_and_target_compiler (
2223- build_compiler,
2224- target_compiler,
2225- )
2226- } ;
2227-
2228- let stamp = match backend {
2229- CodegenBackendKind :: Cranelift => {
2230- builder. ensure ( CraneliftCodegenBackend { compilers : prepare_compilers ( ) } )
2231- }
2232- CodegenBackendKind :: Gcc => {
2233- builder. ensure ( GccCodegenBackend { compilers : prepare_compilers ( ) } )
2234- }
2235- CodegenBackendKind :: Llvm | CodegenBackendKind :: Custom ( _) => continue ,
2236- } ;
2237- codegen_backend_stamps. push ( stamp) ;
2238- }
2239- }
2240-
22412208 let stage = target_compiler. stage ;
22422209 let host = target_compiler. host ;
22432210 let ( host_info, dir_name) = if build_compiler. host == host {
@@ -2296,9 +2263,56 @@ impl Step for Assemble {
22962263 }
22972264 }
22982265
2299- debug ! ( "copying codegen backends to sysroot" ) ;
2300- for stamp in codegen_backend_stamps {
2301- copy_codegen_backends_to_sysroot ( builder, stamp, target_compiler) ;
2266+ {
2267+ #[ cfg( feature = "tracing" ) ]
2268+ let _codegen_backend_span =
2269+ span ! ( tracing:: Level :: DEBUG , "building requested codegen backends" ) . entered ( ) ;
2270+
2271+ for backend in builder. config . enabled_codegen_backends ( target_compiler. host ) {
2272+ // FIXME: this is a horrible hack used to make `x check` work when other codegen
2273+ // backends are enabled.
2274+ // `x check` will check stage 1 rustc, which copies its rmetas to the stage0 sysroot.
2275+ // Then it checks codegen backends, which correctly use these rmetas.
2276+ // Then it needs to check std, but for that it needs to build stage 1 rustc.
2277+ // This copies the build rmetas into the stage0 sysroot, effectively poisoning it,
2278+ // because we then have both check and build rmetas in the same sysroot.
2279+ // That would be fine on its own. However, when another codegen backend is enabled,
2280+ // then building stage 1 rustc implies also building stage 1 codegen backend (even if
2281+ // it isn't used for anything). And since that tries to use the poisoned
2282+ // rmetas, it fails to build.
2283+ // We don't actually need to build rustc-private codegen backends for checking std,
2284+ // so instead we skip that.
2285+ // Note: this would be also an issue for other rustc-private tools, but that is "solved"
2286+ // by check::Std being last in the list of checked things (see
2287+ // `Builder::get_step_descriptions`).
2288+ if builder. kind == Kind :: Check && builder. top_stage == 1 {
2289+ continue ;
2290+ }
2291+
2292+ let prepare_compilers = || {
2293+ RustcPrivateCompilers :: from_build_and_target_compiler (
2294+ build_compiler,
2295+ target_compiler,
2296+ )
2297+ } ;
2298+
2299+ match backend {
2300+ CodegenBackendKind :: Cranelift => {
2301+ let stamp = builder
2302+ . ensure ( CraneliftCodegenBackend { compilers : prepare_compilers ( ) } ) ;
2303+ copy_codegen_backends_to_sysroot ( builder, stamp, target_compiler) ;
2304+ }
2305+ CodegenBackendKind :: Gcc => {
2306+ let output =
2307+ builder. ensure ( GccCodegenBackend { compilers : prepare_compilers ( ) } ) ;
2308+ copy_codegen_backends_to_sysroot ( builder, output. stamp , target_compiler) ;
2309+ // Also copy libgccjit to the library sysroot, so that it is available for
2310+ // the codegen backend.
2311+ output. gcc . install_to ( builder, & rustc_libdir) ;
2312+ }
2313+ CodegenBackendKind :: Llvm | CodegenBackendKind :: Custom ( _) => continue ,
2314+ }
2315+ }
23022316 }
23032317
23042318 if builder. config . lld_enabled {
0 commit comments