@@ -300,7 +300,11 @@ impl Step for StartupObjects {
300
300
}
301
301
302
302
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) ) ;
304
308
}
305
309
}
306
310
}
@@ -454,10 +458,6 @@ impl Step for Rustc {
454
458
455
459
builder. ensure ( Test { compiler, target } ) ;
456
460
457
- // Build LLVM for our target. This will implicitly build the host LLVM
458
- // if necessary.
459
- builder. ensure ( native:: Llvm { target } ) ;
460
-
461
461
if build. force_use_stage1 ( compiler, target) {
462
462
builder. ensure ( Rustc {
463
463
compiler : builder. compiler ( 1 , build. build ) ,
@@ -487,7 +487,7 @@ impl Step for Rustc {
487
487
build. clear_if_dirty ( & stage_out, & libtest_stamp ( build, compiler, target) ) ;
488
488
489
489
let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "build" ) ;
490
- rustc_cargo ( build, target , & mut cargo) ;
490
+ rustc_cargo ( build, & mut cargo) ;
491
491
run_cargo ( build,
492
492
& mut cargo,
493
493
& librustc_stamp ( build, compiler, target) ,
@@ -501,14 +501,14 @@ impl Step for Rustc {
501
501
}
502
502
}
503
503
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 ) {
508
505
cargo. arg ( "--features" ) . arg ( build. rustc_features ( ) )
509
506
. arg ( "--manifest-path" )
510
507
. arg ( build. src . join ( "src/rustc/Cargo.toml" ) ) ;
508
+ rustc_cargo_env ( build, cargo) ;
509
+ }
511
510
511
+ fn rustc_cargo_env ( build : & Build , cargo : & mut Command ) {
512
512
// Set some configuration variables picked up by build scripts and
513
513
// the compiler alike
514
514
cargo. env ( "CFG_RELEASE" , build. rust_release ( ) )
@@ -536,27 +536,6 @@ pub fn rustc_cargo(build: &Build,
536
536
if !build. unstable_features ( ) {
537
537
cargo. env ( "CFG_DISABLE_UNSTABLE_FEATURES" , "1" ) ;
538
538
}
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
- }
560
539
if let Some ( ref s) = build. config . rustc_default_linker {
561
540
cargo. env ( "CFG_DEFAULT_LINKER" , s) ;
562
541
}
@@ -601,6 +580,137 @@ impl Step for RustcLink {
601
580
}
602
581
}
603
582
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
+
604
714
/// Cargo's output path for the standard library in a given stage, compiled
605
715
/// by a particular compiler for the specified target.
606
716
pub 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
619
729
build. cargo_out ( compiler, Mode :: Librustc , target) . join ( ".librustc.stamp" )
620
730
}
621
731
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) ;
625
746
PathBuf :: from ( out. trim ( ) )
626
747
}
627
748
@@ -690,20 +811,23 @@ impl Step for Assemble {
690
811
}
691
812
692
813
// 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 ) ;
707
831
708
832
// Build the libraries for this compiler to link to (i.e., the libraries
709
833
// it uses at runtime). NOTE: Crates the target compiler compiles don't
@@ -721,7 +845,14 @@ impl Step for Assemble {
721
845
builder. ensure ( RustcLink { compiler, target_compiler, target } ) ;
722
846
}
723
847
} 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
+ } ) ;
725
856
}
726
857
727
858
let stage = target_compiler. stage ;
@@ -740,9 +871,12 @@ impl Step for Assemble {
740
871
}
741
872
}
742
873
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) ;
744
877
745
878
// Link the compiler binary itself into place
879
+ let out_dir = build. cargo_out ( build_compiler, Mode :: Librustc , host) ;
746
880
let rustc = out_dir. join ( exe ( "rustc" , & * host) ) ;
747
881
let bindir = sysroot. join ( "bin" ) ;
748
882
t ! ( fs:: create_dir_all( & bindir) ) ;
0 commit comments