1
1
#! /bin/bash
2
2
set -e
3
- USAGE=$( cat << "EOF "
4
- COMMANDS
5
-
6
- ./miri install <flags>:
7
- Installs the miri driver and cargo-miri. <flags> are passed to `cargo
8
- install`. Sets up the rpath such that the installed binary should work in any
9
- working directory. Note that the binaries are placed in the `miri` toolchain
10
- sysroot, to prevent conflicts with other toolchains.
11
-
12
- ./miri build <flags>:
13
- Just build miri. <flags> are passed to `cargo build`.
14
-
15
- ./miri check <flags>:
16
- Just check miri. <flags> are passed to `cargo check`.
17
-
18
- ./miri test <flags>:
19
- Build miri, set up a sysroot and then run the test suite. <flags> are passed
20
- to the final `cargo test` invocation.
21
-
22
- ./miri run <flags>:
23
- Build miri, set up a sysroot and then run the driver with the given <flags>.
24
- (Also respects MIRIFLAGS environment variable.)
25
-
26
- ./miri fmt <flags>:
27
- Format all sources and tests. <flags> are passed to `rustfmt`.
28
-
29
- ./miri clippy <flags>:
30
- Runs clippy on all sources. <flags> are passed to `cargo clippy`.
31
-
32
- ./miri cargo <flags>:
33
- Runs just `cargo <flags>` with the Miri-specific environment variables.
34
- Mainly meant to be invoked by rust-analyzer.
35
-
36
- ./miri many-seeds <command>:
37
- Runs <command> over and over again with different seeds for Miri. The MIRIFLAGS
38
- variable is set to its original value appended with ` -Zmiri-seed=$SEED` for
39
- many different seeds. The MIRI_SEEDS variable controls how many seeds are being
40
- tried; MIRI_SEED_START controls the first seed to try.
41
-
42
- ./miri bench <benches>:
43
- Runs the benchmarks from bench-cargo-miri in hyperfine. hyperfine needs to be installed.
44
- <benches> can explicitly list the benchmarks to run; by default, all of them are run.
45
-
46
- ./miri toolchain <flags>:
47
- Update and activate the rustup toolchain 'miri' to the commit given in the
48
- `rust-version` file.
49
- `rustup-toolchain-install-master` must be installed for this to work. Any extra
50
- flags are passed to `rustup-toolchain-install-master`.
51
-
52
- ./miri rustc-pull <commit>:
53
- Pull and merge Miri changes from the rustc repo. Defaults to fetching the latest
54
- rustc commit. The fetched commit is stored in the `rust-version` file, so the
55
- next `./miri toolchain` will install the rustc that just got pulled.
56
-
57
- ./miri rustc-push <github user> <branch>:
58
- Push Miri changes back to the rustc repo. This will pull a copy of the rustc
59
- history into the Miri repo, unless you set the RUSTC_GIT env var to an existing
60
- clone of the rustc repo.
61
-
62
- ENVIRONMENT VARIABLES
63
-
64
- MIRI_SYSROOT:
65
- If already set, the "sysroot setup" step is skipped.
66
-
67
- CARGO_EXTRA_FLAGS:
68
- Pass extra flags to all cargo invocations. (Ignored by `./miri cargo`.)
69
- EOF
70
- )
71
-
72
- # # We need to know which command to run and some global constants.
73
- COMMAND=" $1 "
74
- if [ -z " $COMMAND " ]; then
75
- echo " $USAGE "
76
- exit 1
77
- fi
78
- shift
79
- # macOS does not have a useful readlink/realpath so we have to use Python instead...
80
- MIRIDIR=$( python3 -c ' import pathlib, sys; print(pathlib.Path(sys.argv[1]).resolve().parent.as_posix())' " $0 " )
81
- # Used for rustc syncs.
82
- JOSH_FILTER=" :rev(75dd959a3a40eb5b4574f8d2e23aa6efbeb33573:prefix=src/tools/miri):/src/tools/miri"
83
- # Needed for `./miri bench`.
84
- TOOLCHAIN=$( cd " $MIRIDIR " ; rustup show active-toolchain | head -n 1 | cut -d ' ' -f 1)
85
-
86
- # # Early commands, that don't do auto-things and don't want the environment-altering things happening below.
87
- case " $COMMAND " in
88
- toolchain)
89
- cd " $MIRIDIR "
90
- NEW_COMMIT=$( cat rust-version)
91
- # Make sure rustup-toolchain-install-master is installed.
92
- if ! which rustup-toolchain-install-master > /dev/null; then
93
- echo " Please install rustup-toolchain-install-master by running 'cargo install rustup-toolchain-install-master'"
94
- exit 1
95
- fi
96
- # Check if we already are at that commit.
97
- CUR_COMMIT=$( rustc +miri --version -v 2> /dev/null | grep " ^commit-hash: " | cut -d " " -f 2)
98
- if [[ " $CUR_COMMIT " == " $NEW_COMMIT " ]]; then
99
- echo " miri toolchain is already at commit $CUR_COMMIT ."
100
- if [[ " $TOOLCHAIN " != " miri" ]]; then
101
- rustup override set miri
102
- fi
103
- exit 0
104
- fi
105
- # Install and setup new toolchain.
106
- rustup toolchain uninstall miri
107
- rustup-toolchain-install-master -n miri -c cargo -c rust-src -c rustc-dev -c llvm-tools -c rustfmt -c clippy " $@ " -- " $NEW_COMMIT "
108
- rustup override set miri
109
- # Cleanup.
110
- cargo clean
111
- # Call 'cargo metadata' on the sources in case that changes the lockfile
112
- # (which fails under some setups when it is done from inside vscode).
113
- cargo metadata --format-version 1 --manifest-path " $( rustc --print sysroot) /lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml" > /dev/null
114
- # Done!
115
- exit 0
116
- ;;
117
- rustc-pull)
118
- cd " $MIRIDIR "
119
- FETCH_COMMIT=" $1 "
120
- if [ -z " $FETCH_COMMIT " ]; then
121
- FETCH_COMMIT=$( git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1)
122
- fi
123
- # Update rust-version file. As a separate commit, since making it part of
124
- # the merge has confused the heck out of josh in the past.
125
- echo " $FETCH_COMMIT " > rust-version
126
- git commit rust-version -m " Preparing for merge from rustc" || (echo " FAILED to commit rust-version file, something went wrong" ; exit 1)
127
- # Fetch given rustc commit and note down which one that was
128
- git fetch http://localhost:8000/rust-lang/rust.git@$FETCH_COMMIT$JOSH_FILTER .git || (echo " FAILED to fetch new commits, something went wrong" ; exit 1)
129
- git merge FETCH_HEAD --no-ff -m " Merge from rustc" || (echo " FAILED to merge new commits ($( git rev-parse FETCH_HEAD) ), something went wrong" ; exit 1)
130
- exit 0
131
- ;;
132
- rustc-push)
133
- USER=" $1 "
134
- BRANCH=" $2 "
135
- if [ -z " $USER " ] || [ -z " $BRANCH " ]; then
136
- echo " Usage: $0 rustc-push <github user> <branch>"
137
- exit 1
138
- fi
139
- if [ -n " $RUSTC_GIT " ]; then
140
- # Use an existing fork for the branch updates.
141
- cd " $RUSTC_GIT "
142
- else
143
- # Do this in the local Miri repo.
144
- echo " This will pull a copy of the rust-lang/rust history into this Miri checkout, growing it by about 1GB."
145
- read -r -p " To avoid that, abort now and set the RUSTC_GIT environment variable to an existing rustc checkout. Proceed? [y/N] "
146
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
147
- exit 1
148
- fi
149
- cd " $MIRIDIR "
150
- fi
151
- # Prepare the branch. Pushing works much better if we use as base exactly
152
- # the commit that we pulled from last time, so we use the `rust-version`
153
- # file as a good approximation of that.
154
- BASE=$( cat " $MIRIDIR /rust-version" )
155
- echo " Preparing $USER /rust (base: $BASE )..."
156
- if git fetch " https://github.com/$USER /rust" " $BRANCH " & > /dev/null; then
157
- echo " The branch '$BRANCH ' seems to already exist in 'https://github.com/$USER /rust'. Please delete it and try again."
158
- exit 1
159
- fi
160
- git fetch https://github.com/rust-lang/rust $BASE
161
- git push https://github.com/$USER /rust $BASE :refs/heads/$BRANCH -f
162
- echo
163
- # Do the actual push.
164
- cd " $MIRIDIR "
165
- echo " Pushing Miri changes..."
166
- git push http://localhost:8000/$USER /rust.git$JOSH_FILTER .git HEAD:$BRANCH
167
- # Do a round-trip check to make sure the push worked as expected.
168
- echo
169
- git fetch http://localhost:8000/$USER /rust.git@$JOSH_FILTER .git $BRANCH & > /dev/null
170
- if [[ $( git rev-parse HEAD) != $( git rev-parse FETCH_HEAD) ]]; then
171
- echo " ERROR: Josh created a non-roundtrip push! Do NOT merge this into rustc!"
172
- exit 1
173
- else
174
- echo " Confirmed that the push round-trips back to Miri properly. Please create a rustc PR:"
175
- echo " https://github.com/$USER /rust/pull/new/$BRANCH "
176
- exit 0
177
- fi
178
- ;;
179
- many-seeds)
180
- MIRI_SEED_START=${MIRI_SEED_START:- 0} # default to 0
181
- MIRI_SEEDS=${MIRI_SEEDS:- 256} # default to 256
182
- for SEED in $( seq $MIRI_SEED_START $(( $MIRI_SEED_START + $MIRI_SEEDS - 1 )) ) ; do
183
- echo " Trying seed: $SEED "
184
- MIRIFLAGS=" $MIRIFLAGS -Zlayout-seed=$SEED -Zmiri-seed=$SEED " $@ || { echo " Failing seed: $SEED " ; break ; }
185
- done
186
- exit 0
187
- ;;
188
- bench)
189
- # The hyperfine to use
190
- HYPERFINE=${HYPERFINE:- hyperfine -w 1 -m 5 --shell=none}
191
- # Make sure we have an up-to-date Miri installed
192
- " $0 " install
193
- # Run the requested benchmarks
194
- if [ -z " ${1+exists} " ]; then
195
- BENCHES=( $( ls " $MIRIDIR /bench-cargo-miri" ) )
196
- else
197
- BENCHES=(" $@ " )
198
- fi
199
- for BENCH in " ${BENCHES[@]} " ; do
200
- $HYPERFINE " cargo +$TOOLCHAIN miri run --manifest-path $MIRIDIR /bench-cargo-miri/$BENCH /Cargo.toml"
201
- done
202
- exit 0
203
- ;;
204
- esac
205
-
206
- # # Run the auto-things.
207
- if [ -z " $MIRI_AUTO_OPS " ]; then
208
- export MIRI_AUTO_OPS=42
209
-
210
- # Run this first, so that the toolchain doesn't change after
211
- # other code has run.
212
- if [ -f " $MIRIDIR /.auto-everything" ] || [ -f " $MIRIDIR /.auto-toolchain" ] ; then
213
- $0 toolchain
214
- # Let's make sure to actually use that toolchain, too.
215
- TOOLCHAIN=miri
216
- fi
217
-
218
- if [ -f " $MIRIDIR /.auto-everything" ] || [ -f " $MIRIDIR /.auto-fmt" ] ; then
219
- $0 fmt
220
- fi
221
-
222
- if [ -f " $MIRIDIR /.auto-everything" ] || [ -f " $MIRIDIR /.auto-clippy" ] ; then
223
- $0 clippy -- -D warnings
224
- fi
225
- fi
226
-
227
- # # Prepare the environment
228
- # Determine some toolchain properties
229
- TARGET=$( rustc +$TOOLCHAIN --version --verbose | grep " ^host:" | cut -d ' ' -f 2)
230
- SYSROOT=$( rustc +$TOOLCHAIN --print sysroot)
231
- LIBDIR=$SYSROOT /lib/rustlib/$TARGET /lib
232
- if ! test -d " $LIBDIR " ; then
233
- echo " Something went wrong determining the library dir."
234
- echo " I got $LIBDIR but that does not exist."
235
- echo " Please report a bug at https://github.com/rust-lang/miri/issues."
236
- exit 2
237
- fi
238
-
239
- # Prepare flags for cargo and rustc.
240
- CARGO=" cargo +$TOOLCHAIN "
241
- # Share target dir between `miri` and `cargo-miri`.
242
- if [ -z " $CARGO_TARGET_DIR " ]; then
243
- export CARGO_TARGET_DIR=" $MIRIDIR /target"
244
- fi
245
- # We configure dev builds to not be unusably slow.
246
- if [ -z " $CARGO_PROFILE_DEV_OPT_LEVEL " ]; then
247
- export CARGO_PROFILE_DEV_OPT_LEVEL=2
248
- fi
249
- # Enable rustc-specific lints (ignored without `-Zunstable-options`).
250
- export RUSTFLAGS=" -Zunstable-options -Wrustc::internal -Wrust_2018_idioms -Wunused_lifetimes -Wsemicolon_in_expressions_from_macros $RUSTFLAGS "
251
- # We set the rpath so that Miri finds the private rustc libraries it needs.
252
- export RUSTFLAGS=" -C link-args=-Wl,-rpath,$LIBDIR $RUSTFLAGS "
253
-
254
- # # Helper functions
255
-
256
- # Build a sysroot and set MIRI_SYSROOT to use it. Arguments are passed to `cargo miri setup`.
257
- build_sysroot () {
258
- if ! MIRI_SYSROOT=" $( $CARGO run $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /cargo-miri/Cargo.toml -- miri setup --print-sysroot " $@ " ) " ; then
259
- # Run it again so the user can see the error.
260
- $CARGO run $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /cargo-miri/Cargo.toml -- miri setup " $@ "
261
- echo " 'cargo miri setup' failed"
262
- exit 1
263
- fi
264
- export MIRI_SYSROOT
265
- }
266
-
267
- # Prepare and set MIRI_SYSROOT. Respects `MIRI_TEST_TARGET` and takes into account
268
- # locally built vs. distributed rustc.
269
- find_sysroot () {
270
- if [ -n " $MIRI_SYSROOT " ]; then
271
- # Sysroot already set, use that.
272
- return 0
273
- fi
274
- # We need to build a sysroot.
275
- if [ -n " $MIRI_TEST_TARGET " ]; then
276
- build_sysroot --target " $MIRI_TEST_TARGET "
277
- else
278
- build_sysroot
279
- fi
280
- }
281
-
282
- # # Main
283
-
284
- # Run command.
285
- case " $COMMAND " in
286
- install)
287
- # Install binaries to the miri toolchain's sysroot so they do not interact with other toolchains.
288
- $CARGO install $CARGO_EXTRA_FLAGS --path " $MIRIDIR " --force --root " $SYSROOT " " $@ "
289
- $CARGO install $CARGO_EXTRA_FLAGS --path " $MIRIDIR " /cargo-miri --force --root " $SYSROOT " " $@ "
290
- ;;
291
- check)
292
- # Check, and let caller control flags.
293
- $CARGO check $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml --all-targets " $@ "
294
- $CARGO check $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /cargo-miri/Cargo.toml " $@ "
295
- ;;
296
- build)
297
- # Build, and let caller control flags.
298
- $CARGO build $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml " $@ "
299
- $CARGO build $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /cargo-miri/Cargo.toml " $@ "
300
- ;;
301
- test|bless)
302
- # First build and get a sysroot.
303
- $CARGO build $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml
304
- find_sysroot
305
- if [ " $COMMAND " = " bless" ]; then
306
- export RUSTC_BLESS=" Gesundheit"
307
- fi
308
- # Then test, and let caller control flags.
309
- # Only in root project as `cargo-miri` has no tests.
310
- $CARGO test $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml " $@ "
311
- ;;
312
- run|run-dep)
313
- # Scan for "--target" to overwrite the "MIRI_TEST_TARGET" env var so
314
- # that we set the MIRI_SYSROOT up the right way.
315
- FOUND_TARGET_OPT=0
316
- for ARG in " $@ " ; do
317
- if [ " $LAST_ARG " = " --target" ]; then
318
- # Found it!
319
- export MIRI_TEST_TARGET=" $ARG "
320
- FOUND_TARGET_OPT=1
321
- break
322
- fi
323
- LAST_ARG=" $ARG "
324
- done
325
- if [ " $FOUND_TARGET_OPT " = " 0" ] && [ -n " $MIRI_TEST_TARGET " ]; then
326
- # Make sure Miri actually uses this target.
327
- MIRIFLAGS=" $MIRIFLAGS --target $MIRI_TEST_TARGET "
328
- fi
329
-
330
- CARGO=" $CARGO --quiet"
331
- # First build and get a sysroot.
332
- $CARGO build $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml
333
- find_sysroot
334
- # Then run the actual command.
335
-
336
- if [ " $COMMAND " = " run-dep" ]; then
337
- exec $CARGO test --test compiletest $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml -- --miri-run-dep-mode $MIRIFLAGS " $@ "
338
- else
339
- exec $CARGO run $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml -- $MIRIFLAGS " $@ "
340
- fi
341
- ;;
342
- fmt)
343
- find " $MIRIDIR " -not \( -name target -prune \) -name ' *.rs' \
344
- | xargs rustfmt +$TOOLCHAIN --edition=2021 --config-path " $MIRIDIR /rustfmt.toml" " $@ "
345
- ;;
346
- clippy)
347
- $CARGO clippy $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /Cargo.toml --all-targets " $@ "
348
- $CARGO clippy $CARGO_EXTRA_FLAGS --manifest-path " $MIRIDIR " /cargo-miri/Cargo.toml " $@ "
349
- ;;
350
- cargo)
351
- # We carefully kept the working dir intact, so this will run cargo *on the workspace in the
352
- # current working dir*, not on the main Miri workspace. That is exactly what RA needs.
353
- $CARGO " $@ "
354
- ;;
355
- * )
356
- echo " Unknown command: $COMMAND "
357
- exit 1
358
- ;;
359
- esac
3
+ # Instead of doing just `cargo run --manifest-path .. $@`, we invoke miri-script binary directly. Invoking `cargo run` goes through
4
+ # rustup (that sets it's own environmental variables), which is undesirable.
5
+ cargo build --manifest-path " $( dirname " $0 " ) " /miri-script/Cargo.toml
6
+ " $( dirname " $0 " ) " /miri-script/target/debug/miri-script $@
0 commit comments