1
1
use std:: fs;
2
- use std:: path:: Path ;
2
+ use std:: path:: { Path , PathBuf } ;
3
3
use std:: process:: { self , Command } ;
4
4
5
5
use super :: path:: { Dirs , RelPath } ;
6
- use super :: rustc_info:: {
7
- get_file_name, get_rustc_version, get_toolchain_name, get_wrapper_file_name,
8
- } ;
6
+ use super :: rustc_info:: { get_file_name, get_rustc_version, get_toolchain_name} ;
9
7
use super :: utils:: { spawn_and_wait, try_hard_link, CargoProject , Compiler } ;
10
8
use super :: SysrootKind ;
11
9
12
10
static DIST_DIR : RelPath = RelPath :: DIST ;
13
11
static BIN_DIR : RelPath = RelPath :: DIST . join ( "bin" ) ;
14
12
static LIB_DIR : RelPath = RelPath :: DIST . join ( "lib" ) ;
15
- static RUSTLIB_DIR : RelPath = LIB_DIR . join ( "rustlib" ) ;
16
13
17
14
pub ( crate ) fn build_sysroot (
18
15
dirs : & Dirs ,
@@ -39,145 +36,169 @@ pub(crate) fn build_sysroot(
39
36
LIB_DIR
40
37
}
41
38
. to_path ( dirs)
42
- . join ( get_file_name ( "rustc_codegen_cranelift" , "dylib" ) ) ;
39
+ . join ( cg_clif_dylib_src . file_name ( ) . unwrap ( ) ) ;
43
40
try_hard_link ( cg_clif_dylib_src, & cg_clif_dylib_path) ;
44
41
45
42
// Build and copy rustc and cargo wrappers
43
+ let wrapper_base_name = get_file_name ( "____" , "bin" ) ;
44
+ let toolchain_name = get_toolchain_name ( ) ;
46
45
for wrapper in [ "rustc-clif" , "rustdoc-clif" , "cargo-clif" ] {
47
- let wrapper_name = get_wrapper_file_name ( wrapper , "bin" ) ;
46
+ let wrapper_name = wrapper_base_name . replace ( "____" , wrapper ) ;
48
47
49
48
let mut build_cargo_wrapper_cmd = Command :: new ( & bootstrap_host_compiler. rustc ) ;
50
49
build_cargo_wrapper_cmd
51
- . env ( "TOOLCHAIN_NAME" , get_toolchain_name ( ) )
50
+ . env ( "TOOLCHAIN_NAME" , toolchain_name . clone ( ) )
52
51
. arg ( RelPath :: SCRIPTS . to_path ( dirs) . join ( & format ! ( "{wrapper}.rs" ) ) )
53
52
. arg ( "-o" )
54
53
. arg ( DIST_DIR . to_path ( dirs) . join ( wrapper_name) )
55
- . arg ( "-g " ) ;
54
+ . arg ( "-Cstrip=debuginfo " ) ;
56
55
spawn_and_wait ( build_cargo_wrapper_cmd) ;
57
56
}
58
57
59
- let default_sysroot = super :: rustc_info:: get_default_sysroot ( & bootstrap_host_compiler. rustc ) ;
58
+ let host = build_sysroot_for_triple (
59
+ dirs,
60
+ channel,
61
+ bootstrap_host_compiler. clone ( ) ,
62
+ & cg_clif_dylib_path,
63
+ sysroot_kind,
64
+ ) ;
65
+ host. install_into_sysroot ( & DIST_DIR . to_path ( dirs) ) ;
60
66
61
- let host_rustlib_lib =
62
- RUSTLIB_DIR . to_path ( dirs) . join ( & bootstrap_host_compiler. triple ) . join ( "lib" ) ;
63
- let target_rustlib_lib = RUSTLIB_DIR . to_path ( dirs) . join ( & target_triple) . join ( "lib" ) ;
64
- fs:: create_dir_all ( & host_rustlib_lib) . unwrap ( ) ;
65
- fs:: create_dir_all ( & target_rustlib_lib) . unwrap ( ) ;
66
-
67
- if target_triple == "x86_64-pc-windows-gnu" {
68
- if !default_sysroot. join ( "lib" ) . join ( "rustlib" ) . join ( & target_triple) . join ( "lib" ) . exists ( ) {
69
- eprintln ! (
70
- "The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
71
- to compile a sysroot for it.",
72
- ) ;
73
- process:: exit ( 1 ) ;
74
- }
75
- for file in fs:: read_dir (
76
- default_sysroot. join ( "lib" ) . join ( "rustlib" ) . join ( & target_triple) . join ( "lib" ) ,
67
+ if !is_native {
68
+ build_sysroot_for_triple (
69
+ dirs,
70
+ channel,
71
+ {
72
+ let mut bootstrap_target_compiler = bootstrap_host_compiler. clone ( ) ;
73
+ bootstrap_target_compiler. triple = target_triple. clone ( ) ;
74
+ bootstrap_target_compiler. set_cross_linker_and_runner ( ) ;
75
+ bootstrap_target_compiler
76
+ } ,
77
+ & cg_clif_dylib_path,
78
+ sysroot_kind,
77
79
)
78
- . unwrap ( )
79
- {
80
- let file = file. unwrap ( ) . path ( ) ;
81
- if file. extension ( ) . map_or ( true , |ext| ext. to_str ( ) . unwrap ( ) != "o" ) {
82
- continue ; // only copy object files
83
- }
84
- try_hard_link ( & file, target_rustlib_lib. join ( file. file_name ( ) . unwrap ( ) ) ) ;
85
- }
80
+ . install_into_sysroot ( & DIST_DIR . to_path ( dirs) ) ;
86
81
}
87
82
88
- match sysroot_kind {
89
- SysrootKind :: None => { } // Nothing to do
90
- SysrootKind :: Llvm => {
91
- for file in fs:: read_dir (
92
- default_sysroot
93
- . join ( "lib" )
94
- . join ( "rustlib" )
95
- . join ( & bootstrap_host_compiler. triple )
96
- . join ( "lib" ) ,
97
- )
98
- . unwrap ( )
99
- {
100
- let file = file. unwrap ( ) . path ( ) ;
101
- let file_name_str = file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
102
- if ( file_name_str. contains ( "rustc_" )
103
- && !file_name_str. contains ( "rustc_std_workspace_" )
104
- && !file_name_str. contains ( "rustc_demangle" ) )
105
- || file_name_str. contains ( "chalk" )
106
- || file_name_str. contains ( "tracing" )
107
- || file_name_str. contains ( "regex" )
108
- {
109
- // These are large crates that are part of the rustc-dev component and are not
110
- // necessary to run regular programs.
111
- continue ;
112
- }
113
- try_hard_link ( & file, host_rustlib_lib. join ( file. file_name ( ) . unwrap ( ) ) ) ;
114
- }
115
-
116
- if !is_native {
117
- for file in fs:: read_dir (
118
- default_sysroot. join ( "lib" ) . join ( "rustlib" ) . join ( & target_triple) . join ( "lib" ) ,
119
- )
120
- . unwrap ( )
121
- {
122
- let file = file. unwrap ( ) . path ( ) ;
123
- try_hard_link ( & file, target_rustlib_lib. join ( file. file_name ( ) . unwrap ( ) ) ) ;
124
- }
125
- }
126
- }
127
- SysrootKind :: Clif => {
128
- build_clif_sysroot_for_triple (
129
- dirs,
130
- channel,
131
- bootstrap_host_compiler. clone ( ) ,
132
- & cg_clif_dylib_path,
133
- ) ;
134
-
135
- if !is_native {
136
- build_clif_sysroot_for_triple (
137
- dirs,
138
- channel,
139
- {
140
- let mut bootstrap_target_compiler = bootstrap_host_compiler. clone ( ) ;
141
- bootstrap_target_compiler. triple = target_triple. clone ( ) ;
142
- bootstrap_target_compiler. set_cross_linker_and_runner ( ) ;
143
- bootstrap_target_compiler
144
- } ,
145
- & cg_clif_dylib_path,
146
- ) ;
147
- }
148
-
149
- // Copy std for the host to the lib dir. This is necessary for the jit mode to find
150
- // libstd.
151
- for file in fs:: read_dir ( host_rustlib_lib) . unwrap ( ) {
152
- let file = file. unwrap ( ) . path ( ) ;
153
- let filename = file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
154
- if filename. contains ( "std-" ) && !filename. contains ( ".rlib" ) {
155
- try_hard_link ( & file, LIB_DIR . to_path ( dirs) . join ( file. file_name ( ) . unwrap ( ) ) ) ;
156
- }
157
- }
83
+ // Copy std for the host to the lib dir. This is necessary for the jit mode to find
84
+ // libstd.
85
+ for lib in host. libs {
86
+ let filename = lib. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
87
+ if filename. contains ( "std-" ) && !filename. contains ( ".rlib" ) {
88
+ try_hard_link ( & lib, LIB_DIR . to_path ( dirs) . join ( lib. file_name ( ) . unwrap ( ) ) ) ;
158
89
}
159
90
}
160
91
161
- let mut target_compiler = Compiler :: clif_with_triple ( & dirs, target_triple) ;
92
+ let mut target_compiler = {
93
+ let dirs: & Dirs = & dirs;
94
+ let rustc_clif =
95
+ RelPath :: DIST . to_path ( & dirs) . join ( wrapper_base_name. replace ( "____" , "rustc-clif" ) ) ;
96
+ let rustdoc_clif =
97
+ RelPath :: DIST . to_path ( & dirs) . join ( wrapper_base_name. replace ( "____" , "rustdoc-clif" ) ) ;
98
+
99
+ Compiler {
100
+ cargo : bootstrap_host_compiler. cargo . clone ( ) ,
101
+ rustc : rustc_clif. clone ( ) ,
102
+ rustdoc : rustdoc_clif. clone ( ) ,
103
+ rustflags : String :: new ( ) ,
104
+ rustdocflags : String :: new ( ) ,
105
+ triple : target_triple,
106
+ runner : vec ! [ ] ,
107
+ }
108
+ } ;
162
109
if !is_native {
163
110
target_compiler. set_cross_linker_and_runner ( ) ;
164
111
}
165
112
target_compiler
166
113
}
167
114
115
+ struct SysrootTarget {
116
+ triple : String ,
117
+ libs : Vec < PathBuf > ,
118
+ }
119
+
120
+ impl SysrootTarget {
121
+ fn install_into_sysroot ( & self , sysroot : & Path ) {
122
+ if self . libs . is_empty ( ) {
123
+ return ;
124
+ }
125
+
126
+ let target_rustlib_lib = sysroot. join ( "lib" ) . join ( "rustlib" ) . join ( & self . triple ) . join ( "lib" ) ;
127
+ fs:: create_dir_all ( & target_rustlib_lib) . unwrap ( ) ;
128
+
129
+ for lib in & self . libs {
130
+ try_hard_link ( lib, target_rustlib_lib. join ( lib. file_name ( ) . unwrap ( ) ) ) ;
131
+ }
132
+ }
133
+ }
134
+
168
135
pub ( crate ) static ORIG_BUILD_SYSROOT : RelPath = RelPath :: SOURCE . join ( "build_sysroot" ) ;
169
136
pub ( crate ) static BUILD_SYSROOT : RelPath = RelPath :: DOWNLOAD . join ( "sysroot" ) ;
170
137
pub ( crate ) static SYSROOT_RUSTC_VERSION : RelPath = BUILD_SYSROOT . join ( "rustc_version" ) ;
171
138
pub ( crate ) static SYSROOT_SRC : RelPath = BUILD_SYSROOT . join ( "sysroot_src" ) ;
172
139
pub ( crate ) static STANDARD_LIBRARY : CargoProject =
173
140
CargoProject :: new ( & BUILD_SYSROOT , "build_sysroot" ) ;
141
+ pub ( crate ) static RTSTARTUP_SYSROOT : RelPath = RelPath :: BUILD . join ( "rtstartup" ) ;
174
142
143
+ #[ must_use]
144
+ fn build_sysroot_for_triple (
145
+ dirs : & Dirs ,
146
+ channel : & str ,
147
+ compiler : Compiler ,
148
+ cg_clif_dylib_path : & Path ,
149
+ sysroot_kind : SysrootKind ,
150
+ ) -> SysrootTarget {
151
+ match sysroot_kind {
152
+ SysrootKind :: None => build_rtstartup ( dirs, & compiler)
153
+ . unwrap_or ( SysrootTarget { triple : compiler. triple , libs : vec ! [ ] } ) ,
154
+ SysrootKind :: Llvm => build_llvm_sysroot_for_triple ( compiler) ,
155
+ SysrootKind :: Clif => {
156
+ build_clif_sysroot_for_triple ( dirs, channel, compiler, & cg_clif_dylib_path)
157
+ }
158
+ }
159
+ }
160
+
161
+ #[ must_use]
162
+ fn build_llvm_sysroot_for_triple ( compiler : Compiler ) -> SysrootTarget {
163
+ let default_sysroot = super :: rustc_info:: get_default_sysroot ( & compiler. rustc ) ;
164
+
165
+ let mut target_libs = SysrootTarget { triple : compiler. triple , libs : vec ! [ ] } ;
166
+
167
+ for entry in fs:: read_dir (
168
+ default_sysroot. join ( "lib" ) . join ( "rustlib" ) . join ( & target_libs. triple ) . join ( "lib" ) ,
169
+ )
170
+ . unwrap ( )
171
+ {
172
+ let entry = entry. unwrap ( ) ;
173
+ if entry. file_type ( ) . unwrap ( ) . is_dir ( ) {
174
+ continue ;
175
+ }
176
+ let file = entry. path ( ) ;
177
+ let file_name_str = file. file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
178
+ if ( file_name_str. contains ( "rustc_" )
179
+ && !file_name_str. contains ( "rustc_std_workspace_" )
180
+ && !file_name_str. contains ( "rustc_demangle" ) )
181
+ || file_name_str. contains ( "chalk" )
182
+ || file_name_str. contains ( "tracing" )
183
+ || file_name_str. contains ( "regex" )
184
+ {
185
+ // These are large crates that are part of the rustc-dev component and are not
186
+ // necessary to run regular programs.
187
+ continue ;
188
+ }
189
+ target_libs. libs . push ( file) ;
190
+ }
191
+
192
+ target_libs
193
+ }
194
+
195
+ #[ must_use]
175
196
fn build_clif_sysroot_for_triple (
176
197
dirs : & Dirs ,
177
198
channel : & str ,
178
199
mut compiler : Compiler ,
179
200
cg_clif_dylib_path : & Path ,
180
- ) {
201
+ ) -> SysrootTarget {
181
202
match fs:: read_to_string ( SYSROOT_RUSTC_VERSION . to_path ( dirs) ) {
182
203
Err ( e) => {
183
204
eprintln ! ( "Failed to get rustc version for patched sysroot source: {}" , e) ;
@@ -196,6 +217,14 @@ fn build_clif_sysroot_for_triple(
196
217
}
197
218
}
198
219
220
+ let mut target_libs = SysrootTarget { triple : compiler. triple . clone ( ) , libs : vec ! [ ] } ;
221
+
222
+ if let Some ( rtstartup_target_libs) = build_rtstartup ( dirs, & compiler) {
223
+ rtstartup_target_libs. install_into_sysroot ( & RTSTARTUP_SYSROOT . to_path ( dirs) ) ;
224
+
225
+ target_libs. libs . extend ( rtstartup_target_libs. libs ) ;
226
+ }
227
+
199
228
let build_dir = STANDARD_LIBRARY . target_dir ( dirs) . join ( & compiler. triple ) . join ( channel) ;
200
229
201
230
if !super :: config:: get_bool ( "keep_sysroot" ) {
@@ -209,7 +238,9 @@ fn build_clif_sysroot_for_triple(
209
238
// Build sysroot
210
239
let mut rustflags = " -Zforce-unstable-if-unmarked -Cpanic=abort" . to_string ( ) ;
211
240
rustflags. push_str ( & format ! ( " -Zcodegen-backend={}" , cg_clif_dylib_path. to_str( ) . unwrap( ) ) ) ;
212
- rustflags. push_str ( & format ! ( " --sysroot={}" , DIST_DIR . to_path( dirs) . to_str( ) . unwrap( ) ) ) ;
241
+ // Necessary for MinGW to find rsbegin.o and rsend.o
242
+ rustflags
243
+ . push_str ( & format ! ( " --sysroot={}" , RTSTARTUP_SYSROOT . to_path( dirs) . to_str( ) . unwrap( ) ) ) ;
213
244
if channel == "release" {
214
245
rustflags. push_str ( " -Zmir-opt-level=3" ) ;
215
246
}
@@ -221,7 +252,6 @@ fn build_clif_sysroot_for_triple(
221
252
build_cmd. env ( "__CARGO_DEFAULT_LIB_METADATA" , "cg_clif" ) ;
222
253
spawn_and_wait ( build_cmd) ;
223
254
224
- // Copy all relevant files to the sysroot
225
255
for entry in fs:: read_dir ( build_dir. join ( "deps" ) ) . unwrap ( ) {
226
256
let entry = entry. unwrap ( ) ;
227
257
if let Some ( ext) = entry. path ( ) . extension ( ) {
@@ -231,9 +261,35 @@ fn build_clif_sysroot_for_triple(
231
261
} else {
232
262
continue ;
233
263
} ;
234
- try_hard_link (
235
- entry. path ( ) ,
236
- RUSTLIB_DIR . to_path ( dirs) . join ( & compiler. triple ) . join ( "lib" ) . join ( entry. file_name ( ) ) ,
237
- ) ;
264
+ target_libs. libs . push ( entry. path ( ) ) ;
265
+ }
266
+
267
+ target_libs
268
+ }
269
+
270
+ fn build_rtstartup ( dirs : & Dirs , compiler : & Compiler ) -> Option < SysrootTarget > {
271
+ if !compiler. triple . ends_with ( "windows-gnu" ) {
272
+ return None ;
273
+ }
274
+
275
+ RTSTARTUP_SYSROOT . ensure_fresh ( dirs) ;
276
+
277
+ let rtstartup_src = SYSROOT_SRC . to_path ( dirs) . join ( "library" ) . join ( "rtstartup" ) ;
278
+ let mut target_libs = SysrootTarget { triple : compiler. triple . clone ( ) , libs : vec ! [ ] } ;
279
+
280
+ for file in [ "rsbegin" , "rsend" ] {
281
+ let obj = RTSTARTUP_SYSROOT . to_path ( dirs) . join ( format ! ( "{file}.o" ) ) ;
282
+ let mut build_rtstartup_cmd = Command :: new ( & compiler. rustc ) ;
283
+ build_rtstartup_cmd
284
+ . arg ( "--target" )
285
+ . arg ( & compiler. triple )
286
+ . arg ( "--emit=obj" )
287
+ . arg ( "-o" )
288
+ . arg ( & obj)
289
+ . arg ( rtstartup_src. join ( format ! ( "{file}.rs" ) ) ) ;
290
+ spawn_and_wait ( build_rtstartup_cmd) ;
291
+ target_libs. libs . push ( obj. clone ( ) ) ;
238
292
}
293
+
294
+ Some ( target_libs)
239
295
}
0 commit comments