1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Implementation of the test-related targets of the build system.
13 //! This file implements the various regression test suites that we execute on
17 use std::ffi::OsString;
20 use std::fs::{self, File};
21 use std::path::{PathBuf, Path};
22 use std::process::Command;
25 use build_helper::{self, output};
27 use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step};
28 use Crate as CargoCrate;
29 use cache::{INTERNER, Interned};
33 use tool::{self, Tool};
34 use util::{self, dylib_path, dylib_path_var};
35 use {Mode, DocTestsOption};
36 use toolstate::ToolState;
38 const ADB_TEST_DIR: &str = "/data/tmp/work";
40 /// The two modes of the test runner; tests or benchmarks.
41 #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
50 // Return the cargo subcommand for this test kind
51 fn subcommand(self) -> &'static str {
53 TestKind::Test => "test",
54 TestKind::Bench => "bench",
59 impl fmt::Display for TestKind {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 f.write_str(match *self {
62 TestKind::Test => "Testing",
63 TestKind::Bench => "Benchmarking",
68 fn try_run(builder: &Builder, cmd: &mut Command) -> bool {
69 if !builder.fail_fast {
70 if !builder.try_run(cmd) {
71 let mut failures = builder.delayed_failures.borrow_mut();
72 failures.push(format!("{:?}", cmd));
81 fn try_run_quiet(builder: &Builder, cmd: &mut Command) -> bool {
82 if !builder.fail_fast {
83 if !builder.try_run_quiet(cmd) {
84 let mut failures = builder.delayed_failures.borrow_mut();
85 failures.push(format!("{:?}", cmd));
89 builder.run_quiet(cmd);
94 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
95 pub struct Linkcheck {
96 host: Interned<String>,
99 impl Step for Linkcheck {
101 const ONLY_HOSTS: bool = true;
102 const DEFAULT: bool = true;
104 /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
106 /// This tool in `src/tools` will verify the validity of all our links in the
107 /// documentation to ensure we don't have a bunch of dead ones.
108 fn run(self, builder: &Builder) {
109 let host = self.host;
111 builder.info(&format!("Linkcheck ({})", host));
113 builder.default_doc(None);
115 let _time = util::timeit(&builder);
116 try_run(builder, builder.tool_cmd(Tool::Linkchecker)
117 .arg(builder.out.join(host).join("doc")));
120 fn should_run(run: ShouldRun) -> ShouldRun {
121 let builder = run.builder;
122 run.path("src/tools/linkchecker").default_condition(builder.config.docs)
125 fn make_run(run: RunConfig) {
126 run.builder.ensure(Linkcheck { host: run.target });
130 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
131 pub struct Cargotest {
133 host: Interned<String>,
136 impl Step for Cargotest {
138 const ONLY_HOSTS: bool = true;
140 fn should_run(run: ShouldRun) -> ShouldRun {
141 run.path("src/tools/cargotest")
144 fn make_run(run: RunConfig) {
145 run.builder.ensure(Cargotest {
146 stage: run.builder.top_stage,
151 /// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
153 /// This tool in `src/tools` will check out a few Rust projects and run `cargo
154 /// test` to ensure that we don't regress the test suites there.
155 fn run(self, builder: &Builder) {
156 let compiler = builder.compiler(self.stage, self.host);
157 builder.ensure(compile::Rustc { compiler, target: compiler.host });
159 // Note that this is a short, cryptic, and not scoped directory name. This
160 // is currently to minimize the length of path on Windows where we otherwise
161 // quickly run into path name limit constraints.
162 let out_dir = builder.out.join("ct");
163 t!(fs::create_dir_all(&out_dir));
165 let _time = util::timeit(&builder);
166 let mut cmd = builder.tool_cmd(Tool::CargoTest);
167 try_run(builder, cmd.arg(&builder.initial_cargo)
169 .env("RUSTC", builder.rustc(compiler))
170 .env("RUSTDOC", builder.rustdoc(compiler.host)));
174 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
177 host: Interned<String>,
180 impl Step for Cargo {
182 const ONLY_HOSTS: bool = true;
184 fn should_run(run: ShouldRun) -> ShouldRun {
185 run.path("src/tools/cargo")
188 fn make_run(run: RunConfig) {
189 run.builder.ensure(Cargo {
190 stage: run.builder.top_stage,
195 /// Runs `cargo test` for `cargo` packaged with Rust.
196 fn run(self, builder: &Builder) {
197 let compiler = builder.compiler(self.stage, self.host);
199 builder.ensure(tool::Cargo { compiler, target: self.host });
200 let mut cargo = builder.cargo(compiler, Mode::Tool, self.host, "test");
201 cargo.arg("--manifest-path").arg(builder.src.join("src/tools/cargo/Cargo.toml"));
202 if !builder.fail_fast {
203 cargo.arg("--no-fail-fast");
206 // Don't build tests dynamically, just a pain to work with
207 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
209 // Don't run cross-compile tests, we may not have cross-compiled libstd libs
211 cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
213 try_run(builder, cargo.env("PATH", &path_for_cargo(builder, compiler)));
217 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
220 host: Interned<String>,
225 const ONLY_HOSTS: bool = true;
227 fn should_run(run: ShouldRun) -> ShouldRun {
228 run.path("src/tools/rls")
231 fn make_run(run: RunConfig) {
232 run.builder.ensure(Rls {
233 stage: run.builder.top_stage,
238 /// Runs `cargo test` for the rls.
239 fn run(self, builder: &Builder) {
240 let stage = self.stage;
241 let host = self.host;
242 let compiler = builder.compiler(stage, host);
244 let build_result = builder.ensure(tool::Rls {
247 extra_features: Vec::new(),
249 if build_result.is_none() {
250 eprintln!("failed to test rls: could not build");
254 let mut cargo = tool::prepare_tool_cargo(builder,
260 // Don't build tests dynamically, just a pain to work with
261 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
263 builder.add_rustc_lib_path(compiler, &mut cargo);
265 if try_run(builder, &mut cargo) {
266 builder.save_toolstate("rls", ToolState::TestPass);
271 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
274 host: Interned<String>,
277 impl Step for Rustfmt {
279 const ONLY_HOSTS: bool = true;
281 fn should_run(run: ShouldRun) -> ShouldRun {
282 run.path("src/tools/rustfmt")
285 fn make_run(run: RunConfig) {
286 run.builder.ensure(Rustfmt {
287 stage: run.builder.top_stage,
292 /// Runs `cargo test` for rustfmt.
293 fn run(self, builder: &Builder) {
294 let stage = self.stage;
295 let host = self.host;
296 let compiler = builder.compiler(stage, host);
298 let build_result = builder.ensure(tool::Rustfmt {
301 extra_features: Vec::new(),
303 if build_result.is_none() {
304 eprintln!("failed to test rustfmt: could not build");
308 let mut cargo = tool::prepare_tool_cargo(builder,
312 "src/tools/rustfmt");
314 // Don't build tests dynamically, just a pain to work with
315 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
317 builder.add_rustc_lib_path(compiler, &mut cargo);
319 if try_run(builder, &mut cargo) {
320 builder.save_toolstate("rustfmt", ToolState::TestPass);
325 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
328 host: Interned<String>,
333 const ONLY_HOSTS: bool = true;
334 const DEFAULT: bool = true;
336 fn should_run(run: ShouldRun) -> ShouldRun {
337 let test_miri = run.builder.config.test_miri;
338 run.path("src/tools/miri").default_condition(test_miri)
341 fn make_run(run: RunConfig) {
342 run.builder.ensure(Miri {
343 stage: run.builder.top_stage,
348 /// Runs `cargo test` for miri.
349 fn run(self, builder: &Builder) {
350 let stage = self.stage;
351 let host = self.host;
352 let compiler = builder.compiler(stage, host);
354 let miri = builder.ensure(tool::Miri {
357 extra_features: Vec::new(),
359 if let Some(miri) = miri {
360 let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
361 cargo.arg("--manifest-path").arg(builder.src.join("src/tools/miri/Cargo.toml"));
363 // Don't build tests dynamically, just a pain to work with
364 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
365 // miri tests need to know about the stage sysroot
366 cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
367 cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
368 cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
369 cargo.env("MIRI_PATH", miri);
371 builder.add_rustc_lib_path(compiler, &mut cargo);
373 if try_run(builder, &mut cargo) {
374 builder.save_toolstate("miri", ToolState::TestPass);
377 eprintln!("failed to test miri: could not build");
382 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
385 host: Interned<String>,
388 impl Step for Clippy {
390 const ONLY_HOSTS: bool = true;
391 const DEFAULT: bool = false;
393 fn should_run(run: ShouldRun) -> ShouldRun {
394 run.path("src/tools/clippy")
397 fn make_run(run: RunConfig) {
398 run.builder.ensure(Clippy {
399 stage: run.builder.top_stage,
404 /// Runs `cargo test` for clippy.
405 fn run(self, builder: &Builder) {
406 let stage = self.stage;
407 let host = self.host;
408 let compiler = builder.compiler(stage, host);
410 let clippy = builder.ensure(tool::Clippy {
413 extra_features: Vec::new(),
415 if let Some(clippy) = clippy {
416 let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
417 cargo.arg("--manifest-path").arg(builder.src.join("src/tools/clippy/Cargo.toml"));
419 // Don't build tests dynamically, just a pain to work with
420 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
421 // clippy tests need to know about the stage sysroot
422 cargo.env("SYSROOT", builder.sysroot(compiler));
423 cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
424 cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
425 let host_libs = builder.stage_out(compiler, Mode::Tool).join(builder.cargo_dir());
426 cargo.env("HOST_LIBS", host_libs);
427 // clippy tests need to find the driver
428 cargo.env("CLIPPY_DRIVER_PATH", clippy);
430 builder.add_rustc_lib_path(compiler, &mut cargo);
432 if try_run(builder, &mut cargo) {
433 builder.save_toolstate("clippy-driver", ToolState::TestPass);
436 eprintln!("failed to test clippy: could not build");
441 fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
442 // Configure PATH to find the right rustc. NB. we have to use PATH
443 // and not RUSTC because the Cargo test suite has tests that will
444 // fail if rustc is not spelled `rustc`.
445 let path = builder.sysroot(compiler).join("bin");
446 let old_path = env::var_os("PATH").unwrap_or_default();
447 env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
450 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
451 pub struct RustdocTheme {
452 pub compiler: Compiler,
455 impl Step for RustdocTheme {
457 const DEFAULT: bool = true;
458 const ONLY_HOSTS: bool = true;
460 fn should_run(run: ShouldRun) -> ShouldRun {
461 run.path("src/tools/rustdoc-themes")
464 fn make_run(run: RunConfig) {
465 let compiler = run.builder.compiler(run.builder.top_stage, run.host);
467 run.builder.ensure(RustdocTheme {
472 fn run(self, builder: &Builder) {
473 let rustdoc = builder.out.join("bootstrap/debug/rustdoc");
474 let mut cmd = builder.tool_cmd(Tool::RustdocTheme);
475 cmd.arg(rustdoc.to_str().unwrap())
476 .arg(builder.src.join("src/librustdoc/html/static/themes").to_str().unwrap())
477 .env("RUSTC_STAGE", self.compiler.stage.to_string())
478 .env("RUSTC_SYSROOT", builder.sysroot(self.compiler))
479 .env("RUSTDOC_LIBDIR", builder.sysroot_libdir(self.compiler, self.compiler.host))
480 .env("CFG_RELEASE_CHANNEL", &builder.config.channel)
481 .env("RUSTDOC_REAL", builder.rustdoc(self.compiler.host))
482 .env("RUSTDOC_CRATE_VERSION", builder.rust_version())
483 .env("RUSTC_BOOTSTRAP", "1");
484 if let Some(linker) = builder.linker(self.compiler.host) {
485 cmd.env("RUSTC_TARGET_LINKER", linker);
487 try_run(builder, &mut cmd);
491 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
492 pub struct RustdocJS {
493 pub host: Interned<String>,
494 pub target: Interned<String>,
497 impl Step for RustdocJS {
499 const DEFAULT: bool = true;
500 const ONLY_HOSTS: bool = true;
502 fn should_run(run: ShouldRun) -> ShouldRun {
503 run.path("src/test/rustdoc-js")
506 fn make_run(run: RunConfig) {
507 run.builder.ensure(RustdocJS {
513 fn run(self, builder: &Builder) {
514 if let Some(ref nodejs) = builder.config.nodejs {
515 let mut command = Command::new(nodejs);
516 command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]);
517 builder.ensure(::doc::Std {
519 stage: builder.top_stage,
521 builder.run(&mut command);
523 builder.info(&format!("No nodejs found, skipping \"src/test/rustdoc-js\" tests"));
528 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
529 pub struct RustdocUi {
530 pub host: Interned<String>,
531 pub target: Interned<String>,
532 pub compiler: Compiler,
535 impl Step for RustdocUi {
537 const DEFAULT: bool = true;
538 const ONLY_HOSTS: bool = true;
540 fn should_run(run: ShouldRun) -> ShouldRun {
541 run.path("src/test/rustdoc-ui")
544 fn make_run(run: RunConfig) {
545 let compiler = run.builder.compiler(run.builder.top_stage, run.host);
546 run.builder.ensure(RustdocUi {
553 fn run(self, builder: &Builder) {
554 builder.ensure(Compiletest {
555 compiler: self.compiler,
564 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
569 const DEFAULT: bool = true;
570 const ONLY_HOSTS: bool = true;
572 /// Runs the `tidy` tool.
574 /// This tool in `src/tools` checks up on various bits and pieces of style and
575 /// otherwise just implements a few lint-like checks that are specific to the
577 fn run(self, builder: &Builder) {
578 let mut cmd = builder.tool_cmd(Tool::Tidy);
579 cmd.arg(builder.src.join("src"));
580 cmd.arg(&builder.initial_cargo);
581 if !builder.config.vendor {
582 cmd.arg("--no-vendor");
584 if builder.config.quiet_tests {
588 let _folder = builder.fold_output(|| "tidy");
589 builder.info(&format!("tidy check"));
590 try_run(builder, &mut cmd);
593 fn should_run(run: ShouldRun) -> ShouldRun {
594 run.path("src/tools/tidy")
597 fn make_run(run: RunConfig) {
598 run.builder.ensure(Tidy);
602 fn testdir(builder: &Builder, host: Interned<String>) -> PathBuf {
603 builder.out.join(host).join("test")
606 macro_rules! default_test {
607 ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => {
608 test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false });
612 macro_rules! default_test_with_compare_mode {
613 ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr,
614 compare_mode: $compare_mode:expr }) => {
615 test_with_compare_mode!($name { path: $path, mode: $mode, suite: $suite, default: true,
616 host: false, compare_mode: $compare_mode });
620 macro_rules! host_test {
621 ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => {
622 test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true });
627 ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr,
628 host: $host:expr }) => {
629 test_definitions!($name { path: $path, mode: $mode, suite: $suite, default: $default,
630 host: $host, compare_mode: None });
634 macro_rules! test_with_compare_mode {
635 ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr,
636 host: $host:expr, compare_mode: $compare_mode:expr }) => {
637 test_definitions!($name { path: $path, mode: $mode, suite: $suite, default: $default,
638 host: $host, compare_mode: Some($compare_mode) });
642 macro_rules! test_definitions {
647 default: $default:expr,
649 compare_mode: $compare_mode:expr
651 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
653 pub compiler: Compiler,
654 pub target: Interned<String>,
657 impl Step for $name {
659 const DEFAULT: bool = $default;
660 const ONLY_HOSTS: bool = $host;
662 fn should_run(run: ShouldRun) -> ShouldRun {
666 fn make_run(run: RunConfig) {
667 let compiler = run.builder.compiler(run.builder.top_stage, run.host);
669 run.builder.ensure($name {
675 fn run(self, builder: &Builder) {
676 builder.ensure(Compiletest {
677 compiler: self.compiler,
681 compare_mode: $compare_mode,
688 default_test_with_compare_mode!(Ui {
695 default_test!(RunPass {
696 path: "src/test/run-pass",
701 default_test!(CompileFail {
702 path: "src/test/compile-fail",
703 mode: "compile-fail",
704 suite: "compile-fail"
707 default_test!(ParseFail {
708 path: "src/test/parse-fail",
713 default_test!(RunFail {
714 path: "src/test/run-fail",
719 default_test!(RunPassValgrind {
720 path: "src/test/run-pass-valgrind",
721 mode: "run-pass-valgrind",
722 suite: "run-pass-valgrind"
725 default_test!(MirOpt {
726 path: "src/test/mir-opt",
731 default_test!(Codegen {
732 path: "src/test/codegen",
737 default_test!(CodegenUnits {
738 path: "src/test/codegen-units",
739 mode: "codegen-units",
740 suite: "codegen-units"
743 default_test!(Incremental {
744 path: "src/test/incremental",
749 default_test!(Debuginfo {
750 path: "src/test/debuginfo",
751 // What this runs varies depending on the native platform being apple
752 mode: "debuginfo-XXX",
756 host_test!(UiFullDeps {
757 path: "src/test/ui-fulldeps",
762 host_test!(RunPassFullDeps {
763 path: "src/test/run-pass-fulldeps",
765 suite: "run-pass-fulldeps"
768 host_test!(RunFailFullDeps {
769 path: "src/test/run-fail-fulldeps",
771 suite: "run-fail-fulldeps"
774 host_test!(CompileFailFullDeps {
775 path: "src/test/compile-fail-fulldeps",
776 mode: "compile-fail",
777 suite: "compile-fail-fulldeps"
780 host_test!(IncrementalFullDeps {
781 path: "src/test/incremental-fulldeps",
783 suite: "incremental-fulldeps"
787 path: "src/test/rustdoc",
793 path: "src/test/pretty",
799 test!(RunPassPretty {
800 path: "src/test/run-pass/pretty",
806 test!(RunFailPretty {
807 path: "src/test/run-fail/pretty",
813 test!(RunPassValgrindPretty {
814 path: "src/test/run-pass-valgrind/pretty",
816 suite: "run-pass-valgrind",
820 test!(RunPassFullDepsPretty {
821 path: "src/test/run-pass-fulldeps/pretty",
823 suite: "run-pass-fulldeps",
827 test!(RunFailFullDepsPretty {
828 path: "src/test/run-fail-fulldeps/pretty",
830 suite: "run-fail-fulldeps",
835 default_test!(RunMake {
836 path: "src/test/run-make",
841 host_test!(RunMakeFullDeps {
842 path: "src/test/run-make-fulldeps",
844 suite: "run-make-fulldeps"
847 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
850 target: Interned<String>,
853 compare_mode: Option<&'static str>,
856 impl Step for Compiletest {
859 fn should_run(run: ShouldRun) -> ShouldRun {
863 /// Executes the `compiletest` tool to run a suite of tests.
865 /// Compiles all tests with `compiler` for `target` with the specified
866 /// compiletest `mode` and `suite` arguments. For example `mode` can be
867 /// "run-pass" or `suite` can be something like `debuginfo`.
868 fn run(self, builder: &Builder) {
869 let compiler = self.compiler;
870 let target = self.target;
871 let mode = self.mode;
872 let suite = self.suite;
873 let compare_mode = self.compare_mode;
875 // Skip codegen tests if they aren't enabled in configuration.
876 if !builder.config.codegen_tests && suite == "codegen" {
880 if suite == "debuginfo" {
881 // Skip debuginfo tests on MSVC
882 if builder.config.build.contains("msvc") {
886 if mode == "debuginfo-XXX" {
887 return if builder.config.build.contains("apple") {
888 builder.ensure(Compiletest {
889 mode: "debuginfo-lldb",
893 builder.ensure(Compiletest {
894 mode: "debuginfo-gdb",
900 builder.ensure(dist::DebuggerScripts {
901 sysroot: builder.sysroot(compiler),
906 if suite.ends_with("fulldeps") ||
907 // FIXME: Does pretty need librustc compiled? Note that there are
908 // fulldeps test suites with mode = pretty as well.
911 builder.ensure(compile::Rustc { compiler, target });
914 builder.ensure(compile::Test { compiler, target });
915 builder.ensure(native::TestHelpers { target });
916 builder.ensure(RemoteCopyLibs { compiler, target });
918 let mut cmd = builder.tool_cmd(Tool::Compiletest);
920 // compiletest currently has... a lot of arguments, so let's just pass all
923 cmd.arg("--compile-lib-path").arg(builder.rustc_libdir(compiler));
924 cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target));
925 cmd.arg("--rustc-path").arg(builder.rustc(compiler));
927 let is_rustdoc_ui = suite.ends_with("rustdoc-ui");
929 // Avoid depending on rustdoc when we don't need it.
930 if mode == "rustdoc" ||
931 (mode == "run-make" && suite.ends_with("fulldeps")) ||
932 (mode == "ui" && is_rustdoc_ui) {
933 cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host));
936 cmd.arg("--src-base").arg(builder.src.join("src/test").join(suite));
937 cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
938 cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
939 cmd.arg("--mode").arg(mode);
940 cmd.arg("--target").arg(target);
941 cmd.arg("--host").arg(&*compiler.host);
942 cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));
944 if let Some(ref nodejs) = builder.config.nodejs {
945 cmd.arg("--nodejs").arg(nodejs);
948 let mut flags = if is_rustdoc_ui {
951 vec!["-Crpath".to_string()]
954 if builder.config.rust_optimize_tests {
955 flags.push("-O".to_string());
957 if builder.config.rust_debuginfo_tests {
958 flags.push("-g".to_string());
961 flags.push("-Zunstable-options".to_string());
962 flags.push(builder.config.cmd.rustc_args().join(" "));
964 if let Some(linker) = builder.linker(target) {
965 cmd.arg("--linker").arg(linker);
968 let hostflags = flags.clone();
969 cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
971 let mut targetflags = flags.clone();
972 targetflags.push(format!("-Lnative={}",
973 builder.test_helpers_out(target).display()));
974 cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
976 cmd.arg("--docck-python").arg(builder.python());
978 if builder.config.build.ends_with("apple-darwin") {
979 // Force /usr/bin/python on macOS for LLDB tests because we're loading the
980 // LLDB plugin's compiled module which only works with the system python
981 // (namely not Homebrew-installed python)
982 cmd.arg("--lldb-python").arg("/usr/bin/python");
984 cmd.arg("--lldb-python").arg(builder.python());
987 if let Some(ref gdb) = builder.config.gdb {
988 cmd.arg("--gdb").arg(gdb);
990 if let Some(ref vers) = builder.lldb_version {
991 cmd.arg("--lldb-version").arg(vers);
993 if let Some(ref dir) = builder.lldb_python_dir {
994 cmd.arg("--lldb-python-dir").arg(dir);
997 cmd.args(&builder.config.cmd.test_args());
999 if builder.is_verbose() {
1000 cmd.arg("--verbose");
1003 if builder.config.quiet_tests {
1007 if builder.config.llvm_enabled {
1008 let llvm_config = builder.ensure(native::Llvm {
1009 target: builder.config.build,
1012 if !builder.config.dry_run {
1013 let llvm_version = output(Command::new(&llvm_config).arg("--version"));
1014 cmd.arg("--llvm-version").arg(llvm_version);
1016 if !builder.is_rust_llvm(target) {
1017 cmd.arg("--system-llvm");
1020 // Only pass correct values for these flags for the `run-make` suite as it
1021 // requires that a C++ compiler was configured which isn't always the case.
1022 if !builder.config.dry_run && suite == "run-make-fulldeps" {
1023 let llvm_components = output(Command::new(&llvm_config).arg("--components"));
1024 let llvm_cxxflags = output(Command::new(&llvm_config).arg("--cxxflags"));
1025 cmd.arg("--cc").arg(builder.cc(target))
1026 .arg("--cxx").arg(builder.cxx(target).unwrap())
1027 .arg("--cflags").arg(builder.cflags(target).join(" "))
1028 .arg("--llvm-components").arg(llvm_components.trim())
1029 .arg("--llvm-cxxflags").arg(llvm_cxxflags.trim());
1030 if let Some(ar) = builder.ar(target) {
1031 cmd.arg("--ar").arg(ar);
1035 if suite == "run-make-fulldeps" && !builder.config.llvm_enabled {
1037 &format!("Ignoring run-make test suite as they generally don't work without LLVM"));
1041 if suite != "run-make-fulldeps" {
1042 cmd.arg("--cc").arg("")
1043 .arg("--cxx").arg("")
1044 .arg("--cflags").arg("")
1045 .arg("--llvm-components").arg("")
1046 .arg("--llvm-cxxflags").arg("");
1049 if builder.remote_tested(target) {
1050 cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
1053 // Running a C compiler on MSVC requires a few env vars to be set, to be
1054 // sure to set them here.
1056 // Note that if we encounter `PATH` we make sure to append to our own `PATH`
1057 // rather than stomp over it.
1058 if target.contains("msvc") {
1059 for &(ref k, ref v) in builder.cc[&target].env() {
1065 cmd.env("RUSTC_BOOTSTRAP", "1");
1066 builder.add_rust_test_threads(&mut cmd);
1068 if builder.config.sanitizers {
1069 cmd.env("SANITIZER_SUPPORT", "1");
1072 if builder.config.profiler {
1073 cmd.env("PROFILER_SUPPORT", "1");
1076 cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp"));
1078 cmd.arg("--adb-path").arg("adb");
1079 cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
1080 if target.contains("android") {
1081 // Assume that cc for this target comes from the android sysroot
1082 cmd.arg("--android-cross-path")
1083 .arg(builder.cc(target).parent().unwrap().parent().unwrap());
1085 cmd.arg("--android-cross-path").arg("");
1088 builder.ci_env.force_coloring_in_ci(&mut cmd);
1090 let _folder = builder.fold_output(|| format!("test_{}", suite));
1091 builder.info(&format!("Check compiletest suite={} mode={} ({} -> {})",
1092 suite, mode, &compiler.host, target));
1093 let _time = util::timeit(&builder);
1094 try_run(builder, &mut cmd);
1096 if let Some(compare_mode) = compare_mode {
1097 cmd.arg("--compare-mode").arg(compare_mode);
1098 let _folder = builder.fold_output(|| format!("test_{}_{}", suite, compare_mode));
1099 builder.info(&format!("Check compiletest suite={} mode={} compare_mode={} ({} -> {})",
1100 suite, mode, compare_mode, &compiler.host, target));
1101 let _time = util::timeit(&builder);
1102 try_run(builder, &mut cmd);
1107 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1115 impl Step for DocTest {
1117 const ONLY_HOSTS: bool = true;
1119 fn should_run(run: ShouldRun) -> ShouldRun {
1123 /// Run `rustdoc --test` for all documentation in `src/doc`.
1125 /// This will run all tests in our markdown documentation (e.g. the book)
1126 /// located in `src/doc`. The `rustdoc` that's run is the one that sits next to
1128 fn run(self, builder: &Builder) {
1129 let compiler = self.compiler;
1131 builder.ensure(compile::Test { compiler, target: compiler.host });
1133 // Do a breadth-first traversal of the `src/doc` directory and just run
1134 // tests for all files that end in `*.md`
1135 let mut stack = vec![builder.src.join(self.path)];
1136 let _time = util::timeit(&builder);
1137 let _folder = builder.fold_output(|| format!("test_{}", self.name));
1139 let mut files = Vec::new();
1140 while let Some(p) = stack.pop() {
1142 stack.extend(t!(p.read_dir()).map(|p| t!(p).path()));
1146 if p.extension().and_then(|s| s.to_str()) != Some("md") {
1150 // The nostarch directory in the book is for no starch, and so isn't
1151 // guaranteed to builder. We don't care if it doesn't build, so skip it.
1152 if p.to_str().map_or(false, |p| p.contains("nostarch")) {
1162 let test_result = markdown_test(builder, compiler, &file);
1163 if self.is_ext_doc {
1164 let toolstate = if test_result {
1169 builder.save_toolstate(self.name, toolstate);
1175 macro_rules! test_book {
1176 ($($name:ident, $path:expr, $book_name:expr, default=$default:expr;)+) => {
1178 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1183 impl Step for $name {
1185 const DEFAULT: bool = $default;
1186 const ONLY_HOSTS: bool = true;
1188 fn should_run(run: ShouldRun) -> ShouldRun {
1192 fn make_run(run: RunConfig) {
1193 run.builder.ensure($name {
1194 compiler: run.builder.compiler(run.builder.top_stage, run.host),
1198 fn run(self, builder: &Builder) {
1199 builder.ensure(DocTest {
1200 compiler: self.compiler,
1203 is_ext_doc: !$default,
1212 Nomicon, "src/doc/nomicon", "nomicon", default=false;
1213 Reference, "src/doc/reference", "reference", default=false;
1214 RustdocBook, "src/doc/rustdoc", "rustdoc", default=true;
1215 RustcBook, "src/doc/rustc", "rustc", default=true;
1216 RustByExample, "src/doc/rust-by-example", "rust-by-example", default=false;
1217 TheBook, "src/doc/book", "book", default=false;
1218 UnstableBook, "src/doc/unstable-book", "unstable-book", default=true;
1221 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1222 pub struct ErrorIndex {
1226 impl Step for ErrorIndex {
1228 const DEFAULT: bool = true;
1229 const ONLY_HOSTS: bool = true;
1231 fn should_run(run: ShouldRun) -> ShouldRun {
1232 run.path("src/tools/error_index_generator")
1235 fn make_run(run: RunConfig) {
1236 run.builder.ensure(ErrorIndex {
1237 compiler: run.builder.compiler(run.builder.top_stage, run.host),
1241 /// Run the error index generator tool to execute the tests located in the error
1244 /// The `error_index_generator` tool lives in `src/tools` and is used to
1245 /// generate a markdown file from the error indexes of the code base which is
1246 /// then passed to `rustdoc --test`.
1247 fn run(self, builder: &Builder) {
1248 let compiler = self.compiler;
1250 builder.ensure(compile::Std { compiler, target: compiler.host });
1252 let dir = testdir(builder, compiler.host);
1253 t!(fs::create_dir_all(&dir));
1254 let output = dir.join("error-index.md");
1256 let mut tool = builder.tool_cmd(Tool::ErrorIndex);
1257 tool.arg("markdown")
1259 .env("CFG_BUILD", &builder.config.build)
1260 .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
1263 let _folder = builder.fold_output(|| "test_error_index");
1264 builder.info(&format!("Testing error-index stage{}", compiler.stage));
1265 let _time = util::timeit(&builder);
1266 builder.run(&mut tool);
1267 markdown_test(builder, compiler, &output);
1271 fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) -> bool {
1272 match File::open(markdown) {
1274 let mut contents = String::new();
1275 t!(file.read_to_string(&mut contents));
1276 if !contents.contains("```") {
1283 builder.info(&format!("doc tests for: {}", markdown.display()));
1284 let mut cmd = builder.rustdoc_cmd(compiler.host);
1285 builder.add_rust_test_threads(&mut cmd);
1288 cmd.env("RUSTC_BOOTSTRAP", "1");
1290 let test_args = builder.config.cmd.test_args().join(" ");
1291 cmd.arg("--test-args").arg(test_args);
1293 if builder.config.quiet_tests {
1294 try_run_quiet(builder, &mut cmd)
1296 try_run(builder, &mut cmd)
1300 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1301 pub struct CrateLibrustc {
1303 target: Interned<String>,
1304 test_kind: TestKind,
1305 krate: Interned<String>,
1308 impl Step for CrateLibrustc {
1310 const DEFAULT: bool = true;
1311 const ONLY_HOSTS: bool = true;
1313 fn should_run(run: ShouldRun) -> ShouldRun {
1314 run.krate("rustc-main")
1317 fn make_run(run: RunConfig) {
1318 let builder = run.builder;
1319 let compiler = builder.compiler(builder.top_stage, run.host);
1321 for krate in builder.in_tree_crates("rustc-main") {
1322 if run.path.ends_with(&krate.path) {
1323 let test_kind = if builder.kind == Kind::Test {
1325 } else if builder.kind == Kind::Bench {
1328 panic!("unexpected builder.kind in crate: {:?}", builder.kind);
1331 builder.ensure(CrateLibrustc {
1341 fn run(self, builder: &Builder) {
1342 builder.ensure(Crate {
1343 compiler: self.compiler,
1344 target: self.target,
1345 mode: Mode::Librustc,
1346 test_kind: self.test_kind,
1352 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1353 pub struct CrateNotDefault {
1355 target: Interned<String>,
1356 test_kind: TestKind,
1357 krate: &'static str,
1360 impl Step for CrateNotDefault {
1363 fn should_run(run: ShouldRun) -> ShouldRun {
1364 run.path("src/liballoc_jemalloc")
1365 .path("src/librustc_asan")
1366 .path("src/librustc_lsan")
1367 .path("src/librustc_msan")
1368 .path("src/librustc_tsan")
1371 fn make_run(run: RunConfig) {
1372 let builder = run.builder;
1373 let compiler = builder.compiler(builder.top_stage, run.host);
1375 let test_kind = if builder.kind == Kind::Test {
1377 } else if builder.kind == Kind::Bench {
1380 panic!("unexpected builder.kind in crate: {:?}", builder.kind);
1383 builder.ensure(CrateNotDefault {
1387 krate: match run.path {
1388 _ if run.path.ends_with("src/liballoc_jemalloc") => "alloc_jemalloc",
1389 _ if run.path.ends_with("src/librustc_asan") => "rustc_asan",
1390 _ if run.path.ends_with("src/librustc_lsan") => "rustc_lsan",
1391 _ if run.path.ends_with("src/librustc_msan") => "rustc_msan",
1392 _ if run.path.ends_with("src/librustc_tsan") => "rustc_tsan",
1393 _ => panic!("unexpected path {:?}", run.path),
1398 fn run(self, builder: &Builder) {
1399 builder.ensure(Crate {
1400 compiler: self.compiler,
1401 target: self.target,
1403 test_kind: self.test_kind,
1404 krate: INTERNER.intern_str(self.krate),
1410 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1413 target: Interned<String>,
1415 test_kind: TestKind,
1416 krate: Interned<String>,
1419 impl Step for Crate {
1421 const DEFAULT: bool = true;
1423 fn should_run(mut run: ShouldRun) -> ShouldRun {
1424 let builder = run.builder;
1425 run = run.krate("test");
1426 for krate in run.builder.in_tree_crates("std") {
1427 if krate.is_local(&run.builder) &&
1428 !krate.name.contains("jemalloc") &&
1429 !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) &&
1430 krate.name != "dlmalloc" {
1431 run = run.path(krate.local_path(&builder).to_str().unwrap());
1437 fn make_run(run: RunConfig) {
1438 let builder = run.builder;
1439 let compiler = builder.compiler(builder.top_stage, run.host);
1441 let make = |mode: Mode, krate: &CargoCrate| {
1442 let test_kind = if builder.kind == Kind::Test {
1444 } else if builder.kind == Kind::Bench {
1447 panic!("unexpected builder.kind in crate: {:?}", builder.kind);
1450 builder.ensure(Crate {
1459 for krate in builder.in_tree_crates("std") {
1460 if run.path.ends_with(&krate.local_path(&builder)) {
1461 make(Mode::Libstd, krate);
1464 for krate in builder.in_tree_crates("test") {
1465 if run.path.ends_with(&krate.local_path(&builder)) {
1466 make(Mode::Libtest, krate);
1471 /// Run all unit tests plus documentation tests for a given crate defined
1472 /// by a `Cargo.toml` (single manifest)
1474 /// This is what runs tests for crates like the standard library, compiler, etc.
1475 /// It essentially is the driver for running `cargo test`.
1477 /// Currently this runs all tests for a DAG by passing a bunch of `-p foo`
1478 /// arguments, and those arguments are discovered from `cargo metadata`.
1479 fn run(self, builder: &Builder) {
1480 let compiler = self.compiler;
1481 let target = self.target;
1482 let mode = self.mode;
1483 let test_kind = self.test_kind;
1484 let krate = self.krate;
1486 builder.ensure(compile::Test { compiler, target });
1487 builder.ensure(RemoteCopyLibs { compiler, target });
1489 // If we're not doing a full bootstrap but we're testing a stage2 version of
1490 // libstd, then what we're actually testing is the libstd produced in
1491 // stage1. Reflect that here by updating the compiler that we're working
1492 // with automatically.
1493 let compiler = if builder.force_use_stage1(compiler, target) {
1494 builder.compiler(1, compiler.host)
1499 let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
1502 compile::std_cargo(builder, &compiler, target, &mut cargo);
1505 compile::test_cargo(builder, &compiler, target, &mut cargo);
1508 builder.ensure(compile::Rustc { compiler, target });
1509 compile::rustc_cargo(builder, &mut cargo);
1511 _ => panic!("can only test libraries"),
1514 // Build up the base `cargo test` command.
1516 // Pass in some standard flags then iterate over the graph we've discovered
1517 // in `cargo metadata` with the maps above and figure out what `-p`
1518 // arguments need to get passed.
1519 if test_kind.subcommand() == "test" && !builder.fail_fast {
1520 cargo.arg("--no-fail-fast");
1522 match builder.doc_tests {
1523 DocTestsOption::Only => {
1526 DocTestsOption::No => {
1527 cargo.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
1529 DocTestsOption::Yes => {}
1532 cargo.arg("-p").arg(krate);
1534 // The tests are going to run with the *target* libraries, so we need to
1535 // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent.
1537 // Note that to run the compiler we need to run with the *host* libraries,
1538 // but our wrapper scripts arrange for that to be the case anyway.
1539 let mut dylib_path = dylib_path();
1540 dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
1541 cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
1544 cargo.args(&builder.config.cmd.test_args());
1546 if builder.config.quiet_tests {
1547 cargo.arg("--quiet");
1550 if target.contains("emscripten") {
1551 cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
1552 builder.config.nodejs.as_ref().expect("nodejs not configured"));
1553 } else if target.starts_with("wasm32") {
1554 // Warn about running tests without the `wasm_syscall` feature enabled.
1555 // The javascript shim implements the syscall interface so that test
1556 // output can be correctly reported.
1557 if !builder.config.wasm_syscall {
1558 builder.info(&format!("Libstd was built without `wasm_syscall` feature enabled: \
1559 test output may not be visible."));
1562 // On the wasm32-unknown-unknown target we're using LTO which is
1563 // incompatible with `-C prefer-dynamic`, so disable that here
1564 cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
1566 let node = builder.config.nodejs.as_ref()
1567 .expect("nodejs not configured");
1568 let runner = format!("{} {}/src/etc/wasm32-shim.js",
1570 builder.src.display());
1571 cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)), &runner);
1572 } else if builder.remote_tested(target) {
1573 cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
1575 builder.tool_exe(Tool::RemoteTestClient).display()));
1578 let _folder = builder.fold_output(|| {
1579 format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate)
1581 builder.info(&format!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage,
1582 &compiler.host, target));
1583 let _time = util::timeit(&builder);
1584 try_run(builder, &mut cargo);
1588 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1589 pub struct CrateRustdoc {
1590 host: Interned<String>,
1591 test_kind: TestKind,
1594 impl Step for CrateRustdoc {
1596 const DEFAULT: bool = true;
1597 const ONLY_HOSTS: bool = true;
1599 fn should_run(run: ShouldRun) -> ShouldRun {
1600 run.paths(&["src/librustdoc", "src/tools/rustdoc"])
1603 fn make_run(run: RunConfig) {
1604 let builder = run.builder;
1606 let test_kind = if builder.kind == Kind::Test {
1608 } else if builder.kind == Kind::Bench {
1611 panic!("unexpected builder.kind in crate: {:?}", builder.kind);
1614 builder.ensure(CrateRustdoc {
1620 fn run(self, builder: &Builder) {
1621 let test_kind = self.test_kind;
1623 let compiler = builder.compiler(builder.top_stage, self.host);
1624 let target = compiler.host;
1626 let mut cargo = tool::prepare_tool_cargo(builder,
1629 test_kind.subcommand(),
1630 "src/tools/rustdoc");
1631 if test_kind.subcommand() == "test" && !builder.fail_fast {
1632 cargo.arg("--no-fail-fast");
1635 cargo.arg("-p").arg("rustdoc:0.0.0");
1638 cargo.args(&builder.config.cmd.test_args());
1640 if builder.config.quiet_tests {
1641 cargo.arg("--quiet");
1644 let _folder = builder.fold_output(|| {
1645 format!("{}_stage{}-rustdoc", test_kind.subcommand(), compiler.stage)
1647 builder.info(&format!("{} rustdoc stage{} ({} -> {})", test_kind, compiler.stage,
1648 &compiler.host, target));
1649 let _time = util::timeit(&builder);
1651 try_run(builder, &mut cargo);
1655 fn envify(s: &str) -> String {
1661 }).flat_map(|c| c.to_uppercase()).collect()
1664 /// Some test suites are run inside emulators or on remote devices, and most
1665 /// of our test binaries are linked dynamically which means we need to ship
1666 /// the standard library and such to the emulator ahead of time. This step
1667 /// represents this and is a dependency of all test suites.
1669 /// Most of the time this is a noop. For some steps such as shipping data to
1670 /// QEMU we have to build our own tools so we've got conditional dependencies
1671 /// on those programs as well. Note that the remote test client is built for
1672 /// the build target (us) and the server is built for the target.
1673 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1674 pub struct RemoteCopyLibs {
1676 target: Interned<String>,
1679 impl Step for RemoteCopyLibs {
1682 fn should_run(run: ShouldRun) -> ShouldRun {
1686 fn run(self, builder: &Builder) {
1687 let compiler = self.compiler;
1688 let target = self.target;
1689 if !builder.remote_tested(target) {
1693 builder.ensure(compile::Test { compiler, target });
1695 builder.info(&format!("REMOTE copy libs to emulator ({})", target));
1696 t!(fs::create_dir_all(builder.out.join("tmp")));
1698 let server = builder.ensure(tool::RemoteTestServer { compiler, target });
1700 // Spawn the emulator and wait for it to come online
1701 let tool = builder.tool_exe(Tool::RemoteTestClient);
1702 let mut cmd = Command::new(&tool);
1703 cmd.arg("spawn-emulator")
1706 .arg(builder.out.join("tmp"));
1707 if let Some(rootfs) = builder.qemu_rootfs(target) {
1710 builder.run(&mut cmd);
1712 // Push all our dylibs to the emulator
1713 for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) {
1715 let name = f.file_name().into_string().unwrap();
1716 if util::is_dylib(&name) {
1717 builder.run(Command::new(&tool)
1725 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1726 pub struct Distcheck;
1728 impl Step for Distcheck {
1731 fn should_run(run: ShouldRun) -> ShouldRun {
1732 run.path("distcheck")
1735 fn make_run(run: RunConfig) {
1736 run.builder.ensure(Distcheck);
1739 /// Run "distcheck", a 'make check' from a tarball
1740 fn run(self, builder: &Builder) {
1741 builder.info(&format!("Distcheck"));
1742 let dir = builder.out.join("tmp").join("distcheck");
1743 let _ = fs::remove_dir_all(&dir);
1744 t!(fs::create_dir_all(&dir));
1746 // Guarantee that these are built before we begin running.
1747 builder.ensure(dist::PlainSourceTarball);
1748 builder.ensure(dist::Src);
1750 let mut cmd = Command::new("tar");
1752 .arg(builder.ensure(dist::PlainSourceTarball))
1753 .arg("--strip-components=1")
1755 builder.run(&mut cmd);
1756 builder.run(Command::new("./configure")
1757 .args(&builder.config.configure_args)
1758 .arg("--enable-vendor")
1759 .current_dir(&dir));
1760 builder.run(Command::new(build_helper::make(&builder.config.build))
1762 .current_dir(&dir));
1764 // Now make sure that rust-src has all of libstd's dependencies
1765 builder.info(&format!("Distcheck rust-src"));
1766 let dir = builder.out.join("tmp").join("distcheck-src");
1767 let _ = fs::remove_dir_all(&dir);
1768 t!(fs::create_dir_all(&dir));
1770 let mut cmd = Command::new("tar");
1772 .arg(builder.ensure(dist::Src))
1773 .arg("--strip-components=1")
1775 builder.run(&mut cmd);
1777 let toml = dir.join("rust-src/lib/rustlib/src/rust/src/libstd/Cargo.toml");
1778 builder.run(Command::new(&builder.initial_cargo)
1779 .arg("generate-lockfile")
1780 .arg("--manifest-path")
1782 .current_dir(&dir));
1786 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1787 pub struct Bootstrap;
1789 impl Step for Bootstrap {
1791 const DEFAULT: bool = true;
1792 const ONLY_HOSTS: bool = true;
1794 /// Test the build system itself
1795 fn run(self, builder: &Builder) {
1796 let mut cmd = Command::new(&builder.initial_cargo);
1798 .current_dir(builder.src.join("src/bootstrap"))
1799 .env("RUSTFLAGS", "-Cdebuginfo=2")
1800 .env("CARGO_TARGET_DIR", builder.out.join("bootstrap"))
1801 .env("RUSTC_BOOTSTRAP", "1")
1802 .env("RUSTC", &builder.initial_rustc);
1803 if let Some(flags) = option_env!("RUSTFLAGS") {
1804 // Use the same rustc flags for testing as for "normal" compilation,
1805 // so that Cargo doesn’t recompile the entire dependency graph every time:
1806 // https://github.com/rust-lang/rust/issues/49215
1807 cmd.env("RUSTFLAGS", flags);
1809 if !builder.fail_fast {
1810 cmd.arg("--no-fail-fast");
1812 cmd.arg("--").args(&builder.config.cmd.test_args());
1813 try_run(builder, &mut cmd);
1816 fn should_run(run: ShouldRun) -> ShouldRun {
1817 run.path("src/bootstrap")
1820 fn make_run(run: RunConfig) {
1821 run.builder.ensure(Bootstrap);