Skip to content

Commit a9eda80

Browse files
authored
Merge pull request #555 from RalfJung/readme
update README to first describe the usual user setup
2 parents 8d2bc97 + 3478c0c commit a9eda80

File tree

2 files changed

+88
-75
lines changed

2 files changed

+88
-75
lines changed

README.md

Lines changed: 83 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,6 @@ for example:
2020
[`unreachable_unchecked`]: https://doc.rust-lang.org/stable/std/hint/fn.unreachable_unchecked.html
2121
[`copy_nonoverlapping`]: https://doc.rust-lang.org/stable/std/ptr/fn.copy_nonoverlapping.html
2222

23-
## Building Miri
24-
25-
We recommend that you install [rustup] to obtain Rust. Then all you have
26-
to do is:
27-
28-
```sh
29-
cargo +nightly build
30-
```
31-
32-
This uses the very latest Rust version. If you experience any problem, refer to
33-
the `rust-version` file which contains a particular Rust nightly version that
34-
has been tested against the version of miri you are using. Make sure to use
35-
that particular `nightly-YYYY-MM-DD` whenever the instructions just say
36-
`nightly`.
37-
38-
To avoid repeating the nightly version all the time, you can use
39-
`rustup override set nightly` (or `rustup override set nightly-YYYY-MM-DD`),
40-
which means `nightly` Rust will automatically be used whenever you are working
41-
in this directory.
42-
43-
[rustup]: https://www.rustup.rs
44-
45-
## Running Miri on tiny examples
46-
47-
```sh
48-
cargo +nightly run -- -Zmiri-disable-validation tests/run-pass/vecs.rs # Or whatever test you like.
49-
```
50-
51-
We have to disable validation because that can lead to errors when libstd is not
52-
compiled the right way.
5323

5424
## Running Miri on your own project('s test suite)
5525

@@ -59,13 +29,17 @@ Install Miri as a cargo subcommand:
5929
cargo +nightly install --git https://github.com/solson/miri/ miri
6030
```
6131

62-
Be aware that if you used `rustup override set` to fix a particular Rust version
63-
for the miri directory, that will *not* apply to your own project directory!
64-
You have to use a consistent Rust version for building miri and your project for
65-
this to work, so remember to either always specify the nightly version manually,
66-
overriding it in your project directory as well, or use `rustup default nightly`
67-
(or `rustup default nightly-YYYY-MM-DD`) to globally make `nightly` the default
68-
toolchain.
32+
If this does not work, try using the nightly version given in
33+
[this file](https://raw.githubusercontent.com/solson/miri/master/rust-version). CI
34+
should ensure that this nightly always works.
35+
36+
You have to use a consistent Rust version for building miri and your project, so
37+
remember to either always specify the nightly version manually (like in the
38+
example above), overriding it in your project directory as well, or use `rustup
39+
default nightly` (or `rustup default nightly-YYYY-MM-DD`) to globally make
40+
`nightly` the default toolchain.
41+
42+
Now you can run your project in miri:
6943

7044
1. Run `cargo clean` to eliminate any cached dependencies. Miri needs your
7145
dependencies to be compiled the right way, that would not happen if they have
@@ -93,53 +67,79 @@ You may be running `cargo miri` with a different compiler version than the one
9367
used to build the custom libstd that Miri uses, and Miri failed to detect that.
9468
Try deleting `~/.cache/miri`.
9569

96-
## Miri `-Z` flags
70+
## Development and Debugging
9771

98-
Several `-Z` flags are relevant for miri:
72+
If you want to hack on miri yourself, great! Here are some resources you might
73+
find useful.
9974

100-
* `-Zmir-opt-level` controls how many MIR optimizations are performed. miri
101-
overrides the default to be `0`; be advised that using any higher level can
102-
make miri miss bugs in your program because they got optimized away.
103-
* `-Zalways-encode-mir` makes rustc dump MIR even for completely monomorphic
104-
functions. This is needed so that miri can execute such functions, so miri
105-
sets this flag per default.
106-
* `-Zmiri-disable-validation` is a custom `-Z` flag added by miri. It disables
107-
enforcing the validity invariant, which is enforced by default. This is
108-
mostly useful for debugging; it means miri will miss bugs in your program.
75+
### Using a nightly rustc
10976

110-
## Development and Debugging
77+
miri heavily relies on internal rustc interfaces to execute MIR. Still, some
78+
things (like adding support for a new intrinsic) can be done by working just on
79+
the miri side.
80+
81+
To prepare, make sure you are using a nightly Rust compiler. You also need to
82+
set up a libstd that enables execution with miri:
83+
84+
```sh
85+
rustup override set nightly # or the nightly in `rust-version`
86+
cargo run --bin cargo-miri -- miri setup
87+
```
88+
89+
The last command should end in printing the directory where the libstd was
90+
built. Set that as your MIRI_SYSROOT environment variable:
91+
92+
```sh
93+
export MIRI_SYSROOT=~/.cache/miri/HOST # or whatever the previous command said
94+
```
95+
96+
### Testing Miri
97+
98+
Now you can run Miri directly, without going through `cargo miri`:
99+
100+
```sh
101+
cargo run tests/run-pass-fullmir/format.rs # or whatever test you like
102+
```
103+
104+
You can also run the test suite with `cargo test --release`. `cargo test
105+
--release FILTER` only runs those tests that contain `FILTER` in their filename
106+
(including the base directory, e.g. `cargo test --release fail` will run all
107+
compile-fail tests). We recommend using `--release` to make test running take
108+
less time.
109+
110+
Now you are set up! You can write a failing test case, and tweak miri until it
111+
fails no more.
112+
113+
### Using a locally built rustc
111114

112115
Since the heart of Miri (the main interpreter engine) lives in rustc, working on
113-
Miri will often require using a locally built rustc. This includes getting a
114-
trace of the execution, as distributed rustc has `debug!` and `trace!` disabled.
116+
Miri will often require using a locally built rustc. The bug you want to fix
117+
may actually be on the rustc side, or you just need to get more detailed trace
118+
of the execution -- in both cases, you should develop miri against a rustc you
119+
compiled yourself, with debug assertions (and hence tracing) enabled.
115120

116-
The first-time setup for a local rustc looks as follows:
121+
The setup for a local rustc works as follows:
117122
```sh
118123
git clone https://github.com/rust-lang/rust/ rustc
119124
cd rustc
120125
cp config.toml.example config.toml
121126
# Now edit `config.toml` and set `debug-assertions = true` and `test-miri = true`.
122127
# The latter is important to build libstd with the right flags for miri.
128+
# This step can take 30 minutes and more.
123129
./x.py build src/rustc
130+
# If you change something, you can get a faster rebuild by doing
131+
./x.py --keep-stage 0 build src/rustc
124132
# You may have to change the architecture in the next command
125133
rustup toolchain link custom build/x86_64-unknown-linux-gnu/stage2
126-
# Now cd to your Miri directory
134+
# Now cd to your Miri directory, then configure rustup
127135
rustup override set custom
136+
# We also need to tell Miri where to find its sysroot. Since we set
137+
# `test-miri` above, we can just use rustc' sysroot.
138+
export MIRI_SYSROOT=$(rustc --print sysroot)
128139
```
129-
The `build` step can take 30 minutes and more.
130140

131-
Now you can `cargo build` Miri, and you can `cargo test --release` it. `cargo
132-
test --release FILTER` only runs those tests that contain `FILTER` in their
133-
filename (including the base directory, e.g. `cargo test --release fail` will
134-
run all compile-fail tests). We recommend using `--release` to make test
135-
running take less time.
136-
137-
Notice that the "fullmir" tests only run if you have `MIRI_SYSROOT` set, the
138-
test runner does not realized that your libstd comes with full MIR. The
139-
following will set it correctly:
140-
```sh
141-
MIRI_SYSROOT=$(rustc --print sysroot) cargo test --release
142-
```
141+
With this, you should now have a working development setup! See
142+
["Testing Miri"](#testing-miri) above for how to proceed.
143143

144144
Moreover, you can now run Miri with a trace of all execution steps:
145145
```sh
@@ -157,18 +157,28 @@ MIRI_LOG=rustc_mir::interpret=debug,miri::stacked_borrows cargo run tests/run-pa
157157
In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
158158
evaluation error was originally created.
159159

160-
If you changed something in rustc and want to re-build, run
161-
```
162-
./x.py --keep-stage 0 build src/rustc
163-
```
164-
This avoids rebuilding the entire stage 0, which can save a lot of time.
160+
### Miri `-Z` flags
161+
162+
Several `-Z` flags are relevant for miri:
163+
164+
* `-Zmir-opt-level` controls how many MIR optimizations are performed. miri
165+
overrides the default to be `0`; be advised that using any higher level can
166+
make miri miss bugs in your program because they got optimized away.
167+
* `-Zalways-encode-mir` makes rustc dump MIR even for completely monomorphic
168+
functions. This is needed so that miri can execute such functions, so miri
169+
sets this flag per default.
170+
* `-Zmiri-disable-validation` is a custom `-Z` flag added by miri. It disables
171+
enforcing the validity invariant, which is enforced by default. This is
172+
mostly useful for debugging; it means miri will miss bugs in your program.
165173

166174
## Contributing and getting help
167175

168176
Check out the issues on this GitHub repository for some ideas. There's lots that
169177
needs to be done that I haven't documented in the issues yet, however. For more
170-
ideas or help with running or hacking on Miri, you can contact me (`scott`) on
171-
Mozilla IRC in any of the Rust IRC channels (`#rust`, `#rust-offtopic`, etc).
178+
ideas or help with running or hacking on Miri, you can open an issue here on
179+
GitHub or contact us (`oli-obk` and `RalfJ`) on the [Rust Zulip].
180+
181+
[Rust Zulip]: https://rust-lang.zulipchat.com
172182

173183
## History
174184

src/bin/cargo-miri.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ fn setup(ask_user: bool) {
149149
let dirs = directories::ProjectDirs::from("miri", "miri", "miri").unwrap();
150150
let dir = dirs.cache_dir();
151151
if !dir.exists() {
152-
println!("Creating `{}` and using it for miri's build of libstd", dir.display());
153152
fs::create_dir_all(&dir).unwrap();
154153
}
155154
// The interesting bit: Xargo.toml
@@ -184,7 +183,11 @@ path = "lib.rs"
184183
}
185184

186185
// That should be it!
187-
std::env::set_var("MIRI_SYSROOT", dir.join("HOST"));
186+
let sysroot = dir.join("HOST");
187+
std::env::set_var("MIRI_SYSROOT", &sysroot);
188+
if !ask_user {
189+
println!("A libstd for miri is now available in `{}`", sysroot.display());
190+
}
188191
}
189192

190193
fn main() {

0 commit comments

Comments
 (0)