-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support when build-std
is set for Cargo
#3078
Conversation
| "compiler_builtins" | ||
) { | ||
// We are compiling the standard library. | ||
args.push("-Cdebug-assertions=off".into()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have also written a version of this which attempts to fix existing "-Cdebug-assertions", "-Coverflow-checks", etc. options if they are present (and also accounting for, e.g., if "-C" and "debug-assertions" are separate arguments), and only resorts to appending new arguments if the options are not present. However, I'm not sure if this extra complexity is warranted, because I think rustc can handle duplicate codegen options just fine, so probably the only benefit would be to make the rustc invocation "nicer" for someone debugging the interaction between miri and rustc
Thanks for the PR! :) It will be reviewed eventually but that might take a bit, at least I am rather busy currently. I am quite concerned about that list of crate names in the Miri driver, that sounds like something that we really want to avoid. |
|
||
/// Checks if Cargo's build-std setting is enabled for one or more crates. | ||
pub fn is_build_std_set() -> bool { | ||
let cmd = cargo() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to pass cargo_extra_flags()
as arguments to ensure that if the user sets --cfg unstable.build-std
that will be respected. Also what about -Zbuild-std
? I don't think I understand how these flags even interact.
It might be worth having a little helper function that invokes cargo config
to get the value of an arbitrary key.
.output() | ||
.expect("failed to get Cargo config"); | ||
// TODO: Cargo will exit with an error code if the `unstable.build-std` key is not set. Should | ||
// we still return false if an unrelated error has occurred? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we'd distinguish these cases. Which status code does cargo return when the key is absent? The least we can do is raise an error on any unexpected status code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I think Cargo returns 101 for most errors (unless I am misunderstanding your question). This includes when the key is absent but also, e.g., when the key a.b
cannot be resolved in the first place because a
exists and is not a table. I'm sure there are many other error cases for cargo config get
which return 101.
Relevant Cargo code: https://github.com/rust-lang/cargo/blob/f5418fcfebe7d01536b891c8b2ceb32c4eaf098c/src/cargo/util/errors.rs#L324C1-L341C2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that's unfortunate.
But still you can then treat only error 101 as "absent" and all other codes as actual errors.
println!("WARNING: `MIRI_NO_STD` has no effect when Cargo has `build-std` enabled."); | ||
} | ||
} | ||
let cargo_cmd = match subcommand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you move the cargo_cmd
logic up? This is confusing now, since the match
has too many jobs.
Also we want to call setup
before any of the other logic here. I think this should be more like
let miri_sysroot = if has_build_std {
Some(setup(...))
} else { None };
"Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set" | ||
) | ||
}); | ||
if env::var_os("MIRI_STD_AWARE_CARGO").is_some() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would strongly prefer if we could avoid having such hacks in the Miri driver. This should all be taken care of by cargo-miri
.
cargo-miri
already injects itself into every invocation from cargo, so it should be entirely possible to do any further command-line argument adjustments there rather than doing them inside the Miri driver.
| "compiler_builtins" | ||
) { | ||
// We are compiling the standard library. | ||
args.push("-Cdebug-assertions=off".into()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want this? If the user has enabled debug assertions then we should honor that. We should behave like regular cargo run
, which for build-std will also apply flags to the std build.
Miri no longer sets -Cdebug-assertions=on
either, so I see no reason why we'd start messing with -C
flags again.
// See `cargo_miri::phase_rustc`. | ||
if crate_name == "panic_abort" { | ||
args.push("-Cpanic=abort".into()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really needed? If build-std with regular rustc doesn't need it then we shouldn't need it either. AFAIK build-std will simply only build the panic runtime that is actually needed for this crate and this avoids the issue that comes up when building the panic runtime for a sysroot.
@@ -16,6 +16,7 @@ issue_1567 = { path = "issue-1567" } | |||
issue_1691 = { path = "issue-1691" } | |||
issue_1705 = { path = "issue-1705" } | |||
issue_1760 = { path = "issue-1760" } | |||
issue_2705 = { path = "issue-2705" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was expecting we would add something somewhere that calls cargo miri run -Zbuild-std
; why is this a separate crate?
☔ The latest upstream changes (presumably #3259) made this pull request unmergeable. Please resolve the merge conflicts. |
See #2705. This is my first contribution to a rust-lang project, and I am not extremely familiar with the internals of Miri and Cargo, so I apologize if there obvious deficiencies in this PR (besides the ones I am about to list, which are:)
build-std
is set,cargo-miri
will not setMIRI_SYSROOT
, which may be problematic for things that expectMIRI_SYSROOT
to always be set aftercargo miri setup
--print-syroot
is ignored bycargo miri setup
whenbuild-std
is set (but what else can it do)--crate-name
from the CLI arguments using a dedicated function, but ideally we'd want to borrow functionality from thearg
module incargo-miri
?std
orcore
or something, in which case, ifbuild-std
is also set, the Miri driver will naively assume that crate is really part of the standard library and disable debug assertions, enable overflow checks, etc. (I'm not actually sure if this can happen or not; someone please clarify if I'm wrong here)build-std
caseI have created a test crate with
build-std
set and a target spec for the PlayStation 2 CPU, with the expectation that Miri will see thatbuild-std
is set and skip building the sysroot. I am not actually able to test this at the moment.