add 'x.py miri', and make it work for 'library/{core,alloc,std}'
This commit is contained in:
parent
b390f2f458
commit
a6803b9de4
14 changed files with 423 additions and 31 deletions
|
@ -5,6 +5,11 @@ const WARMUP_N: usize = 100;
|
|||
const BENCH_N: usize = 1000;
|
||||
|
||||
fn main() {
|
||||
if cfg!(miri) {
|
||||
// Don't benchmark Miri...
|
||||
// (Due to bootstrap quirks, this gets picked up by `x.py miri library/alloc --no-doc`.)
|
||||
return;
|
||||
}
|
||||
let a: VecDeque<i32> = (0..VECDEQUE_LEN).collect();
|
||||
let b: VecDeque<i32> = (0..VECDEQUE_LEN).collect();
|
||||
|
||||
|
|
4
library/alloc/src/lib.miri.rs
Normal file
4
library/alloc/src/lib.miri.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
|
||||
#![no_std]
|
||||
extern crate alloc as realalloc;
|
||||
pub use realalloc::*;
|
4
library/core/src/lib.miri.rs
Normal file
4
library/core/src/lib.miri.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
|
||||
#![no_std]
|
||||
extern crate core as realcore;
|
||||
pub use realcore::*;
|
4
library/std/src/lib.miri.rs
Normal file
4
library/std/src/lib.miri.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
|
||||
#![no_std]
|
||||
extern crate std as realstd;
|
||||
pub use realstd::*;
|
|
@ -2536,9 +2536,14 @@ fn prepare_cargo_test(
|
|||
//
|
||||
// Note that to run the compiler we need to run with the *host* libraries,
|
||||
// but our wrapper scripts arrange for that to be the case anyway.
|
||||
let mut dylib_path = dylib_path();
|
||||
dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
|
||||
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
//
|
||||
// We skip everything on Miri as then this overwrites the libdir set up
|
||||
// by `Cargo::new` and that actually makes things go wrong.
|
||||
if builder.kind != Kind::Miri {
|
||||
let mut dylib_path = dylib_path();
|
||||
dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
|
||||
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
}
|
||||
|
||||
if builder.remote_tested(target) {
|
||||
cargo.env(
|
||||
|
@ -2594,28 +2599,62 @@ impl Step for Crate {
|
|||
let target = self.target;
|
||||
let mode = self.mode;
|
||||
|
||||
// Prepare sysroot
|
||||
// See [field@compile::Std::force_recompile].
|
||||
builder.ensure(compile::Std::force_recompile(compiler, compiler.host));
|
||||
|
||||
if builder.config.build != target {
|
||||
builder.ensure(compile::Std::force_recompile(compiler, target));
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
}
|
||||
|
||||
// If we're not doing a full bootstrap but we're testing a stage2
|
||||
// version of libstd, then what we're actually testing is the libstd
|
||||
// produced in stage1. Reflect that here by updating the compiler that
|
||||
// we're working with automatically.
|
||||
let compiler = builder.compiler_for(compiler.stage, compiler.host, target);
|
||||
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
mode,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
builder.kind.as_str(),
|
||||
);
|
||||
let mut cargo = if builder.kind == Kind::Miri {
|
||||
if builder.top_stage == 0 {
|
||||
eprintln!("ERROR: `x.py miri` requires stage 1 or higher");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
// Build `cargo miri test` command
|
||||
// (Implicitly prepares target sysroot)
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
mode,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
"miri-test",
|
||||
);
|
||||
// This hack helps bootstrap run standard library tests in Miri. The issue is as
|
||||
// follows: when running `cargo miri test` on libcore, cargo builds a local copy of core
|
||||
// and makes it a dependency of the integration test crate. This copy duplicates all the
|
||||
// lang items, so the build fails. (Regular testing avoids this because the sysroot is a
|
||||
// literal copy of what `cargo build` produces, but since Miri builds its own sysroot
|
||||
// this does not work for us.) So we need to make it so that the locally built libcore
|
||||
// contains all the items from `core`, but does not re-define them -- we want to replace
|
||||
// the entire crate but a re-export of the sysroot crate. We do this by swapping out the
|
||||
// source file: if `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set and we are building a
|
||||
// `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that
|
||||
// instead. But crucially we only do that for the library, not the test builds.
|
||||
cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1");
|
||||
cargo
|
||||
} else {
|
||||
// Also prepare a sysroot for the target.
|
||||
if builder.config.build != target {
|
||||
builder.ensure(compile::Std::force_recompile(compiler, target));
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
}
|
||||
|
||||
// Build `cargo test` command
|
||||
builder::Cargo::new(
|
||||
builder,
|
||||
compiler,
|
||||
mode,
|
||||
SourceType::InTree,
|
||||
target,
|
||||
builder.kind.as_str(),
|
||||
)
|
||||
};
|
||||
|
||||
match mode {
|
||||
Mode::Std => {
|
||||
|
|
|
@ -631,6 +631,7 @@ pub enum Kind {
|
|||
Format,
|
||||
#[value(alias = "t")]
|
||||
Test,
|
||||
Miri,
|
||||
Bench,
|
||||
#[value(alias = "d")]
|
||||
Doc,
|
||||
|
@ -673,6 +674,7 @@ impl Kind {
|
|||
Kind::Fix => "fix",
|
||||
Kind::Format => "fmt",
|
||||
Kind::Test => "test",
|
||||
Kind::Miri => "miri",
|
||||
Kind::Bench => "bench",
|
||||
Kind::Doc => "doc",
|
||||
Kind::Clean => "clean",
|
||||
|
@ -822,6 +824,7 @@ impl<'a> Builder<'a> {
|
|||
// Run run-make last, since these won't pass without make on Windows
|
||||
test::RunMake,
|
||||
),
|
||||
Kind::Miri => describe!(test::Crate),
|
||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
||||
Kind::Doc => describe!(
|
||||
doc::UnstableBook,
|
||||
|
@ -970,6 +973,7 @@ impl<'a> Builder<'a> {
|
|||
Subcommand::Fix => (Kind::Fix, &paths[..]),
|
||||
Subcommand::Doc { .. } => (Kind::Doc, &paths[..]),
|
||||
Subcommand::Test { .. } => (Kind::Test, &paths[..]),
|
||||
Subcommand::Miri { .. } => (Kind::Miri, &paths[..]),
|
||||
Subcommand::Bench { .. } => (Kind::Bench, &paths[..]),
|
||||
Subcommand::Dist => (Kind::Dist, &paths[..]),
|
||||
Subcommand::Install => (Kind::Install, &paths[..]),
|
||||
|
@ -1309,7 +1313,11 @@ impl<'a> Builder<'a> {
|
|||
if cmd == "clippy" {
|
||||
cargo = self.cargo_clippy_cmd(compiler);
|
||||
cargo.arg(cmd);
|
||||
} else if let Some(subcmd) = cmd.strip_prefix("miri-") {
|
||||
} else if let Some(subcmd) = cmd.strip_prefix("miri") {
|
||||
// Command must be "miri-X".
|
||||
let subcmd = subcmd
|
||||
.strip_prefix("-")
|
||||
.unwrap_or_else(|| panic!("expected `miri-$subcommand`, but got {}", cmd));
|
||||
cargo = self.cargo_miri_cmd(compiler);
|
||||
cargo.arg("miri").arg(subcmd);
|
||||
} else {
|
||||
|
|
|
@ -2022,7 +2022,7 @@ impl Config {
|
|||
Subcommand::Build { .. } => {
|
||||
flags.stage.or(build_stage).unwrap_or(if download_rustc { 2 } else { 1 })
|
||||
}
|
||||
Subcommand::Test { .. } => {
|
||||
Subcommand::Test { .. } | Subcommand::Miri { .. } => {
|
||||
flags.stage.or(test_stage).unwrap_or(if download_rustc { 2 } else { 1 })
|
||||
}
|
||||
Subcommand::Bench { .. } => flags.stage.or(bench_stage).unwrap_or(2),
|
||||
|
@ -2044,6 +2044,7 @@ impl Config {
|
|||
if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None {
|
||||
match config.cmd {
|
||||
Subcommand::Test { .. }
|
||||
| Subcommand::Miri { .. }
|
||||
| Subcommand::Doc { .. }
|
||||
| Subcommand::Build { .. }
|
||||
| Subcommand::Bench { .. }
|
||||
|
@ -2099,7 +2100,9 @@ impl Config {
|
|||
|
||||
pub(crate) fn test_args(&self) -> Vec<&str> {
|
||||
let mut test_args = match self.cmd {
|
||||
Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => {
|
||||
Subcommand::Test { ref test_args, .. }
|
||||
| Subcommand::Bench { ref test_args, .. }
|
||||
| Subcommand::Miri { ref test_args, .. } => {
|
||||
test_args.iter().flat_map(|s| s.split_whitespace()).collect()
|
||||
}
|
||||
_ => vec![],
|
||||
|
|
|
@ -382,6 +382,25 @@ pub enum Subcommand {
|
|||
/// `/<build_base>/rustfix_missing_coverage.txt`
|
||||
rustfix_coverage: bool,
|
||||
},
|
||||
/// Build and run some test suites *in Miri*
|
||||
Miri {
|
||||
#[arg(long)]
|
||||
/// run all tests regardless of failure
|
||||
no_fail_fast: bool,
|
||||
#[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
|
||||
/// extra arguments to be passed for the test tool being used
|
||||
/// (e.g. libtest, compiletest or rustdoc)
|
||||
test_args: Vec<String>,
|
||||
/// extra options to pass the compiler when running tests
|
||||
#[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
|
||||
rustc_args: Vec<String>,
|
||||
#[arg(long)]
|
||||
/// do not run doc tests
|
||||
no_doc: bool,
|
||||
#[arg(long)]
|
||||
/// only run doc tests
|
||||
doc: bool,
|
||||
},
|
||||
/// Build and run some benchmarks
|
||||
Bench {
|
||||
#[arg(long, allow_hyphen_values(true))]
|
||||
|
@ -453,6 +472,7 @@ impl Subcommand {
|
|||
Subcommand::Fix { .. } => Kind::Fix,
|
||||
Subcommand::Format { .. } => Kind::Format,
|
||||
Subcommand::Test { .. } => Kind::Test,
|
||||
Subcommand::Miri { .. } => Kind::Miri,
|
||||
Subcommand::Clean { .. } => Kind::Clean,
|
||||
Subcommand::Dist { .. } => Kind::Dist,
|
||||
Subcommand::Install { .. } => Kind::Install,
|
||||
|
@ -464,7 +484,7 @@ impl Subcommand {
|
|||
|
||||
pub fn rustc_args(&self) -> Vec<&str> {
|
||||
match *self {
|
||||
Subcommand::Test { ref rustc_args, .. } => {
|
||||
Subcommand::Test { ref rustc_args, .. } | Subcommand::Miri { ref rustc_args, .. } => {
|
||||
rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
|
||||
}
|
||||
_ => vec![],
|
||||
|
@ -473,14 +493,16 @@ impl Subcommand {
|
|||
|
||||
pub fn fail_fast(&self) -> bool {
|
||||
match *self {
|
||||
Subcommand::Test { no_fail_fast, .. } => !no_fail_fast,
|
||||
Subcommand::Test { no_fail_fast, .. } | Subcommand::Miri { no_fail_fast, .. } => {
|
||||
!no_fail_fast
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn doc_tests(&self) -> DocTests {
|
||||
match *self {
|
||||
Subcommand::Test { doc, no_doc, .. } => {
|
||||
Subcommand::Test { doc, no_doc, .. } | Subcommand::Miri { no_doc, doc, .. } => {
|
||||
if doc {
|
||||
DocTests::Only
|
||||
} else if no_doc {
|
||||
|
|
|
@ -39,6 +39,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "fix" -d 'Run cargo fix'
|
|||
complete -c x.py -n "__fish_use_subcommand" -f -a "fmt" -d 'Run rustfmt'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "doc" -d 'Build documentation'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "test" -d 'Build and run some test suites'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "miri" -d 'Build and run some test suites *in Miri*'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "bench" -d 'Build and run some benchmarks'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "clean" -d 'Clean out build directories'
|
||||
complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Build distribution artifacts'
|
||||
|
@ -308,6 +309,45 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate
|
|||
complete -c x.py -n "__fish_seen_subcommand_from test" -l enable-bolt-settings -d 'Enable BOLT link flags'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l config -d 'TOML configuration file for build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l build -d 'build target of the stage0 compiler' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l host -d 'host targets to build' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l target -d 'target targets to build' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l exclude -d 'build paths to exclude' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l skip -d 'build paths to skip' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l rustc-error-format -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny '',warn '',default ''}"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l error-format -d 'rustc error format' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always '',never '',auto ''}"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true '',false ''}"
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l set -d 'override options in config.toml' -r -f
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l no-fail-fast -d 'run all tests regardless of failure'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l no-doc -d 'do not run doc tests'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l doc -d 'only run doc tests'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -s i -l incremental -d 'use incremental compilation'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l include-default-paths -d 'include default paths in addition to the provided ones'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l dry-run -d 'dry run; don\'t build anything'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l json-output -d 'use message-format=json'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l enable-bolt-settings -d 'Enable BOLT link flags'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from miri" -s h -l help -d 'Print help (see more with \'--help\')'
|
||||
complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r
|
||||
complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F
|
||||
complete -c x.py -n "__fish_seen_subcommand_from bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
|
||||
|
|
|
@ -66,6 +66,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
|
|||
[CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Run rustfmt')
|
||||
[CompletionResult]::new('doc', 'doc', [CompletionResultType]::ParameterValue, 'Build documentation')
|
||||
[CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Build and run some test suites')
|
||||
[CompletionResult]::new('miri', 'miri', [CompletionResultType]::ParameterValue, 'Build and run some test suites *in Miri*')
|
||||
[CompletionResult]::new('bench', 'bench', [CompletionResultType]::ParameterValue, 'Build and run some benchmarks')
|
||||
[CompletionResult]::new('clean', 'clean', [CompletionResultType]::ParameterValue, 'Clean out build directories')
|
||||
[CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Build distribution artifacts')
|
||||
|
@ -386,6 +387,52 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
|
|||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
|
||||
break
|
||||
}
|
||||
'x.py;miri' {
|
||||
[CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
|
||||
[CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
|
||||
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
|
||||
[CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
|
||||
[CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
|
||||
[CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
|
||||
[CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
|
||||
[CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
|
||||
[CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
|
||||
[CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
|
||||
[CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
|
||||
[CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
|
||||
[CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
|
||||
[CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
|
||||
[CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
|
||||
[CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
|
||||
[CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
|
||||
[CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
|
||||
[CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
|
||||
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
|
||||
[CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
|
||||
[CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
|
||||
[CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
|
||||
[CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
|
||||
[CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
|
||||
[CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
|
||||
[CompletionResult]::new('--no-fail-fast', 'no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
|
||||
[CompletionResult]::new('--no-doc', 'no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
|
||||
[CompletionResult]::new('--doc', 'doc', [CompletionResultType]::ParameterName, 'only run doc tests')
|
||||
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
|
||||
[CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
|
||||
[CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
|
||||
[CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
|
||||
[CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
|
||||
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
|
||||
[CompletionResult]::new('--dump-bootstrap-shims', 'dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
|
||||
[CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
|
||||
[CompletionResult]::new('--bypass-bootstrap-lock', 'bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
|
||||
[CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
|
||||
[CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
|
||||
[CompletionResult]::new('--skip-stage0-validation', 'skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
|
||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
|
||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
|
||||
break
|
||||
}
|
||||
'x.py;bench' {
|
||||
[CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'test-args')
|
||||
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
|
||||
|
|
|
@ -42,6 +42,9 @@ _x.py() {
|
|||
bootstrap,install)
|
||||
cmd="bootstrap__install"
|
||||
;;
|
||||
bootstrap,miri)
|
||||
cmd="bootstrap__miri"
|
||||
;;
|
||||
bootstrap,run)
|
||||
cmd="bootstrap__run"
|
||||
;;
|
||||
|
@ -61,7 +64,7 @@ _x.py() {
|
|||
|
||||
case "${cmd}" in
|
||||
x.py)
|
||||
opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
|
||||
opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest"
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
@ -1290,6 +1293,124 @@ _x.py() {
|
|||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
;;
|
||||
x.py__miri)
|
||||
opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
fi
|
||||
case "${prev}" in
|
||||
--test-args)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rustc-args)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--config)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--build-dir)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--build)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--host)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--target)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--exclude)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--skip)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rustc-error-format)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--on-fail)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--stage)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--keep-stage)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--keep-stage-std)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--src)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--jobs)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
-j)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--warnings)
|
||||
COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--error-format)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
--color)
|
||||
COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--llvm-skip-rebuild)
|
||||
COMPREPLY=($(compgen -W "true false" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rust-profile-generate)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--rust-profile-use)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--llvm-profile-use)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--reproducible-artifact)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--set)
|
||||
COMPREPLY=("${cur}")
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=()
|
||||
;;
|
||||
esac
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
;;
|
||||
x.py__run)
|
||||
opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
|
||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
|
||||
|
|
|
@ -389,6 +389,54 @@ _arguments "${_arguments_options[@]}" \
|
|||
'*::paths -- paths for the subcommand:_files' \
|
||||
&& ret=0
|
||||
;;
|
||||
(miri)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
|
||||
'*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
|
||||
'--config=[TOML configuration file for build]:FILE:_files' \
|
||||
'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
|
||||
'--build=[build target of the stage0 compiler]:BUILD:( )' \
|
||||
'--host=[host targets to build]:HOST:( )' \
|
||||
'--target=[target targets to build]:TARGET:( )' \
|
||||
'*--exclude=[build paths to exclude]:PATH:_files' \
|
||||
'*--skip=[build paths to skip]:PATH:_files' \
|
||||
'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
|
||||
'--on-fail=[command to run on failure]:CMD:_cmdstring' \
|
||||
'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
|
||||
'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
|
||||
'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
|
||||
'--src=[path to the root of the rust checkout]:DIR:_files -/' \
|
||||
'-j+[number of jobs to run in parallel]:JOBS:( )' \
|
||||
'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
|
||||
'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
|
||||
'--error-format=[rustc error format]:FORMAT:( )' \
|
||||
'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
|
||||
'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \
|
||||
'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
|
||||
'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
|
||||
'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
|
||||
'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
|
||||
'*--set=[override options in config.toml]:section.option=value:( )' \
|
||||
'--no-fail-fast[run all tests regardless of failure]' \
|
||||
'--no-doc[do not run doc tests]' \
|
||||
'--doc[only run doc tests]' \
|
||||
'*-v[use verbose output (-vv for very verbose)]' \
|
||||
'*--verbose[use verbose output (-vv for very verbose)]' \
|
||||
'-i[use incremental compilation]' \
|
||||
'--incremental[use incremental compilation]' \
|
||||
'--include-default-paths[include default paths in addition to the provided ones]' \
|
||||
'--dry-run[dry run; don'\''t build anything]' \
|
||||
'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
|
||||
'--json-output[use message-format=json]' \
|
||||
'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
|
||||
'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
|
||||
'--enable-bolt-settings[Enable BOLT link flags]' \
|
||||
'--skip-stage0-validation[Skip stage0 compiler validation]' \
|
||||
'-h[Print help (see more with '\''--help'\'')]' \
|
||||
'--help[Print help (see more with '\''--help'\'')]' \
|
||||
'*::paths -- paths for the subcommand:_files' \
|
||||
&& ret=0
|
||||
;;
|
||||
(bench)
|
||||
_arguments "${_arguments_options[@]}" \
|
||||
'*--test-args=[]:TEST_ARGS: ' \
|
||||
|
@ -710,6 +758,7 @@ _x.py_commands() {
|
|||
'fmt:Run rustfmt' \
|
||||
'doc:Build documentation' \
|
||||
'test:Build and run some test suites' \
|
||||
'miri:Build and run some test suites *in Miri*' \
|
||||
'bench:Build and run some benchmarks' \
|
||||
'clean:Clean out build directories' \
|
||||
'dist:Build distribution artifacts' \
|
||||
|
@ -770,6 +819,11 @@ _x.py__install_commands() {
|
|||
local commands; commands=()
|
||||
_describe -t commands 'x.py install commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_x.py__miri_commands] )) ||
|
||||
_x.py__miri_commands() {
|
||||
local commands; commands=()
|
||||
_describe -t commands 'x.py miri commands' commands "$@"
|
||||
}
|
||||
(( $+functions[_x.py__run_commands] )) ||
|
||||
_x.py__run_commands() {
|
||||
local commands; commands=()
|
||||
|
|
|
@ -507,6 +507,8 @@ binaries, and as such worth documenting:
|
|||
crate currently being compiled.
|
||||
* `MIRI_ORIG_RUSTDOC` is set and read by different phases of `cargo-miri` to remember the
|
||||
value of `RUSTDOC` from before it was overwritten.
|
||||
* `MIRI_REPLACE_LIBRS_IF_NOT_TEST` when set to any value enables a hack that helps bootstrap
|
||||
run the standard library tests in Miri.
|
||||
* `MIRI_VERBOSE` when set to any value tells the various `cargo-miri` phases to
|
||||
perform verbose logging.
|
||||
* `MIRI_HOST_SYSROOT` is set by bootstrap to tell `cargo-miri` which sysroot to use for *host*
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use rustc_version::VersionMeta;
|
||||
|
@ -412,9 +412,25 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
|
|||
// Arguments are treated very differently depending on whether this crate is
|
||||
// for interpretation by Miri, or for use by a build script / proc macro.
|
||||
if target_crate {
|
||||
// Forward arguments, but remove "link" from "--emit" to make this a check-only build.
|
||||
// Forward arguments, but patched.
|
||||
let emit_flag = "--emit";
|
||||
// This hack helps bootstrap run standard library tests in Miri. The issue is as follows:
|
||||
// when running `cargo miri test` on libcore, cargo builds a local copy of core and makes it
|
||||
// a dependency of the integration test crate. This copy duplicates all the lang items, so
|
||||
// the build fails. (Regular testing avoids this because the sysroot is a literal copy of
|
||||
// what `cargo build` produces, but since Miri builds its own sysroot this does not work for
|
||||
// us.) So we need to make it so that the locally built libcore contains all the items from
|
||||
// `core`, but does not re-define them -- we want to replace the entire crate but a
|
||||
// re-export of the sysroot crate. We do this by swapping out the source file: if
|
||||
// `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set and we are building a `lib.rs` file, and a
|
||||
// `lib.miri.rs` file exists in the same folder, we build that instead. But crucially we
|
||||
// only do that for the library, not the unit test crate (which would be runnable) or
|
||||
// rustdoc (which would have a different `phase`).
|
||||
let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some()
|
||||
&& !runnable_crate
|
||||
&& phase == RustcPhase::Build;
|
||||
while let Some(arg) = args.next() {
|
||||
// Patch `--emit`: remove "link" from "--emit" to make this a check-only build.
|
||||
if let Some(val) = arg.strip_prefix(emit_flag) {
|
||||
// Patch this argument. First, extract its value.
|
||||
let val =
|
||||
|
@ -429,13 +445,36 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
|
|||
}
|
||||
}
|
||||
cmd.arg(format!("{emit_flag}={}", val.join(",")));
|
||||
} else if arg == "--extern" {
|
||||
// Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
|
||||
// https://github.com/rust-lang/miri/issues/1705
|
||||
forward_patched_extern_arg(&mut args, &mut cmd);
|
||||
} else {
|
||||
cmd.arg(arg);
|
||||
continue;
|
||||
}
|
||||
// Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
|
||||
// https://github.com/rust-lang/miri/issues/1705
|
||||
if arg == "--extern" {
|
||||
forward_patched_extern_arg(&mut args, &mut cmd);
|
||||
continue;
|
||||
}
|
||||
// If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a
|
||||
// `lib.miri.rs` file exists, then build that instead. We only consider relative paths
|
||||
// as cargo uses those for files in the workspace; dependencies from crates.io get
|
||||
// absolute paths.
|
||||
if replace_librs {
|
||||
let path = Path::new(&arg);
|
||||
if path.is_relative()
|
||||
&& path.file_name().is_some_and(|f| f == "lib.rs")
|
||||
&& path.is_file()
|
||||
{
|
||||
let miri_rs = Path::new(&arg).with_extension("miri.rs");
|
||||
if miri_rs.is_file() {
|
||||
if verbose > 0 {
|
||||
eprintln!("Performing REPLACE_LIBRS hack: {arg:?} -> {miri_rs:?}");
|
||||
}
|
||||
cmd.arg(miri_rs);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback: just propagate the argument.
|
||||
cmd.arg(arg);
|
||||
}
|
||||
|
||||
// During setup, patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
|
||||
|
|
Loading…
Add table
Reference in a new issue