@@ -300,7 +300,11 @@ impl Step for StartupObjects {
300300 }
301301
302302 for obj in [ "crt2.o" , "dllcrt2.o" ] . iter ( ) {
303- copy ( & compiler_file ( build. cc ( target) , obj) , & sysroot_dir. join ( obj) ) ;
303+ let src = compiler_file ( build,
304+ build. cc ( target) ,
305+ target,
306+ obj) ;
307+ copy ( & src, & sysroot_dir. join ( obj) ) ;
304308 }
305309 }
306310}
@@ -454,10 +458,6 @@ impl Step for Rustc {
454458
455459 builder. ensure ( Test { compiler, target } ) ;
456460
457- // Build LLVM for our target. This will implicitly build the host LLVM
458- // if necessary.
459- builder. ensure ( native:: Llvm { target } ) ;
460-
461461 if build. force_use_stage1 ( compiler, target) {
462462 builder. ensure ( Rustc {
463463 compiler : builder. compiler ( 1 , build. build ) ,
@@ -487,7 +487,7 @@ impl Step for Rustc {
487487 build. clear_if_dirty ( & stage_out, & libtest_stamp ( build, compiler, target) ) ;
488488
489489 let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "build" ) ;
490- rustc_cargo ( build, target , & mut cargo) ;
490+ rustc_cargo ( build, & mut cargo) ;
491491 run_cargo ( build,
492492 & mut cargo,
493493 & librustc_stamp ( build, compiler, target) ,
@@ -501,14 +501,14 @@ impl Step for Rustc {
501501 }
502502}
503503
504- /// Same as `std_cargo`, but for libtest
505- pub fn rustc_cargo ( build : & Build ,
506- target : Interned < String > ,
507- cargo : & mut Command ) {
504+ pub fn rustc_cargo ( build : & Build , cargo : & mut Command ) {
508505 cargo. arg ( "--features" ) . arg ( build. rustc_features ( ) )
509506 . arg ( "--manifest-path" )
510507 . arg ( build. src . join ( "src/rustc/Cargo.toml" ) ) ;
508+ rustc_cargo_env ( build, cargo) ;
509+ }
511510
511+ fn rustc_cargo_env ( build : & Build , cargo : & mut Command ) {
512512 // Set some configuration variables picked up by build scripts and
513513 // the compiler alike
514514 cargo. env ( "CFG_RELEASE" , build. rust_release ( ) )
@@ -536,27 +536,6 @@ pub fn rustc_cargo(build: &Build,
536536 if !build. unstable_features ( ) {
537537 cargo. env ( "CFG_DISABLE_UNSTABLE_FEATURES" , "1" ) ;
538538 }
539- // Flag that rust llvm is in use
540- if build. is_rust_llvm ( target) {
541- cargo. env ( "LLVM_RUSTLLVM" , "1" ) ;
542- }
543- cargo. env ( "LLVM_CONFIG" , build. llvm_config ( target) ) ;
544- let target_config = build. config . target_config . get ( & target) ;
545- if let Some ( s) = target_config. and_then ( |c| c. llvm_config . as_ref ( ) ) {
546- cargo. env ( "CFG_LLVM_ROOT" , s) ;
547- }
548- // Building with a static libstdc++ is only supported on linux right now,
549- // not for MSVC or macOS
550- if build. config . llvm_static_stdcpp &&
551- !target. contains ( "freebsd" ) &&
552- !target. contains ( "windows" ) &&
553- !target. contains ( "apple" ) {
554- cargo. env ( "LLVM_STATIC_STDCPP" ,
555- compiler_file ( build. cxx ( target) . unwrap ( ) , "libstdc++.a" ) ) ;
556- }
557- if build. config . llvm_link_shared {
558- cargo. env ( "LLVM_LINK_SHARED" , "1" ) ;
559- }
560539 if let Some ( ref s) = build. config . rustc_default_linker {
561540 cargo. env ( "CFG_DEFAULT_LINKER" , s) ;
562541 }
@@ -601,6 +580,137 @@ impl Step for RustcLink {
601580 }
602581}
603582
583+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
584+ pub struct RustcTrans {
585+ pub compiler : Compiler ,
586+ pub target : Interned < String > ,
587+ }
588+
589+ impl Step for RustcTrans {
590+ type Output = ( ) ;
591+ const ONLY_HOSTS : bool = true ;
592+ const DEFAULT : bool = true ;
593+
594+ fn should_run ( run : ShouldRun ) -> ShouldRun {
595+ run. path ( "src/librustc_trans" ) . krate ( "rustc_trans" )
596+ }
597+
598+ fn make_run ( run : RunConfig ) {
599+ run. builder . ensure ( RustcTrans {
600+ compiler : run. builder . compiler ( run. builder . top_stage , run. host ) ,
601+ target : run. target ,
602+ } ) ;
603+ }
604+
605+ fn run ( self , builder : & Builder ) {
606+ let build = builder. build ;
607+ let compiler = self . compiler ;
608+ let target = self . target ;
609+
610+ builder. ensure ( Rustc { compiler, target } ) ;
611+
612+ // Build LLVM for our target. This will implicitly build the host LLVM
613+ // if necessary.
614+ builder. ensure ( native:: Llvm { target } ) ;
615+
616+ if build. force_use_stage1 ( compiler, target) {
617+ builder. ensure ( RustcTrans {
618+ compiler : builder. compiler ( 1 , build. build ) ,
619+ target,
620+ } ) ;
621+ return ;
622+ }
623+
624+ let _folder = build. fold_output ( || format ! ( "stage{}-rustc_trans" , compiler. stage) ) ;
625+ println ! ( "Building stage{} trans artifacts ({} -> {})" ,
626+ compiler. stage, & compiler. host, target) ;
627+
628+ let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "build" ) ;
629+ cargo. arg ( "--manifest-path" )
630+ . arg ( build. src . join ( "src/librustc_trans/Cargo.toml" ) )
631+ . arg ( "--features" ) . arg ( build. rustc_features ( ) ) ;
632+ rustc_cargo_env ( build, & mut cargo) ;
633+
634+ // Pass down configuration from the LLVM build into the build of
635+ // librustc_llvm and librustc_trans.
636+ if build. is_rust_llvm ( target) {
637+ cargo. env ( "LLVM_RUSTLLVM" , "1" ) ;
638+ }
639+ cargo. env ( "LLVM_CONFIG" , build. llvm_config ( target) ) ;
640+ let target_config = build. config . target_config . get ( & target) ;
641+ if let Some ( s) = target_config. and_then ( |c| c. llvm_config . as_ref ( ) ) {
642+ cargo. env ( "CFG_LLVM_ROOT" , s) ;
643+ }
644+ // Building with a static libstdc++ is only supported on linux right now,
645+ // not for MSVC or macOS
646+ if build. config . llvm_static_stdcpp &&
647+ !target. contains ( "freebsd" ) &&
648+ !target. contains ( "windows" ) &&
649+ !target. contains ( "apple" ) {
650+ let file = compiler_file ( build,
651+ build. cxx ( target) . unwrap ( ) ,
652+ target,
653+ "libstdc++.a" ) ;
654+ cargo. env ( "LLVM_STATIC_STDCPP" , file) ;
655+ }
656+ if build. config . llvm_link_shared {
657+ cargo. env ( "LLVM_LINK_SHARED" , "1" ) ;
658+ }
659+
660+ run_cargo ( build,
661+ & mut cargo,
662+ & librustc_trans_stamp ( build, compiler, target) ,
663+ false ) ;
664+ }
665+ }
666+
667+ /// Creates the `codegen-backends` folder for a compiler that's about to be
668+ /// assembled as a complete compiler.
669+ ///
670+ /// This will take the codegen artifacts produced by `compiler` and link them
671+ /// into an appropriate location for `target_compiler` to be a functional
672+ /// compiler.
673+ fn copy_codegen_backends_to_sysroot ( builder : & Builder ,
674+ compiler : Compiler ,
675+ target_compiler : Compiler ) {
676+ let build = builder. build ;
677+ let target = target_compiler. host ;
678+
679+ // Note that this step is different than all the other `*Link` steps in
680+ // that it's not assembling a bunch of libraries but rather is primarily
681+ // moving the codegen backend into place. The codegen backend of rustc is
682+ // not linked into the main compiler by default but is rather dynamically
683+ // selected at runtime for inclusion.
684+ //
685+ // Here we're looking for the output dylib of the `RustcTrans` step and
686+ // we're copying that into the `codegen-backends` folder.
687+ let libdir = builder. sysroot_libdir ( target_compiler, target) ;
688+ let dst = libdir. join ( "codegen-backends" ) ;
689+ t ! ( fs:: create_dir_all( & dst) ) ;
690+ let stamp = librustc_trans_stamp ( build, compiler, target) ;
691+
692+ let mut copied = None ;
693+ for file in read_stamp_file ( & stamp) {
694+ let filename = match file. file_name ( ) . and_then ( |s| s. to_str ( ) ) {
695+ Some ( s) => s,
696+ None => continue ,
697+ } ;
698+ if !is_dylib ( filename) || !filename. contains ( "rustc_trans-" ) {
699+ continue
700+ }
701+ match copied {
702+ None => copied = Some ( file. clone ( ) ) ,
703+ Some ( ref s) => {
704+ panic ! ( "copied two codegen backends:\n {}\n {}" ,
705+ s. display( ) ,
706+ file. display( ) ) ;
707+ }
708+ }
709+ copy ( & file, & dst. join ( filename) ) ;
710+ }
711+ assert ! ( copied. is_some( ) , "failed to find a codegen backend to copy" ) ;
712+ }
713+
604714/// Cargo's output path for the standard library in a given stage, compiled
605715/// by a particular compiler for the specified target.
606716pub fn libstd_stamp ( build : & Build , compiler : Compiler , target : Interned < String > ) -> PathBuf {
@@ -619,9 +729,20 @@ pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String
619729 build. cargo_out ( compiler, Mode :: Librustc , target) . join ( ".librustc.stamp" )
620730}
621731
622- fn compiler_file ( compiler : & Path , file : & str ) -> PathBuf {
623- let out = output ( Command :: new ( compiler)
624- . arg ( format ! ( "-print-file-name={}" , file) ) ) ;
732+ pub fn librustc_trans_stamp ( build : & Build ,
733+ compiler : Compiler ,
734+ target : Interned < String > ) -> PathBuf {
735+ build. cargo_out ( compiler, Mode :: Librustc , target) . join ( ".librustc_trans.stamp" )
736+ }
737+
738+ fn compiler_file ( build : & Build ,
739+ compiler : & Path ,
740+ target : Interned < String > ,
741+ file : & str ) -> PathBuf {
742+ let mut cmd = Command :: new ( compiler) ;
743+ cmd. args ( build. cflags ( target) ) ;
744+ cmd. arg ( format ! ( "-print-file-name={}" , file) ) ;
745+ let out = output ( & mut cmd) ;
625746 PathBuf :: from ( out. trim ( ) )
626747}
627748
@@ -690,20 +811,23 @@ impl Step for Assemble {
690811 }
691812
692813 // Get the compiler that we'll use to bootstrap ourselves.
693- let build_compiler = if target_compiler. host != build. build {
694- // Build a compiler for the host platform. We cannot use the stage0
695- // compiler for the host platform for this because it doesn't have
696- // the libraries we need. FIXME: Perhaps we should download those
697- // libraries? It would make builds faster...
698- // FIXME: It may be faster if we build just a stage 1
699- // compiler and then use that to bootstrap this compiler
700- // forward.
701- builder. compiler ( target_compiler. stage - 1 , build. build )
702- } else {
703- // Build the compiler we'll use to build the stage requested. This
704- // may build more than one compiler (going down to stage 0).
705- builder. compiler ( target_compiler. stage - 1 , target_compiler. host )
706- } ;
814+ //
815+ // Note that this is where the recursive nature of the bootstrap
816+ // happens, as this will request the previous stage's compiler on
817+ // downwards to stage 0.
818+ //
819+ // Also note that we're building a compiler for the host platform. We
820+ // only assume that we can run `build` artifacts, which means that to
821+ // produce some other architecture compiler we need to start from
822+ // `build` to get there.
823+ //
824+ // FIXME: Perhaps we should download those libraries?
825+ // It would make builds faster...
826+ //
827+ // FIXME: It may be faster if we build just a stage 1 compiler and then
828+ // use that to bootstrap this compiler forward.
829+ let build_compiler =
830+ builder. compiler ( target_compiler. stage - 1 , build. build ) ;
707831
708832 // Build the libraries for this compiler to link to (i.e., the libraries
709833 // it uses at runtime). NOTE: Crates the target compiler compiles don't
@@ -721,7 +845,14 @@ impl Step for Assemble {
721845 builder. ensure ( RustcLink { compiler, target_compiler, target } ) ;
722846 }
723847 } else {
724- builder. ensure ( Rustc { compiler : build_compiler, target : target_compiler. host } ) ;
848+ builder. ensure ( Rustc {
849+ compiler : build_compiler,
850+ target : target_compiler. host ,
851+ } ) ;
852+ builder. ensure ( RustcTrans {
853+ compiler : build_compiler,
854+ target : target_compiler. host ,
855+ } ) ;
725856 }
726857
727858 let stage = target_compiler. stage ;
@@ -740,9 +871,12 @@ impl Step for Assemble {
740871 }
741872 }
742873
743- let out_dir = build. cargo_out ( build_compiler, Mode :: Librustc , host) ;
874+ copy_codegen_backends_to_sysroot ( builder,
875+ build_compiler,
876+ target_compiler) ;
744877
745878 // Link the compiler binary itself into place
879+ let out_dir = build. cargo_out ( build_compiler, Mode :: Librustc , host) ;
746880 let rustc = out_dir. join ( exe ( "rustc" , & * host) ) ;
747881 let bindir = sysroot. join ( "bin" ) ;
748882 t ! ( fs:: create_dir_all( & bindir) ) ;
0 commit comments