]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/compile.rs
Rollup merge of #80467 - LingMan:more_matches, r=oli-obk
[rust.git] / src / bootstrap / compile.rs
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
5 //! which is where Cargo is used to compiler the standard library, libtest, and
6 //! compiler. This module is also responsible for assembling the sysroot as it
7 //! goes along from the output of the previous stage.
8
9 use std::borrow::Cow;
10 use std::collections::HashSet;
11 use std::env;
12 use std::fs;
13 use std::io::prelude::*;
14 use std::io::BufReader;
15 use std::path::{Path, PathBuf};
16 use std::process::{exit, Command, Stdio};
17 use std::str;
18
19 use build_helper::{output, t, up_to_date};
20 use filetime::FileTime;
21 use serde::Deserialize;
22
23 use crate::builder::Cargo;
24 use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
25 use crate::cache::{Interned, INTERNER};
26 use crate::config::TargetSelection;
27 use crate::dist;
28 use crate::native;
29 use crate::tool::SourceType;
30 use crate::util::{exe, is_dylib, symlink_dir};
31 use crate::{Compiler, DependencyType, GitRepo, Mode};
32
33 #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
34 pub struct Std {
35     pub target: TargetSelection,
36     pub compiler: Compiler,
37 }
38
39 impl Step for Std {
40     type Output = ();
41     const DEFAULT: bool = true;
42
43     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
44         run.all_krates("test")
45     }
46
47     fn make_run(run: RunConfig<'_>) {
48         run.builder.ensure(Std {
49             compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
50             target: run.target,
51         });
52     }
53
54     /// Builds the standard library.
55     ///
56     /// This will build the standard library for a particular stage of the build
57     /// using the `compiler` targeting the `target` architecture. The artifacts
58     /// created will also be linked into the sysroot directory.
59     fn run(self, builder: &Builder<'_>) {
60         let target = self.target;
61         let compiler = self.compiler;
62
63         if builder.config.keep_stage.contains(&compiler.stage)
64             || builder.config.keep_stage_std.contains(&compiler.stage)
65         {
66             builder.info("Warning: Using a potentially old libstd. This may not behave well.");
67             builder.ensure(StdLink { compiler, target_compiler: compiler, target });
68             return;
69         }
70
71         let mut target_deps = builder.ensure(StartupObjects { compiler, target });
72
73         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
74         if compiler_to_use != compiler {
75             builder.ensure(Std { compiler: compiler_to_use, target });
76             builder.info(&format!("Uplifting stage1 std ({} -> {})", compiler_to_use.host, target));
77
78             // Even if we're not building std this stage, the new sysroot must
79             // still contain the third party objects needed by various targets.
80             copy_third_party_objects(builder, &compiler, target);
81             copy_self_contained_objects(builder, &compiler, target);
82
83             builder.ensure(StdLink {
84                 compiler: compiler_to_use,
85                 target_compiler: compiler,
86                 target,
87             });
88             return;
89         }
90
91         target_deps.extend(copy_third_party_objects(builder, &compiler, target));
92         target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
93
94         let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
95         std_cargo(builder, target, compiler.stage, &mut cargo);
96
97         builder.info(&format!(
98             "Building stage{} std artifacts ({} -> {})",
99             compiler.stage, &compiler.host, target
100         ));
101         run_cargo(
102             builder,
103             cargo,
104             vec![],
105             &libstd_stamp(builder, compiler, target),
106             target_deps,
107             false,
108         );
109
110         builder.ensure(StdLink {
111             compiler: builder.compiler(compiler.stage, builder.config.build),
112             target_compiler: compiler,
113             target,
114         });
115     }
116 }
117
118 fn copy_and_stamp(
119     builder: &Builder<'_>,
120     libdir: &Path,
121     sourcedir: &Path,
122     name: &str,
123     target_deps: &mut Vec<(PathBuf, DependencyType)>,
124     dependency_type: DependencyType,
125 ) {
126     let target = libdir.join(name);
127     builder.copy(&sourcedir.join(name), &target);
128
129     target_deps.push((target, dependency_type));
130 }
131
132 /// Copies third party objects needed by various targets.
133 fn copy_third_party_objects(
134     builder: &Builder<'_>,
135     compiler: &Compiler,
136     target: TargetSelection,
137 ) -> Vec<(PathBuf, DependencyType)> {
138     let mut target_deps = vec![];
139
140     // FIXME: remove this in 2021
141     if target == "x86_64-fortanix-unknown-sgx" {
142         if env::var_os("X86_FORTANIX_SGX_LIBS").is_some() {
143             builder.info("Warning: X86_FORTANIX_SGX_LIBS environment variable is ignored, libunwind is now compiled as part of rustbuild");
144         }
145     }
146
147     if builder.config.sanitizers_enabled(target) && compiler.stage != 0 {
148         // The sanitizers are only copied in stage1 or above,
149         // to avoid creating dependency on LLVM.
150         target_deps.extend(
151             copy_sanitizers(builder, &compiler, target)
152                 .into_iter()
153                 .map(|d| (d, DependencyType::Target)),
154         );
155     }
156
157     target_deps
158 }
159
160 /// Copies third party objects needed by various targets for self-contained linkage.
161 fn copy_self_contained_objects(
162     builder: &Builder<'_>,
163     compiler: &Compiler,
164     target: TargetSelection,
165 ) -> Vec<(PathBuf, DependencyType)> {
166     let libdir_self_contained = builder.sysroot_libdir(*compiler, target).join("self-contained");
167     t!(fs::create_dir_all(&libdir_self_contained));
168     let mut target_deps = vec![];
169
170     // Copies the CRT objects.
171     //
172     // rustc historically provides a more self-contained installation for musl targets
173     // not requiring the presence of a native musl toolchain. For example, it can fall back
174     // to using gcc from a glibc-targeting toolchain for linking.
175     // To do that we have to distribute musl startup objects as a part of Rust toolchain
176     // and link with them manually in the self-contained mode.
177     if target.contains("musl") {
178         let srcdir = builder.musl_libdir(target).unwrap();
179         for &obj in &["crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] {
180             copy_and_stamp(
181                 builder,
182                 &libdir_self_contained,
183                 &srcdir,
184                 obj,
185                 &mut target_deps,
186                 DependencyType::TargetSelfContained,
187             );
188         }
189     } else if target.ends_with("-wasi") {
190         let srcdir = builder.wasi_root(target).unwrap().join("lib/wasm32-wasi");
191         copy_and_stamp(
192             builder,
193             &libdir_self_contained,
194             &srcdir,
195             "crt1.o",
196             &mut target_deps,
197             DependencyType::TargetSelfContained,
198         );
199     } else if target.contains("windows-gnu") {
200         for obj in ["crt2.o", "dllcrt2.o"].iter() {
201             let src = compiler_file(builder, builder.cc(target), target, obj);
202             let target = libdir_self_contained.join(obj);
203             builder.copy(&src, &target);
204             target_deps.push((target, DependencyType::TargetSelfContained));
205         }
206     }
207
208     target_deps
209 }
210
211 /// Configure cargo to compile the standard library, adding appropriate env vars
212 /// and such.
213 pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
214     if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
215         cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
216     }
217
218     // Determine if we're going to compile in optimized C intrinsics to
219     // the `compiler-builtins` crate. These intrinsics live in LLVM's
220     // `compiler-rt` repository, but our `src/llvm-project` submodule isn't
221     // always checked out, so we need to conditionally look for this. (e.g. if
222     // an external LLVM is used we skip the LLVM submodule checkout).
223     //
224     // Note that this shouldn't affect the correctness of `compiler-builtins`,
225     // but only its speed. Some intrinsics in C haven't been translated to Rust
226     // yet but that's pretty rare. Other intrinsics have optimized
227     // implementations in C which have only had slower versions ported to Rust,
228     // so we favor the C version where we can, but it's not critical.
229     //
230     // If `compiler-rt` is available ensure that the `c` feature of the
231     // `compiler-builtins` crate is enabled and it's configured to learn where
232     // `compiler-rt` is located.
233     let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt");
234     let compiler_builtins_c_feature = if compiler_builtins_root.exists() {
235         // Note that `libprofiler_builtins/build.rs` also computes this so if
236         // you're changing something here please also change that.
237         cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root);
238         " compiler-builtins-c"
239     } else {
240         ""
241     };
242
243     if builder.no_std(target) == Some(true) {
244         let mut features = "compiler-builtins-mem".to_string();
245         features.push_str(compiler_builtins_c_feature);
246
247         // for no-std targets we only compile a few no_std crates
248         cargo
249             .args(&["-p", "alloc"])
250             .arg("--manifest-path")
251             .arg(builder.src.join("library/alloc/Cargo.toml"))
252             .arg("--features")
253             .arg(features);
254     } else {
255         let mut features = builder.std_features(target);
256         features.push_str(compiler_builtins_c_feature);
257
258         cargo
259             .arg("--features")
260             .arg(features)
261             .arg("--manifest-path")
262             .arg(builder.src.join("library/test/Cargo.toml"));
263
264         // Help the libc crate compile by assisting it in finding various
265         // sysroot native libraries.
266         if target.contains("musl") {
267             if let Some(p) = builder.musl_libdir(target) {
268                 let root = format!("native={}", p.to_str().unwrap());
269                 cargo.rustflag("-L").rustflag(&root);
270             }
271         }
272
273         if target.ends_with("-wasi") {
274             if let Some(p) = builder.wasi_root(target) {
275                 let root = format!("native={}/lib/wasm32-wasi", p.to_str().unwrap());
276                 cargo.rustflag("-L").rustflag(&root);
277             }
278         }
279     }
280
281     // By default, rustc uses `-Cembed-bitcode=yes`, and Cargo overrides that
282     // with `-Cembed-bitcode=no` for non-LTO builds. However, libstd must be
283     // built with bitcode so that the produced rlibs can be used for both LTO
284     // builds (which use bitcode) and non-LTO builds (which use object code).
285     // So we override the override here!
286     //
287     // But we don't bother for the stage 0 compiler because it's never used
288     // with LTO.
289     if stage >= 1 {
290         cargo.rustflag("-Cembed-bitcode=yes");
291     }
292
293     // By default, rustc does not include unwind tables unless they are required
294     // for a particular target. They are not required by RISC-V targets, but
295     // compiling the standard library with them means that users can get
296     // backtraces without having to recompile the standard library themselves.
297     //
298     // This choice was discussed in https://github.com/rust-lang/rust/pull/69890
299     if target.contains("riscv") {
300         cargo.rustflag("-Cforce-unwind-tables=yes");
301     }
302 }
303
304 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
305 struct StdLink {
306     pub compiler: Compiler,
307     pub target_compiler: Compiler,
308     pub target: TargetSelection,
309 }
310
311 impl Step for StdLink {
312     type Output = ();
313
314     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
315         run.never()
316     }
317
318     /// Link all libstd rlibs/dylibs into the sysroot location.
319     ///
320     /// Links those artifacts generated by `compiler` to the `stage` compiler's
321     /// sysroot for the specified `host` and `target`.
322     ///
323     /// Note that this assumes that `compiler` has already generated the libstd
324     /// libraries for `target`, and this method will find them in the relevant
325     /// output directory.
326     fn run(self, builder: &Builder<'_>) {
327         let compiler = self.compiler;
328         let target_compiler = self.target_compiler;
329         let target = self.target;
330         builder.info(&format!(
331             "Copying stage{} std from stage{} ({} -> {} / {})",
332             target_compiler.stage, compiler.stage, &compiler.host, target_compiler.host, target
333         ));
334         let libdir = builder.sysroot_libdir(target_compiler, target);
335         let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
336         add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
337     }
338 }
339
340 /// Copies sanitizer runtime libraries into target libdir.
341 fn copy_sanitizers(
342     builder: &Builder<'_>,
343     compiler: &Compiler,
344     target: TargetSelection,
345 ) -> Vec<PathBuf> {
346     let runtimes: Vec<native::SanitizerRuntime> = builder.ensure(native::Sanitizers { target });
347
348     if builder.config.dry_run {
349         return Vec::new();
350     }
351
352     let mut target_deps = Vec::new();
353     let libdir = builder.sysroot_libdir(*compiler, target);
354
355     for runtime in &runtimes {
356         let dst = libdir.join(&runtime.name);
357         builder.copy(&runtime.path, &dst);
358
359         if target == "x86_64-apple-darwin" {
360             // Update the library install name reflect the fact it has been renamed.
361             let status = Command::new("install_name_tool")
362                 .arg("-id")
363                 .arg(format!("@rpath/{}", runtime.name))
364                 .arg(&dst)
365                 .status()
366                 .expect("failed to execute `install_name_tool`");
367             assert!(status.success());
368         }
369
370         target_deps.push(dst);
371     }
372
373     target_deps
374 }
375
376 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
377 pub struct StartupObjects {
378     pub compiler: Compiler,
379     pub target: TargetSelection,
380 }
381
382 impl Step for StartupObjects {
383     type Output = Vec<(PathBuf, DependencyType)>;
384
385     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
386         run.path("library/rtstartup")
387     }
388
389     fn make_run(run: RunConfig<'_>) {
390         run.builder.ensure(StartupObjects {
391             compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
392             target: run.target,
393         });
394     }
395
396     /// Builds and prepare startup objects like rsbegin.o and rsend.o
397     ///
398     /// These are primarily used on Windows right now for linking executables/dlls.
399     /// They don't require any library support as they're just plain old object
400     /// files, so we just use the nightly snapshot compiler to always build them (as
401     /// no other compilers are guaranteed to be available).
402     fn run(self, builder: &Builder<'_>) -> Vec<(PathBuf, DependencyType)> {
403         let for_compiler = self.compiler;
404         let target = self.target;
405         if !target.contains("windows-gnu") {
406             return vec![];
407         }
408
409         let mut target_deps = vec![];
410
411         let src_dir = &builder.src.join("library").join("rtstartup");
412         let dst_dir = &builder.native_dir(target).join("rtstartup");
413         let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
414         t!(fs::create_dir_all(dst_dir));
415
416         for file in &["rsbegin", "rsend"] {
417             let src_file = &src_dir.join(file.to_string() + ".rs");
418             let dst_file = &dst_dir.join(file.to_string() + ".o");
419             if !up_to_date(src_file, dst_file) {
420                 let mut cmd = Command::new(&builder.initial_rustc);
421                 builder.run(
422                     cmd.env("RUSTC_BOOTSTRAP", "1")
423                         .arg("--cfg")
424                         .arg("bootstrap")
425                         .arg("--target")
426                         .arg(target.rustc_target_arg())
427                         .arg("--emit=obj")
428                         .arg("-o")
429                         .arg(dst_file)
430                         .arg(src_file),
431                 );
432             }
433
434             let target = sysroot_dir.join((*file).to_string() + ".o");
435             builder.copy(dst_file, &target);
436             target_deps.push((target, DependencyType::Target));
437         }
438
439         target_deps
440     }
441 }
442
443 #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
444 pub struct Rustc {
445     pub target: TargetSelection,
446     pub compiler: Compiler,
447 }
448
449 impl Step for Rustc {
450     type Output = ();
451     const ONLY_HOSTS: bool = true;
452     const DEFAULT: bool = false;
453
454     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
455         run.path("compiler/rustc")
456     }
457
458     fn make_run(run: RunConfig<'_>) {
459         run.builder.ensure(Rustc {
460             compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
461             target: run.target,
462         });
463     }
464
465     /// Builds the compiler.
466     ///
467     /// This will build the compiler for a particular stage of the build using
468     /// the `compiler` targeting the `target` architecture. The artifacts
469     /// created will also be linked into the sysroot directory.
470     fn run(self, builder: &Builder<'_>) {
471         let compiler = self.compiler;
472         let target = self.target;
473
474         builder.ensure(Std { compiler, target });
475
476         if builder.config.keep_stage.contains(&compiler.stage) {
477             builder.info("Warning: Using a potentially old librustc. This may not behave well.");
478             builder.info("Warning: Use `--keep-stage-std` if you want to rebuild the compiler when it changes");
479             builder.ensure(RustcLink { compiler, target_compiler: compiler, target });
480             return;
481         }
482
483         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
484         if compiler_to_use != compiler {
485             builder.ensure(Rustc { compiler: compiler_to_use, target });
486             builder
487                 .info(&format!("Uplifting stage1 rustc ({} -> {})", builder.config.build, target));
488             builder.ensure(RustcLink {
489                 compiler: compiler_to_use,
490                 target_compiler: compiler,
491                 target,
492             });
493             return;
494         }
495
496         // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
497         builder.ensure(Std {
498             compiler: builder.compiler(self.compiler.stage, builder.config.build),
499             target: builder.config.build,
500         });
501
502         let mut cargo = builder.cargo(compiler, Mode::Rustc, SourceType::InTree, target, "build");
503         rustc_cargo(builder, &mut cargo, target);
504
505         if builder.config.rust_profile_use.is_some()
506             && builder.config.rust_profile_generate.is_some()
507         {
508             panic!("Cannot use and generate PGO profiles at the same time");
509         }
510
511         let is_collecting = if let Some(path) = &builder.config.rust_profile_generate {
512             if compiler.stage == 1 {
513                 cargo.rustflag(&format!("-Cprofile-generate={}", path));
514                 // Apparently necessary to avoid overflowing the counters during
515                 // a Cargo build profile
516                 cargo.rustflag("-Cllvm-args=-vp-counters-per-site=4");
517                 true
518             } else {
519                 false
520             }
521         } else if let Some(path) = &builder.config.rust_profile_use {
522             if compiler.stage == 1 {
523                 cargo.rustflag(&format!("-Cprofile-use={}", path));
524                 cargo.rustflag("-Cllvm-args=-pgo-warn-missing-function");
525                 true
526             } else {
527                 false
528             }
529         } else {
530             false
531         };
532         if is_collecting {
533             // Ensure paths to Rust sources are relative, not absolute.
534             cargo.rustflag(&format!(
535                 "-Cllvm-args=-static-func-strip-dirname-prefix={}",
536                 builder.config.src.components().count()
537             ));
538         }
539
540         builder.info(&format!(
541             "Building stage{} compiler artifacts ({} -> {})",
542             compiler.stage, &compiler.host, target
543         ));
544         run_cargo(
545             builder,
546             cargo,
547             vec![],
548             &librustc_stamp(builder, compiler, target),
549             vec![],
550             false,
551         );
552
553         builder.ensure(RustcLink {
554             compiler: builder.compiler(compiler.stage, builder.config.build),
555             target_compiler: compiler,
556             target,
557         });
558     }
559 }
560
561 pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
562     cargo
563         .arg("--features")
564         .arg(builder.rustc_features())
565         .arg("--manifest-path")
566         .arg(builder.src.join("compiler/rustc/Cargo.toml"));
567     rustc_cargo_env(builder, cargo, target);
568 }
569
570 pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
571     // Set some configuration variables picked up by build scripts and
572     // the compiler alike
573     cargo
574         .env("CFG_RELEASE", builder.rust_release())
575         .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
576         .env("CFG_VERSION", builder.rust_version())
577         .env("CFG_PREFIX", builder.config.prefix.clone().unwrap_or_default());
578
579     let libdir_relative = builder.config.libdir_relative().unwrap_or_else(|| Path::new("lib"));
580     cargo.env("CFG_LIBDIR_RELATIVE", libdir_relative);
581
582     if let Some(ref ver_date) = builder.rust_info.commit_date() {
583         cargo.env("CFG_VER_DATE", ver_date);
584     }
585     if let Some(ref ver_hash) = builder.rust_info.sha() {
586         cargo.env("CFG_VER_HASH", ver_hash);
587     }
588     if !builder.unstable_features() {
589         cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
590     }
591     if let Some(ref s) = builder.config.rustc_default_linker {
592         cargo.env("CFG_DEFAULT_LINKER", s);
593     }
594     if builder.config.rustc_parallel {
595         cargo.rustflag("--cfg=parallel_compiler");
596     }
597     if builder.config.rust_verify_llvm_ir {
598         cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
599     }
600
601     // Pass down configuration from the LLVM build into the build of
602     // rustc_llvm and rustc_codegen_llvm.
603     //
604     // Note that this is disabled if LLVM itself is disabled or we're in a check
605     // build. If we are in a check build we still go ahead here presuming we've
606     // detected that LLVM is alreay built and good to go which helps prevent
607     // busting caches (e.g. like #71152).
608     if builder.config.llvm_enabled()
609         && (builder.kind != Kind::Check
610             || crate::native::prebuilt_llvm_config(builder, target).is_ok())
611     {
612         if builder.is_rust_llvm(target) {
613             cargo.env("LLVM_RUSTLLVM", "1");
614         }
615         let llvm_config = builder.ensure(native::Llvm { target });
616         cargo.env("LLVM_CONFIG", &llvm_config);
617         let target_config = builder.config.target_config.get(&target);
618         if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
619             cargo.env("CFG_LLVM_ROOT", s);
620         }
621         // Some LLVM linker flags (-L and -l) may be needed to link rustc_llvm.
622         if let Some(ref s) = builder.config.llvm_ldflags {
623             cargo.env("LLVM_LINKER_FLAGS", s);
624         }
625         // Building with a static libstdc++ is only supported on linux right now,
626         // not for MSVC or macOS
627         if builder.config.llvm_static_stdcpp
628             && !target.contains("freebsd")
629             && !target.contains("msvc")
630             && !target.contains("apple")
631         {
632             let file = compiler_file(builder, builder.cxx(target).unwrap(), target, "libstdc++.a");
633             cargo.env("LLVM_STATIC_STDCPP", file);
634         }
635         if builder.config.llvm_link_shared {
636             cargo.env("LLVM_LINK_SHARED", "1");
637         }
638         if builder.config.llvm_use_libcxx {
639             cargo.env("LLVM_USE_LIBCXX", "1");
640         }
641         if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo {
642             cargo.env("LLVM_NDEBUG", "1");
643         }
644     }
645 }
646
647 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
648 struct RustcLink {
649     pub compiler: Compiler,
650     pub target_compiler: Compiler,
651     pub target: TargetSelection,
652 }
653
654 impl Step for RustcLink {
655     type Output = ();
656
657     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
658         run.never()
659     }
660
661     /// Same as `std_link`, only for librustc
662     fn run(self, builder: &Builder<'_>) {
663         let compiler = self.compiler;
664         let target_compiler = self.target_compiler;
665         let target = self.target;
666         builder.info(&format!(
667             "Copying stage{} rustc from stage{} ({} -> {} / {})",
668             target_compiler.stage, compiler.stage, &compiler.host, target_compiler.host, target
669         ));
670         add_to_sysroot(
671             builder,
672             &builder.sysroot_libdir(target_compiler, target),
673             &builder.sysroot_libdir(target_compiler, compiler.host),
674             &librustc_stamp(builder, compiler, target),
675         );
676     }
677 }
678
679 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
680 pub struct CodegenBackend {
681     pub target: TargetSelection,
682     pub compiler: Compiler,
683     pub backend: Interned<String>,
684 }
685
686 impl Step for CodegenBackend {
687     type Output = ();
688     const ONLY_HOSTS: bool = true;
689     // Only the backends specified in the `codegen-backends` entry of `config.toml` are built.
690     const DEFAULT: bool = true;
691
692     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
693         run.path("compiler/rustc_codegen_cranelift")
694     }
695
696     fn make_run(run: RunConfig<'_>) {
697         for &backend in &run.builder.config.rust_codegen_backends {
698             if backend == "llvm" {
699                 continue; // Already built as part of rustc
700             }
701
702             run.builder.ensure(CodegenBackend {
703                 target: run.target,
704                 compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
705                 backend,
706             });
707         }
708     }
709
710     fn run(self, builder: &Builder<'_>) {
711         let compiler = self.compiler;
712         let target = self.target;
713         let backend = self.backend;
714
715         builder.ensure(Rustc { compiler, target });
716
717         if builder.config.keep_stage.contains(&compiler.stage) {
718             builder.info(
719                 "Warning: Using a potentially old codegen backend. \
720                 This may not behave well.",
721             );
722             // Codegen backends are linked separately from this step today, so we don't do
723             // anything here.
724             return;
725         }
726
727         let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
728         if compiler_to_use != compiler {
729             builder.ensure(CodegenBackend { compiler: compiler_to_use, target, backend });
730             return;
731         }
732
733         let out_dir = builder.cargo_out(compiler, Mode::Codegen, target);
734
735         let mut cargo =
736             builder.cargo(compiler, Mode::Codegen, SourceType::Submodule, target, "build");
737         cargo
738             .arg("--manifest-path")
739             .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
740         rustc_cargo_env(builder, &mut cargo, target);
741
742         let tmp_stamp = out_dir.join(".tmp.stamp");
743
744         let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false);
745         if builder.config.dry_run {
746             return;
747         }
748         let mut files = files.into_iter().filter(|f| {
749             let filename = f.file_name().unwrap().to_str().unwrap();
750             is_dylib(filename) && filename.contains("rustc_codegen_")
751         });
752         let codegen_backend = match files.next() {
753             Some(f) => f,
754             None => panic!("no dylibs built for codegen backend?"),
755         };
756         if let Some(f) = files.next() {
757             panic!(
758                 "codegen backend built two dylibs:\n{}\n{}",
759                 codegen_backend.display(),
760                 f.display()
761             );
762         }
763         let stamp = codegen_backend_stamp(builder, compiler, target, backend);
764         let codegen_backend = codegen_backend.to_str().unwrap();
765         t!(fs::write(&stamp, &codegen_backend));
766     }
767 }
768
769 /// Creates the `codegen-backends` folder for a compiler that's about to be
770 /// assembled as a complete compiler.
771 ///
772 /// This will take the codegen artifacts produced by `compiler` and link them
773 /// into an appropriate location for `target_compiler` to be a functional
774 /// compiler.
775 fn copy_codegen_backends_to_sysroot(
776     builder: &Builder<'_>,
777     compiler: Compiler,
778     target_compiler: Compiler,
779 ) {
780     let target = target_compiler.host;
781
782     // Note that this step is different than all the other `*Link` steps in
783     // that it's not assembling a bunch of libraries but rather is primarily
784     // moving the codegen backend into place. The codegen backend of rustc is
785     // not linked into the main compiler by default but is rather dynamically
786     // selected at runtime for inclusion.
787     //
788     // Here we're looking for the output dylib of the `CodegenBackend` step and
789     // we're copying that into the `codegen-backends` folder.
790     let dst = builder.sysroot_codegen_backends(target_compiler);
791     t!(fs::create_dir_all(&dst), dst);
792
793     if builder.config.dry_run {
794         return;
795     }
796
797     for backend in builder.config.rust_codegen_backends.iter() {
798         if backend == "llvm" {
799             continue; // Already built as part of rustc
800         }
801
802         let stamp = codegen_backend_stamp(builder, compiler, target, *backend);
803         let dylib = t!(fs::read_to_string(&stamp));
804         let file = Path::new(&dylib);
805         let filename = file.file_name().unwrap().to_str().unwrap();
806         // change `librustc_codegen_cranelift-xxxxxx.so` to
807         // `librustc_codegen_cranelift-release.so`
808         let target_filename = {
809             let dash = filename.find('-').unwrap();
810             let dot = filename.find('.').unwrap();
811             format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..])
812         };
813         builder.copy(&file, &dst.join(target_filename));
814     }
815 }
816
817 /// Cargo's output path for the standard library in a given stage, compiled
818 /// by a particular compiler for the specified target.
819 pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
820     builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
821 }
822
823 /// Cargo's output path for librustc in a given stage, compiled by a particular
824 /// compiler for the specified target.
825 pub fn librustc_stamp(
826     builder: &Builder<'_>,
827     compiler: Compiler,
828     target: TargetSelection,
829 ) -> PathBuf {
830     builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
831 }
832
833 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
834 /// compiler for the specified target and backend.
835 fn codegen_backend_stamp(
836     builder: &Builder<'_>,
837     compiler: Compiler,
838     target: TargetSelection,
839     backend: Interned<String>,
840 ) -> PathBuf {
841     builder
842         .cargo_out(compiler, Mode::Codegen, target)
843         .join(format!(".librustc_codegen_{}.stamp", backend))
844 }
845
846 pub fn compiler_file(
847     builder: &Builder<'_>,
848     compiler: &Path,
849     target: TargetSelection,
850     file: &str,
851 ) -> PathBuf {
852     let mut cmd = Command::new(compiler);
853     cmd.args(builder.cflags(target, GitRepo::Rustc));
854     cmd.arg(format!("-print-file-name={}", file));
855     let out = output(&mut cmd);
856     PathBuf::from(out.trim())
857 }
858
859 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
860 pub struct Sysroot {
861     pub compiler: Compiler,
862 }
863
864 impl Step for Sysroot {
865     type Output = Interned<PathBuf>;
866
867     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
868         run.never()
869     }
870
871     /// Returns the sysroot for the `compiler` specified that *this build system
872     /// generates*.
873     ///
874     /// That is, the sysroot for the stage0 compiler is not what the compiler
875     /// thinks it is by default, but it's the same as the default for stages
876     /// 1-3.
877     fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
878         let compiler = self.compiler;
879         let sysroot = if compiler.stage == 0 {
880             builder.out.join(&compiler.host.triple).join("stage0-sysroot")
881         } else {
882             builder.out.join(&compiler.host.triple).join(format!("stage{}", compiler.stage))
883         };
884         let _ = fs::remove_dir_all(&sysroot);
885         t!(fs::create_dir_all(&sysroot));
886
887         // Symlink the source root into the same location inside the sysroot,
888         // where `rust-src` component would go (`$sysroot/lib/rustlib/src/rust`),
889         // so that any tools relying on `rust-src` also work for local builds,
890         // and also for translating the virtual `/rustc/$hash` back to the real
891         // directory (for running tests with `rust.remap-debuginfo = true`).
892         let sysroot_lib_rustlib_src = sysroot.join("lib/rustlib/src");
893         t!(fs::create_dir_all(&sysroot_lib_rustlib_src));
894         let sysroot_lib_rustlib_src_rust = sysroot_lib_rustlib_src.join("rust");
895         if let Err(e) = symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_src_rust) {
896             eprintln!(
897                 "warning: creating symbolic link `{}` to `{}` failed with {}",
898                 sysroot_lib_rustlib_src_rust.display(),
899                 builder.src.display(),
900                 e,
901             );
902             if builder.config.rust_remap_debuginfo {
903                 eprintln!(
904                     "warning: some `src/test/ui` tests will fail when lacking `{}`",
905                     sysroot_lib_rustlib_src_rust.display(),
906                 );
907             }
908         }
909
910         INTERNER.intern_path(sysroot)
911     }
912 }
913
914 #[derive(Debug, Copy, PartialOrd, Ord, Clone, PartialEq, Eq, Hash)]
915 pub struct Assemble {
916     /// The compiler which we will produce in this step. Assemble itself will
917     /// take care of ensuring that the necessary prerequisites to do so exist,
918     /// that is, this target can be a stage2 compiler and Assemble will build
919     /// previous stages for you.
920     pub target_compiler: Compiler,
921 }
922
923 impl Step for Assemble {
924     type Output = Compiler;
925
926     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
927         run.never()
928     }
929
930     /// Prepare a new compiler from the artifacts in `stage`
931     ///
932     /// This will assemble a compiler in `build/$host/stage$stage`. The compiler
933     /// must have been previously produced by the `stage - 1` builder.build
934     /// compiler.
935     fn run(self, builder: &Builder<'_>) -> Compiler {
936         let target_compiler = self.target_compiler;
937
938         if target_compiler.stage == 0 {
939             assert_eq!(
940                 builder.config.build, target_compiler.host,
941                 "Cannot obtain compiler for non-native build triple at stage 0"
942             );
943             // The stage 0 compiler for the build triple is always pre-built.
944             return target_compiler;
945         }
946
947         // Get the compiler that we'll use to bootstrap ourselves.
948         //
949         // Note that this is where the recursive nature of the bootstrap
950         // happens, as this will request the previous stage's compiler on
951         // downwards to stage 0.
952         //
953         // Also note that we're building a compiler for the host platform. We
954         // only assume that we can run `build` artifacts, which means that to
955         // produce some other architecture compiler we need to start from
956         // `build` to get there.
957         //
958         // FIXME: Perhaps we should download those libraries?
959         //        It would make builds faster...
960         //
961         // FIXME: It may be faster if we build just a stage 1 compiler and then
962         //        use that to bootstrap this compiler forward.
963         let build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build);
964
965         // Build the libraries for this compiler to link to (i.e., the libraries
966         // it uses at runtime). NOTE: Crates the target compiler compiles don't
967         // link to these. (FIXME: Is that correct? It seems to be correct most
968         // of the time but I think we do link to these for stage2/bin compilers
969         // when not performing a full bootstrap).
970         builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host });
971
972         for &backend in builder.config.rust_codegen_backends.iter() {
973             if backend == "llvm" {
974                 continue; // Already built as part of rustc
975             }
976
977             builder.ensure(CodegenBackend {
978                 compiler: build_compiler,
979                 target: target_compiler.host,
980                 backend,
981             });
982         }
983
984         let lld_install = if builder.config.lld_enabled {
985             Some(builder.ensure(native::Lld { target: target_compiler.host }))
986         } else {
987             None
988         };
989
990         let stage = target_compiler.stage;
991         let host = target_compiler.host;
992         builder.info(&format!("Assembling stage{} compiler ({})", stage, host));
993
994         // Link in all dylibs to the libdir
995         let stamp = librustc_stamp(builder, build_compiler, target_compiler.host);
996         let proc_macros = builder
997             .read_stamp_file(&stamp)
998             .into_iter()
999             .filter_map(|(path, dependency_type)| {
1000                 if dependency_type == DependencyType::Host {
1001                     Some(path.file_name().unwrap().to_owned().into_string().unwrap())
1002                 } else {
1003                     None
1004                 }
1005             })
1006             .collect::<HashSet<_>>();
1007
1008         let sysroot = builder.sysroot(target_compiler);
1009         let rustc_libdir = builder.rustc_libdir(target_compiler);
1010         t!(fs::create_dir_all(&rustc_libdir));
1011         let src_libdir = builder.sysroot_libdir(build_compiler, host);
1012         for f in builder.read_dir(&src_libdir) {
1013             let filename = f.file_name().into_string().unwrap();
1014             if is_dylib(&filename) && !proc_macros.contains(&filename) {
1015                 builder.copy(&f.path(), &rustc_libdir.join(&filename));
1016             }
1017         }
1018
1019         copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler);
1020
1021         // We prepend this bin directory to the user PATH when linking Rust binaries. To
1022         // avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
1023         let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
1024         let libdir_bin = libdir.parent().unwrap().join("bin");
1025         t!(fs::create_dir_all(&libdir_bin));
1026
1027         if let Some(lld_install) = lld_install {
1028             let src_exe = exe("lld", target_compiler.host);
1029             let dst_exe = exe("rust-lld", target_compiler.host);
1030             builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
1031         }
1032
1033         // Similarly, copy `llvm-dwp` into libdir for Split DWARF.
1034         {
1035             let src_exe = exe("llvm-dwp", target_compiler.host);
1036             let dst_exe = exe("rust-llvm-dwp", target_compiler.host);
1037             let llvm_config_bin = builder.ensure(native::Llvm { target: target_compiler.host });
1038             let llvm_bin_dir = llvm_config_bin.parent().unwrap();
1039             builder.copy(&llvm_bin_dir.join(&src_exe), &libdir_bin.join(&dst_exe));
1040         }
1041
1042         // Ensure that `libLLVM.so` ends up in the newly build compiler directory,
1043         // so that it can be found when the newly built `rustc` is run.
1044         dist::maybe_install_llvm_runtime(builder, target_compiler.host, &sysroot);
1045         dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot);
1046
1047         // Link the compiler binary itself into place
1048         let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
1049         let rustc = out_dir.join(exe("rustc-main", host));
1050         let bindir = sysroot.join("bin");
1051         t!(fs::create_dir_all(&bindir));
1052         let compiler = builder.rustc(target_compiler);
1053         builder.copy(&rustc, &compiler);
1054
1055         target_compiler
1056     }
1057 }
1058
1059 /// Link some files into a rustc sysroot.
1060 ///
1061 /// For a particular stage this will link the file listed in `stamp` into the
1062 /// `sysroot_dst` provided.
1063 pub fn add_to_sysroot(
1064     builder: &Builder<'_>,
1065     sysroot_dst: &Path,
1066     sysroot_host_dst: &Path,
1067     stamp: &Path,
1068 ) {
1069     let self_contained_dst = &sysroot_dst.join("self-contained");
1070     t!(fs::create_dir_all(&sysroot_dst));
1071     t!(fs::create_dir_all(&sysroot_host_dst));
1072     t!(fs::create_dir_all(&self_contained_dst));
1073     for (path, dependency_type) in builder.read_stamp_file(stamp) {
1074         let dst = match dependency_type {
1075             DependencyType::Host => sysroot_host_dst,
1076             DependencyType::Target => sysroot_dst,
1077             DependencyType::TargetSelfContained => self_contained_dst,
1078         };
1079         builder.copy(&path, &dst.join(path.file_name().unwrap()));
1080     }
1081 }
1082
1083 pub fn run_cargo(
1084     builder: &Builder<'_>,
1085     cargo: Cargo,
1086     tail_args: Vec<String>,
1087     stamp: &Path,
1088     additional_target_deps: Vec<(PathBuf, DependencyType)>,
1089     is_check: bool,
1090 ) -> Vec<PathBuf> {
1091     if builder.config.dry_run {
1092         return Vec::new();
1093     }
1094
1095     // `target_root_dir` looks like $dir/$target/release
1096     let target_root_dir = stamp.parent().unwrap();
1097     // `target_deps_dir` looks like $dir/$target/release/deps
1098     let target_deps_dir = target_root_dir.join("deps");
1099     // `host_root_dir` looks like $dir/release
1100     let host_root_dir = target_root_dir
1101         .parent()
1102         .unwrap() // chop off `release`
1103         .parent()
1104         .unwrap() // chop off `$target`
1105         .join(target_root_dir.file_name().unwrap());
1106
1107     // Spawn Cargo slurping up its JSON output. We'll start building up the
1108     // `deps` array of all files it generated along with a `toplevel` array of
1109     // files we need to probe for later.
1110     let mut deps = Vec::new();
1111     let mut toplevel = Vec::new();
1112     let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
1113         let (filenames, crate_types) = match msg {
1114             CargoMessage::CompilerArtifact {
1115                 filenames,
1116                 target: CargoTarget { crate_types },
1117                 ..
1118             } => (filenames, crate_types),
1119             _ => return,
1120         };
1121         for filename in filenames {
1122             // Skip files like executables
1123             if !(filename.ends_with(".rlib")
1124                 || filename.ends_with(".lib")
1125                 || filename.ends_with(".a")
1126                 || is_dylib(&filename)
1127                 || (is_check && filename.ends_with(".rmeta")))
1128             {
1129                 continue;
1130             }
1131
1132             let filename = Path::new(&*filename);
1133
1134             // If this was an output file in the "host dir" we don't actually
1135             // worry about it, it's not relevant for us
1136             if filename.starts_with(&host_root_dir) {
1137                 // Unless it's a proc macro used in the compiler
1138                 if crate_types.iter().any(|t| t == "proc-macro") {
1139                     deps.push((filename.to_path_buf(), DependencyType::Host));
1140                 }
1141                 continue;
1142             }
1143
1144             // If this was output in the `deps` dir then this is a precise file
1145             // name (hash included) so we start tracking it.
1146             if filename.starts_with(&target_deps_dir) {
1147                 deps.push((filename.to_path_buf(), DependencyType::Target));
1148                 continue;
1149             }
1150
1151             // Otherwise this was a "top level artifact" which right now doesn't
1152             // have a hash in the name, but there's a version of this file in
1153             // the `deps` folder which *does* have a hash in the name. That's
1154             // the one we'll want to we'll probe for it later.
1155             //
1156             // We do not use `Path::file_stem` or `Path::extension` here,
1157             // because some generated files may have multiple extensions e.g.
1158             // `std-<hash>.dll.lib` on Windows. The aforementioned methods only
1159             // split the file name by the last extension (`.lib`) while we need
1160             // to split by all extensions (`.dll.lib`).
1161             let expected_len = t!(filename.metadata()).len();
1162             let filename = filename.file_name().unwrap().to_str().unwrap();
1163             let mut parts = filename.splitn(2, '.');
1164             let file_stem = parts.next().unwrap().to_owned();
1165             let extension = parts.next().unwrap().to_owned();
1166
1167             toplevel.push((file_stem, extension, expected_len));
1168         }
1169     });
1170
1171     if !ok {
1172         exit(1);
1173     }
1174
1175     // Ok now we need to actually find all the files listed in `toplevel`. We've
1176     // got a list of prefix/extensions and we basically just need to find the
1177     // most recent file in the `deps` folder corresponding to each one.
1178     let contents = t!(target_deps_dir.read_dir())
1179         .map(|e| t!(e))
1180         .map(|e| (e.path(), e.file_name().into_string().unwrap(), t!(e.metadata())))
1181         .collect::<Vec<_>>();
1182     for (prefix, extension, expected_len) in toplevel {
1183         let candidates = contents.iter().filter(|&&(_, ref filename, ref meta)| {
1184             meta.len() == expected_len
1185                 && filename
1186                     .strip_prefix(&prefix[..])
1187                     .map(|s| s.starts_with('-') && s.ends_with(&extension[..]))
1188                     .unwrap_or(false)
1189         });
1190         let max = candidates
1191             .max_by_key(|&&(_, _, ref metadata)| FileTime::from_last_modification_time(metadata));
1192         let path_to_add = match max {
1193             Some(triple) => triple.0.to_str().unwrap(),
1194             None => panic!("no output generated for {:?} {:?}", prefix, extension),
1195         };
1196         if is_dylib(path_to_add) {
1197             let candidate = format!("{}.lib", path_to_add);
1198             let candidate = PathBuf::from(candidate);
1199             if candidate.exists() {
1200                 deps.push((candidate, DependencyType::Target));
1201             }
1202         }
1203         deps.push((path_to_add.into(), DependencyType::Target));
1204     }
1205
1206     deps.extend(additional_target_deps);
1207     deps.sort();
1208     let mut new_contents = Vec::new();
1209     for (dep, dependency_type) in deps.iter() {
1210         new_contents.extend(match *dependency_type {
1211             DependencyType::Host => b"h",
1212             DependencyType::Target => b"t",
1213             DependencyType::TargetSelfContained => b"s",
1214         });
1215         new_contents.extend(dep.to_str().unwrap().as_bytes());
1216         new_contents.extend(b"\0");
1217     }
1218     t!(fs::write(&stamp, &new_contents));
1219     deps.into_iter().map(|(d, _)| d).collect()
1220 }
1221
1222 pub fn stream_cargo(
1223     builder: &Builder<'_>,
1224     cargo: Cargo,
1225     tail_args: Vec<String>,
1226     cb: &mut dyn FnMut(CargoMessage<'_>),
1227 ) -> bool {
1228     let mut cargo = Command::from(cargo);
1229     if builder.config.dry_run {
1230         return true;
1231     }
1232     // Instruct Cargo to give us json messages on stdout, critically leaving
1233     // stderr as piped so we can get those pretty colors.
1234     let mut message_format = if builder.config.json_output {
1235         String::from("json")
1236     } else {
1237         String::from("json-render-diagnostics")
1238     };
1239     if let Some(s) = &builder.config.rustc_error_format {
1240         message_format.push_str(",json-diagnostic-");
1241         message_format.push_str(s);
1242     }
1243     cargo.arg("--message-format").arg(message_format).stdout(Stdio::piped());
1244
1245     for arg in tail_args {
1246         cargo.arg(arg);
1247     }
1248
1249     builder.verbose(&format!("running: {:?}", cargo));
1250     let mut child = match cargo.spawn() {
1251         Ok(child) => child,
1252         Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e),
1253     };
1254
1255     // Spawn Cargo slurping up its JSON output. We'll start building up the
1256     // `deps` array of all files it generated along with a `toplevel` array of
1257     // files we need to probe for later.
1258     let stdout = BufReader::new(child.stdout.take().unwrap());
1259     for line in stdout.lines() {
1260         let line = t!(line);
1261         match serde_json::from_str::<CargoMessage<'_>>(&line) {
1262             Ok(msg) => {
1263                 if builder.config.json_output {
1264                     // Forward JSON to stdout.
1265                     println!("{}", line);
1266                 }
1267                 cb(msg)
1268             }
1269             // If this was informational, just print it out and continue
1270             Err(_) => println!("{}", line),
1271         }
1272     }
1273
1274     // Make sure Cargo actually succeeded after we read all of its stdout.
1275     let status = t!(child.wait());
1276     if !status.success() {
1277         eprintln!(
1278             "command did not execute successfully: {:?}\n\
1279                   expected success, got: {}",
1280             cargo, status
1281         );
1282     }
1283     status.success()
1284 }
1285
1286 #[derive(Deserialize)]
1287 pub struct CargoTarget<'a> {
1288     crate_types: Vec<Cow<'a, str>>,
1289 }
1290
1291 #[derive(Deserialize)]
1292 #[serde(tag = "reason", rename_all = "kebab-case")]
1293 pub enum CargoMessage<'a> {
1294     CompilerArtifact {
1295         package_id: Cow<'a, str>,
1296         features: Vec<Cow<'a, str>>,
1297         filenames: Vec<Cow<'a, str>>,
1298         target: CargoTarget<'a>,
1299     },
1300     BuildScriptExecuted {
1301         package_id: Cow<'a, str>,
1302     },
1303     BuildFinished {
1304         success: bool,
1305     },
1306 }