]> git.proxmox.com Git - rustc.git/blame - src/bootstrap/compile.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / src / bootstrap / compile.rs
CommitLineData
a7813a04
XL
1//! Implementation of compiling various phases of the compiler and standard
2//! library.
3//!
4//! This module contains some of the real meat in the rustbuild build system
136023e0
XL
5//! which is where Cargo is used to compile the standard library, libtest, and
6//! the compiler. This module is also responsible for assembling the sysroot as it
a7813a04
XL
7//! goes along from the output of the previous stage.
8
0531ce1d 9use std::borrow::Cow;
5869c6ff 10use std::collections::HashSet;
7cac9316 11use std::env;
49aad941 12use std::ffi::OsStr;
0731742a 13use std::fs;
7cac9316 14use std::io::prelude::*;
dfeec247 15use std::io::BufReader;
7453a54e 16use std::path::{Path, PathBuf};
064997fb 17use std::process::{Command, Stdio};
7cac9316 18use std::str;
7453a54e 19
9ffffee4 20use serde_derive::Deserialize;
7453a54e 21
9c376795 22use crate::builder::crate_description;
e1599b0c 23use crate::builder::Cargo;
353b0b11 24use crate::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath};
f035d41b 25use crate::cache::{Interned, INTERNER};
2b03887a 26use crate::config::{LlvmLibunwind, RustcLto, TargetSelection};
dfeec247 27use crate::dist;
353b0b11 28use crate::llvm;
f035d41b 29use crate::tool::SourceType;
064997fb 30use crate::util::get_clang_cl_resource_dir;
5e7ed085 31use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date};
a2a8927a 32use crate::LLVM_TOOLS;
5099ac24 33use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
3b2f2976 34
064997fb 35#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
3b2f2976 36pub struct Std {
3dfed10e 37 pub target: TargetSelection,
3b2f2976 38 pub compiler: Compiler,
064997fb
FG
39 /// Whether to build only a subset of crates in the standard library.
40 ///
41 /// This shouldn't be used from other steps; see the comment on [`Rustc`].
42 crates: Interned<Vec<String>>,
fe692bf9
FG
43 /// When using download-rustc, we need to use a new build of `std` for running unit tests of Std itself,
44 /// but we need to use the downloaded copy of std for linking to rustdoc. Allow this to be overriden by `builder.ensure` from other steps.
45 force_recompile: bool,
064997fb
FG
46}
47
48impl Std {
49 pub fn new(compiler: Compiler, target: TargetSelection) -> Self {
fe692bf9
FG
50 Self { target, compiler, crates: Default::default(), force_recompile: false }
51 }
52
53 pub fn force_recompile(compiler: Compiler, target: TargetSelection) -> Self {
54 Self { target, compiler, crates: Default::default(), force_recompile: true }
064997fb
FG
55 }
56}
57
fe692bf9
FG
58/// Given an `alias` selected by the `Step` and the paths passed on the command line,
59/// return a list of the crates that should be built.
60///
61/// Normally, people will pass *just* `library` if they pass it.
62/// But it's possible (although strange) to pass something like `library std core`.
63/// Build all crates anyway, as if they hadn't passed the other args.
64pub(crate) fn make_run_crates(run: &RunConfig<'_>, alias: &str) -> Interned<Vec<String>> {
65 let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias));
66 if has_alias { Default::default() } else { run.cargo_crates_in_set() }
67}
68
3b2f2976
XL
69impl Step for Std {
70 type Output = ();
71 const DEFAULT: bool = true;
72
9fa01778 73 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
6a06907d
XL
74 // When downloading stage1, the standard library has already been copied to the sysroot, so
75 // there's no need to rebuild it.
923072b8 76 let builder = run.builder;
49aad941 77 run.crate_or_deps("sysroot")
923072b8
FG
78 .path("library")
79 .lazy_default_condition(Box::new(|| !builder.download_rustc()))
3b2f2976
XL
80 }
81
9fa01778 82 fn make_run(run: RunConfig<'_>) {
3b2f2976 83 run.builder.ensure(Std {
1b1a35ee 84 compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
3b2f2976 85 target: run.target,
fe692bf9
FG
86 crates: make_run_crates(&run, "library"),
87 force_recompile: false,
3b2f2976
XL
88 });
89 }
90
9fa01778 91 /// Builds the standard library.
3b2f2976
XL
92 ///
93 /// This will build the standard library for a particular stage of the build
94 /// using the `compiler` targeting the `target` architecture. The artifacts
95 /// created will also be linked into the sysroot directory.
9fa01778 96 fn run(self, builder: &Builder<'_>) {
3b2f2976
XL
97 let target = self.target;
98 let compiler = self.compiler;
99
fe692bf9
FG
100 // When using `download-rustc`, we already have artifacts for the host available. Don't
101 // recompile them.
102 if builder.download_rustc() && target == builder.build.build
103 // NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so
104 // its artifacts can't be reused.
105 && compiler.stage != 0
106 // This check is specific to testing std itself; see `test::Std` for more details.
107 && !self.force_recompile
108 {
109 cp_rustc_component_to_ci_sysroot(
110 builder,
111 compiler,
112 builder.config.ci_rust_std_contents(),
113 );
6a06907d
XL
114 return;
115 }
116
1b1a35ee
XL
117 if builder.config.keep_stage.contains(&compiler.stage)
118 || builder.config.keep_stage_std.contains(&compiler.stage)
119 {
8faf50e0 120 builder.info("Warning: Using a potentially old libstd. This may not behave well.");
fe692bf9
FG
121
122 copy_third_party_objects(builder, &compiler, target);
123 copy_self_contained_objects(builder, &compiler, target);
124
064997fb 125 builder.ensure(StdLink::from_std(self, compiler));
8faf50e0
XL
126 return;
127 }
128
136023e0
XL
129 builder.update_submodule(&Path::new("library").join("stdarch"));
130
064997fb
FG
131 // Profiler information requires LLVM's compiler-rt
132 if builder.config.profiler {
133 builder.update_submodule(&Path::new("src/llvm-project"));
134 }
135
e74abb32 136 let mut target_deps = builder.ensure(StartupObjects { compiler, target });
3b2f2976 137
dc9dc135
XL
138 let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
139 if compiler_to_use != compiler {
064997fb 140 builder.ensure(Std::new(compiler_to_use, target));
9ffffee4
FG
141 let msg = if compiler_to_use.host == target {
142 format!(
143 "Uplifting library (stage{} -> stage{})",
144 compiler_to_use.stage, compiler.stage
145 )
146 } else {
147 format!(
148 "Uplifting library (stage{}:{} -> stage{}:{})",
149 compiler_to_use.stage, compiler_to_use.host, compiler.stage, target
150 )
151 };
152 builder.info(&msg);
3b2f2976
XL
153
154 // Even if we're not building std this stage, the new sysroot must
0731742a
XL
155 // still contain the third party objects needed by various targets.
156 copy_third_party_objects(builder, &compiler, target);
f035d41b 157 copy_self_contained_objects(builder, &compiler, target);
3b2f2976 158
064997fb 159 builder.ensure(StdLink::from_std(self, compiler_to_use));
3b2f2976
XL
160 return;
161 }
162
f035d41b
XL
163 target_deps.extend(copy_third_party_objects(builder, &compiler, target));
164 target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
3b2f2976 165
f035d41b 166 let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
f9f354fc 167 std_cargo(builder, target, compiler.stage, &mut cargo);
9c376795
FG
168 for krate in &*self.crates {
169 cargo.arg("-p").arg(krate);
170 }
0531ce1d 171
fe692bf9
FG
172 // See src/bootstrap/synthetic_targets.rs
173 if target.is_synthetic() {
174 cargo.env("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET", "1");
175 }
176
49aad941
FG
177 let _guard = builder.msg(
178 Kind::Build,
179 compiler.stage,
180 format_args!("library artifacts{}", crate_description(&self.crates)),
181 compiler.host,
182 target,
183 );
dfeec247
XL
184 run_cargo(
185 builder,
186 cargo,
9c376795 187 vec![],
dfeec247
XL
188 &libstd_stamp(builder, compiler, target),
189 target_deps,
190 false,
9c376795 191 false,
dfeec247 192 );
3b2f2976 193
064997fb
FG
194 builder.ensure(StdLink::from_std(
195 self,
196 builder.compiler(compiler.stage, builder.config.build),
197 ));
3b2f2976
XL
198 }
199}
200
f035d41b
XL
201fn copy_and_stamp(
202 builder: &Builder<'_>,
203 libdir: &Path,
204 sourcedir: &Path,
205 name: &str,
206 target_deps: &mut Vec<(PathBuf, DependencyType)>,
207 dependency_type: DependencyType,
208) {
209 let target = libdir.join(name);
210 builder.copy(&sourcedir.join(name), &target);
211
212 target_deps.push((target, dependency_type));
213}
214
94222f64 215fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf {
353b0b11 216 let libunwind_path = builder.ensure(llvm::Libunwind { target });
94222f64
XL
217 let libunwind_source = libunwind_path.join("libunwind.a");
218 let libunwind_target = libdir.join("libunwind.a");
219 builder.copy(&libunwind_source, &libunwind_target);
220 libunwind_target
221}
222
60c5eb7d 223/// Copies third party objects needed by various targets.
dfeec247
XL
224fn copy_third_party_objects(
225 builder: &Builder<'_>,
226 compiler: &Compiler,
3dfed10e 227 target: TargetSelection,
f035d41b 228) -> Vec<(PathBuf, DependencyType)> {
e74abb32
XL
229 let mut target_deps = vec![];
230
f035d41b
XL
231 // FIXME: remove this in 2021
232 if target == "x86_64-fortanix-unknown-sgx" {
233 if env::var_os("X86_FORTANIX_SGX_LIBS").is_some() {
234 builder.info("Warning: X86_FORTANIX_SGX_LIBS environment variable is ignored, libunwind is now compiled as part of rustbuild");
235 }
236 }
237
29967ef6 238 if builder.config.sanitizers_enabled(target) && compiler.stage != 0 {
f035d41b
XL
239 // The sanitizers are only copied in stage1 or above,
240 // to avoid creating dependency on LLVM.
241 target_deps.extend(
242 copy_sanitizers(builder, &compiler, target)
243 .into_iter()
244 .map(|d| (d, DependencyType::Target)),
245 );
246 }
247
94222f64 248 if target == "x86_64-fortanix-unknown-sgx"
923072b8 249 || builder.config.llvm_libunwind(target) == LlvmLibunwind::InTree
94222f64
XL
250 && (target.contains("linux") || target.contains("fuchsia"))
251 {
252 let libunwind_path =
253 copy_llvm_libunwind(builder, target, &builder.sysroot_libdir(*compiler, target));
254 target_deps.push((libunwind_path, DependencyType::Target));
255 }
256
f035d41b
XL
257 target_deps
258}
259
260/// Copies third party objects needed by various targets for self-contained linkage.
261fn copy_self_contained_objects(
262 builder: &Builder<'_>,
263 compiler: &Compiler,
3dfed10e 264 target: TargetSelection,
f035d41b 265) -> Vec<(PathBuf, DependencyType)> {
3dfed10e 266 let libdir_self_contained = builder.sysroot_libdir(*compiler, target).join("self-contained");
f035d41b
XL
267 t!(fs::create_dir_all(&libdir_self_contained));
268 let mut target_deps = vec![];
e74abb32 269
3c0e092e 270 // Copies the libc and CRT objects.
0731742a 271 //
f9f354fc
XL
272 // rustc historically provides a more self-contained installation for musl targets
273 // not requiring the presence of a native musl toolchain. For example, it can fall back
274 // to using gcc from a glibc-targeting toolchain for linking.
275 // To do that we have to distribute musl startup objects as a part of Rust toolchain
276 // and link with them manually in the self-contained mode.
0731742a 277 if target.contains("musl") {
6a06907d
XL
278 let srcdir = builder.musl_libdir(target).unwrap_or_else(|| {
279 panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple)
280 });
3c0e092e 281 for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] {
f035d41b
XL
282 copy_and_stamp(
283 builder,
284 &libdir_self_contained,
285 &srcdir,
286 obj,
287 &mut target_deps,
288 DependencyType::TargetSelfContained,
289 );
0731742a 290 }
353b0b11 291 let crt_path = builder.ensure(llvm::CrtBeginEnd { target });
6a06907d 292 for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] {
cdc7bbd5 293 let src = crt_path.join(obj);
6a06907d
XL
294 let target = libdir_self_contained.join(obj);
295 builder.copy(&src, &target);
296 target_deps.push((target, DependencyType::TargetSelfContained));
297 }
94222f64 298
5099ac24
FG
299 if !target.starts_with("s390x") {
300 let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained);
301 target_deps.push((libunwind_path, DependencyType::TargetSelfContained));
302 }
532ac7d7 303 } else if target.ends_with("-wasi") {
6a06907d
XL
304 let srcdir = builder
305 .wasi_root(target)
306 .unwrap_or_else(|| {
307 panic!("Target {:?} does not have a \"wasi-root\" key", target.triple)
308 })
309 .join("lib/wasm32-wasi");
3c0e092e 310 for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
5869c6ff
XL
311 copy_and_stamp(
312 builder,
313 &libdir_self_contained,
314 &srcdir,
315 obj,
316 &mut target_deps,
317 DependencyType::TargetSelfContained,
318 );
319 }
04454e1e 320 } else if target.ends_with("windows-gnu") {
f035d41b 321 for obj in ["crt2.o", "dllcrt2.o"].iter() {
fe692bf9 322 let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj);
f035d41b
XL
323 let target = libdir_self_contained.join(obj);
324 builder.copy(&src, &target);
325 target_deps.push((target, DependencyType::TargetSelfContained));
326 }
dfeec247
XL
327 }
328
e74abb32 329 target_deps
3b2f2976
XL
330}
331
332/// Configure cargo to compile the standard library, adding appropriate env vars
333/// and such.
3dfed10e 334pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
041b39d2 335 if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
8bb4bdeb
XL
336 cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
337 }
338
dc9dc135
XL
339 // Determine if we're going to compile in optimized C intrinsics to
340 // the `compiler-builtins` crate. These intrinsics live in LLVM's
487cf647
FG
341 // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
342 // always checked out, so we need to conditionally look for this. (e.g. if
343 // an external LLVM is used we skip the LLVM submodule checkout).
dc9dc135
XL
344 //
345 // Note that this shouldn't affect the correctness of `compiler-builtins`,
346 // but only its speed. Some intrinsics in C haven't been translated to Rust
347 // yet but that's pretty rare. Other intrinsics have optimized
348 // implementations in C which have only had slower versions ported to Rust,
349 // so we favor the C version where we can, but it's not critical.
350 //
351 // If `compiler-rt` is available ensure that the `c` feature of the
352 // `compiler-builtins` crate is enabled and it's configured to learn where
353 // `compiler-rt` is located.
487cf647
FG
354 let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
355 let compiler_builtins_c_feature = if compiler_builtins_root.exists() {
ba9703b0
XL
356 // Note that `libprofiler_builtins/build.rs` also computes this so if
357 // you're changing something here please also change that.
dc9dc135 358 cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
29967ef6 359 " compiler-builtins-c"
dc9dc135 360 } else {
29967ef6 361 ""
dc9dc135
XL
362 };
363
353b0b11
FG
364 // `libtest` uses this to know whether or not to support
365 // `-Zunstable-options`.
366 if !builder.unstable_features() {
367 cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
368 }
369
9c376795
FG
370 let mut features = String::new();
371
372 // Cranelift doesn't support `asm`.
373 if stage != 0 && builder.config.default_codegen_backend().unwrap_or_default() == "cranelift" {
374 features += " compiler-builtins-no-asm";
375 }
376
83c7162d 377 if builder.no_std(target) == Some(true) {
9c376795 378 features += " compiler-builtins-mem";
17df50a5
XL
379 if !target.starts_with("bpf") {
380 features.push_str(compiler_builtins_c_feature);
381 }
dc9dc135 382
83c7162d 383 // for no-std targets we only compile a few no_std crates
0731742a 384 cargo
83c7162d 385 .args(&["-p", "alloc"])
83c7162d 386 .arg("--manifest-path")
3dfed10e 387 .arg(builder.src.join("library/alloc/Cargo.toml"))
0731742a 388 .arg("--features")
29967ef6 389 .arg(features);
83c7162d 390 } else {
9c376795 391 features += &builder.std_features(target);
29967ef6 392 features.push_str(compiler_builtins_c_feature);
8bb4bdeb 393
dfeec247
XL
394 cargo
395 .arg("--features")
396 .arg(features)
83c7162d 397 .arg("--manifest-path")
49aad941 398 .arg(builder.src.join("library/sysroot/Cargo.toml"));
7453a54e 399
e1599b0c
XL
400 // Help the libc crate compile by assisting it in finding various
401 // sysroot native libraries.
83c7162d 402 if target.contains("musl") {
f035d41b
XL
403 if let Some(p) = builder.musl_libdir(target) {
404 let root = format!("native={}", p.to_str().unwrap());
e1599b0c 405 cargo.rustflag("-L").rustflag(&root);
83c7162d 406 }
7453a54e 407 }
532ac7d7
XL
408
409 if target.ends_with("-wasi") {
410 if let Some(p) = builder.wasi_root(target) {
e1599b0c
XL
411 let root = format!("native={}/lib/wasm32-wasi", p.to_str().unwrap());
412 cargo.rustflag("-L").rustflag(&root);
532ac7d7
XL
413 }
414 }
7453a54e 415 }
f9f354fc
XL
416
417 // By default, rustc uses `-Cembed-bitcode=yes`, and Cargo overrides that
418 // with `-Cembed-bitcode=no` for non-LTO builds. However, libstd must be
419 // built with bitcode so that the produced rlibs can be used for both LTO
420 // builds (which use bitcode) and non-LTO builds (which use object code).
421 // So we override the override here!
422 //
423 // But we don't bother for the stage 0 compiler because it's never used
424 // with LTO.
425 if stage >= 1 {
426 cargo.rustflag("-Cembed-bitcode=yes");
427 }
9ffffee4
FG
428 if builder.config.rust_lto == RustcLto::Off {
429 cargo.rustflag("-Clto=off");
430 }
f035d41b
XL
431
432 // By default, rustc does not include unwind tables unless they are required
433 // for a particular target. They are not required by RISC-V targets, but
434 // compiling the standard library with them means that users can get
435 // backtraces without having to recompile the standard library themselves.
436 //
437 // This choice was discussed in https://github.com/rust-lang/rust/pull/69890
438 if target.contains("riscv") {
439 cargo.rustflag("-Cforce-unwind-tables=yes");
440 }
17df50a5
XL
441
442 let html_root =
443 format!("-Zcrate-attr=doc(html_root_url=\"{}/\")", builder.doc_rust_lang_org_channel(),);
444 cargo.rustflag(&html_root);
445 cargo.rustdocflag(&html_root);
49aad941
FG
446
447 cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)");
7453a54e
SL
448}
449
3b2f2976
XL
450#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
451struct StdLink {
452 pub compiler: Compiler,
453 pub target_compiler: Compiler,
3dfed10e 454 pub target: TargetSelection,
064997fb
FG
455 /// Not actually used; only present to make sure the cache invalidation is correct.
456 crates: Interned<Vec<String>>,
fe692bf9
FG
457 /// See [`Std::force_recompile`].
458 force_recompile: bool,
064997fb
FG
459}
460
461impl StdLink {
462 fn from_std(std: Std, host_compiler: Compiler) -> Self {
463 Self {
464 compiler: host_compiler,
465 target_compiler: std.compiler,
466 target: std.target,
467 crates: std.crates,
fe692bf9 468 force_recompile: std.force_recompile,
064997fb
FG
469 }
470 }
54a0048b
SL
471}
472
3b2f2976
XL
473impl Step for StdLink {
474 type Output = ();
475
9fa01778 476 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
477 run.never()
478 }
479
480 /// Link all libstd rlibs/dylibs into the sysroot location.
481 ///
a1dfa0c6 482 /// Links those artifacts generated by `compiler` to the `stage` compiler's
3b2f2976
XL
483 /// sysroot for the specified `host` and `target`.
484 ///
485 /// Note that this assumes that `compiler` has already generated the libstd
486 /// libraries for `target`, and this method will find them in the relevant
487 /// output directory.
9fa01778 488 fn run(self, builder: &Builder<'_>) {
3b2f2976
XL
489 let compiler = self.compiler;
490 let target_compiler = self.target_compiler;
491 let target = self.target;
fe692bf9
FG
492
493 // NOTE: intentionally does *not* check `target == builder.build` to avoid having to add the same check in `test::Crate`.
494 let (libdir, hostdir) = if self.force_recompile && builder.download_rustc() {
495 // NOTE: copies part of `sysroot_libdir` to avoid having to add a new `force_recompile` argument there too
496 let lib = builder.sysroot_libdir_relative(self.compiler);
497 let sysroot = builder.ensure(crate::compile::Sysroot {
498 compiler: self.compiler,
499 force_recompile: self.force_recompile,
500 });
501 let libdir = sysroot.join(lib).join("rustlib").join(target.triple).join("lib");
502 let hostdir = sysroot.join(lib).join("rustlib").join(compiler.host.triple).join("lib");
503 (INTERNER.intern_path(libdir), INTERNER.intern_path(hostdir))
504 } else {
505 let libdir = builder.sysroot_libdir(target_compiler, target);
506 let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
507 (libdir, hostdir)
508 };
509
532ac7d7 510 add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
54a0048b 511 }
7453a54e
SL
512}
513
dfeec247
XL
514/// Copies sanitizer runtime libraries into target libdir.
515fn copy_sanitizers(
9fa01778 516 builder: &Builder<'_>,
dfeec247 517 compiler: &Compiler,
3dfed10e 518 target: TargetSelection,
dfeec247 519) -> Vec<PathBuf> {
353b0b11 520 let runtimes: Vec<llvm::SanitizerRuntime> = builder.ensure(llvm::Sanitizers { target });
dfeec247 521
487cf647 522 if builder.config.dry_run() {
dfeec247
XL
523 return Vec::new();
524 }
525
526 let mut target_deps = Vec::new();
527 let libdir = builder.sysroot_libdir(*compiler, target);
528
529 for runtime in &runtimes {
530 let dst = libdir.join(&runtime.name);
531 builder.copy(&runtime.path, &dst);
532
9ffffee4
FG
533 if target == "x86_64-apple-darwin"
534 || target == "aarch64-apple-darwin"
535 || target == "aarch64-apple-ios"
536 || target == "aarch64-apple-ios-sim"
537 || target == "x86_64-apple-ios"
538 {
2b03887a 539 // Update the library’s install name to reflect that it has been renamed.
5869c6ff
XL
540 apple_darwin_update_library_name(&dst, &format!("@rpath/{}", &runtime.name));
541 // Upon renaming the install name, the code signature of the file will invalidate,
542 // so we will sign it again.
543 apple_darwin_sign_file(&dst);
dfeec247
XL
544 }
545
546 target_deps.push(dst);
7cac9316 547 }
dfeec247
XL
548
549 target_deps
7cac9316
XL
550}
551
5869c6ff
XL
552fn apple_darwin_update_library_name(library_path: &Path, new_name: &str) {
553 let status = Command::new("install_name_tool")
554 .arg("-id")
555 .arg(new_name)
556 .arg(library_path)
557 .status()
558 .expect("failed to execute `install_name_tool`");
559 assert!(status.success());
560}
561
562fn apple_darwin_sign_file(file_path: &Path) {
563 let status = Command::new("codesign")
564 .arg("-f") // Force to rewrite the existing signature
565 .arg("-s")
566 .arg("-")
567 .arg(file_path)
568 .status()
569 .expect("failed to execute `codesign`");
570 assert!(status.success());
571}
572
3b2f2976
XL
573#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
574pub struct StartupObjects {
575 pub compiler: Compiler,
3dfed10e 576 pub target: TargetSelection,
3b2f2976
XL
577}
578
579impl Step for StartupObjects {
f035d41b 580 type Output = Vec<(PathBuf, DependencyType)>;
3b2f2976 581
9fa01778 582 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3dfed10e 583 run.path("library/rtstartup")
3b2f2976
XL
584 }
585
9fa01778 586 fn make_run(run: RunConfig<'_>) {
3b2f2976 587 run.builder.ensure(StartupObjects {
1b1a35ee 588 compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
3b2f2976
XL
589 target: run.target,
590 });
591 }
592
9fa01778 593 /// Builds and prepare startup objects like rsbegin.o and rsend.o
3b2f2976
XL
594 ///
595 /// These are primarily used on Windows right now for linking executables/dlls.
596 /// They don't require any library support as they're just plain old object
597 /// files, so we just use the nightly snapshot compiler to always build them (as
598 /// no other compilers are guaranteed to be available).
f035d41b 599 fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> {
3b2f2976
XL
600 let for_compiler = self.compiler;
601 let target = self.target;
04454e1e 602 if !target.ends_with("windows-gnu") {
dfeec247 603 return vec![];
8bb4bdeb 604 }
7453a54e 605
e74abb32
XL
606 let mut target_deps = vec![];
607
3dfed10e 608 let src_dir = &builder.src.join("library").join("rtstartup");
83c7162d 609 let dst_dir = &builder.native_dir(target).join("rtstartup");
3b2f2976
XL
610 let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
611 t!(fs::create_dir_all(dst_dir));
612
613 for file in &["rsbegin", "rsend"] {
614 let src_file = &src_dir.join(file.to_string() + ".rs");
615 let dst_file = &dst_dir.join(file.to_string() + ".o");
616 if !up_to_date(src_file, dst_file) {
83c7162d 617 let mut cmd = Command::new(&builder.initial_rustc);
cdc7bbd5
XL
618 cmd.env("RUSTC_BOOTSTRAP", "1");
619 if !builder.local_rebuild {
620 // a local_rebuild compiler already has stage1 features
621 cmd.arg("--cfg").arg("bootstrap");
622 }
dfeec247 623 builder.run(
cdc7bbd5 624 cmd.arg("--target")
3dfed10e 625 .arg(target.rustc_target_arg())
dfeec247
XL
626 .arg("--emit=obj")
627 .arg("-o")
628 .arg(dst_file)
629 .arg(src_file),
630 );
3b2f2976
XL
631 }
632
74b04a01 633 let target = sysroot_dir.join((*file).to_string() + ".o");
e74abb32 634 builder.copy(dst_file, &target);
f035d41b 635 target_deps.push((target, DependencyType::Target));
3b2f2976 636 }
e74abb32
XL
637
638 target_deps
7453a54e 639 }
3b2f2976
XL
640}
641
fe692bf9
FG
642fn cp_rustc_component_to_ci_sysroot(
643 builder: &Builder<'_>,
644 compiler: Compiler,
645 contents: Vec<String>,
646) {
647 let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
648
649 let ci_rustc_dir = builder.out.join(&*builder.build.build.triple).join("ci-rustc");
650 for file in contents {
651 let src = ci_rustc_dir.join(&file);
652 let dst = sysroot.join(file);
653 if src.is_dir() {
654 t!(fs::create_dir_all(dst));
655 } else {
656 builder.copy(&src, &dst);
657 }
658 }
659}
660
83c7162d 661#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
3b2f2976 662pub struct Rustc {
3dfed10e 663 pub target: TargetSelection,
83c7162d 664 pub compiler: Compiler,
064997fb
FG
665 /// Whether to build a subset of crates, rather than the whole compiler.
666 ///
667 /// This should only be requested by the user, not used within rustbuild itself.
668 /// Using it within rustbuild can lead to confusing situation where lints are replayed
669 /// in two different steps.
670 crates: Interned<Vec<String>>,
671}
672
673impl Rustc {
674 pub fn new(compiler: Compiler, target: TargetSelection) -> Self {
675 Self { target, compiler, crates: Default::default() }
676 }
3b2f2976
XL
677}
678
679impl Step for Rustc {
680 type Output = ();
681 const ONLY_HOSTS: bool = true;
3dfed10e 682 const DEFAULT: bool = false;
3b2f2976 683
9fa01778 684 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
064997fb
FG
685 let mut crates = run.builder.in_tree_crates("rustc-main", None);
686 for (i, krate) in crates.iter().enumerate() {
fe692bf9
FG
687 // We can't allow `build rustc` as an alias for this Step, because that's reserved by `Assemble`.
688 // Ideally Assemble would use `build compiler` instead, but that seems too confusing to be worth the breaking change.
064997fb
FG
689 if krate.name == "rustc-main" {
690 crates.swap_remove(i);
691 break;
692 }
693 }
694 run.crates(crates)
3b2f2976
XL
695 }
696
9fa01778 697 fn make_run(run: RunConfig<'_>) {
9c376795 698 let crates = run.cargo_crates_in_set();
3b2f2976 699 run.builder.ensure(Rustc {
1b1a35ee 700 compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
3b2f2976 701 target: run.target,
064997fb 702 crates,
3b2f2976
XL
703 });
704 }
705
9fa01778 706 /// Builds the compiler.
3b2f2976
XL
707 ///
708 /// This will build the compiler for a particular stage of the build using
709 /// the `compiler` targeting the `target` architecture. The artifacts
710 /// created will also be linked into the sysroot directory.
9fa01778 711 fn run(self, builder: &Builder<'_>) {
3b2f2976
XL
712 let compiler = self.compiler;
713 let target = self.target;
714
cdc7bbd5
XL
715 // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler,
716 // so its artifacts can't be reused.
923072b8 717 if builder.download_rustc() && compiler.stage != 0 {
6a06907d 718 // Copy the existing artifacts instead of rebuilding them.
49aad941 719 // NOTE: this path is only taken for tools linking to rustc-dev (including ui-fulldeps tests).
fe692bf9
FG
720 cp_rustc_component_to_ci_sysroot(
721 builder,
722 compiler,
723 builder.config.ci_rustc_dev_contents(),
724 );
6a06907d
XL
725 return;
726 }
727
064997fb 728 builder.ensure(Std::new(compiler, target));
3b2f2976 729
8faf50e0
XL
730 if builder.config.keep_stage.contains(&compiler.stage) {
731 builder.info("Warning: Using a potentially old librustc. This may not behave well.");
1b1a35ee 732 builder.info("Warning: Use `--keep-stage-std` if you want to rebuild the compiler when it changes");
064997fb 733 builder.ensure(RustcLink::from_rustc(self, compiler));
8faf50e0
XL
734 return;
735 }
736
dc9dc135
XL
737 let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
738 if compiler_to_use != compiler {
064997fb 739 builder.ensure(Rustc::new(compiler_to_use, target));
9ffffee4
FG
740 let msg = if compiler_to_use.host == target {
741 format!(
742 "Uplifting rustc (stage{} -> stage{})",
743 compiler_to_use.stage,
744 compiler.stage + 1
745 )
746 } else {
747 format!(
748 "Uplifting rustc (stage{}:{} -> stage{}:{})",
749 compiler_to_use.stage,
750 compiler_to_use.host,
751 compiler.stage + 1,
752 target
753 )
754 };
755 builder.info(&msg);
064997fb 756 builder.ensure(RustcLink::from_rustc(self, compiler_to_use));
3b2f2976
XL
757 return;
758 }
759
532ac7d7 760 // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
064997fb
FG
761 builder.ensure(Std::new(
762 builder.compiler(self.compiler.stage, builder.config.build),
763 builder.config.build,
764 ));
0531ce1d 765
f035d41b 766 let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
353b0b11 767 rustc_cargo(builder, &mut cargo, target, compiler.stage);
3b2f2976 768
fc512014
XL
769 if builder.config.rust_profile_use.is_some()
770 && builder.config.rust_profile_generate.is_some()
771 {
772 panic!("Cannot use and generate PGO profiles at the same time");
773 }
774
064997fb
FG
775 // With LLD, we can use ICF (identical code folding) to reduce the executable size
776 // of librustc_driver/rustc and to improve i-cache utilization.
f2b60f7d
FG
777 //
778 // -Wl,[link options] doesn't work on MSVC. However, /OPT:ICF (technically /OPT:REF,ICF)
779 // is already on by default in MSVC optimized builds, which is interpreted as --icf=all:
780 // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746
781 // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827
782 if builder.config.use_lld && !compiler.host.contains("msvc") {
064997fb
FG
783 cargo.rustflag("-Clink-args=-Wl,--icf=all");
784 }
785
fc512014
XL
786 let is_collecting = if let Some(path) = &builder.config.rust_profile_generate {
787 if compiler.stage == 1 {
788 cargo.rustflag(&format!("-Cprofile-generate={}", path));
789 // Apparently necessary to avoid overflowing the counters during
790 // a Cargo build profile
791 cargo.rustflag("-Cllvm-args=-vp-counters-per-site=4");
792 true
793 } else {
794 false
795 }
796 } else if let Some(path) = &builder.config.rust_profile_use {
797 if compiler.stage == 1 {
798 cargo.rustflag(&format!("-Cprofile-use={}", path));
799 cargo.rustflag("-Cllvm-args=-pgo-warn-missing-function");
800 true
801 } else {
802 false
803 }
804 } else {
805 false
806 };
807 if is_collecting {
808 // Ensure paths to Rust sources are relative, not absolute.
809 cargo.rustflag(&format!(
810 "-Cllvm-args=-static-func-strip-dirname-prefix={}",
811 builder.config.src.components().count()
812 ));
813 }
814
9c376795
FG
815 // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary
816 // and may just be a time sink.
2b03887a
FG
817 if compiler.stage != 0 {
818 match builder.config.rust_lto {
819 RustcLto::Thin | RustcLto::Fat => {
820 // Since using LTO for optimizing dylibs is currently experimental,
821 // we need to pass -Zdylib-lto.
822 cargo.rustflag("-Zdylib-lto");
823 // Cargo by default passes `-Cembed-bitcode=no` and doesn't pass `-Clto` when
824 // compiling dylibs (and their dependencies), even when LTO is enabled for the
825 // crate. Therefore, we need to override `-Clto` and `-Cembed-bitcode` here.
826 let lto_type = match builder.config.rust_lto {
827 RustcLto::Thin => "thin",
828 RustcLto::Fat => "fat",
829 _ => unreachable!(),
830 };
831 cargo.rustflag(&format!("-Clto={}", lto_type));
832 cargo.rustflag("-Cembed-bitcode=yes");
833 }
834 RustcLto::ThinLocal => { /* Do nothing, this is the default */ }
9ffffee4
FG
835 RustcLto::Off => {
836 cargo.rustflag("-Clto=off");
837 }
838 }
839 } else {
840 if builder.config.rust_lto == RustcLto::Off {
841 cargo.rustflag("-Clto=off");
2b03887a
FG
842 }
843 }
844
9c376795
FG
845 for krate in &*self.crates {
846 cargo.arg("-p").arg(krate);
847 }
848
49aad941
FG
849 let _guard = builder.msg_sysroot_tool(
850 Kind::Build,
851 compiler.stage,
852 format_args!("compiler artifacts{}", crate_description(&self.crates)),
853 compiler.host,
854 target,
855 );
dfeec247
XL
856 run_cargo(
857 builder,
858 cargo,
9c376795 859 vec![],
dfeec247
XL
860 &librustc_stamp(builder, compiler, target),
861 vec![],
862 false,
9c376795 863 true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files.
dfeec247 864 );
3b2f2976 865
064997fb
FG
866 builder.ensure(RustcLink::from_rustc(
867 self,
868 builder.compiler(compiler.stage, builder.config.build),
869 ));
3b2f2976
XL
870 }
871}
872
353b0b11 873pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection, stage: u32) {
dfeec247
XL
874 cargo
875 .arg("--features")
5e7ed085 876 .arg(builder.rustc_features(builder.kind))
dfeec247 877 .arg("--manifest-path")
1b1a35ee 878 .arg(builder.src.join("compiler/rustc/Cargo.toml"));
49aad941
FG
879
880 cargo.rustdocflag("-Zcrate-attr=warn(rust_2018_idioms)");
881
353b0b11 882 rustc_cargo_env(builder, cargo, target, stage);
2c00a5a8 883}
7453a54e 884
353b0b11
FG
885pub fn rustc_cargo_env(
886 builder: &Builder<'_>,
887 cargo: &mut Cargo,
888 target: TargetSelection,
889 stage: u32,
890) {
7453a54e
SL
891 // Set some configuration variables picked up by build scripts and
892 // the compiler alike
dfeec247
XL
893 cargo
894 .env("CFG_RELEASE", builder.rust_release())
895 .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
17df50a5 896 .env("CFG_VERSION", builder.rust_version());
32a655c1 897
9c376795 898 if let Some(backend) = builder.config.default_codegen_backend() {
5e7ed085
FG
899 cargo.env("CFG_DEFAULT_CODEGEN_BACKEND", backend);
900 }
901
74b04a01 902 let libdir_relative = builder.config.libdir_relative().unwrap_or_else(|| Path::new("lib"));
a2a8927a
XL
903 let target_config = builder.config.target_config.get(&target);
904
2c00a5a8 905 cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
7453a54e 906
487cf647 907 if let Some(ref ver_date) = builder.rust_info().commit_date() {
7453a54e
SL
908 cargo.env("CFG_VER_DATE", ver_date);
909 }
487cf647 910 if let Some(ref ver_hash) = builder.rust_info().sha() {
7453a54e
SL
911 cargo.env("CFG_VER_HASH", ver_hash);
912 }
83c7162d 913 if !builder.unstable_features() {
7453a54e
SL
914 cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
915 }
a2a8927a
XL
916
917 // Prefer the current target's own default_linker, else a globally
918 // specified one.
919 if let Some(s) = target_config.and_then(|c| c.default_linker.as_ref()) {
920 cargo.env("CFG_DEFAULT_LINKER", s);
921 } else if let Some(ref s) = builder.config.rustc_default_linker {
7453a54e
SL
922 cargo.env("CFG_DEFAULT_LINKER", s);
923 }
a2a8927a 924
9fa01778 925 if builder.config.rustc_parallel {
5e7ed085
FG
926 // keep in sync with `bootstrap/lib.rs:Build::rustc_features`
927 // `cfg` option for rustc, `features` option for cargo, for conditional compilation
e1599b0c 928 cargo.rustflag("--cfg=parallel_compiler");
17df50a5 929 cargo.rustdocflag("--cfg=parallel_compiler");
ff7c6d11 930 }
0bf4aa26
XL
931 if builder.config.rust_verify_llvm_ir {
932 cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
933 }
60c5eb7d 934
60c5eb7d 935 // Note that this is disabled if LLVM itself is disabled or we're in a check
f9f354fc 936 // build. If we are in a check build we still go ahead here presuming we've
5e7ed085 937 // detected that LLVM is already built and good to go which helps prevent
f9f354fc 938 // busting caches (e.g. like #71152).
353b0b11
FG
939 if builder.config.llvm_enabled() {
940 let building_is_expensive = crate::llvm::prebuilt_llvm_config(builder, target).is_err();
941 // `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler
942 let can_skip_build = builder.kind == Kind::Check && builder.top_stage == stage;
943 let should_skip_build = building_is_expensive && can_skip_build;
944 if !should_skip_build {
945 rustc_llvm_env(builder, cargo, target)
60c5eb7d 946 }
353b0b11
FG
947 }
948}
064997fb 949
353b0b11
FG
950/// Pass down configuration from the LLVM build into the build of
951/// rustc_llvm and rustc_codegen_llvm.
952fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
953 let target_config = builder.config.target_config.get(&target);
064997fb 954
353b0b11
FG
955 if builder.is_rust_llvm(target) {
956 cargo.env("LLVM_RUSTLLVM", "1");
957 }
958 let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target });
959 cargo.env("LLVM_CONFIG", &llvm_config);
960 if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
961 cargo.env("CFG_LLVM_ROOT", s);
962 }
963
964 // Some LLVM linker flags (-L and -l) may be needed to link `rustc_llvm`. Its build script
965 // expects these to be passed via the `LLVM_LINKER_FLAGS` env variable, separated by
966 // whitespace.
967 //
968 // For example:
969 // - on windows, when `clang-cl` is used with instrumentation, we need to manually add
970 // clang's runtime library resource directory so that the profiler runtime library can be
971 // found. This is to avoid the linker errors about undefined references to
972 // `__llvm_profile_instrument_memop` when linking `rustc_driver`.
973 let mut llvm_linker_flags = String::new();
974 if builder.config.llvm_profile_generate && target.contains("msvc") {
975 if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl {
976 // Add clang's runtime library directory to the search path
977 let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path);
978 llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display()));
064997fb 979 }
353b0b11 980 }
064997fb 981
353b0b11
FG
982 // The config can also specify its own llvm linker flags.
983 if let Some(ref s) = builder.config.llvm_ldflags {
064997fb 984 if !llvm_linker_flags.is_empty() {
353b0b11 985 llvm_linker_flags.push_str(" ");
60c5eb7d 986 }
353b0b11
FG
987 llvm_linker_flags.push_str(s);
988 }
064997fb 989
353b0b11
FG
990 // Set the linker flags via the env var that `rustc_llvm`'s build script will read.
991 if !llvm_linker_flags.is_empty() {
992 cargo.env("LLVM_LINKER_FLAGS", llvm_linker_flags);
993 }
994
995 // Building with a static libstdc++ is only supported on linux right now,
996 // not for MSVC or macOS
997 if builder.config.llvm_static_stdcpp
998 && !target.contains("freebsd")
999 && !target.contains("msvc")
1000 && !target.contains("apple")
1001 && !target.contains("solaris")
1002 {
fe692bf9
FG
1003 let file = compiler_file(
1004 builder,
1005 &builder.cxx(target).unwrap(),
1006 target,
1007 CLang::Cxx,
1008 "libstdc++.a",
1009 );
353b0b11
FG
1010 cargo.env("LLVM_STATIC_STDCPP", file);
1011 }
1012 if builder.llvm_link_shared() {
1013 cargo.env("LLVM_LINK_SHARED", "1");
1014 }
1015 if builder.config.llvm_use_libcxx {
1016 cargo.env("LLVM_USE_LIBCXX", "1");
1017 }
1018 if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
1019 cargo.env("LLVM_NDEBUG", "1");
60c5eb7d 1020 }
7453a54e
SL
1021}
1022
3b2f2976
XL
1023#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1024struct RustcLink {
1025 pub compiler: Compiler,
1026 pub target_compiler: Compiler,
3dfed10e 1027 pub target: TargetSelection,
064997fb
FG
1028 /// Not actually used; only present to make sure the cache invalidation is correct.
1029 crates: Interned<Vec<String>>,
1030}
1031
1032impl RustcLink {
1033 fn from_rustc(rustc: Rustc, host_compiler: Compiler) -> Self {
1034 Self {
1035 compiler: host_compiler,
1036 target_compiler: rustc.compiler,
1037 target: rustc.target,
1038 crates: rustc.crates,
1039 }
1040 }
3b2f2976
XL
1041}
1042
1043impl Step for RustcLink {
1044 type Output = ();
1045
9fa01778 1046 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
1047 run.never()
1048 }
1049
1050 /// Same as `std_link`, only for librustc
9fa01778 1051 fn run(self, builder: &Builder<'_>) {
3b2f2976
XL
1052 let compiler = self.compiler;
1053 let target_compiler = self.target_compiler;
1054 let target = self.target;
532ac7d7
XL
1055 add_to_sysroot(
1056 builder,
1057 &builder.sysroot_libdir(target_compiler, target),
1058 &builder.sysroot_libdir(target_compiler, compiler.host),
dfeec247 1059 &librustc_stamp(builder, compiler, target),
532ac7d7 1060 );
3b2f2976 1061 }
7453a54e
SL
1062}
1063
29967ef6
XL
1064#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1065pub struct CodegenBackend {
1066 pub target: TargetSelection,
1067 pub compiler: Compiler,
1068 pub backend: Interned<String>,
1069}
1070
353b0b11
FG
1071fn needs_codegen_config(run: &RunConfig<'_>) -> bool {
1072 let mut needs_codegen_cfg = false;
1073 for path_set in &run.paths {
1074 needs_codegen_cfg = match path_set {
1075 PathSet::Set(set) => set.iter().any(|p| is_codegen_cfg_needed(p, run)),
1076 PathSet::Suite(suite) => is_codegen_cfg_needed(&suite, run),
1077 }
1078 }
1079 needs_codegen_cfg
1080}
1081
1082const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_";
1083
1084fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool {
1085 if path.path.to_str().unwrap().contains(&CODEGEN_BACKEND_PREFIX) {
1086 let mut needs_codegen_backend_config = true;
1087 for &backend in &run.builder.config.rust_codegen_backends {
1088 if path
1089 .path
1090 .to_str()
1091 .unwrap()
1092 .ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + &backend))
1093 {
1094 needs_codegen_backend_config = false;
1095 }
1096 }
1097 if needs_codegen_backend_config {
1098 run.builder.info(
1099 "Warning: no codegen-backends config matched the requested path to build a codegen backend. \
1100 Help: add backend to codegen-backends in config.toml.",
1101 );
1102 return true;
1103 }
1104 }
1105
1106 return false;
1107}
1108
29967ef6
XL
1109impl Step for CodegenBackend {
1110 type Output = ();
1111 const ONLY_HOSTS: bool = true;
1112 // Only the backends specified in the `codegen-backends` entry of `config.toml` are built.
1113 const DEFAULT: bool = true;
1114
1115 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
04454e1e 1116 run.paths(&["compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_gcc"])
29967ef6
XL
1117 }
1118
1119 fn make_run(run: RunConfig<'_>) {
353b0b11
FG
1120 if needs_codegen_config(&run) {
1121 return;
1122 }
1123
29967ef6
XL
1124 for &backend in &run.builder.config.rust_codegen_backends {
1125 if backend == "llvm" {
1126 continue; // Already built as part of rustc
1127 }
1128
1129 run.builder.ensure(CodegenBackend {
1130 target: run.target,
1131 compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
1132 backend,
1133 });
1134 }
1135 }
1136
1137 fn run(self, builder: &Builder<'_>) {
1138 let compiler = self.compiler;
1139 let target = self.target;
1140 let backend = self.backend;
1141
064997fb 1142 builder.ensure(Rustc::new(compiler, target));
29967ef6
XL
1143
1144 if builder.config.keep_stage.contains(&compiler.stage) {
1145 builder.info(
1146 "Warning: Using a potentially old codegen backend. \
1147 This may not behave well.",
1148 );
1149 // Codegen backends are linked separately from this step today, so we don't do
1150 // anything here.
1151 return;
1152 }
1153
1154 let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
1155 if compiler_to_use != compiler {
1156 builder.ensure(CodegenBackend { compiler: compiler_to_use, target, backend });
1157 return;
1158 }
1159
1160 let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
1161
c295e0f8 1162 let mut cargo = builder.cargo(compiler, Mode::Codegen, SourceType::InTree, target, "build");
29967ef6
XL
1163 cargo
1164 .arg("--manifest-path")
1165 .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
353b0b11 1166 rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
29967ef6
XL
1167
1168 let tmp_stamp = out_dir.join(".tmp.stamp");
1169
49aad941 1170 let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target);
9c376795 1171 let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false);
487cf647 1172 if builder.config.dry_run() {
29967ef6
XL
1173 return;
1174 }
1175 let mut files = files.into_iter().filter(|f| {
1176 let filename = f.file_name().unwrap().to_str().unwrap();
1177 is_dylib(filename) && filename.contains("rustc_codegen_")
1178 });
1179 let codegen_backend = match files.next() {
1180 Some(f) => f,
1181 None => panic!("no dylibs built for codegen backend?"),
1182 };
1183 if let Some(f) = files.next() {
1184 panic!(
1185 "codegen backend built two dylibs:\n{}\n{}",
1186 codegen_backend.display(),
1187 f.display()
1188 );
1189 }
1190 let stamp = codegen_backend_stamp(builder, compiler, target, backend);
1191 let codegen_backend = codegen_backend.to_str().unwrap();
1192 t!(fs::write(&stamp, &codegen_backend));
1193 }
1194}
1195
1196/// Creates the `codegen-backends` folder for a compiler that's about to be
1197/// assembled as a complete compiler.
1198///
1199/// This will take the codegen artifacts produced by `compiler` and link them
1200/// into an appropriate location for `target_compiler` to be a functional
1201/// compiler.
1202fn copy_codegen_backends_to_sysroot(
1203 builder: &Builder<'_>,
1204 compiler: Compiler,
1205 target_compiler: Compiler,
1206) {
1207 let target = target_compiler.host;
1208
1209 // Note that this step is different than all the other `*Link` steps in
1210 // that it's not assembling a bunch of libraries but rather is primarily
1211 // moving the codegen backend into place. The codegen backend of rustc is
1212 // not linked into the main compiler by default but is rather dynamically
1213 // selected at runtime for inclusion.
1214 //
1215 // Here we're looking for the output dylib of the `CodegenBackend` step and
1216 // we're copying that into the `codegen-backends` folder.
1217 let dst = builder.sysroot_codegen_backends(target_compiler);
fc512014 1218 t!(fs::create_dir_all(&dst), dst);
29967ef6 1219
487cf647 1220 if builder.config.dry_run() {
29967ef6
XL
1221 return;
1222 }
1223
1224 for backend in builder.config.rust_codegen_backends.iter() {
1225 if backend == "llvm" {
1226 continue; // Already built as part of rustc
1227 }
1228
1229 let stamp = codegen_backend_stamp(builder, compiler, target, *backend);
1230 let dylib = t!(fs::read_to_string(&stamp));
1231 let file = Path::new(&dylib);
1232 let filename = file.file_name().unwrap().to_str().unwrap();
1233 // change `librustc_codegen_cranelift-xxxxxx.so` to
1234 // `librustc_codegen_cranelift-release.so`
1235 let target_filename = {
1236 let dash = filename.find('-').unwrap();
1237 let dot = filename.find('.').unwrap();
1238 format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..])
1239 };
1240 builder.copy(&file, &dst.join(target_filename));
1241 }
1242}
1243
7453a54e
SL
1244/// Cargo's output path for the standard library in a given stage, compiled
1245/// by a particular compiler for the specified target.
3dfed10e 1246pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
94b46f34 1247 builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
7453a54e
SL
1248}
1249
cc61c64b
XL
1250/// Cargo's output path for librustc in a given stage, compiled by a particular
1251/// compiler for the specified target.
9fa01778
XL
1252pub fn librustc_stamp(
1253 builder: &Builder<'_>,
1254 compiler: Compiler,
3dfed10e 1255 target: TargetSelection,
9fa01778 1256) -> PathBuf {
94b46f34 1257 builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
cc61c64b
XL
1258}
1259
29967ef6
XL
1260/// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
1261/// compiler for the specified target and backend.
1262fn codegen_backend_stamp(
1263 builder: &Builder<'_>,
1264 compiler: Compiler,
1265 target: TargetSelection,
1266 backend: Interned<String>,
1267) -> PathBuf {
1268 builder
1269 .cargo_out(compiler, Mode::Codegen, target)
1270 .join(format!(".librustc_codegen_{}.stamp", backend))
1271}
1272
9fa01778
XL
1273pub fn compiler_file(
1274 builder: &Builder<'_>,
1275 compiler: &Path,
3dfed10e 1276 target: TargetSelection,
5099ac24 1277 c: CLang,
9fa01778
XL
1278 file: &str,
1279) -> PathBuf {
fe692bf9
FG
1280 if builder.config.dry_run() {
1281 return PathBuf::new();
1282 }
2c00a5a8 1283 let mut cmd = Command::new(compiler);
5099ac24 1284 cmd.args(builder.cflags(target, GitRepo::Rustc, c));
2c00a5a8
XL
1285 cmd.arg(format!("-print-file-name={}", file));
1286 let out = output(&mut cmd);
54a0048b 1287 PathBuf::from(out.trim())
7453a54e
SL
1288}
1289
3b2f2976
XL
1290#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1291pub struct Sysroot {
1292 pub compiler: Compiler,
fe692bf9
FG
1293 /// See [`Std::force_recompile`].
1294 force_recompile: bool,
1295}
1296
1297impl Sysroot {
1298 pub(crate) fn new(compiler: Compiler) -> Self {
1299 Sysroot { compiler, force_recompile: false }
1300 }
32a655c1
SL
1301}
1302
3b2f2976
XL
1303impl Step for Sysroot {
1304 type Output = Interned<PathBuf>;
1305
9fa01778 1306 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976 1307 run.never()
7453a54e
SL
1308 }
1309
3b2f2976
XL
1310 /// Returns the sysroot for the `compiler` specified that *this build system
1311 /// generates*.
1312 ///
1313 /// That is, the sysroot for the stage0 compiler is not what the compiler
1314 /// thinks it is by default, but it's the same as the default for stages
1315 /// 1-3.
9fa01778 1316 fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
3b2f2976 1317 let compiler = self.compiler;
2b03887a 1318 let host_dir = builder.out.join(&compiler.host.triple);
487cf647
FG
1319
1320 let sysroot_dir = |stage| {
1321 if stage == 0 {
1322 host_dir.join("stage0-sysroot")
fe692bf9
FG
1323 } else if self.force_recompile && stage == compiler.stage {
1324 host_dir.join(format!("stage{stage}-test-sysroot"))
487cf647
FG
1325 } else if builder.download_rustc() && compiler.stage != builder.top_stage {
1326 host_dir.join("ci-rustc-sysroot")
1327 } else {
1328 host_dir.join(format!("stage{}", stage))
1329 }
3b2f2976 1330 };
487cf647
FG
1331 let sysroot = sysroot_dir(compiler.stage);
1332
49aad941 1333 builder.verbose(&format!("Removing sysroot {} to avoid caching bugs", sysroot.display()));
3b2f2976
XL
1334 let _ = fs::remove_dir_all(&sysroot);
1335 t!(fs::create_dir_all(&sysroot));
ba9703b0 1336
6a06907d 1337 // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0.
923072b8 1338 if builder.download_rustc() && compiler.stage != 0 {
6a06907d
XL
1339 assert_eq!(
1340 builder.config.build, compiler.host,
1341 "Cross-compiling is not yet supported with `download-rustc`",
1342 );
2b03887a 1343
487cf647
FG
1344 // #102002, cleanup old toolchain folders when using download-rustc so people don't use them by accident.
1345 for stage in 0..=2 {
1346 if stage != compiler.stage {
1347 let dir = sysroot_dir(stage);
1348 if !dir.ends_with("ci-rustc-sysroot") {
1349 let _ = fs::remove_dir_all(dir);
1350 }
1351 }
1352 }
2b03887a 1353
6a06907d 1354 // Copy the compiler into the correct sysroot.
49aad941
FG
1355 // NOTE(#108767): We intentionally don't copy `rustc-dev` artifacts until they're requested with `builder.ensure(Rustc)`.
1356 // This fixes an issue where we'd have multiple copies of libc in the sysroot with no way to tell which to load.
1357 // There are a few quirks of bootstrap that interact to make this reliable:
1358 // 1. The order `Step`s are run is hard-coded in `builder.rs` and not configurable. This
1359 // avoids e.g. reordering `test::UiFulldeps` before `test::Ui` and causing the latter to
1360 // fail because of duplicate metadata.
1361 // 2. The sysroot is deleted and recreated between each invocation, so running `x test
1362 // ui-fulldeps && x test ui` can't cause failures.
1363 let mut filtered_files = Vec::new();
fe692bf9
FG
1364 let mut add_filtered_files = |suffix, contents| {
1365 for path in contents {
1366 let path = Path::new(&path);
1367 if path.parent().map_or(false, |parent| parent.ends_with(&suffix)) {
1368 filtered_files.push(path.file_name().unwrap().to_owned());
1369 }
49aad941 1370 }
fe692bf9
FG
1371 };
1372 let suffix = format!("lib/rustlib/{}/lib", compiler.host);
1373 add_filtered_files(suffix.as_str(), builder.config.ci_rustc_dev_contents());
1374 // NOTE: we can't copy std eagerly because `stage2-test-sysroot` needs to have only the
1375 // newly compiled std, not the downloaded std.
1376 add_filtered_files("lib", builder.config.ci_rust_std_contents());
1377
1378 let filtered_extensions = [
1379 OsStr::new("rmeta"),
1380 OsStr::new("rlib"),
1381 // FIXME: this is wrong when compiler.host != build, but we don't support that today
1382 OsStr::new(std::env::consts::DLL_EXTENSION),
1383 ];
49aad941
FG
1384 let ci_rustc_dir = builder.ci_rustc_dir(builder.config.build);
1385 builder.cp_filtered(&ci_rustc_dir, &sysroot, &|path| {
1386 if path.extension().map_or(true, |ext| !filtered_extensions.contains(&ext)) {
1387 return true;
1388 }
1389 if !path.parent().map_or(true, |p| p.ends_with(&suffix)) {
1390 return true;
1391 }
1392 if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) {
1393 builder.verbose_than(1, &format!("ignoring {}", path.display()));
1394 false
1395 } else {
1396 true
1397 }
1398 });
6a06907d
XL
1399 }
1400
ba9703b0
XL
1401 // Symlink the source root into the same location inside the sysroot,
1402 // where `rust-src` component would go (`$sysroot/lib/rustlib/src/rust`),
1403 // so that any tools relying on `rust-src` also work for local builds,
1404 // and also for translating the virtual `/rustc/$hash` back to the real
1405 // directory (for running tests with `rust.remap-debuginfo = true`).
1406 let sysroot_lib_rustlib_src = sysroot.join("lib/rustlib/src");
1407 t!(fs::create_dir_all(&sysroot_lib_rustlib_src));
1408 let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust");
1409 if let Err(e) = symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_src_rust) {
1410 eprintln!(
1411 "warning: creating symbolic link `{}` to `{}` failed with {}",
1412 sysroot_lib_rustlib_src_rust.display(),
1413 builder.src.display(),
1414 e,
1415 );
1416 if builder.config.rust_remap_debuginfo {
1417 eprintln!(
9c376795 1418 "warning: some `tests/ui` tests will fail when lacking `{}`",
ba9703b0
XL
1419 sysroot_lib_rustlib_src_rust.display(),
1420 );
1421 }
1422 }
2b03887a
FG
1423 // Same for the rustc-src component.
1424 let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src");
1425 t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc));
1426 let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust");
1427 if let Err(e) =
1428 symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust)
1429 {
1430 eprintln!(
1431 "warning: creating symbolic link `{}` to `{}` failed with {}",
1432 sysroot_lib_rustlib_rustcsrc_rust.display(),
1433 builder.src.display(),
1434 e,
1435 );
1436 }
ba9703b0 1437
3b2f2976
XL
1438 INTERNER.intern_path(sysroot)
1439 }
1440}
1441
83c7162d 1442#[derive(Debug, Copy, PartialOrd, Ord, Clone, PartialEq, Eq, Hash)]
3b2f2976
XL
1443pub struct Assemble {
1444 /// The compiler which we will produce in this step. Assemble itself will
1445 /// take care of ensuring that the necessary prerequisites to do so exist,
1446 /// that is, this target can be a stage2 compiler and Assemble will build
1447 /// previous stages for you.
1448 pub target_compiler: Compiler,
1449}
7453a54e 1450
3b2f2976
XL
1451impl Step for Assemble {
1452 type Output = Compiler;
c295e0f8 1453 const ONLY_HOSTS: bool = true;
7453a54e 1454
9fa01778 1455 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
04454e1e 1456 run.path("compiler/rustc").path("compiler")
c295e0f8
XL
1457 }
1458
1459 fn make_run(run: RunConfig<'_>) {
1460 run.builder.ensure(Assemble {
1461 target_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target),
1462 });
3b2f2976
XL
1463 }
1464
1465 /// Prepare a new compiler from the artifacts in `stage`
1466 ///
1467 /// This will assemble a compiler in `build/$host/stage$stage`. The compiler
83c7162d 1468 /// must have been previously produced by the `stage - 1` builder.build
3b2f2976 1469 /// compiler.
9fa01778 1470 fn run(self, builder: &Builder<'_>) -> Compiler {
3b2f2976
XL
1471 let target_compiler = self.target_compiler;
1472
1473 if target_compiler.stage == 0 {
dfeec247
XL
1474 assert_eq!(
1475 builder.config.build, target_compiler.host,
1476 "Cannot obtain compiler for non-native build triple at stage 0"
1477 );
3b2f2976
XL
1478 // The stage 0 compiler for the build triple is always pre-built.
1479 return target_compiler;
1480 }
1481
1482 // Get the compiler that we'll use to bootstrap ourselves.
2c00a5a8
XL
1483 //
1484 // Note that this is where the recursive nature of the bootstrap
1485 // happens, as this will request the previous stage's compiler on
1486 // downwards to stage 0.
1487 //
1488 // Also note that we're building a compiler for the host platform. We
1489 // only assume that we can run `build` artifacts, which means that to
1490 // produce some other architecture compiler we need to start from
1491 // `build` to get there.
1492 //
2c00a5a8
XL
1493 // FIXME: It may be faster if we build just a stage 1 compiler and then
1494 // use that to bootstrap this compiler forward.
dfeec247 1495 let build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build);
3b2f2976 1496
6a06907d 1497 // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0.
923072b8 1498 if builder.download_rustc() {
fe692bf9
FG
1499 let sysroot =
1500 builder.ensure(Sysroot { compiler: target_compiler, force_recompile: false });
353b0b11
FG
1501 // Ensure that `libLLVM.so` ends up in the newly created target directory,
1502 // so that tools using `rustc_private` can use it.
1503 dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot);
fe692bf9
FG
1504 // Lower stages use `ci-rustc-sysroot`, not stageN
1505 if target_compiler.stage == builder.top_stage {
1506 builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage));
1507 }
6a06907d
XL
1508 return target_compiler;
1509 }
1510
3b2f2976
XL
1511 // Build the libraries for this compiler to link to (i.e., the libraries
1512 // it uses at runtime). NOTE: Crates the target compiler compiles don't
1513 // link to these. (FIXME: Is that correct? It seems to be correct most
1514 // of the time but I think we do link to these for stage2/bin compilers
1515 // when not performing a full bootstrap).
064997fb 1516 builder.ensure(Rustc::new(build_compiler, target_compiler.host));
3b2f2976 1517
353b0b11
FG
1518 // FIXME: For now patch over problems noted in #90244 by early returning here, even though
1519 // we've not properly assembled the target sysroot. A full fix is pending further investigation,
1520 // for now full bootstrap usage is rare enough that this is OK.
1521 if target_compiler.stage >= 3 && !builder.config.full_bootstrap {
1522 return target_compiler;
1523 }
1524
29967ef6
XL
1525 for &backend in builder.config.rust_codegen_backends.iter() {
1526 if backend == "llvm" {
1527 continue; // Already built as part of rustc
1528 }
1529
1530 builder.ensure(CodegenBackend {
1531 compiler: build_compiler,
1532 target: target_compiler.host,
1533 backend,
1534 });
1535 }
1536
83c7162d 1537 let lld_install = if builder.config.lld_enabled {
353b0b11 1538 Some(builder.ensure(llvm::Lld { target: target_compiler.host }))
0531ce1d
XL
1539 } else {
1540 None
1541 };
1542
3b2f2976
XL
1543 let stage = target_compiler.stage;
1544 let host = target_compiler.host;
fe692bf9
FG
1545 let (host_info, dir_name) = if build_compiler.host == host {
1546 ("".into(), "host".into())
9ffffee4 1547 } else {
fe692bf9 1548 (format!(" ({host})"), host.to_string())
9ffffee4 1549 };
fe692bf9
FG
1550 // NOTE: "Creating a sysroot" is somewhat inconsistent with our internal terminology, since
1551 // sysroots can temporarily be empty until we put the compiler inside. However,
1552 // `ensure(Sysroot)` isn't really something that's user facing, so there shouldn't be any
1553 // ambiguity.
1554 let msg = format!(
1555 "Creating a sysroot for stage{stage} compiler{host_info} (use `rustup toolchain link 'name' build/{dir_name}/stage{stage}`)"
1556 );
9ffffee4 1557 builder.info(&msg);
3b2f2976
XL
1558
1559 // Link in all dylibs to the libdir
5869c6ff
XL
1560 let stamp = librustc_stamp(builder, build_compiler, target_compiler.host);
1561 let proc_macros = builder
1562 .read_stamp_file(&stamp)
1563 .into_iter()
1564 .filter_map(|(path, dependency_type)| {
1565 if dependency_type == DependencyType::Host {
1566 Some(path.file_name().unwrap().to_owned().into_string().unwrap())
1567 } else {
1568 None
1569 }
1570 })
1571 .collect::<HashSet<_>>();
1572
3b2f2976 1573 let sysroot = builder.sysroot(target_compiler);
532ac7d7
XL
1574 let rustc_libdir = builder.rustc_libdir(target_compiler);
1575 t!(fs::create_dir_all(&rustc_libdir));
3b2f2976 1576 let src_libdir = builder.sysroot_libdir(build_compiler, host);
83c7162d 1577 for f in builder.read_dir(&src_libdir) {
3b2f2976 1578 let filename = f.file_name().into_string().unwrap();
6a06907d
XL
1579 if (is_dylib(&filename) || is_debug_info(&filename)) && !proc_macros.contains(&filename)
1580 {
532ac7d7 1581 builder.copy(&f.path(), &rustc_libdir.join(&filename));
3b2f2976
XL
1582 }
1583 }
1584
29967ef6
XL
1585 copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler);
1586
fc512014
XL
1587 // We prepend this bin directory to the user PATH when linking Rust binaries. To
1588 // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
60c5eb7d 1589 let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
fc512014
XL
1590 let libdir_bin = libdir.parent().unwrap().join("bin");
1591 t!(fs::create_dir_all(&libdir_bin));
0531ce1d 1592 if let Some(lld_install) = lld_install {
3dfed10e
XL
1593 let src_exe = exe("lld", target_compiler.host);
1594 let dst_exe = exe("rust-lld", target_compiler.host);
fc512014 1595 builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
17df50a5
XL
1596 // for `-Z gcc-ld=lld`
1597 let gcc_ld_dir = libdir_bin.join("gcc-ld");
1598 t!(fs::create_dir(&gcc_ld_dir));
923072b8
FG
1599 let lld_wrapper_exe = builder.ensure(crate::tool::LldWrapper {
1600 compiler: build_compiler,
1601 target: target_compiler.host,
1602 });
f2b60f7d
FG
1603 for name in crate::LLD_FILE_NAMES {
1604 builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(name, target_compiler.host)));
1605 }
fc512014
XL
1606 }
1607
5869c6ff 1608 if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) {
353b0b11
FG
1609 let llvm::LlvmResult { llvm_config, .. } =
1610 builder.ensure(llvm::Llvm { target: target_compiler.host });
487cf647 1611 if !builder.config.dry_run() {
9c376795 1612 let llvm_bin_dir = output(Command::new(llvm_config).arg("--bindir"));
fc512014 1613 let llvm_bin_dir = Path::new(llvm_bin_dir.trim());
a2a8927a
XL
1614
1615 // Since we've already built the LLVM tools, install them to the sysroot.
1616 // This is the equivalent of installing the `llvm-tools-preview` component via
1617 // rustup, and lets developers use a locally built toolchain to
1618 // build projects that expect llvm tools to be present in the sysroot
1619 // (e.g. the `bootimage` crate).
1620 for tool in LLVM_TOOLS {
1621 let tool_exe = exe(tool, target_compiler.host);
1622 let src_path = llvm_bin_dir.join(&tool_exe);
5e7ed085 1623 // When using `download-ci-llvm`, some of the tools
a2a8927a
XL
1624 // may not exist, so skip trying to copy them.
1625 if src_path.exists() {
1626 builder.copy(&src_path, &libdir_bin.join(&tool_exe));
1627 }
1628 }
fc512014 1629 }
0531ce1d 1630 }
3b2f2976 1631
60c5eb7d
XL
1632 // Ensure that `libLLVM.so` ends up in the newly build compiler directory,
1633 // so that it can be found when the newly built `rustc` is run.
f9f354fc
XL
1634 dist::maybe_install_llvm_runtime(builder, target_compiler.host, &sysroot);
1635 dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot);
0731742a 1636
3b2f2976 1637 // Link the compiler binary itself into place
94b46f34 1638 let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
1b1a35ee 1639 let rustc = out_dir.join(exe("rustc-main", host));
3b2f2976
XL
1640 let bindir = sysroot.join("bin");
1641 t!(fs::create_dir_all(&bindir));
1642 let compiler = builder.rustc(target_compiler);
83c7162d 1643 builder.copy(&rustc, &compiler);
3b2f2976
XL
1644
1645 target_compiler
7453a54e
SL
1646 }
1647}
1648
1649/// Link some files into a rustc sysroot.
1650///
7cac9316
XL
1651/// For a particular stage this will link the file listed in `stamp` into the
1652/// `sysroot_dst` provided.
532ac7d7
XL
1653pub fn add_to_sysroot(
1654 builder: &Builder<'_>,
1655 sysroot_dst: &Path,
1656 sysroot_host_dst: &Path,
dfeec247 1657 stamp: &Path,
532ac7d7 1658) {
f035d41b 1659 let self_contained_dst = &sysroot_dst.join("self-contained");
7cac9316 1660 t!(fs::create_dir_all(&sysroot_dst));
532ac7d7 1661 t!(fs::create_dir_all(&sysroot_host_dst));
f035d41b
XL
1662 t!(fs::create_dir_all(&self_contained_dst));
1663 for (path, dependency_type) in builder.read_stamp_file(stamp) {
1664 let dst = match dependency_type {
1665 DependencyType::Host => sysroot_host_dst,
1666 DependencyType::Target => sysroot_dst,
1667 DependencyType::TargetSelfContained => self_contained_dst,
1668 };
1669 builder.copy(&path, &dst.join(path.file_name().unwrap()));
7453a54e
SL
1670 }
1671}
54a0048b 1672
dfeec247
XL
1673pub fn run_cargo(
1674 builder: &Builder<'_>,
1675 cargo: Cargo,
1676 tail_args: Vec<String>,
1677 stamp: &Path,
f035d41b 1678 additional_target_deps: Vec<(PathBuf, DependencyType)>,
dfeec247 1679 is_check: bool,
9c376795 1680 rlib_only_metadata: bool,
dfeec247 1681) -> Vec<PathBuf> {
487cf647 1682 if builder.config.dry_run() {
83c7162d
XL
1683 return Vec::new();
1684 }
1685
7cac9316
XL
1686 // `target_root_dir` looks like $dir/$target/release
1687 let target_root_dir = stamp.parent().unwrap();
1688 // `target_deps_dir` looks like $dir/$target/release/deps
1689 let target_deps_dir = target_root_dir.join("deps");
1690 // `host_root_dir` looks like $dir/release
dfeec247
XL
1691 let host_root_dir = target_root_dir
1692 .parent()
1693 .unwrap() // chop off `release`
1694 .parent()
1695 .unwrap() // chop off `$target`
1696 .join(target_root_dir.file_name().unwrap());
7cac9316
XL
1697
1698 // Spawn Cargo slurping up its JSON output. We'll start building up the
1699 // `deps` array of all files it generated along with a `toplevel` array of
1700 // files we need to probe for later.
1701 let mut deps = Vec::new();
1702 let mut toplevel = Vec::new();
dc9dc135 1703 let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
532ac7d7
XL
1704 let (filenames, crate_types) = match msg {
1705 CargoMessage::CompilerArtifact {
1706 filenames,
dfeec247 1707 target: CargoTarget { crate_types },
532ac7d7
XL
1708 ..
1709 } => (filenames, crate_types),
0531ce1d 1710 _ => return,
7cac9316 1711 };
0531ce1d 1712 for filename in filenames {
7cac9316 1713 // Skip files like executables
9c376795
FG
1714 let mut keep = false;
1715 if filename.ends_with(".lib")
74b04a01 1716 || filename.ends_with(".a")
6a06907d 1717 || is_debug_info(&filename)
74b04a01 1718 || is_dylib(&filename)
dfeec247 1719 {
9c376795
FG
1720 // Always keep native libraries, rust dylibs and debuginfo
1721 keep = true;
1722 }
1723 if is_check && filename.ends_with(".rmeta") {
1724 // During check builds we need to keep crate metadata
1725 keep = true;
1726 } else if rlib_only_metadata {
1727 if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") {
1728 // jemalloc_sys and rustc_smir are not linked into librustc_driver.so,
1729 // so we need to distribute them as rlib to be able to use them.
1730 keep |= filename.ends_with(".rlib");
1731 } else {
1732 // Distribute the rest of the rustc crates as rmeta files only to reduce
1733 // the tarball sizes by about 50%. The object files are linked into
1734 // librustc_driver.so, so it is still possible to link against them.
1735 keep |= filename.ends_with(".rmeta");
1736 }
1737 } else {
1738 // In all other cases keep all rlibs
1739 keep |= filename.ends_with(".rlib");
1740 }
1741
1742 if !keep {
8faf50e0 1743 continue;
7cac9316
XL
1744 }
1745
0531ce1d 1746 let filename = Path::new(&*filename);
7cac9316
XL
1747
1748 // If this was an output file in the "host dir" we don't actually
532ac7d7 1749 // worry about it, it's not relevant for us
7cac9316 1750 if filename.starts_with(&host_root_dir) {
532ac7d7
XL
1751 // Unless it's a proc macro used in the compiler
1752 if crate_types.iter().any(|t| t == "proc-macro") {
f035d41b 1753 deps.push((filename.to_path_buf(), DependencyType::Host));
532ac7d7 1754 }
8faf50e0 1755 continue;
041b39d2 1756 }
7cac9316
XL
1757
1758 // If this was output in the `deps` dir then this is a precise file
1759 // name (hash included) so we start tracking it.
041b39d2 1760 if filename.starts_with(&target_deps_dir) {
f035d41b 1761 deps.push((filename.to_path_buf(), DependencyType::Target));
8faf50e0 1762 continue;
041b39d2 1763 }
7cac9316
XL
1764
1765 // Otherwise this was a "top level artifact" which right now doesn't
1766 // have a hash in the name, but there's a version of this file in
1767 // the `deps` folder which *does* have a hash in the name. That's
1768 // the one we'll want to we'll probe for it later.
abe05a73
XL
1769 //
1770 // We do not use `Path::file_stem` or `Path::extension` here,
1771 // because some generated files may have multiple extensions e.g.
1772 // `std-<hash>.dll.lib` on Windows. The aforementioned methods only
1773 // split the file name by the last extension (`.lib`) while we need
1774 // to split by all extensions (`.dll.lib`).
1775 let expected_len = t!(filename.metadata()).len();
1776 let filename = filename.file_name().unwrap().to_str().unwrap();
1777 let mut parts = filename.splitn(2, '.');
1778 let file_stem = parts.next().unwrap().to_owned();
1779 let extension = parts.next().unwrap().to_owned();
1780
1781 toplevel.push((file_stem, extension, expected_len));
7cac9316 1782 }
0531ce1d 1783 });
7cac9316 1784
0531ce1d 1785 if !ok {
fe692bf9 1786 crate::detail_exit_macro!(1);
7cac9316
XL
1787 }
1788
1789 // Ok now we need to actually find all the files listed in `toplevel`. We've
1790 // got a list of prefix/extensions and we basically just need to find the
1791 // most recent file in the `deps` folder corresponding to each one.
1792 let contents = t!(target_deps_dir.read_dir())
1793 .map(|e| t!(e))
1794 .map(|e| (e.path(), e.file_name().into_string().unwrap(), t!(e.metadata())))
1795 .collect::<Vec<_>>();
abe05a73
XL
1796 for (prefix, extension, expected_len) in toplevel {
1797 let candidates = contents.iter().filter(|&&(_, ref filename, ref meta)| {
f035d41b
XL
1798 meta.len() == expected_len
1799 && filename
1800 .strip_prefix(&prefix[..])
1801 .map(|s| s.starts_with('-') && s.ends_with(&extension[..]))
1802 .unwrap_or(false)
7cac9316 1803 });
5e7ed085
FG
1804 let max = candidates.max_by_key(|&&(_, _, ref metadata)| {
1805 metadata.modified().expect("mtime should be available on all relevant OSes")
1806 });
7cac9316
XL
1807 let path_to_add = match max {
1808 Some(triple) => triple.0.to_str().unwrap(),
1809 None => panic!("no output generated for {:?} {:?}", prefix, extension),
1810 };
1811 if is_dylib(path_to_add) {
1812 let candidate = format!("{}.lib", path_to_add);
1813 let candidate = PathBuf::from(candidate);
1814 if candidate.exists() {
f035d41b 1815 deps.push((candidate, DependencyType::Target));
7cac9316
XL
1816 }
1817 }
f035d41b 1818 deps.push((path_to_add.into(), DependencyType::Target));
7cac9316
XL
1819 }
1820
f035d41b 1821 deps.extend(additional_target_deps);
7cac9316 1822 deps.sort();
7cac9316 1823 let mut new_contents = Vec::new();
f035d41b
XL
1824 for (dep, dependency_type) in deps.iter() {
1825 new_contents.extend(match *dependency_type {
1826 DependencyType::Host => b"h",
1827 DependencyType::Target => b"t",
1828 DependencyType::TargetSelfContained => b"s",
1829 });
7cac9316
XL
1830 new_contents.extend(dep.to_str().unwrap().as_bytes());
1831 new_contents.extend(b"\0");
1832 }
0731742a 1833 t!(fs::write(&stamp, &new_contents));
532ac7d7 1834 deps.into_iter().map(|(d, _)| d).collect()
9e0c209e 1835}
0531ce1d
XL
1836
1837pub fn stream_cargo(
9fa01778 1838 builder: &Builder<'_>,
e1599b0c 1839 cargo: Cargo,
dc9dc135 1840 tail_args: Vec<String>,
9fa01778 1841 cb: &mut dyn FnMut(CargoMessage<'_>),
0531ce1d 1842) -> bool {
e1599b0c 1843 let mut cargo = Command::from(cargo);
487cf647 1844 if builder.config.dry_run() {
83c7162d
XL
1845 return true;
1846 }
0531ce1d
XL
1847 // Instruct Cargo to give us json messages on stdout, critically leaving
1848 // stderr as piped so we can get those pretty colors.
ba9703b0
XL
1849 let mut message_format = if builder.config.json_output {
1850 String::from("json")
1851 } else {
1852 String::from("json-render-diagnostics")
1853 };
dfeec247 1854 if let Some(s) = &builder.config.rustc_error_format {
e1599b0c
XL
1855 message_format.push_str(",json-diagnostic-");
1856 message_format.push_str(s);
1857 }
1858 cargo.arg("--message-format").arg(message_format).stdout(Stdio::piped());
0531ce1d 1859
dc9dc135
XL
1860 for arg in tail_args {
1861 cargo.arg(arg);
1862 }
1863
83c7162d 1864 builder.verbose(&format!("running: {:?}", cargo));
0531ce1d
XL
1865 let mut child = match cargo.spawn() {
1866 Ok(child) => child,
1867 Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e),
1868 };
1869
1870 // Spawn Cargo slurping up its JSON output. We'll start building up the
1871 // `deps` array of all files it generated along with a `toplevel` array of
1872 // files we need to probe for later.
1873 let stdout = BufReader::new(child.stdout.take().unwrap());
1874 for line in stdout.lines() {
1875 let line = t!(line);
9fa01778 1876 match serde_json::from_str::<CargoMessage<'_>>(&line) {
f035d41b
XL
1877 Ok(msg) => {
1878 if builder.config.json_output {
1879 // Forward JSON to stdout.
1880 println!("{}", line);
1881 }
1882 cb(msg)
1883 }
0531ce1d 1884 // If this was informational, just print it out and continue
dfeec247 1885 Err(_) => println!("{}", line),
0531ce1d
XL
1886 }
1887 }
1888
1889 // Make sure Cargo actually succeeded after we read all of its stdout.
1890 let status = t!(child.wait());
136023e0 1891 if builder.is_verbose() && !status.success() {
dfeec247
XL
1892 eprintln!(
1893 "command did not execute successfully: {:?}\n\
0531ce1d 1894 expected success, got: {}",
dfeec247
XL
1895 cargo, status
1896 );
0531ce1d
XL
1897 }
1898 status.success()
1899}
1900
532ac7d7
XL
1901#[derive(Deserialize)]
1902pub struct CargoTarget<'a> {
1903 crate_types: Vec<Cow<'a, str>>,
1904}
1905
0531ce1d
XL
1906#[derive(Deserialize)]
1907#[serde(tag = "reason", rename_all = "kebab-case")]
1908pub enum CargoMessage<'a> {
1909 CompilerArtifact {
1910 package_id: Cow<'a, str>,
1911 features: Vec<Cow<'a, str>>,
1912 filenames: Vec<Cow<'a, str>>,
532ac7d7 1913 target: CargoTarget<'a>,
0531ce1d
XL
1914 },
1915 BuildScriptExecuted {
1916 package_id: Cow<'a, str>,
dc9dc135 1917 },
f9f354fc
XL
1918 BuildFinished {
1919 success: bool,
1920 },
dc9dc135 1921}