@@ -581,24 +581,30 @@ impl Step for RustcLink {
581
581
}
582
582
583
583
#[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
584
- pub struct RustcTrans {
584
+ pub struct CodegenBackend {
585
585
pub compiler : Compiler ,
586
586
pub target : Interned < String > ,
587
+ pub backend : Interned < String > ,
587
588
}
588
589
589
- impl Step for RustcTrans {
590
+ impl Step for CodegenBackend {
590
591
type Output = ( ) ;
591
592
const ONLY_HOSTS : bool = true ;
592
593
const DEFAULT : bool = true ;
593
594
594
595
fn should_run ( run : ShouldRun ) -> ShouldRun {
595
- run. path ( "src/librustc_trans" ) . krate ( "rustc_trans" )
596
+ run. path ( "src/librustc_trans" )
596
597
}
597
598
598
599
fn make_run ( run : RunConfig ) {
599
- run. builder . ensure ( RustcTrans {
600
+ let backend = run. builder . config . rust_codegen_backends . get ( 0 ) ;
601
+ let backend = backend. cloned ( ) . unwrap_or_else ( || {
602
+ INTERNER . intern_str ( "llvm" )
603
+ } ) ;
604
+ run. builder . ensure ( CodegenBackend {
600
605
compiler : run. builder . compiler ( run. builder . top_stage , run. host ) ,
601
606
target : run. target ,
607
+ backend
602
608
} ) ;
603
609
}
604
610
@@ -609,58 +615,92 @@ impl Step for RustcTrans {
609
615
610
616
builder. ensure ( Rustc { compiler, target } ) ;
611
617
612
- // Build LLVM for our target. This will implicitly build the host LLVM
613
- // if necessary.
614
- builder. ensure ( native:: Llvm { target } ) ;
615
-
616
618
if build. force_use_stage1 ( compiler, target) {
617
- builder. ensure ( RustcTrans {
619
+ builder. ensure ( CodegenBackend {
618
620
compiler : builder. compiler ( 1 , build. build ) ,
619
621
target,
622
+ backend : self . backend ,
620
623
} ) ;
621
624
return ;
622
625
}
623
626
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
627
let mut cargo = builder. cargo ( compiler, Mode :: Librustc , target, "build" ) ;
628
+ let mut features = build. rustc_features ( ) . to_string ( ) ;
629
629
cargo. arg ( "--manifest-path" )
630
- . arg ( build. src . join ( "src/librustc_trans/Cargo.toml" ) )
631
- . arg ( "--features" ) . arg ( build. rustc_features ( ) ) ;
630
+ . arg ( build. src . join ( "src/librustc_trans/Cargo.toml" ) ) ;
632
631
rustc_cargo_env ( build, & mut cargo) ;
633
632
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" ) ;
633
+ match & * self . backend {
634
+ "llvm" | "emscripten" => {
635
+ // Build LLVM for our target. This will implicitly build the
636
+ // host LLVM if necessary.
637
+ let llvm_config = builder. ensure ( native:: Llvm {
638
+ target,
639
+ emscripten : self . backend == "emscripten" ,
640
+ } ) ;
641
+
642
+ if self . backend == "emscripten" {
643
+ features. push_str ( " emscripten" ) ;
644
+ }
645
+
646
+ let _folder = build. fold_output ( || format ! ( "stage{}-rustc_trans" , compiler. stage) ) ;
647
+ println ! ( "Building stage{} codegen artifacts ({} -> {}, {})" ,
648
+ compiler. stage, & compiler. host, target, self . backend) ;
649
+
650
+ // Pass down configuration from the LLVM build into the build of
651
+ // librustc_llvm and librustc_trans.
652
+ if build. is_rust_llvm ( target) {
653
+ cargo. env ( "LLVM_RUSTLLVM" , "1" ) ;
654
+ }
655
+ cargo. env ( "LLVM_CONFIG" , & llvm_config) ;
656
+ if self . backend != "emscripten" {
657
+ let target_config = build. config . target_config . get ( & target) ;
658
+ if let Some ( s) = target_config. and_then ( |c| c. llvm_config . as_ref ( ) ) {
659
+ cargo. env ( "CFG_LLVM_ROOT" , s) ;
660
+ }
661
+ }
662
+ // Building with a static libstdc++ is only supported on linux right now,
663
+ // not for MSVC or macOS
664
+ if build. config . llvm_static_stdcpp &&
665
+ !target. contains ( "freebsd" ) &&
666
+ !target. contains ( "windows" ) &&
667
+ !target. contains ( "apple" ) {
668
+ let file = compiler_file ( build,
669
+ build. cxx ( target) . unwrap ( ) ,
670
+ target,
671
+ "libstdc++.a" ) ;
672
+ cargo. env ( "LLVM_STATIC_STDCPP" , file) ;
673
+ }
674
+ if build. config . llvm_link_shared {
675
+ cargo. env ( "LLVM_LINK_SHARED" , "1" ) ;
676
+ }
677
+ }
678
+ _ => panic ! ( "unknown backend: {}" , self . backend) ,
658
679
}
659
680
660
- run_cargo ( build,
661
- & mut cargo,
662
- & librustc_trans_stamp ( build, compiler, target) ,
663
- false ) ;
681
+ let tmp_stamp = build. cargo_out ( compiler, Mode :: Librustc , target)
682
+ . join ( ".tmp.stamp" ) ;
683
+ let files = run_cargo ( build,
684
+ cargo. arg ( "--features" ) . arg ( features) ,
685
+ & tmp_stamp,
686
+ false ) ;
687
+ let mut files = files. into_iter ( )
688
+ . filter ( |f| {
689
+ let filename = f. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
690
+ is_dylib ( filename) && filename. contains ( "rustc_trans-" )
691
+ } ) ;
692
+ let codegen_backend = match files. next ( ) {
693
+ Some ( f) => f,
694
+ None => panic ! ( "no dylibs built for codegen backend?" ) ,
695
+ } ;
696
+ if let Some ( f) = files. next ( ) {
697
+ panic ! ( "codegen backend built two dylibs:\n {}\n {}" ,
698
+ codegen_backend. display( ) ,
699
+ f. display( ) ) ;
700
+ }
701
+ let stamp = codegen_backend_stamp ( build, compiler, target, self . backend ) ;
702
+ let codegen_backend = codegen_backend. to_str ( ) . unwrap ( ) ;
703
+ t ! ( t!( File :: create( & stamp) ) . write_all( codegen_backend. as_bytes( ) ) ) ;
664
704
}
665
705
}
666
706
@@ -682,33 +722,29 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder,
682
722
// not linked into the main compiler by default but is rather dynamically
683
723
// selected at runtime for inclusion.
684
724
//
685
- // Here we're looking for the output dylib of the `RustcTrans ` step and
725
+ // Here we're looking for the output dylib of the `CodegenBackend ` step and
686
726
// we're copying that into the `codegen-backends` folder.
687
727
let libdir = builder. sysroot_libdir ( target_compiler, target) ;
688
728
let dst = libdir. join ( "codegen-backends" ) ;
689
729
t ! ( fs:: create_dir_all( & dst) ) ;
690
- let stamp = librustc_trans_stamp ( build, compiler, target) ;
691
730
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 ,
731
+ for backend in builder. config . rust_codegen_backends . iter ( ) {
732
+ let stamp = codegen_backend_stamp ( build, compiler, target, * backend) ;
733
+ let mut dylib = String :: new ( ) ;
734
+ t ! ( t!( File :: open( & stamp) ) . read_to_string( & mut dylib) ) ;
735
+ let file = Path :: new ( & dylib) ;
736
+ let filename = file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
737
+ // change `librustc_trans-xxxxxx.so` to `librustc_trans-llvm.so`
738
+ let target_filename = {
739
+ let dash = filename. find ( "-" ) . unwrap ( ) ;
740
+ let dot = filename. find ( "." ) . unwrap ( ) ;
741
+ format ! ( "{}-{}{}" ,
742
+ & filename[ ..dash] ,
743
+ backend,
744
+ & filename[ dot..] )
697
745
} ;
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) ) ;
746
+ copy ( & file, & dst. join ( target_filename) ) ;
710
747
}
711
- assert ! ( copied. is_some( ) , "failed to find a codegen backend to copy" ) ;
712
748
}
713
749
714
750
/// Cargo's output path for the standard library in a given stage, compiled
@@ -729,10 +765,12 @@ pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String
729
765
build. cargo_out ( compiler, Mode :: Librustc , target) . join ( ".librustc.stamp" )
730
766
}
731
767
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" )
768
+ fn codegen_backend_stamp ( build : & Build ,
769
+ compiler : Compiler ,
770
+ target : Interned < String > ,
771
+ backend : Interned < String > ) -> PathBuf {
772
+ build. cargo_out ( compiler, Mode :: Librustc , target)
773
+ . join ( format ! ( ".librustc_trans-{}.stamp" , backend) )
736
774
}
737
775
738
776
fn compiler_file ( build : & Build ,
@@ -849,10 +887,13 @@ impl Step for Assemble {
849
887
compiler : build_compiler,
850
888
target : target_compiler. host ,
851
889
} ) ;
852
- builder. ensure ( RustcTrans {
853
- compiler : build_compiler,
854
- target : target_compiler. host ,
855
- } ) ;
890
+ for & backend in build. config . rust_codegen_backends . iter ( ) {
891
+ builder. ensure ( CodegenBackend {
892
+ compiler : build_compiler,
893
+ target : target_compiler. host ,
894
+ backend,
895
+ } ) ;
896
+ }
856
897
}
857
898
858
899
let stage = target_compiler. stage ;
@@ -922,7 +963,9 @@ fn stderr_isatty() -> bool {
922
963
}
923
964
}
924
965
925
- pub fn run_cargo ( build : & Build , cargo : & mut Command , stamp : & Path , is_check : bool ) {
966
+ pub fn run_cargo ( build : & Build , cargo : & mut Command , stamp : & Path , is_check : bool )
967
+ -> Vec < PathBuf >
968
+ {
926
969
// Instruct Cargo to give us json messages on stdout, critically leaving
927
970
// stderr as piped so we can get those pretty colors.
928
971
cargo. arg ( "--message-format" ) . arg ( "json" )
@@ -1066,8 +1109,8 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
1066
1109
let mut new_contents = Vec :: new ( ) ;
1067
1110
let mut max = None ;
1068
1111
let mut max_path = None ;
1069
- for dep in deps {
1070
- let mtime = mtime ( & dep) ;
1112
+ for dep in deps. iter ( ) {
1113
+ let mtime = mtime ( dep) ;
1071
1114
if Some ( mtime) > max {
1072
1115
max = Some ( mtime) ;
1073
1116
max_path = Some ( dep. clone ( ) ) ;
@@ -1080,12 +1123,13 @@ pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: boo
1080
1123
if stamp_contents == new_contents && max <= stamp_mtime {
1081
1124
build. verbose ( & format ! ( "not updating {:?}; contents equal and {} <= {}" ,
1082
1125
stamp, max, stamp_mtime) ) ;
1083
- return
1126
+ return deps
1084
1127
}
1085
1128
if max > stamp_mtime {
1086
1129
build. verbose ( & format ! ( "updating {:?} as {:?} changed" , stamp, max_path) ) ;
1087
1130
} else {
1088
1131
build. verbose ( & format ! ( "updating {:?} as deps changed" , stamp) ) ;
1089
1132
}
1090
1133
t ! ( t!( File :: create( stamp) ) . write_all( & new_contents) ) ;
1134
+ deps
1091
1135
}
0 commit comments