@@ -23,7 +23,7 @@ use crate::builder::Cargo;
2323use crate :: dist;
2424use crate :: native;
2525use crate :: util:: { exe, is_dylib, symlink_dir} ;
26- use crate :: { Compiler , GitRepo , Mode } ;
26+ use crate :: { Compiler , DependencyType , GitRepo , Mode } ;
2727
2828use crate :: builder:: { Builder , Kind , RunConfig , ShouldRun , Step } ;
2929use crate :: cache:: { Interned , INTERNER } ;
@@ -74,6 +74,7 @@ impl Step for Std {
7474 // Even if we're not building std this stage, the new sysroot must
7575 // still contain the third party objects needed by various targets.
7676 copy_third_party_objects ( builder, & compiler, target) ;
77+ copy_self_contained_objects ( builder, & compiler, target) ;
7778
7879 builder. ensure ( StdLink {
7980 compiler : compiler_to_use,
@@ -83,7 +84,8 @@ impl Step for Std {
8384 return ;
8485 }
8586
86- target_deps. extend ( copy_third_party_objects ( builder, & compiler, target) . into_iter ( ) ) ;
87+ target_deps. extend ( copy_third_party_objects ( builder, & compiler, target) ) ;
88+ target_deps. extend ( copy_self_contained_objects ( builder, & compiler, target) ) ;
8789
8890 let mut cargo = builder. cargo ( compiler, Mode :: Std , target, "build" ) ;
8991 std_cargo ( builder, target, compiler. stage , & mut cargo) ;
@@ -109,21 +111,76 @@ impl Step for Std {
109111 }
110112}
111113
114+ fn copy_and_stamp (
115+ builder : & Builder < ' _ > ,
116+ libdir : & Path ,
117+ sourcedir : & Path ,
118+ name : & str ,
119+ target_deps : & mut Vec < ( PathBuf , DependencyType ) > ,
120+ dependency_type : DependencyType ,
121+ ) {
122+ let target = libdir. join ( name) ;
123+ builder. copy ( & sourcedir. join ( name) , & target) ;
124+
125+ target_deps. push ( ( target, dependency_type) ) ;
126+ }
127+
112128/// Copies third party objects needed by various targets.
113129fn copy_third_party_objects (
114130 builder : & Builder < ' _ > ,
115131 compiler : & Compiler ,
116132 target : Interned < String > ,
117- ) -> Vec < PathBuf > {
133+ ) -> Vec < ( PathBuf , DependencyType ) > {
118134 let libdir = builder. sysroot_libdir ( * compiler, target) ;
119-
120135 let mut target_deps = vec ! [ ] ;
121136
122- let mut copy_and_stamp = |sourcedir : & Path , name : & str | {
123- let target = libdir. join ( name) ;
124- builder. copy ( & sourcedir. join ( name) , & target) ;
125- target_deps. push ( target) ;
137+ // Copies libunwind.a compiled to be linked with x86_64-fortanix-unknown-sgx.
138+ //
139+ // This target needs to be linked to Fortanix's port of llvm's libunwind.
140+ // libunwind requires support for rwlock and printing to stderr,
141+ // which is provided by std for this target.
142+ if target == "x86_64-fortanix-unknown-sgx" {
143+ let src_path_env = "X86_FORTANIX_SGX_LIBS" ;
144+ let src =
145+ env:: var ( src_path_env) . unwrap_or_else ( |_| panic ! ( "{} not found in env" , src_path_env) ) ;
146+ copy_and_stamp (
147+ builder,
148+ & * libdir,
149+ Path :: new ( & src) ,
150+ "libunwind.a" ,
151+ & mut target_deps,
152+ DependencyType :: Target ,
153+ ) ;
154+ }
155+
156+ if builder. config . sanitizers && compiler. stage != 0 {
157+ // The sanitizers are only copied in stage1 or above,
158+ // to avoid creating dependency on LLVM.
159+ target_deps. extend (
160+ copy_sanitizers ( builder, & compiler, target)
161+ . into_iter ( )
162+ . map ( |d| ( d, DependencyType :: Target ) ) ,
163+ ) ;
164+ }
165+
166+ target_deps
167+ }
168+
169+ /// Copies third party objects needed by various targets for self-contained linkage.
170+ fn copy_self_contained_objects (
171+ builder : & Builder < ' _ > ,
172+ compiler : & Compiler ,
173+ target : Interned < String > ,
174+ ) -> Vec < ( PathBuf , DependencyType ) > {
175+ // cfg(bootstrap)
176+ // Remove when upgrading bootstrap compiler.
177+ let libdir_self_contained = if compiler. stage == 0 {
178+ builder. sysroot_libdir ( * compiler, target) . to_path_buf ( )
179+ } else {
180+ builder. sysroot_libdir ( * compiler, target) . join ( "self-contained" )
126181 } ;
182+ t ! ( fs:: create_dir_all( & libdir_self_contained) ) ;
183+ let mut target_deps = vec ! [ ] ;
127184
128185 // Copies the CRT objects.
129186 //
@@ -135,29 +192,32 @@ fn copy_third_party_objects(
135192 if target. contains ( "musl" ) {
136193 let srcdir = builder. musl_root ( target) . unwrap ( ) . join ( "lib" ) ;
137194 for & obj in & [ "crt1.o" , "Scrt1.o" , "rcrt1.o" , "crti.o" , "crtn.o" ] {
138- copy_and_stamp ( & srcdir, obj) ;
195+ copy_and_stamp (
196+ builder,
197+ & libdir_self_contained,
198+ & srcdir,
199+ obj,
200+ & mut target_deps,
201+ DependencyType :: TargetSelfContained ,
202+ ) ;
139203 }
140204 } else if target. ends_with ( "-wasi" ) {
141205 let srcdir = builder. wasi_root ( target) . unwrap ( ) . join ( "lib/wasm32-wasi" ) ;
142- copy_and_stamp ( & srcdir, "crt1.o" ) ;
143- }
144-
145- // Copies libunwind.a compiled to be linked with x86_64-fortanix-unknown-sgx.
146- //
147- // This target needs to be linked to Fortanix's port of llvm's libunwind.
148- // libunwind requires support for rwlock and printing to stderr,
149- // which is provided by std for this target.
150- if target == "x86_64-fortanix-unknown-sgx" {
151- let src_path_env = "X86_FORTANIX_SGX_LIBS" ;
152- let src =
153- env:: var ( src_path_env) . unwrap_or_else ( |_| panic ! ( "{} not found in env" , src_path_env) ) ;
154- copy_and_stamp ( Path :: new ( & src) , "libunwind.a" ) ;
155- }
156-
157- if builder. config . sanitizers && compiler. stage != 0 {
158- // The sanitizers are only copied in stage1 or above,
159- // to avoid creating dependency on LLVM.
160- target_deps. extend ( copy_sanitizers ( builder, & compiler, target) ) ;
206+ copy_and_stamp (
207+ builder,
208+ & libdir_self_contained,
209+ & srcdir,
210+ "crt1.o" ,
211+ & mut target_deps,
212+ DependencyType :: TargetSelfContained ,
213+ ) ;
214+ } else if target. contains ( "windows-gnu" ) {
215+ for obj in [ "crt2.o" , "dllcrt2.o" ] . iter ( ) {
216+ let src = compiler_file ( builder, builder. cc ( target) , target, obj) ;
217+ let target = libdir_self_contained. join ( obj) ;
218+ builder. copy ( & src, & target) ;
219+ target_deps. push ( ( target, DependencyType :: TargetSelfContained ) ) ;
220+ }
161221 }
162222
163223 target_deps
@@ -335,7 +395,7 @@ pub struct StartupObjects {
335395}
336396
337397impl Step for StartupObjects {
338- type Output = Vec < PathBuf > ;
398+ type Output = Vec < ( PathBuf , DependencyType ) > ;
339399
340400 fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
341401 run. path ( "src/rtstartup" )
@@ -354,7 +414,7 @@ impl Step for StartupObjects {
354414 /// They don't require any library support as they're just plain old object
355415 /// files, so we just use the nightly snapshot compiler to always build them (as
356416 /// no other compilers are guaranteed to be available).
357- fn run ( self , builder : & Builder < ' _ > ) -> Vec < PathBuf > {
417+ fn run ( self , builder : & Builder < ' _ > ) -> Vec < ( PathBuf , DependencyType ) > {
358418 let for_compiler = self . compiler ;
359419 let target = self . target ;
360420 if !target. contains ( "windows-gnu" ) {
@@ -388,14 +448,7 @@ impl Step for StartupObjects {
388448
389449 let target = sysroot_dir. join ( ( * file) . to_string ( ) + ".o" ) ;
390450 builder. copy ( dst_file, & target) ;
391- target_deps. push ( target) ;
392- }
393-
394- for obj in [ "crt2.o" , "dllcrt2.o" ] . iter ( ) {
395- let src = compiler_file ( builder, builder. cc ( target) , target, obj) ;
396- let target = sysroot_dir. join ( obj) ;
397- builder. copy ( & src, & target) ;
398- target_deps. push ( target) ;
451+ target_deps. push ( ( target, DependencyType :: Target ) ) ;
399452 }
400453
401454 target_deps
@@ -808,14 +861,17 @@ pub fn add_to_sysroot(
808861 sysroot_host_dst : & Path ,
809862 stamp : & Path ,
810863) {
864+ let self_contained_dst = & sysroot_dst. join ( "self-contained" ) ;
811865 t ! ( fs:: create_dir_all( & sysroot_dst) ) ;
812866 t ! ( fs:: create_dir_all( & sysroot_host_dst) ) ;
813- for ( path, host) in builder. read_stamp_file ( stamp) {
814- if host {
815- builder. copy ( & path, & sysroot_host_dst. join ( path. file_name ( ) . unwrap ( ) ) ) ;
816- } else {
817- builder. copy ( & path, & sysroot_dst. join ( path. file_name ( ) . unwrap ( ) ) ) ;
818- }
867+ t ! ( fs:: create_dir_all( & self_contained_dst) ) ;
868+ for ( path, dependency_type) in builder. read_stamp_file ( stamp) {
869+ let dst = match dependency_type {
870+ DependencyType :: Host => sysroot_host_dst,
871+ DependencyType :: Target => sysroot_dst,
872+ DependencyType :: TargetSelfContained => self_contained_dst,
873+ } ;
874+ builder. copy ( & path, & dst. join ( path. file_name ( ) . unwrap ( ) ) ) ;
819875 }
820876}
821877
@@ -824,7 +880,7 @@ pub fn run_cargo(
824880 cargo : Cargo ,
825881 tail_args : Vec < String > ,
826882 stamp : & Path ,
827- additional_target_deps : Vec < PathBuf > ,
883+ additional_target_deps : Vec < ( PathBuf , DependencyType ) > ,
828884 is_check : bool ,
829885) -> Vec < PathBuf > {
830886 if builder. config . dry_run {
@@ -875,15 +931,15 @@ pub fn run_cargo(
875931 if filename. starts_with ( & host_root_dir) {
876932 // Unless it's a proc macro used in the compiler
877933 if crate_types. iter ( ) . any ( |t| t == "proc-macro" ) {
878- deps. push ( ( filename. to_path_buf ( ) , true ) ) ;
934+ deps. push ( ( filename. to_path_buf ( ) , DependencyType :: Host ) ) ;
879935 }
880936 continue ;
881937 }
882938
883939 // If this was output in the `deps` dir then this is a precise file
884940 // name (hash included) so we start tracking it.
885941 if filename. starts_with ( & target_deps_dir) {
886- deps. push ( ( filename. to_path_buf ( ) , false ) ) ;
942+ deps. push ( ( filename. to_path_buf ( ) , DependencyType :: Target ) ) ;
887943 continue ;
888944 }
889945
@@ -935,17 +991,21 @@ pub fn run_cargo(
935991 let candidate = format ! ( "{}.lib" , path_to_add) ;
936992 let candidate = PathBuf :: from ( candidate) ;
937993 if candidate. exists ( ) {
938- deps. push ( ( candidate, false ) ) ;
994+ deps. push ( ( candidate, DependencyType :: Target ) ) ;
939995 }
940996 }
941- deps. push ( ( path_to_add. into ( ) , false ) ) ;
997+ deps. push ( ( path_to_add. into ( ) , DependencyType :: Target ) ) ;
942998 }
943999
944- deps. extend ( additional_target_deps. into_iter ( ) . map ( |d| ( d , false ) ) ) ;
1000+ deps. extend ( additional_target_deps) ;
9451001 deps. sort ( ) ;
9461002 let mut new_contents = Vec :: new ( ) ;
947- for ( dep, proc_macro) in deps. iter ( ) {
948- new_contents. extend ( if * proc_macro { b"h" } else { b"t" } ) ;
1003+ for ( dep, dependency_type) in deps. iter ( ) {
1004+ new_contents. extend ( match * dependency_type {
1005+ DependencyType :: Host => b"h" ,
1006+ DependencyType :: Target => b"t" ,
1007+ DependencyType :: TargetSelfContained => b"s" ,
1008+ } ) ;
9491009 new_contents. extend ( dep. to_str ( ) . unwrap ( ) . as_bytes ( ) ) ;
9501010 new_contents. extend ( b"\0 " ) ;
9511011 }
0 commit comments