@@ -23,7 +23,7 @@ use crate::builder::Cargo;
23
23
use crate :: dist;
24
24
use crate :: native;
25
25
use crate :: util:: { exe, is_dylib, symlink_dir} ;
26
- use crate :: { Compiler , GitRepo , Mode } ;
26
+ use crate :: { Compiler , DependencyType , GitRepo , Mode } ;
27
27
28
28
use crate :: builder:: { Builder , Kind , RunConfig , ShouldRun , Step } ;
29
29
use crate :: cache:: { Interned , INTERNER } ;
@@ -74,6 +74,7 @@ impl Step for Std {
74
74
// Even if we're not building std this stage, the new sysroot must
75
75
// still contain the third party objects needed by various targets.
76
76
copy_third_party_objects ( builder, & compiler, target) ;
77
+ copy_self_contained_objects ( builder, & compiler, target) ;
77
78
78
79
builder. ensure ( StdLink {
79
80
compiler : compiler_to_use,
@@ -83,7 +84,8 @@ impl Step for Std {
83
84
return ;
84
85
}
85
86
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) ) ;
87
89
88
90
let mut cargo = builder. cargo ( compiler, Mode :: Std , target, "build" ) ;
89
91
std_cargo ( builder, target, compiler. stage , & mut cargo) ;
@@ -109,21 +111,76 @@ impl Step for Std {
109
111
}
110
112
}
111
113
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
+
112
128
/// Copies third party objects needed by various targets.
113
129
fn copy_third_party_objects (
114
130
builder : & Builder < ' _ > ,
115
131
compiler : & Compiler ,
116
132
target : Interned < String > ,
117
- ) -> Vec < PathBuf > {
133
+ ) -> Vec < ( PathBuf , DependencyType ) > {
118
134
let libdir = builder. sysroot_libdir ( * compiler, target) ;
119
-
120
135
let mut target_deps = vec ! [ ] ;
121
136
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" )
126
181
} ;
182
+ t ! ( fs:: create_dir_all( & libdir_self_contained) ) ;
183
+ let mut target_deps = vec ! [ ] ;
127
184
128
185
// Copies the CRT objects.
129
186
//
@@ -135,29 +192,32 @@ fn copy_third_party_objects(
135
192
if target. contains ( "musl" ) {
136
193
let srcdir = builder. musl_root ( target) . unwrap ( ) . join ( "lib" ) ;
137
194
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
+ ) ;
139
203
}
140
204
} else if target. ends_with ( "-wasi" ) {
141
205
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
+ }
161
221
}
162
222
163
223
target_deps
@@ -335,7 +395,7 @@ pub struct StartupObjects {
335
395
}
336
396
337
397
impl Step for StartupObjects {
338
- type Output = Vec < PathBuf > ;
398
+ type Output = Vec < ( PathBuf , DependencyType ) > ;
339
399
340
400
fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
341
401
run. path ( "src/rtstartup" )
@@ -354,7 +414,7 @@ impl Step for StartupObjects {
354
414
/// They don't require any library support as they're just plain old object
355
415
/// files, so we just use the nightly snapshot compiler to always build them (as
356
416
/// 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 ) > {
358
418
let for_compiler = self . compiler ;
359
419
let target = self . target ;
360
420
if !target. contains ( "windows-gnu" ) {
@@ -388,14 +448,7 @@ impl Step for StartupObjects {
388
448
389
449
let target = sysroot_dir. join ( ( * file) . to_string ( ) + ".o" ) ;
390
450
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 ) ) ;
399
452
}
400
453
401
454
target_deps
@@ -808,14 +861,17 @@ pub fn add_to_sysroot(
808
861
sysroot_host_dst : & Path ,
809
862
stamp : & Path ,
810
863
) {
864
+ let self_contained_dst = & sysroot_dst. join ( "self-contained" ) ;
811
865
t ! ( fs:: create_dir_all( & sysroot_dst) ) ;
812
866
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 ( ) ) ) ;
819
875
}
820
876
}
821
877
@@ -824,7 +880,7 @@ pub fn run_cargo(
824
880
cargo : Cargo ,
825
881
tail_args : Vec < String > ,
826
882
stamp : & Path ,
827
- additional_target_deps : Vec < PathBuf > ,
883
+ additional_target_deps : Vec < ( PathBuf , DependencyType ) > ,
828
884
is_check : bool ,
829
885
) -> Vec < PathBuf > {
830
886
if builder. config . dry_run {
@@ -875,15 +931,15 @@ pub fn run_cargo(
875
931
if filename. starts_with ( & host_root_dir) {
876
932
// Unless it's a proc macro used in the compiler
877
933
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 ) ) ;
879
935
}
880
936
continue ;
881
937
}
882
938
883
939
// If this was output in the `deps` dir then this is a precise file
884
940
// name (hash included) so we start tracking it.
885
941
if filename. starts_with ( & target_deps_dir) {
886
- deps. push ( ( filename. to_path_buf ( ) , false ) ) ;
942
+ deps. push ( ( filename. to_path_buf ( ) , DependencyType :: Target ) ) ;
887
943
continue ;
888
944
}
889
945
@@ -935,17 +991,21 @@ pub fn run_cargo(
935
991
let candidate = format ! ( "{}.lib" , path_to_add) ;
936
992
let candidate = PathBuf :: from ( candidate) ;
937
993
if candidate. exists ( ) {
938
- deps. push ( ( candidate, false ) ) ;
994
+ deps. push ( ( candidate, DependencyType :: Target ) ) ;
939
995
}
940
996
}
941
- deps. push ( ( path_to_add. into ( ) , false ) ) ;
997
+ deps. push ( ( path_to_add. into ( ) , DependencyType :: Target ) ) ;
942
998
}
943
999
944
- deps. extend ( additional_target_deps. into_iter ( ) . map ( |d| ( d , false ) ) ) ;
1000
+ deps. extend ( additional_target_deps) ;
945
1001
deps. sort ( ) ;
946
1002
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
+ } ) ;
949
1009
new_contents. extend ( dep. to_str ( ) . unwrap ( ) . as_bytes ( ) ) ;
950
1010
new_contents. extend ( b"\0 " ) ;
951
1011
}
0 commit comments