Skip to content

Commit f2279fa

Browse files
committed
Auto merge of rust-lang#2282 - rust-lang:no_std, r=RalfJung
Support no-std targets and test it in CI cc `@jamesmunns` This is a bit annoying as you need to have `MIRI_NO_STD=1` set at all times, but it works ™️ Once libstd's `restricted_std` feature becomes more usable, we can probably do away with that env var. I also added a test to CI to make sure it keeps working. This test only builds libcore and runs a single test, so it's pretty fast.
2 parents 9f50296 + a9f9d48 commit f2279fa

File tree

5 files changed

+44
-8
lines changed

5 files changed

+44
-8
lines changed

CONTRIBUTING.md

+10
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ and you can (cross-)run the entire test suite using:
7171
MIRI_TEST_TARGET=i686-unknown-linux-gnu ./miri test
7272
```
7373

74+
If your target doesn't support libstd, you can run miri with
75+
76+
```
77+
MIRI_NO_STD=1 MIRI_TEST_TARGET=thumbv7em-none-eabihf ./miri test tests/fail/alloc/no_global_allocator.rs
78+
MIRI_NO_STD=1 ./miri run tests/pass/no_std.rs --target thumbv7em-none-eabihf
79+
```
80+
81+
to avoid attempting (and failing) to build libstd. Note that almost no tests will pass
82+
this way, but you can run individual tests.
83+
7484
`./miri test FILTER` only runs those tests that contain `FILTER` in their
7585
filename (including the base directory, e.g. `./miri test fail` will run all
7686
compile-fail tests).

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ Moreover, Miri recognizes some environment variables:
419419
* `MIRI_TEST_TARGET` (recognized by the test suite) indicates which target
420420
architecture to test against. `miri` and `cargo miri` accept the `--target`
421421
flag for the same purpose.
422+
* `MIRI_NO_STD` (recognized by `cargo miri` and the test suite) makes sure that the target's
423+
sysroot is built without libstd. This allows testing and running no_std programs.
422424
* `MIRI_BLESS` (recognized by the test suite) overwrite all `stderr` and `stdout` files
423425
instead of checking whether the output matches.
424426
* `MIRI_SKIP_UI_CHECKS` (recognized by the test suite) don't check whether the

cargo-miri/bin.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -398,20 +398,22 @@ fn setup(subcommand: MiriCommand) {
398398
if !dir.exists() {
399399
fs::create_dir_all(&dir).unwrap();
400400
}
401-
// The interesting bit: Xargo.toml
402-
File::create(dir.join("Xargo.toml"))
403-
.unwrap()
404-
.write_all(
405-
br#"
401+
let mut xargo_toml = File::create(dir.join("Xargo.toml")).unwrap();
402+
if std::env::var_os("MIRI_NO_STD").is_none() {
403+
// The interesting bit: Xargo.toml (only needs content if we actually need std)
404+
xargo_toml
405+
.write_all(
406+
br#"
406407
[dependencies.std]
407408
default_features = false
408409
# We support unwinding, so enable that panic runtime.
409410
features = ["panic_unwind", "backtrace"]
410411
411412
[dependencies.test]
412413
"#,
413-
)
414-
.unwrap();
414+
)
415+
.unwrap();
416+
}
415417
// The boring bits: a dummy project for xargo.
416418
// FIXME: With xargo-check, can we avoid doing this?
417419
File::create(dir.join("Cargo.toml"))
@@ -428,7 +430,7 @@ path = "lib.rs"
428430
"#,
429431
)
430432
.unwrap();
431-
File::create(dir.join("lib.rs")).unwrap();
433+
File::create(dir.join("lib.rs")).unwrap().write_all(b"#![no_std]").unwrap();
432434

433435
// Determine architectures.
434436
// We always need to set a target so rustc bootstrap can tell apart host from target crates.

ci.sh

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ case $HOST_TARGET in
6161
MIRI_TEST_TARGET=aarch64-apple-darwin run_tests
6262
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
6363
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec
64+
MIRI_NO_STD=1 ./miri run tests/pass/no_std.rs --target thumbv7em-none-eabihf # no_std embedded architecture minimal test
6465
;;
6566
x86_64-apple-darwin)
6667
MIRI_TEST_TARGET=mips64-unknown-linux-gnuabi64 run_tests # big-endian architecture

tests/pass/no_std.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(lang_items, start)]
2+
#![no_std]
3+
// windows tls dtors go through libstd right now, thus this test
4+
// cannot pass. When windows tls dtors go through the special magic
5+
// windows linker section, we can run this test on windows again.
6+
// ignore-windows
7+
8+
#[start]
9+
fn start(_: isize, _: *const *const u8) -> isize {
10+
for _ in 0..10 {}
11+
12+
0
13+
}
14+
15+
#[panic_handler]
16+
fn panic_handler(_: &core::panic::PanicInfo) -> ! {
17+
loop {}
18+
}
19+
20+
#[lang = "eh_personality"]
21+
fn eh_personality() {}

0 commit comments

Comments
 (0)