1 //! Implementation of the test-related targets of the build system.
3 //! This file implements the various regression test suites that we execute on
7 use std
::ffi
::OsString
;
11 use std
::path
::{Path, PathBuf}
;
12 use std
::process
::Command
;
14 use build_helper
::{self, output, t}
;
16 use crate::builder
::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}
;
17 use crate::cache
::Interned
;
19 use crate::config
::TargetSelection
;
21 use crate::flags
::Subcommand
;
23 use crate::tool
::{self, SourceType, Tool}
;
24 use crate::toolstate
::ToolState
;
25 use crate::util
::{self, add_link_lib_path, dylib_path, dylib_path_var}
;
26 use crate::Crate
as CargoCrate
;
27 use crate::{envify, DocTests, GitRepo, Mode}
;
29 const ADB_TEST_DIR
: &str = "/data/tmp/work";
31 /// The two modes of the test runner; tests or benchmarks.
32 #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord)]
36 /// Run `cargo bench`.
40 impl From
<Kind
> for TestKind
{
41 fn from(kind
: Kind
) -> Self {
43 Kind
::Test
=> TestKind
::Test
,
44 Kind
::Bench
=> TestKind
::Bench
,
45 _
=> panic
!("unexpected kind in crate: {:?}", kind
),
51 // Return the cargo subcommand for this test kind
52 fn subcommand(self) -> &'
static str {
54 TestKind
::Test
=> "test",
55 TestKind
::Bench
=> "bench",
60 impl fmt
::Display
for TestKind
{
61 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
62 f
.write_str(match *self {
63 TestKind
::Test
=> "Testing",
64 TestKind
::Bench
=> "Benchmarking",
69 fn try_run(builder
: &Builder
<'_
>, cmd
: &mut Command
) -> bool
{
70 if !builder
.fail_fast
{
71 if !builder
.try_run(cmd
) {
72 let mut failures
= builder
.delayed_failures
.borrow_mut();
73 failures
.push(format
!("{:?}", cmd
));
82 fn try_run_quiet(builder
: &Builder
<'_
>, cmd
: &mut Command
) -> bool
{
83 if !builder
.fail_fast
{
84 if !builder
.try_run_quiet(cmd
) {
85 let mut failures
= builder
.delayed_failures
.borrow_mut();
86 failures
.push(format
!("{:?}", cmd
));
90 builder
.run_quiet(cmd
);
95 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
96 pub struct Linkcheck
{
97 host
: TargetSelection
,
100 impl Step
for Linkcheck
{
102 const ONLY_HOSTS
: bool
= true;
103 const DEFAULT
: bool
= true;
105 /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
107 /// This tool in `src/tools` will verify the validity of all our links in the
108 /// documentation to ensure we don't have a bunch of dead ones.
109 fn run(self, builder
: &Builder
<'_
>) {
110 let host
= self.host
;
111 let hosts
= &builder
.hosts
;
112 let targets
= &builder
.targets
;
114 // if we have different hosts and targets, some things may be built for
115 // the host (e.g. rustc) and others for the target (e.g. std). The
116 // documentation built for each will contain broken links to
117 // docs built for the other platform (e.g. rustc linking to cargo)
118 if (hosts
!= targets
) && !hosts
.is_empty() && !targets
.is_empty() {
120 "Linkcheck currently does not support builds with different hosts and targets.
121 You can skip linkcheck with --exclude src/tools/linkchecker"
125 builder
.info(&format
!("Linkcheck ({})", host
));
127 builder
.default_doc(&[]);
129 let _time
= util
::timeit(&builder
);
132 builder
.tool_cmd(Tool
::Linkchecker
).arg(builder
.out
.join(host
.triple
).join("doc")),
136 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
137 let builder
= run
.builder
;
138 let run
= run
.path("src/tools/linkchecker");
139 run
.default_condition(builder
.config
.docs
)
142 fn make_run(run
: RunConfig
<'_
>) {
143 run
.builder
.ensure(Linkcheck { host: run.target }
);
147 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
148 pub struct Cargotest
{
150 host
: TargetSelection
,
153 impl Step
for Cargotest
{
155 const ONLY_HOSTS
: bool
= true;
157 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
158 run
.path("src/tools/cargotest")
161 fn make_run(run
: RunConfig
<'_
>) {
162 run
.builder
.ensure(Cargotest { stage: run.builder.top_stage, host: run.target }
);
165 /// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
167 /// This tool in `src/tools` will check out a few Rust projects and run `cargo
168 /// test` to ensure that we don't regress the test suites there.
169 fn run(self, builder
: &Builder
<'_
>) {
170 let compiler
= builder
.compiler(self.stage
, self.host
);
171 builder
.ensure(compile
::Rustc { compiler, target: compiler.host }
);
172 let cargo
= builder
.ensure(tool
::Cargo { compiler, target: compiler.host }
);
174 // Note that this is a short, cryptic, and not scoped directory name. This
175 // is currently to minimize the length of path on Windows where we otherwise
176 // quickly run into path name limit constraints.
177 let out_dir
= builder
.out
.join("ct");
178 t
!(fs
::create_dir_all(&out_dir
));
180 let _time
= util
::timeit(&builder
);
181 let mut cmd
= builder
.tool_cmd(Tool
::CargoTest
);
186 .args(builder
.config
.cmd
.test_args())
187 .env("RUSTC", builder
.rustc(compiler
))
188 .env("RUSTDOC", builder
.rustdoc(compiler
)),
193 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
196 host
: TargetSelection
,
199 impl Step
for Cargo
{
201 const ONLY_HOSTS
: bool
= true;
203 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
204 run
.path("src/tools/cargo")
207 fn make_run(run
: RunConfig
<'_
>) {
208 run
.builder
.ensure(Cargo { stage: run.builder.top_stage, host: run.target }
);
211 /// Runs `cargo test` for `cargo` packaged with Rust.
212 fn run(self, builder
: &Builder
<'_
>) {
213 let compiler
= builder
.compiler(self.stage
, self.host
);
215 builder
.ensure(tool
::Cargo { compiler, target: self.host }
);
216 let mut cargo
= tool
::prepare_tool_cargo(
223 SourceType
::Submodule
,
227 if !builder
.fail_fast
{
228 cargo
.arg("--no-fail-fast");
230 cargo
.arg("--").args(builder
.config
.cmd
.test_args());
232 // Don't run cross-compile tests, we may not have cross-compiled libstd libs
234 cargo
.env("CFG_DISABLE_CROSS_TESTS", "1");
235 // Disable a test that has issues with mingw.
236 cargo
.env("CARGO_TEST_DISABLE_GIT_CLI", "1");
237 // Forcibly disable tests using nightly features since any changes to
238 // those features won't be able to land.
239 cargo
.env("CARGO_TEST_DISABLE_NIGHTLY", "1");
241 cargo
.env("PATH", &path_for_cargo(builder
, compiler
));
243 try_run(builder
, &mut cargo
.into());
247 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
250 host
: TargetSelection
,
255 const ONLY_HOSTS
: bool
= true;
257 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
258 run
.path("src/tools/rls")
261 fn make_run(run
: RunConfig
<'_
>) {
262 run
.builder
.ensure(Rls { stage: run.builder.top_stage, host: run.target }
);
265 /// Runs `cargo test` for the rls.
266 fn run(self, builder
: &Builder
<'_
>) {
267 let stage
= self.stage
;
268 let host
= self.host
;
269 let compiler
= builder
.compiler(stage
, host
);
272 builder
.ensure(tool
::Rls { compiler, target: self.host, extra_features: Vec::new() }
);
273 if build_result
.is_none() {
274 eprintln
!("failed to test rls: could not build");
278 let mut cargo
= tool
::prepare_tool_cargo(
285 SourceType
::Submodule
,
289 cargo
.add_rustc_lib_path(builder
, compiler
);
290 cargo
.arg("--").args(builder
.config
.cmd
.test_args());
292 if try_run(builder
, &mut cargo
.into()) {
293 builder
.save_toolstate("rls", ToolState
::TestPass
);
298 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
301 host
: TargetSelection
,
304 impl Step
for Rustfmt
{
306 const ONLY_HOSTS
: bool
= true;
308 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
309 run
.path("src/tools/rustfmt")
312 fn make_run(run
: RunConfig
<'_
>) {
313 run
.builder
.ensure(Rustfmt { stage: run.builder.top_stage, host: run.target }
);
316 /// Runs `cargo test` for rustfmt.
317 fn run(self, builder
: &Builder
<'_
>) {
318 let stage
= self.stage
;
319 let host
= self.host
;
320 let compiler
= builder
.compiler(stage
, host
);
323 .ensure(tool
::Rustfmt { compiler, target: self.host, extra_features: Vec::new() }
)
324 .expect("in-tree tool");
326 let mut cargo
= tool
::prepare_tool_cargo(
333 SourceType
::Submodule
,
337 let dir
= testdir(builder
, compiler
.host
);
338 t
!(fs
::create_dir_all(&dir
));
339 cargo
.env("RUSTFMT_TEST_DIR", dir
);
341 cargo
.add_rustc_lib_path(builder
, compiler
);
343 builder
.run(&mut cargo
.into());
347 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
348 pub struct RustDemangler
{
350 host
: TargetSelection
,
353 impl Step
for RustDemangler
{
355 const ONLY_HOSTS
: bool
= true;
357 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
358 run
.path("src/tools/rust-demangler")
361 fn make_run(run
: RunConfig
<'_
>) {
362 run
.builder
.ensure(RustDemangler { stage: run.builder.top_stage, host: run.target }
);
365 /// Runs `cargo test` for rust-demangler.
366 fn run(self, builder
: &Builder
<'_
>) {
367 let stage
= self.stage
;
368 let host
= self.host
;
369 let compiler
= builder
.compiler(stage
, host
);
371 let rust_demangler
= builder
372 .ensure(tool
::RustDemangler { compiler, target: self.host, extra_features: Vec::new() }
)
373 .expect("in-tree tool");
374 let mut cargo
= tool
::prepare_tool_cargo(
380 "src/tools/rust-demangler",
385 let dir
= testdir(builder
, compiler
.host
);
386 t
!(fs
::create_dir_all(&dir
));
388 cargo
.env("RUST_DEMANGLER_DRIVER_PATH", rust_demangler
);
390 cargo
.arg("--").args(builder
.config
.cmd
.test_args());
392 cargo
.add_rustc_lib_path(builder
, compiler
);
394 builder
.run(&mut cargo
.into());
398 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
401 host
: TargetSelection
,
406 const ONLY_HOSTS
: bool
= true;
408 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
409 run
.path("src/tools/miri")
412 fn make_run(run
: RunConfig
<'_
>) {
413 run
.builder
.ensure(Miri { stage: run.builder.top_stage, host: run.target }
);
416 /// Runs `cargo test` for miri.
417 fn run(self, builder
: &Builder
<'_
>) {
418 let stage
= self.stage
;
419 let host
= self.host
;
420 let compiler
= builder
.compiler(stage
, host
);
423 builder
.ensure(tool
::Miri { compiler, target: self.host, extra_features: Vec::new() }
);
424 let cargo_miri
= builder
.ensure(tool
::CargoMiri
{
427 extra_features
: Vec
::new(),
429 if let (Some(miri
), Some(_cargo_miri
)) = (miri
, cargo_miri
) {
431 builder
.cargo(compiler
, Mode
::ToolRustc
, SourceType
::Submodule
, host
, "install");
433 // Configure `cargo install` path. cargo adds a `bin/`.
434 cargo
.env("CARGO_INSTALL_ROOT", &builder
.out
);
436 let mut cargo
= Command
::from(cargo
);
437 if !try_run(builder
, &mut cargo
) {
441 // # Run `cargo miri setup`.
442 let mut cargo
= tool
::prepare_tool_cargo(
448 "src/tools/miri/cargo-miri",
449 SourceType
::Submodule
,
452 cargo
.add_rustc_lib_path(builder
, compiler
);
453 cargo
.arg("--").arg("miri").arg("setup");
455 // Tell `cargo miri setup` where to find the sources.
456 cargo
.env("XARGO_RUST_SRC", builder
.src
.join("library"));
457 // Tell it where to find Miri.
458 cargo
.env("MIRI", &miri
);
460 cargo
.env("RUST_BACKTRACE", "1");
461 // Let cargo-miri know where xargo ended up.
462 cargo
.env("XARGO_CHECK", builder
.out
.join("bin").join("xargo-check"));
464 let mut cargo
= Command
::from(cargo
);
465 if !try_run(builder
, &mut cargo
) {
469 // # Determine where Miri put its sysroot.
470 // To this end, we run `cargo miri setup --print-sysroot` and capture the output.
471 // (We do this separately from the above so that when the setup actually
472 // happens we get some output.)
473 // We re-use the `cargo` from above.
474 cargo
.arg("--print-sysroot");
476 // FIXME: Is there a way in which we can re-use the usual `run` helpers?
477 let miri_sysroot
= if builder
.config
.dry_run
{
480 builder
.verbose(&format
!("running: {:?}", cargo
));
483 .expect("We already ran `cargo miri setup` before and that worked");
484 assert
!(out
.status
.success(), "`cargo miri setup` returned with non-0 exit code");
485 // Output is "<sysroot>\n".
486 let stdout
= String
::from_utf8(out
.stdout
)
487 .expect("`cargo miri setup` stdout is not valid UTF-8");
488 let sysroot
= stdout
.trim_end();
489 builder
.verbose(&format
!("`cargo miri setup --print-sysroot` said: {:?}", sysroot
));
493 // # Run `cargo test`.
494 let mut cargo
= tool
::prepare_tool_cargo(
501 SourceType
::Submodule
,
504 cargo
.add_rustc_lib_path(builder
, compiler
);
506 // miri tests need to know about the stage sysroot
507 cargo
.env("MIRI_SYSROOT", miri_sysroot
);
508 cargo
.env("RUSTC_LIB_PATH", builder
.rustc_libdir(compiler
));
509 cargo
.env("MIRI", miri
);
511 cargo
.arg("--").args(builder
.config
.cmd
.test_args());
513 let mut cargo
= Command
::from(cargo
);
514 if !try_run(builder
, &mut cargo
) {
518 // # Run `cargo test` with `-Zmir-opt-level=4`.
519 cargo
.env("MIRIFLAGS", "-O -Zmir-opt-level=4");
520 if !try_run(builder
, &mut cargo
) {
525 builder
.save_toolstate("miri", ToolState
::TestPass
);
527 eprintln
!("failed to test miri: could not build");
532 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
533 pub struct CompiletestTest
{
534 host
: TargetSelection
,
537 impl Step
for CompiletestTest
{
540 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
541 run
.path("src/tools/compiletest")
544 fn make_run(run
: RunConfig
<'_
>) {
545 run
.builder
.ensure(CompiletestTest { host: run.target }
);
548 /// Runs `cargo test` for compiletest.
549 fn run(self, builder
: &Builder
<'_
>) {
550 let host
= self.host
;
551 let compiler
= builder
.compiler(0, host
);
553 // We need `ToolStd` for the locally-built sysroot because
554 // compiletest uses unstable features of the `test` crate.
555 builder
.ensure(compile
::Std { compiler, target: host }
);
556 let cargo
= tool
::prepare_tool_cargo(
562 "src/tools/compiletest",
567 try_run(builder
, &mut cargo
.into());
571 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
574 host
: TargetSelection
,
577 impl Step
for Clippy
{
579 const ONLY_HOSTS
: bool
= true;
580 const DEFAULT
: bool
= false;
582 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
583 run
.path("src/tools/clippy")
586 fn make_run(run
: RunConfig
<'_
>) {
587 run
.builder
.ensure(Clippy { stage: run.builder.top_stage, host: run.target }
);
590 /// Runs `cargo test` for clippy.
591 fn run(self, builder
: &Builder
<'_
>) {
592 let stage
= self.stage
;
593 let host
= self.host
;
594 let compiler
= builder
.compiler(stage
, host
);
597 .ensure(tool
::Clippy { compiler, target: self.host, extra_features: Vec::new() }
)
598 .expect("in-tree tool");
599 let mut cargo
= tool
::prepare_tool_cargo(
610 // clippy tests need to know about the stage sysroot
611 cargo
.env("SYSROOT", builder
.sysroot(compiler
));
612 cargo
.env("RUSTC_TEST_SUITE", builder
.rustc(compiler
));
613 cargo
.env("RUSTC_LIB_PATH", builder
.rustc_libdir(compiler
));
614 let host_libs
= builder
.stage_out(compiler
, Mode
::ToolRustc
).join(builder
.cargo_dir());
615 let target_libs
= builder
616 .stage_out(compiler
, Mode
::ToolRustc
)
617 .join(&self.host
.triple
)
618 .join(builder
.cargo_dir());
619 cargo
.env("HOST_LIBS", host_libs
);
620 cargo
.env("TARGET_LIBS", target_libs
);
621 // clippy tests need to find the driver
622 cargo
.env("CLIPPY_DRIVER_PATH", clippy
);
624 cargo
.arg("--").args(builder
.config
.cmd
.test_args());
626 cargo
.add_rustc_lib_path(builder
, compiler
);
628 if builder
.try_run(&mut cargo
.into()) {
629 // The tests succeeded; nothing to do.
633 if !builder
.config
.cmd
.bless() {
634 std
::process
::exit(1);
637 let mut cargo
= builder
.cargo(compiler
, Mode
::ToolRustc
, SourceType
::InTree
, host
, "run");
638 cargo
.arg("-p").arg("clippy_dev");
639 // clippy_dev gets confused if it can't find `clippy/Cargo.toml`
640 cargo
.current_dir(&builder
.src
.join("src").join("tools").join("clippy"));
641 if builder
.config
.rust_optimize
{
642 cargo
.env("PROFILE", "release");
644 cargo
.env("PROFILE", "debug");
648 builder
.run(&mut cargo
.into());
652 fn path_for_cargo(builder
: &Builder
<'_
>, compiler
: Compiler
) -> OsString
{
653 // Configure PATH to find the right rustc. NB. we have to use PATH
654 // and not RUSTC because the Cargo test suite has tests that will
655 // fail if rustc is not spelled `rustc`.
656 let path
= builder
.sysroot(compiler
).join("bin");
657 let old_path
= env
::var_os("PATH").unwrap_or_default();
658 env
::join_paths(iter
::once(path
).chain(env
::split_paths(&old_path
))).expect("")
661 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
662 pub struct RustdocTheme
{
663 pub compiler
: Compiler
,
666 impl Step
for RustdocTheme
{
668 const DEFAULT
: bool
= true;
669 const ONLY_HOSTS
: bool
= true;
671 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
672 run
.path("src/tools/rustdoc-themes")
675 fn make_run(run
: RunConfig
<'_
>) {
676 let compiler
= run
.builder
.compiler(run
.builder
.top_stage
, run
.target
);
678 run
.builder
.ensure(RustdocTheme { compiler }
);
681 fn run(self, builder
: &Builder
<'_
>) {
682 let rustdoc
= builder
.out
.join("bootstrap/debug/rustdoc");
683 let mut cmd
= builder
.tool_cmd(Tool
::RustdocTheme
);
684 cmd
.arg(rustdoc
.to_str().unwrap())
685 .arg(builder
.src
.join("src/librustdoc/html/static/themes").to_str().unwrap())
686 .env("RUSTC_STAGE", self.compiler
.stage
.to_string())
687 .env("RUSTC_SYSROOT", builder
.sysroot(self.compiler
))
688 .env("RUSTDOC_LIBDIR", builder
.sysroot_libdir(self.compiler
, self.compiler
.host
))
689 .env("CFG_RELEASE_CHANNEL", &builder
.config
.channel
)
690 .env("RUSTDOC_REAL", builder
.rustdoc(self.compiler
))
691 .env("RUSTC_BOOTSTRAP", "1");
692 if let Some(linker
) = builder
.linker(self.compiler
.host
) {
693 cmd
.env("RUSTDOC_LINKER", linker
);
695 if builder
.is_fuse_ld_lld(self.compiler
.host
) {
696 cmd
.env("RUSTDOC_FUSE_LD_LLD", "1");
698 try_run(builder
, &mut cmd
);
702 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
703 pub struct RustdocJSStd
{
704 pub target
: TargetSelection
,
707 impl Step
for RustdocJSStd
{
709 const DEFAULT
: bool
= true;
710 const ONLY_HOSTS
: bool
= true;
712 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
713 run
.path("src/test/rustdoc-js-std")
716 fn make_run(run
: RunConfig
<'_
>) {
717 run
.builder
.ensure(RustdocJSStd { target: run.target }
);
720 fn run(self, builder
: &Builder
<'_
>) {
721 if let Some(ref nodejs
) = builder
.config
.nodejs
{
722 let mut command
= Command
::new(nodejs
);
724 .arg(builder
.src
.join("src/tools/rustdoc-js/tester.js"))
727 .arg("--resource-suffix")
728 .arg(&builder
.version
)
730 .arg(builder
.doc_out(self.target
))
731 .arg("--test-folder")
732 .arg(builder
.src
.join("src/test/rustdoc-js-std"));
733 builder
.ensure(crate::doc
::Std { target: self.target, stage: builder.top_stage }
);
734 builder
.run(&mut command
);
736 builder
.info("No nodejs found, skipping \"src/test/rustdoc-js-std\" tests");
741 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
742 pub struct RustdocJSNotStd
{
743 pub target
: TargetSelection
,
744 pub compiler
: Compiler
,
747 impl Step
for RustdocJSNotStd
{
749 const DEFAULT
: bool
= true;
750 const ONLY_HOSTS
: bool
= true;
752 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
753 run
.path("src/test/rustdoc-js")
756 fn make_run(run
: RunConfig
<'_
>) {
757 let compiler
= run
.builder
.compiler(run
.builder
.top_stage
, run
.build_triple());
758 run
.builder
.ensure(RustdocJSNotStd { target: run.target, compiler }
);
761 fn run(self, builder
: &Builder
<'_
>) {
762 if builder
.config
.nodejs
.is_some() {
763 builder
.ensure(Compiletest
{
764 compiler
: self.compiler
,
768 path
: "src/test/rustdoc-js",
772 builder
.info("No nodejs found, skipping \"src/test/rustdoc-js\" tests");
777 fn check_if_browser_ui_test_is_installed_global(npm
: &Path
, global
: bool
) -> bool
{
778 let mut command
= Command
::new(&npm
);
779 command
.arg("list").arg("--depth=0");
781 command
.arg("--global");
785 .map(|output
| String
::from_utf8_lossy(&output
.stdout
).into_owned())
786 .unwrap_or(String
::new());
787 lines
.contains(&" browser-ui-test@")
790 fn check_if_browser_ui_test_is_installed(npm
: &Path
) -> bool
{
791 check_if_browser_ui_test_is_installed_global(npm
, false)
792 || check_if_browser_ui_test_is_installed_global(npm
, true)
795 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
796 pub struct RustdocGUI
{
797 pub target
: TargetSelection
,
798 pub compiler
: Compiler
,
801 impl Step
for RustdocGUI
{
803 const DEFAULT
: bool
= true;
804 const ONLY_HOSTS
: bool
= true;
806 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
807 let builder
= run
.builder
;
808 let run
= run
.path("src/test/rustdoc-gui");
809 run
.default_condition(
810 builder
.config
.nodejs
.is_some()
815 .map(|p
| check_if_browser_ui_test_is_installed(p
))
820 fn make_run(run
: RunConfig
<'_
>) {
821 let compiler
= run
.builder
.compiler(run
.builder
.top_stage
, run
.build_triple());
822 run
.builder
.ensure(RustdocGUI { target: run.target, compiler }
);
825 fn run(self, builder
: &Builder
<'_
>) {
826 let nodejs
= builder
.config
.nodejs
.as_ref().expect("nodejs isn't available");
827 let npm
= builder
.config
.npm
.as_ref().expect("npm isn't available");
829 builder
.ensure(compile
::Std { compiler: self.compiler, target: self.target }
);
831 // The goal here is to check if the necessary packages are installed, and if not, we
833 if !check_if_browser_ui_test_is_installed(&npm
) {
835 "error: rustdoc-gui test suite cannot be run because npm `browser-ui-test` \
836 dependency is missing",
839 "If you want to install the `{0}` dependency, run `npm install {0}`",
842 panic
!("Cannot run rustdoc-gui tests");
845 let out_dir
= builder
.test_out(self.target
).join("rustdoc-gui");
847 // We remove existing folder to be sure there won't be artifacts remaining.
848 let _
= fs
::remove_dir_all(&out_dir
);
850 let mut nb_generated
= 0;
851 // We generate docs for the libraries present in the rustdoc-gui's src folder.
852 let libs_dir
= builder
.build
.src
.join("src/test/rustdoc-gui/src");
853 for entry
in libs_dir
.read_dir().expect("read_dir call failed") {
854 let entry
= entry
.expect("invalid entry");
855 let path
= entry
.path();
856 if path
.extension().map(|e
| e
== "rs").unwrap_or(false) {
857 let mut command
= builder
.rustdoc_cmd(self.compiler
);
858 command
.arg(path
).arg("-o").arg(&out_dir
);
859 builder
.run(&mut command
);
863 assert
!(nb_generated
> 0, "no documentation was generated...");
865 // We now run GUI tests.
866 let mut command
= Command
::new(&nodejs
);
868 .arg(builder
.build
.src
.join("src/tools/rustdoc-gui/tester.js"))
871 .arg("--tests-folder")
872 .arg(builder
.build
.src
.join("src/test/rustdoc-gui"));
873 builder
.run(&mut command
);
877 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
882 const DEFAULT
: bool
= true;
883 const ONLY_HOSTS
: bool
= true;
885 /// Runs the `tidy` tool.
887 /// This tool in `src/tools` checks up on various bits and pieces of style and
888 /// otherwise just implements a few lint-like checks that are specific to the
891 /// Once tidy passes, this step also runs `fmt --check` if tests are being run
892 /// for the `dev` or `nightly` channels.
893 fn run(self, builder
: &Builder
<'_
>) {
894 let mut cmd
= builder
.tool_cmd(Tool
::Tidy
);
895 cmd
.arg(&builder
.src
);
896 cmd
.arg(&builder
.initial_cargo
);
897 cmd
.arg(&builder
.out
);
898 cmd
.arg(builder
.jobs().to_string());
899 if builder
.is_verbose() {
900 cmd
.arg("--verbose");
903 builder
.info("tidy check");
904 try_run(builder
, &mut cmd
);
906 if builder
.config
.channel
== "dev" || builder
.config
.channel
== "nightly" {
907 builder
.info("fmt check");
908 if builder
.config
.initial_rustfmt
.is_none() {
909 let inferred_rustfmt_dir
= builder
.config
.initial_rustc
.parent().unwrap();
912 error: no `rustfmt` binary found in {PATH}
913 info: `rust.channel` is currently set to \"{CHAN}\"
914 help: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file
915 help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` to `x.py test`",
916 PATH
= inferred_rustfmt_dir
.display(),
917 CHAN
= builder
.config
.channel
,
919 std
::process
::exit(1);
921 crate::format
::format(&builder
.build
, !builder
.config
.cmd
.bless(), &[]);
925 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
926 run
.path("src/tools/tidy")
929 fn make_run(run
: RunConfig
<'_
>) {
930 run
.builder
.ensure(Tidy
);
934 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
935 pub struct ExpandYamlAnchors
;
937 impl Step
for ExpandYamlAnchors
{
939 const ONLY_HOSTS
: bool
= true;
941 /// Ensure the `generate-ci-config` tool was run locally.
943 /// The tool in `src/tools` reads the CI definition in `src/ci/builders.yml` and generates the
944 /// appropriate configuration for all our CI providers. This step ensures the tool was called
945 /// by the user before committing CI changes.
946 fn run(self, builder
: &Builder
<'_
>) {
947 builder
.info("Ensuring the YAML anchors in the GitHub Actions config were expanded");
950 &mut builder
.tool_cmd(Tool
::ExpandYamlAnchors
).arg("check").arg(&builder
.src
),
954 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
955 run
.path("src/tools/expand-yaml-anchors")
958 fn make_run(run
: RunConfig
<'_
>) {
959 run
.builder
.ensure(ExpandYamlAnchors
);
963 fn testdir(builder
: &Builder
<'_
>, host
: TargetSelection
) -> PathBuf
{
964 builder
.out
.join(host
.triple
).join("test")
967 macro_rules
! default_test
{
968 ($name
:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }
) => {
969 test
!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false }
);
973 macro_rules
! default_test_with_compare_mode
{
974 ($name
:ident
{ path
: $path
:expr
, mode
: $mode
:expr
, suite
: $suite
:expr
,
975 compare_mode
: $compare_mode
:expr
}) => {
976 test_with_compare_mode
!($name
{
982 compare_mode
: $compare_mode
987 macro_rules
! host_test
{
988 ($name
:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }
) => {
989 test
!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true }
);
994 ($name
:ident
{ path
: $path
:expr
, mode
: $mode
:expr
, suite
: $suite
:expr
, default: $
default:expr
,
995 host
: $host
:expr
}) => {
996 test_definitions
!($name
{
1007 macro_rules
! test_with_compare_mode
{
1008 ($name
:ident
{ path
: $path
:expr
, mode
: $mode
:expr
, suite
: $suite
:expr
, default: $
default:expr
,
1009 host
: $host
:expr
, compare_mode
: $compare_mode
:expr
}) => {
1010 test_definitions
!($name
{
1016 compare_mode
: Some($compare_mode
)
1021 macro_rules
! test_definitions
{
1026 default: $
default:expr
,
1028 compare_mode
: $compare_mode
:expr
1030 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1032 pub compiler
: Compiler
,
1033 pub target
: TargetSelection
,
1036 impl Step
for $name
{
1038 const DEFAULT
: bool
= $
default;
1039 const ONLY_HOSTS
: bool
= $host
;
1041 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1042 run
.suite_path($path
)
1045 fn make_run(run
: RunConfig
<'_
>) {
1046 let compiler
= run
.builder
.compiler(run
.builder
.top_stage
, run
.build_triple());
1048 run
.builder
.ensure($name { compiler, target: run.target }
);
1051 fn run(self, builder
: &Builder
<'_
>) {
1052 builder
.ensure(Compiletest
{
1053 compiler
: self.compiler
,
1054 target
: self.target
,
1058 compare_mode
: $compare_mode
,
1065 default_test_with_compare_mode
!(Ui
{
1066 path
: "src/test/ui",
1072 default_test
!(RunPassValgrind
{
1073 path
: "src/test/run-pass-valgrind",
1074 mode
: "run-pass-valgrind",
1075 suite
: "run-pass-valgrind"
1078 default_test
!(MirOpt { path: "src/test/mir-opt", mode: "mir-opt", suite: "mir-opt" }
);
1080 default_test
!(Codegen { path: "src/test/codegen", mode: "codegen", suite: "codegen" }
);
1082 default_test
!(CodegenUnits
{
1083 path
: "src/test/codegen-units",
1084 mode
: "codegen-units",
1085 suite
: "codegen-units"
1088 default_test
!(Incremental
{
1089 path
: "src/test/incremental",
1090 mode
: "incremental",
1091 suite
: "incremental"
1094 default_test_with_compare_mode
!(Debuginfo
{
1095 path
: "src/test/debuginfo",
1098 compare_mode
: "split-dwarf"
1101 host_test
!(UiFullDeps { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }
);
1103 host_test
!(Rustdoc { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" }
);
1104 host_test
!(RustdocUi { path: "src/test/rustdoc-ui", mode: "ui", suite: "rustdoc-ui" }
);
1106 host_test
!(RustdocJson
{
1107 path
: "src/test/rustdoc-json",
1108 mode
: "rustdoc-json",
1109 suite
: "rustdoc-json"
1112 host_test
!(Pretty { path: "src/test/pretty", mode: "pretty", suite: "pretty" }
);
1114 default_test
!(RunMake { path: "src/test/run-make", mode: "run-make", suite: "run-make" }
);
1116 host_test
!(RunMakeFullDeps
{
1117 path
: "src/test/run-make-fulldeps",
1119 suite
: "run-make-fulldeps"
1122 default_test
!(Assembly { path: "src/test/assembly", mode: "assembly", suite: "assembly" }
);
1124 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1125 struct Compiletest
{
1127 target
: TargetSelection
,
1129 suite
: &'
static str,
1131 compare_mode
: Option
<&'
static str>,
1134 impl Step
for Compiletest
{
1137 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1141 /// Executes the `compiletest` tool to run a suite of tests.
1143 /// Compiles all tests with `compiler` for `target` with the specified
1144 /// compiletest `mode` and `suite` arguments. For example `mode` can be
1145 /// "run-pass" or `suite` can be something like `debuginfo`.
1146 fn run(self, builder
: &Builder
<'_
>) {
1147 if builder
.top_stage
== 0 && env
::var("COMPILETEST_FORCE_STAGE0").is_err() {
1149 error: `--stage 0` runs compiletest on the beta compiler, not your local changes, and will almost always cause tests to fail
1150 help: to test the compiler, use `--stage 1` instead
1151 help: to test the standard library, use `--stage 0 library/std` instead
1152 note: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`."
1154 std
::process
::exit(1);
1157 let compiler
= self.compiler
;
1158 let target
= self.target
;
1159 let mode
= self.mode
;
1160 let suite
= self.suite
;
1162 // Path for test suite
1163 let suite_path
= self.path
;
1165 // Skip codegen tests if they aren't enabled in configuration.
1166 if !builder
.config
.codegen_tests
&& suite
== "codegen" {
1170 if suite
== "debuginfo" {
1172 .ensure(dist
::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target }
);
1175 if suite
.ends_with("fulldeps") {
1176 builder
.ensure(compile
::Rustc { compiler, target }
);
1179 builder
.ensure(compile
::Std { compiler, target }
);
1180 // ensure that `libproc_macro` is available on the host.
1181 builder
.ensure(compile
::Std { compiler, target: compiler.host }
);
1183 // Also provide `rust_test_helpers` for the host.
1184 builder
.ensure(native
::TestHelpers { target: compiler.host }
);
1186 // As well as the target, except for plain wasm32, which can't build it
1187 if !target
.contains("wasm32") || target
.contains("emscripten") {
1188 builder
.ensure(native
::TestHelpers { target }
);
1191 builder
.ensure(RemoteCopyLibs { compiler, target }
);
1193 let mut cmd
= builder
.tool_cmd(Tool
::Compiletest
);
1195 // compiletest currently has... a lot of arguments, so let's just pass all
1198 cmd
.arg("--compile-lib-path").arg(builder
.rustc_libdir(compiler
));
1199 cmd
.arg("--run-lib-path").arg(builder
.sysroot_libdir(compiler
, target
));
1200 cmd
.arg("--rustc-path").arg(builder
.rustc(compiler
));
1202 let is_rustdoc
= suite
.ends_with("rustdoc-ui") || suite
.ends_with("rustdoc-js");
1204 // Avoid depending on rustdoc when we don't need it.
1205 if mode
== "rustdoc"
1206 || mode
== "run-make"
1207 || (mode
== "ui" && is_rustdoc
)
1208 || mode
== "js-doc-test"
1209 || mode
== "rustdoc-json"
1211 cmd
.arg("--rustdoc-path").arg(builder
.rustdoc(compiler
));
1214 if mode
== "rustdoc-json" {
1215 // Use the beta compiler for jsondocck
1216 let json_compiler
= compiler
.with_stage(0);
1217 cmd
.arg("--jsondocck-path")
1218 .arg(builder
.ensure(tool
::JsonDocCk { compiler: json_compiler, target }
));
1221 if mode
== "run-make" && suite
.ends_with("fulldeps") {
1222 let rust_demangler
= builder
1223 .ensure(tool
::RustDemangler { compiler, target, extra_features: Vec::new() }
)
1224 .expect("in-tree tool");
1225 cmd
.arg("--rust-demangler-path").arg(rust_demangler
);
1228 cmd
.arg("--src-base").arg(builder
.src
.join("src/test").join(suite
));
1229 cmd
.arg("--build-base").arg(testdir(builder
, compiler
.host
).join(suite
));
1230 cmd
.arg("--stage-id").arg(format
!("stage{}-{}", compiler
.stage
, target
));
1231 cmd
.arg("--suite").arg(suite
);
1232 cmd
.arg("--mode").arg(mode
);
1233 cmd
.arg("--target").arg(target
.rustc_target_arg());
1234 cmd
.arg("--host").arg(&*compiler
.host
.triple
);
1235 cmd
.arg("--llvm-filecheck").arg(builder
.llvm_filecheck(builder
.config
.build
));
1237 if builder
.config
.cmd
.bless() {
1242 builder
.config
.cmd
.compare_mode().or_else(|| {
1243 if builder
.config
.test_compare_mode { self.compare_mode }
else { None }
1246 if let Some(ref pass
) = builder
.config
.cmd
.pass() {
1251 if let Some(ref run
) = builder
.config
.cmd
.run() {
1256 if let Some(ref nodejs
) = builder
.config
.nodejs
{
1257 cmd
.arg("--nodejs").arg(nodejs
);
1259 if let Some(ref npm
) = builder
.config
.npm
{
1260 cmd
.arg("--npm").arg(npm
);
1263 let mut flags
= if is_rustdoc { Vec::new() }
else { vec!["-Crpath".to_string()] }
;
1265 if builder
.config
.rust_optimize_tests
{
1266 flags
.push("-O".to_string());
1269 flags
.push(format
!("-Cdebuginfo={}", builder
.config
.rust_debuginfo_level_tests
));
1270 flags
.push(builder
.config
.cmd
.rustc_args().join(" "));
1272 if let Some(linker
) = builder
.linker(target
) {
1273 cmd
.arg("--linker").arg(linker
);
1276 let mut hostflags
= flags
.clone();
1277 hostflags
.push(format
!("-Lnative={}", builder
.test_helpers_out(compiler
.host
).display()));
1278 hostflags
.extend(builder
.lld_flags(compiler
.host
));
1279 cmd
.arg("--host-rustcflags").arg(hostflags
.join(" "));
1281 let mut targetflags
= flags
;
1282 targetflags
.push(format
!("-Lnative={}", builder
.test_helpers_out(target
).display()));
1283 targetflags
.extend(builder
.lld_flags(target
));
1284 cmd
.arg("--target-rustcflags").arg(targetflags
.join(" "));
1286 cmd
.arg("--docck-python").arg(builder
.python());
1288 if builder
.config
.build
.ends_with("apple-darwin") {
1289 // Force /usr/bin/python3 on macOS for LLDB tests because we're loading the
1290 // LLDB plugin's compiled module which only works with the system python
1291 // (namely not Homebrew-installed python)
1292 cmd
.arg("--lldb-python").arg("/usr/bin/python3");
1294 cmd
.arg("--lldb-python").arg(builder
.python());
1297 if let Some(ref gdb
) = builder
.config
.gdb
{
1298 cmd
.arg("--gdb").arg(gdb
);
1301 let run
= |cmd
: &mut Command
| {
1302 cmd
.output().map(|output
| {
1303 String
::from_utf8_lossy(&output
.stdout
)
1306 .unwrap_or_else(|| panic
!("{:?} failed {:?}", cmd
, output
))
1310 let lldb_exe
= "lldb";
1311 let lldb_version
= Command
::new(lldb_exe
)
1314 .map(|output
| String
::from_utf8_lossy(&output
.stdout
).to_string())
1316 if let Some(ref vers
) = lldb_version
{
1317 cmd
.arg("--lldb-version").arg(vers
);
1318 let lldb_python_dir
= run(Command
::new(lldb_exe
).arg("-P")).ok();
1319 if let Some(ref dir
) = lldb_python_dir
{
1320 cmd
.arg("--lldb-python-dir").arg(dir
);
1324 if util
::forcing_clang_based_tests() {
1325 let clang_exe
= builder
.llvm_out(target
).join("bin").join("clang");
1326 cmd
.arg("--run-clang-based-tests-with").arg(clang_exe
);
1329 // Get paths from cmd args
1330 let paths
= match &builder
.config
.cmd
{
1331 Subcommand
::Test { ref paths, .. }
=> &paths
[..],
1335 // Get test-args by striping suite path
1336 let mut test_args
: Vec
<&str> = paths
1338 .map(|p
| match p
.strip_prefix(".") {
1342 .filter(|p
| p
.starts_with(suite_path
))
1344 let exists
= p
.is_dir() || p
.is_file();
1346 if let Some(p
) = p
.to_str() {
1347 builder
.info(&format
!(
1348 "Warning: Skipping \"{}\": not a regular file or directory",
1356 // Since test suite paths are themselves directories, if we don't
1357 // specify a directory or file, we'll get an empty string here
1358 // (the result of the test suite directory without its suite prefix).
1359 // Therefore, we need to filter these out, as only the first --test-args
1360 // flag is respected, so providing an empty --test-args conflicts with
1361 // any following it.
1362 match p
.strip_prefix(suite_path
).ok().and_then(|p
| p
.to_str()) {
1363 Some(s
) if !s
.is_empty() => Some(s
),
1369 test_args
.append(&mut builder
.config
.cmd
.test_args());
1371 cmd
.args(&test_args
);
1373 if builder
.is_verbose() {
1374 cmd
.arg("--verbose");
1377 if !builder
.config
.verbose_tests
{
1381 let mut llvm_components_passed
= false;
1382 let mut copts_passed
= false;
1383 if builder
.config
.llvm_enabled() {
1384 let llvm_config
= builder
.ensure(native
::Llvm { target: builder.config.build }
);
1385 if !builder
.config
.dry_run
{
1386 let llvm_version
= output(Command
::new(&llvm_config
).arg("--version"));
1387 let llvm_components
= output(Command
::new(&llvm_config
).arg("--components"));
1388 // Remove trailing newline from llvm-config output.
1389 cmd
.arg("--llvm-version")
1390 .arg(llvm_version
.trim())
1391 .arg("--llvm-components")
1392 .arg(llvm_components
.trim());
1393 llvm_components_passed
= true;
1395 if !builder
.is_rust_llvm(target
) {
1396 cmd
.arg("--system-llvm");
1399 // Tests that use compiler libraries may inherit the `-lLLVM` link
1400 // requirement, but the `-L` library path is not propagated across
1401 // separate compilations. We can add LLVM's library path to the
1402 // platform-specific environment variable as a workaround.
1403 if !builder
.config
.dry_run
&& suite
.ends_with("fulldeps") {
1404 let llvm_libdir
= output(Command
::new(&llvm_config
).arg("--libdir"));
1405 add_link_lib_path(vec
![llvm_libdir
.trim().into()], &mut cmd
);
1408 // Only pass correct values for these flags for the `run-make` suite as it
1409 // requires that a C++ compiler was configured which isn't always the case.
1410 if !builder
.config
.dry_run
&& matches
!(suite
, "run-make" | "run-make-fulldeps") {
1411 // The llvm/bin directory contains many useful cross-platform
1412 // tools. Pass the path to run-make tests so they can use them.
1413 let llvm_bin_path
= llvm_config
1415 .expect("Expected llvm-config to be contained in directory");
1416 assert
!(llvm_bin_path
.is_dir());
1417 cmd
.arg("--llvm-bin-dir").arg(llvm_bin_path
);
1419 // If LLD is available, add it to the PATH
1420 if builder
.config
.lld_enabled
{
1421 let lld_install_root
=
1422 builder
.ensure(native
::Lld { target: builder.config.build }
);
1424 let lld_bin_path
= lld_install_root
.join("bin");
1426 let old_path
= env
::var_os("PATH").unwrap_or_default();
1427 let new_path
= env
::join_paths(
1428 std
::iter
::once(lld_bin_path
).chain(env
::split_paths(&old_path
)),
1430 .expect("Could not add LLD bin path to PATH");
1431 cmd
.env("PATH", new_path
);
1436 // Only pass correct values for these flags for the `run-make` suite as it
1437 // requires that a C++ compiler was configured which isn't always the case.
1438 if !builder
.config
.dry_run
&& matches
!(suite
, "run-make" | "run-make-fulldeps") {
1440 .arg(builder
.cc(target
))
1442 .arg(builder
.cxx(target
).unwrap())
1444 .arg(builder
.cflags(target
, GitRepo
::Rustc
).join(" "));
1445 copts_passed
= true;
1446 if let Some(ar
) = builder
.ar(target
) {
1447 cmd
.arg("--ar").arg(ar
);
1451 if !llvm_components_passed
{
1452 cmd
.arg("--llvm-components").arg("");
1455 cmd
.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg("");
1458 if builder
.remote_tested(target
) {
1459 cmd
.arg("--remote-test-client").arg(builder
.tool_exe(Tool
::RemoteTestClient
));
1462 // Running a C compiler on MSVC requires a few env vars to be set, to be
1463 // sure to set them here.
1465 // Note that if we encounter `PATH` we make sure to append to our own `PATH`
1466 // rather than stomp over it.
1467 if target
.contains("msvc") {
1468 for &(ref k
, ref v
) in builder
.cc
[&target
].env() {
1474 cmd
.env("RUSTC_BOOTSTRAP", "1");
1475 cmd
.env("DOC_RUST_LANG_ORG_CHANNEL", builder
.doc_rust_lang_org_channel());
1476 builder
.add_rust_test_threads(&mut cmd
);
1478 if builder
.config
.sanitizers_enabled(target
) {
1479 cmd
.env("RUSTC_SANITIZER_SUPPORT", "1");
1482 if builder
.config
.profiler_enabled(target
) {
1483 cmd
.env("RUSTC_PROFILER_SUPPORT", "1");
1486 let tmp
= builder
.out
.join("tmp");
1487 std
::fs
::create_dir_all(&tmp
).unwrap();
1488 cmd
.env("RUST_TEST_TMPDIR", tmp
);
1490 cmd
.arg("--adb-path").arg("adb");
1491 cmd
.arg("--adb-test-dir").arg(ADB_TEST_DIR
);
1492 if target
.contains("android") {
1493 // Assume that cc for this target comes from the android sysroot
1494 cmd
.arg("--android-cross-path")
1495 .arg(builder
.cc(target
).parent().unwrap().parent().unwrap());
1497 cmd
.arg("--android-cross-path").arg("");
1500 if builder
.config
.cmd
.rustfix_coverage() {
1501 cmd
.arg("--rustfix-coverage");
1504 cmd
.env("BOOTSTRAP_CARGO", &builder
.initial_cargo
);
1506 cmd
.arg("--channel").arg(&builder
.config
.channel
);
1508 builder
.ci_env
.force_coloring_in_ci(&mut cmd
);
1510 builder
.info(&format
!(
1511 "Check compiletest suite={} mode={} ({} -> {})",
1512 suite
, mode
, &compiler
.host
, target
1514 let _time
= util
::timeit(&builder
);
1515 try_run(builder
, &mut cmd
);
1517 if let Some(compare_mode
) = compare_mode
{
1518 cmd
.arg("--compare-mode").arg(compare_mode
);
1519 builder
.info(&format
!(
1520 "Check compiletest suite={} mode={} compare_mode={} ({} -> {})",
1521 suite
, mode
, compare_mode
, &compiler
.host
, target
1523 let _time
= util
::timeit(&builder
);
1524 try_run(builder
, &mut cmd
);
1529 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
1537 impl Step
for BookTest
{
1539 const ONLY_HOSTS
: bool
= true;
1541 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1545 /// Runs the documentation tests for a book in `src/doc`.
1547 /// This uses the `rustdoc` that sits next to `compiler`.
1548 fn run(self, builder
: &Builder
<'_
>) {
1549 // External docs are different from local because:
1550 // - Some books need pre-processing by mdbook before being tested.
1551 // - They need to save their state to toolstate.
1552 // - They are only tested on the "checktools" builders.
1554 // The local docs are tested by default, and we don't want to pay the
1555 // cost of building mdbook, so they use `rustdoc --test` directly.
1556 // Also, the unstable book is special because SUMMARY.md is generated,
1557 // so it is easier to just run `rustdoc` on its files.
1558 if self.is_ext_doc
{
1559 self.run_ext_doc(builder
);
1561 self.run_local_doc(builder
);
1567 /// This runs the equivalent of `mdbook test` (via the rustbook wrapper)
1568 /// which in turn runs `rustdoc --test` on each file in the book.
1569 fn run_ext_doc(self, builder
: &Builder
<'_
>) {
1570 let compiler
= self.compiler
;
1572 builder
.ensure(compile
::Std { compiler, target: compiler.host }
);
1574 // mdbook just executes a binary named "rustdoc", so we need to update
1575 // PATH so that it points to our rustdoc.
1576 let mut rustdoc_path
= builder
.rustdoc(compiler
);
1578 let old_path
= env
::var_os("PATH").unwrap_or_default();
1579 let new_path
= env
::join_paths(iter
::once(rustdoc_path
).chain(env
::split_paths(&old_path
)))
1580 .expect("could not add rustdoc to PATH");
1582 let mut rustbook_cmd
= builder
.tool_cmd(Tool
::Rustbook
);
1583 let path
= builder
.src
.join(&self.path
);
1584 rustbook_cmd
.env("PATH", new_path
).arg("test").arg(path
);
1585 builder
.add_rust_test_threads(&mut rustbook_cmd
);
1586 builder
.info(&format
!("Testing rustbook {}", self.path
.display()));
1587 let _time
= util
::timeit(&builder
);
1588 let toolstate
= if try_run(builder
, &mut rustbook_cmd
) {
1593 builder
.save_toolstate(self.name
, toolstate
);
1596 /// This runs `rustdoc --test` on all `.md` files in the path.
1597 fn run_local_doc(self, builder
: &Builder
<'_
>) {
1598 let compiler
= self.compiler
;
1600 builder
.ensure(compile
::Std { compiler, target: compiler.host }
);
1602 // Do a breadth-first traversal of the `src/doc` directory and just run
1603 // tests for all files that end in `*.md`
1604 let mut stack
= vec
![builder
.src
.join(self.path
)];
1605 let _time
= util
::timeit(&builder
);
1606 let mut files
= Vec
::new();
1607 while let Some(p
) = stack
.pop() {
1609 stack
.extend(t
!(p
.read_dir()).map(|p
| t
!(p
).path()));
1613 if p
.extension().and_then(|s
| s
.to_str()) != Some("md") {
1623 markdown_test(builder
, compiler
, &file
);
1628 macro_rules
! test_book
{
1629 ($
($name
:ident
, $path
:expr
, $book_name
:expr
, default=$
default:expr
;)+) => {
1631 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1636 impl Step
for $name
{
1638 const DEFAULT
: bool
= $
default;
1639 const ONLY_HOSTS
: bool
= true;
1641 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1645 fn make_run(run
: RunConfig
<'_
>) {
1646 run
.builder
.ensure($name
{
1647 compiler
: run
.builder
.compiler(run
.builder
.top_stage
, run
.target
),
1651 fn run(self, builder
: &Builder
<'_
>) {
1652 builder
.ensure(BookTest
{
1653 compiler
: self.compiler
,
1654 path
: PathBuf
::from($path
),
1656 is_ext_doc
: !$
default,
1665 Nomicon
, "src/doc/nomicon", "nomicon", default=false;
1666 Reference
, "src/doc/reference", "reference", default=false;
1667 RustdocBook
, "src/doc/rustdoc", "rustdoc", default=true;
1668 RustcBook
, "src/doc/rustc", "rustc", default=true;
1669 RustByExample
, "src/doc/rust-by-example", "rust-by-example", default=false;
1670 EmbeddedBook
, "src/doc/embedded-book", "embedded-book", default=false;
1671 TheBook
, "src/doc/book", "book", default=false;
1672 UnstableBook
, "src/doc/unstable-book", "unstable-book", default=true;
1673 EditionGuide
, "src/doc/edition-guide", "edition-guide", default=false;
1676 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1677 pub struct ErrorIndex
{
1681 impl Step
for ErrorIndex
{
1683 const DEFAULT
: bool
= true;
1684 const ONLY_HOSTS
: bool
= true;
1686 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1687 run
.path("src/tools/error_index_generator")
1690 fn make_run(run
: RunConfig
<'_
>) {
1691 // error_index_generator depends on librustdoc. Use the compiler that
1692 // is normally used to build rustdoc for other tests (like compiletest
1693 // tests in src/test/rustdoc) so that it shares the same artifacts.
1694 let compiler
= run
.builder
.compiler(run
.builder
.top_stage
, run
.builder
.config
.build
);
1695 run
.builder
.ensure(ErrorIndex { compiler }
);
1698 /// Runs the error index generator tool to execute the tests located in the error
1701 /// The `error_index_generator` tool lives in `src/tools` and is used to
1702 /// generate a markdown file from the error indexes of the code base which is
1703 /// then passed to `rustdoc --test`.
1704 fn run(self, builder
: &Builder
<'_
>) {
1705 let compiler
= self.compiler
;
1707 let dir
= testdir(builder
, compiler
.host
);
1708 t
!(fs
::create_dir_all(&dir
));
1709 let output
= dir
.join("error-index.md");
1711 let mut tool
= tool
::ErrorIndex
::command(builder
);
1712 tool
.arg("markdown").arg(&output
);
1714 builder
.info(&format
!("Testing error-index stage{}", compiler
.stage
));
1715 let _time
= util
::timeit(&builder
);
1716 builder
.run_quiet(&mut tool
);
1717 // The tests themselves need to link to std, so make sure it is
1719 builder
.ensure(compile
::Std { compiler, target: compiler.host }
);
1720 markdown_test(builder
, compiler
, &output
);
1724 fn markdown_test(builder
: &Builder
<'_
>, compiler
: Compiler
, markdown
: &Path
) -> bool
{
1725 if let Ok(contents
) = fs
::read_to_string(markdown
) {
1726 if !contents
.contains("```") {
1731 builder
.info(&format
!("doc tests for: {}", markdown
.display()));
1732 let mut cmd
= builder
.rustdoc_cmd(compiler
);
1733 builder
.add_rust_test_threads(&mut cmd
);
1734 // allow for unstable options such as new editions
1736 cmd
.arg("unstable-options");
1739 cmd
.env("RUSTC_BOOTSTRAP", "1");
1741 let test_args
= builder
.config
.cmd
.test_args().join(" ");
1742 cmd
.arg("--test-args").arg(test_args
);
1744 if builder
.config
.verbose_tests
{
1745 try_run(builder
, &mut cmd
)
1747 try_run_quiet(builder
, &mut cmd
)
1751 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1752 pub struct RustcGuide
;
1754 impl Step
for RustcGuide
{
1756 const DEFAULT
: bool
= false;
1757 const ONLY_HOSTS
: bool
= true;
1759 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1760 run
.path("src/doc/rustc-dev-guide")
1763 fn make_run(run
: RunConfig
<'_
>) {
1764 run
.builder
.ensure(RustcGuide
);
1767 fn run(self, builder
: &Builder
<'_
>) {
1768 let src
= builder
.src
.join("src/doc/rustc-dev-guide");
1769 let mut rustbook_cmd
= builder
.tool_cmd(Tool
::Rustbook
);
1770 let toolstate
= if try_run(builder
, rustbook_cmd
.arg("linkcheck").arg(&src
)) {
1775 builder
.save_toolstate("rustc-dev-guide", toolstate
);
1779 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1780 pub struct CrateLibrustc
{
1782 target
: TargetSelection
,
1783 test_kind
: TestKind
,
1784 krate
: Interned
<String
>,
1787 impl Step
for CrateLibrustc
{
1789 const DEFAULT
: bool
= true;
1790 const ONLY_HOSTS
: bool
= true;
1792 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1793 run
.krate("rustc-main")
1796 fn make_run(run
: RunConfig
<'_
>) {
1797 let builder
= run
.builder
;
1798 let compiler
= builder
.compiler(builder
.top_stage
, run
.build_triple());
1800 for krate
in builder
.in_tree_crates("rustc-main", Some(run
.target
)) {
1801 if krate
.path
.ends_with(&run
.path
) {
1802 let test_kind
= builder
.kind
.into();
1804 builder
.ensure(CrateLibrustc
{
1814 fn run(self, builder
: &Builder
<'_
>) {
1815 builder
.ensure(Crate
{
1816 compiler
: self.compiler
,
1817 target
: self.target
,
1819 test_kind
: self.test_kind
,
1825 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1827 pub compiler
: Compiler
,
1828 pub target
: TargetSelection
,
1830 pub test_kind
: TestKind
,
1831 pub krate
: Interned
<String
>,
1834 impl Step
for Crate
{
1836 const DEFAULT
: bool
= true;
1838 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1842 fn make_run(run
: RunConfig
<'_
>) {
1843 let builder
= run
.builder
;
1844 let compiler
= builder
.compiler(builder
.top_stage
, run
.build_triple());
1846 let make
= |mode
: Mode
, krate
: &CargoCrate
| {
1847 let test_kind
= builder
.kind
.into();
1849 builder
.ensure(Crate
{
1858 for krate
in builder
.in_tree_crates("test", Some(run
.target
)) {
1859 if krate
.path
.ends_with(&run
.path
) {
1860 make(Mode
::Std
, krate
);
1865 /// Runs all unit tests plus documentation tests for a given crate defined
1866 /// by a `Cargo.toml` (single manifest)
1868 /// This is what runs tests for crates like the standard library, compiler, etc.
1869 /// It essentially is the driver for running `cargo test`.
1871 /// Currently this runs all tests for a DAG by passing a bunch of `-p foo`
1872 /// arguments, and those arguments are discovered from `cargo metadata`.
1873 fn run(self, builder
: &Builder
<'_
>) {
1874 let compiler
= self.compiler
;
1875 let target
= self.target
;
1876 let mode
= self.mode
;
1877 let test_kind
= self.test_kind
;
1878 let krate
= self.krate
;
1880 builder
.ensure(compile
::Std { compiler, target }
);
1881 builder
.ensure(RemoteCopyLibs { compiler, target }
);
1883 // If we're not doing a full bootstrap but we're testing a stage2
1884 // version of libstd, then what we're actually testing is the libstd
1885 // produced in stage1. Reflect that here by updating the compiler that
1886 // we're working with automatically.
1887 let compiler
= builder
.compiler_for(compiler
.stage
, compiler
.host
, target
);
1890 builder
.cargo(compiler
, mode
, SourceType
::InTree
, target
, test_kind
.subcommand());
1893 compile
::std_cargo(builder
, target
, compiler
.stage
, &mut cargo
);
1896 builder
.ensure(compile
::Rustc { compiler, target }
);
1897 compile
::rustc_cargo(builder
, &mut cargo
, target
);
1899 _
=> panic
!("can only test libraries"),
1902 // Build up the base `cargo test` command.
1904 // Pass in some standard flags then iterate over the graph we've discovered
1905 // in `cargo metadata` with the maps above and figure out what `-p`
1906 // arguments need to get passed.
1907 if test_kind
.subcommand() == "test" && !builder
.fail_fast
{
1908 cargo
.arg("--no-fail-fast");
1910 match builder
.doc_tests
{
1915 cargo
.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
1920 cargo
.arg("-p").arg(krate
);
1922 // The tests are going to run with the *target* libraries, so we need to
1923 // ensure that those libraries show up in the LD_LIBRARY_PATH equivalent.
1925 // Note that to run the compiler we need to run with the *host* libraries,
1926 // but our wrapper scripts arrange for that to be the case anyway.
1927 let mut dylib_path
= dylib_path();
1928 dylib_path
.insert(0, PathBuf
::from(&*builder
.sysroot_libdir(compiler
, target
)));
1929 cargo
.env(dylib_path_var(), env
::join_paths(&dylib_path
).unwrap());
1932 cargo
.args(&builder
.config
.cmd
.test_args());
1934 if !builder
.config
.verbose_tests
{
1935 cargo
.arg("--quiet");
1938 if target
.contains("emscripten") {
1940 format
!("CARGO_TARGET_{}_RUNNER", envify(&target
.triple
)),
1941 builder
.config
.nodejs
.as_ref().expect("nodejs not configured"),
1943 } else if target
.starts_with("wasm32") {
1944 let node
= builder
.config
.nodejs
.as_ref().expect("nodejs not configured");
1946 format
!("{} {}/src/etc/wasm32-shim.js", node
.display(), builder
.src
.display());
1947 cargo
.env(format
!("CARGO_TARGET_{}_RUNNER", envify(&target
.triple
)), &runner
);
1948 } else if builder
.remote_tested(target
) {
1950 format
!("CARGO_TARGET_{}_RUNNER", envify(&target
.triple
)),
1951 format
!("{} run 0", builder
.tool_exe(Tool
::RemoteTestClient
).display()),
1955 builder
.info(&format
!(
1956 "{} {} stage{} ({} -> {})",
1957 test_kind
, krate
, compiler
.stage
, &compiler
.host
, target
1959 let _time
= util
::timeit(&builder
);
1960 try_run(builder
, &mut cargo
.into());
1964 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1965 pub struct CrateRustdoc
{
1966 host
: TargetSelection
,
1967 test_kind
: TestKind
,
1970 impl Step
for CrateRustdoc
{
1972 const DEFAULT
: bool
= true;
1973 const ONLY_HOSTS
: bool
= true;
1975 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1976 run
.paths(&["src/librustdoc", "src/tools/rustdoc"])
1979 fn make_run(run
: RunConfig
<'_
>) {
1980 let builder
= run
.builder
;
1982 let test_kind
= builder
.kind
.into();
1984 builder
.ensure(CrateRustdoc { host: run.target, test_kind }
);
1987 fn run(self, builder
: &Builder
<'_
>) {
1988 let test_kind
= self.test_kind
;
1989 let target
= self.host
;
1991 // Use the previous stage compiler to reuse the artifacts that are
1992 // created when running compiletest for src/test/rustdoc. If this used
1993 // `compiler`, then it would cause rustdoc to be built *again*, which
1994 // isn't really necessary.
1995 let compiler
= builder
.compiler_for(builder
.top_stage
, target
, target
);
1996 builder
.ensure(compile
::Rustc { compiler, target }
);
1998 let mut cargo
= tool
::prepare_tool_cargo(
2003 test_kind
.subcommand(),
2004 "src/tools/rustdoc",
2008 if test_kind
.subcommand() == "test" && !builder
.fail_fast
{
2009 cargo
.arg("--no-fail-fast");
2012 cargo
.arg("-p").arg("rustdoc:0.0.0");
2015 cargo
.args(&builder
.config
.cmd
.test_args());
2017 if self.host
.contains("musl") {
2018 cargo
.arg("'-Ctarget-feature=-crt-static'");
2021 // This is needed for running doctests on librustdoc. This is a bit of
2022 // an unfortunate interaction with how bootstrap works and how cargo
2023 // sets up the dylib path, and the fact that the doctest (in
2024 // html/markdown.rs) links to rustc-private libs. For stage1, the
2025 // compiler host dylibs (in stage1/lib) are not the same as the target
2026 // dylibs (in stage1/lib/rustlib/...). This is different from a normal
2027 // rust distribution where they are the same.
2029 // On the cargo side, normal tests use `target_process` which handles
2030 // setting up the dylib for a *target* (stage1/lib/rustlib/... in this
2031 // case). However, for doctests it uses `rustdoc_process` which only
2032 // sets up the dylib path for the *host* (stage1/lib), which is the
2035 // It should be considered to just stop running doctests on
2036 // librustdoc. There is only one test, and it doesn't look too
2037 // important. There might be other ways to avoid this, but it seems
2038 // pretty convoluted.
2040 // See also https://github.com/rust-lang/rust/issues/13983 where the
2041 // host vs target dylibs for rustdoc are consistently tricky to deal
2043 let mut dylib_path
= dylib_path();
2044 dylib_path
.insert(0, PathBuf
::from(&*builder
.sysroot_libdir(compiler
, target
)));
2045 cargo
.env(dylib_path_var(), env
::join_paths(&dylib_path
).unwrap());
2047 if !builder
.config
.verbose_tests
{
2048 cargo
.arg("--quiet");
2051 builder
.info(&format
!(
2052 "{} rustdoc stage{} ({} -> {})",
2053 test_kind
, compiler
.stage
, &compiler
.host
, target
2055 let _time
= util
::timeit(&builder
);
2057 try_run(builder
, &mut cargo
.into());
2061 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2062 pub struct CrateRustdocJsonTypes
{
2063 host
: TargetSelection
,
2064 test_kind
: TestKind
,
2067 impl Step
for CrateRustdocJsonTypes
{
2069 const DEFAULT
: bool
= true;
2070 const ONLY_HOSTS
: bool
= true;
2072 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2073 run
.path("src/rustdoc-json-types")
2076 fn make_run(run
: RunConfig
<'_
>) {
2077 let builder
= run
.builder
;
2079 let test_kind
= builder
.kind
.into();
2081 builder
.ensure(CrateRustdocJsonTypes { host: run.target, test_kind }
);
2084 fn run(self, builder
: &Builder
<'_
>) {
2085 let test_kind
= self.test_kind
;
2086 let target
= self.host
;
2088 // Use the previous stage compiler to reuse the artifacts that are
2089 // created when running compiletest for src/test/rustdoc. If this used
2090 // `compiler`, then it would cause rustdoc to be built *again*, which
2091 // isn't really necessary.
2092 let compiler
= builder
.compiler_for(builder
.top_stage
, target
, target
);
2093 builder
.ensure(compile
::Rustc { compiler, target }
);
2095 let mut cargo
= tool
::prepare_tool_cargo(
2100 test_kind
.subcommand(),
2101 "src/rustdoc-json-types",
2105 if test_kind
.subcommand() == "test" && !builder
.fail_fast
{
2106 cargo
.arg("--no-fail-fast");
2109 cargo
.arg("-p").arg("rustdoc-json-types");
2112 cargo
.args(&builder
.config
.cmd
.test_args());
2114 if self.host
.contains("musl") {
2115 cargo
.arg("'-Ctarget-feature=-crt-static'");
2118 if !builder
.config
.verbose_tests
{
2119 cargo
.arg("--quiet");
2122 builder
.info(&format
!(
2123 "{} rustdoc-json-types stage{} ({} -> {})",
2124 test_kind
, compiler
.stage
, &compiler
.host
, target
2126 let _time
= util
::timeit(&builder
);
2128 try_run(builder
, &mut cargo
.into());
2132 /// Some test suites are run inside emulators or on remote devices, and most
2133 /// of our test binaries are linked dynamically which means we need to ship
2134 /// the standard library and such to the emulator ahead of time. This step
2135 /// represents this and is a dependency of all test suites.
2137 /// Most of the time this is a no-op. For some steps such as shipping data to
2138 /// QEMU we have to build our own tools so we've got conditional dependencies
2139 /// on those programs as well. Note that the remote test client is built for
2140 /// the build target (us) and the server is built for the target.
2141 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2142 pub struct RemoteCopyLibs
{
2144 target
: TargetSelection
,
2147 impl Step
for RemoteCopyLibs
{
2150 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2154 fn run(self, builder
: &Builder
<'_
>) {
2155 let compiler
= self.compiler
;
2156 let target
= self.target
;
2157 if !builder
.remote_tested(target
) {
2161 builder
.ensure(compile
::Std { compiler, target }
);
2163 builder
.info(&format
!("REMOTE copy libs to emulator ({})", target
));
2164 t
!(fs
::create_dir_all(builder
.out
.join("tmp")));
2166 let server
= builder
.ensure(tool
::RemoteTestServer { compiler, target }
);
2168 // Spawn the emulator and wait for it to come online
2169 let tool
= builder
.tool_exe(Tool
::RemoteTestClient
);
2170 let mut cmd
= Command
::new(&tool
);
2171 cmd
.arg("spawn-emulator").arg(target
.triple
).arg(&server
).arg(builder
.out
.join("tmp"));
2172 if let Some(rootfs
) = builder
.qemu_rootfs(target
) {
2175 builder
.run(&mut cmd
);
2177 // Push all our dylibs to the emulator
2178 for f
in t
!(builder
.sysroot_libdir(compiler
, target
).read_dir()) {
2180 let name
= f
.file_name().into_string().unwrap();
2181 if util
::is_dylib(&name
) {
2182 builder
.run(Command
::new(&tool
).arg("push").arg(f
.path()));
2188 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2189 pub struct Distcheck
;
2191 impl Step
for Distcheck
{
2194 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2195 run
.path("distcheck")
2198 fn make_run(run
: RunConfig
<'_
>) {
2199 run
.builder
.ensure(Distcheck
);
2202 /// Runs "distcheck", a 'make check' from a tarball
2203 fn run(self, builder
: &Builder
<'_
>) {
2204 builder
.info("Distcheck");
2205 let dir
= builder
.out
.join("tmp").join("distcheck");
2206 let _
= fs
::remove_dir_all(&dir
);
2207 t
!(fs
::create_dir_all(&dir
));
2209 // Guarantee that these are built before we begin running.
2210 builder
.ensure(dist
::PlainSourceTarball
);
2211 builder
.ensure(dist
::Src
);
2213 let mut cmd
= Command
::new("tar");
2215 .arg(builder
.ensure(dist
::PlainSourceTarball
).tarball())
2216 .arg("--strip-components=1")
2218 builder
.run(&mut cmd
);
2220 Command
::new("./configure")
2221 .args(&builder
.config
.configure_args
)
2222 .arg("--enable-vendor")
2226 Command
::new(build_helper
::make(&builder
.config
.build
.triple
))
2231 // Now make sure that rust-src has all of libstd's dependencies
2232 builder
.info("Distcheck rust-src");
2233 let dir
= builder
.out
.join("tmp").join("distcheck-src");
2234 let _
= fs
::remove_dir_all(&dir
);
2235 t
!(fs
::create_dir_all(&dir
));
2237 let mut cmd
= Command
::new("tar");
2239 .arg(builder
.ensure(dist
::Src
).tarball())
2240 .arg("--strip-components=1")
2242 builder
.run(&mut cmd
);
2244 let toml
= dir
.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
2246 Command
::new(&builder
.initial_cargo
)
2247 .arg("generate-lockfile")
2248 .arg("--manifest-path")
2255 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2256 pub struct Bootstrap
;
2258 impl Step
for Bootstrap
{
2260 const DEFAULT
: bool
= true;
2261 const ONLY_HOSTS
: bool
= true;
2263 /// Tests the build system itself.
2264 fn run(self, builder
: &Builder
<'_
>) {
2265 let mut cmd
= Command
::new(&builder
.initial_cargo
);
2267 .current_dir(builder
.src
.join("src/bootstrap"))
2268 .env("RUSTFLAGS", "-Cdebuginfo=2")
2269 .env("CARGO_TARGET_DIR", builder
.out
.join("bootstrap"))
2270 .env("BOOTSTRAP_OUTPUT_DIRECTORY", &builder
.config
.out
)
2271 .env("BOOTSTRAP_INITIAL_CARGO", &builder
.config
.initial_cargo
)
2272 .env("RUSTC_BOOTSTRAP", "1")
2273 .env("RUSTC", &builder
.initial_rustc
);
2274 if let Some(flags
) = option_env
!("RUSTFLAGS") {
2275 // Use the same rustc flags for testing as for "normal" compilation,
2276 // so that Cargo doesn’t recompile the entire dependency graph every time:
2277 // https://github.com/rust-lang/rust/issues/49215
2278 cmd
.env("RUSTFLAGS", flags
);
2280 if !builder
.fail_fast
{
2281 cmd
.arg("--no-fail-fast");
2283 cmd
.arg("--").args(&builder
.config
.cmd
.test_args());
2284 // rustbuild tests are racy on directory creation so just run them one at a time.
2285 // Since there's not many this shouldn't be a problem.
2286 cmd
.arg("--test-threads=1");
2287 try_run(builder
, &mut cmd
);
2290 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2291 run
.path("src/bootstrap")
2294 fn make_run(run
: RunConfig
<'_
>) {
2295 run
.builder
.ensure(Bootstrap
);
2299 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2300 pub struct TierCheck
{
2301 pub compiler
: Compiler
,
2304 impl Step
for TierCheck
{
2306 const DEFAULT
: bool
= true;
2307 const ONLY_HOSTS
: bool
= true;
2309 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2310 run
.path("src/tools/tier-check")
2313 fn make_run(run
: RunConfig
<'_
>) {
2315 run
.builder
.compiler_for(run
.builder
.top_stage
, run
.builder
.build
.build
, run
.target
);
2316 run
.builder
.ensure(TierCheck { compiler }
);
2319 /// Tests the Platform Support page in the rustc book.
2320 fn run(self, builder
: &Builder
<'_
>) {
2321 builder
.ensure(compile
::Std { compiler: self.compiler, target: self.compiler.host }
);
2322 let mut cargo
= tool
::prepare_tool_cargo(
2328 "src/tools/tier-check",
2332 cargo
.arg(builder
.src
.join("src/doc/rustc/src/platform-support.md"));
2333 cargo
.arg(&builder
.rustc(self.compiler
));
2334 if builder
.is_verbose() {
2335 cargo
.arg("--verbose");
2338 builder
.info("platform support check");
2339 try_run(builder
, &mut cargo
.into());
2343 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2344 pub struct LintDocs
{
2345 pub compiler
: Compiler
,
2346 pub target
: TargetSelection
,
2349 impl Step
for LintDocs
{
2351 const DEFAULT
: bool
= true;
2352 const ONLY_HOSTS
: bool
= true;
2354 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2355 run
.path("src/tools/lint-docs")
2358 fn make_run(run
: RunConfig
<'_
>) {
2359 run
.builder
.ensure(LintDocs
{
2360 compiler
: run
.builder
.compiler(run
.builder
.top_stage
, run
.builder
.config
.build
),
2365 /// Tests that the lint examples in the rustc book generate the correct
2366 /// lints and have the expected format.
2367 fn run(self, builder
: &Builder
<'_
>) {
2368 builder
.ensure(crate::doc
::RustcBook
{
2369 compiler
: self.compiler
,
2370 target
: self.target
,