Can't find crate for `panic_abort` / the crate `panic_abort` is not a panic runtime

I'm trying to compile a program that uses std for a Cortex-M3. I downloaded the cortex-m-quickstart template and made a few minor changes:

  1. Switch the target in .cargo/config to target = "thumbv7m-unknown-eabi.json"
  2. Comment out all of the dependencies in Cargo.toml (some of the cortex crates don't like the unknown in the target triple).
  3. Strip down the code to literally just this (I think this will need to be changed later but I wanted to simplify things):
fn main() -> ! {
    loop {}
}
  1. Add a thumv7m-unknown-eabi-json target like this:
{
  "os": "unknown",
  "arch": "arm",
  "data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
  "eliminate-frame-pointer": false,
  "emit-debug-gdb-scripts": false,
  "executables": true,
  "linker": "rust-lld",
  "linker-flavor": "ld.lld",
  "llvm-target": "thumbv7m-unknown-eabi",
  "max-atomic-width": 32,
  "panic-strategy": "abort",
  "relocation-model": "static",
  "target-pointer-width": "32",
  "unsupported-abis": [
    "stdcall",
    "fastcall",
    "vectorcall",
    "thiscall",
    "win64",
    "sysv64"
  ]
}
  1. Finally built it like this: cargo +nightly build -Z build-std --verbose

Unfortunately I get this mysterious error:

  Compiling cortex-m-quickstart v0.1.0 (/Users/tim/cortex-m-quickstart)
     Running `rustc --crate-name cortex_m_quickstart --edition=2018 src/main.rs --error-format=json --json=diagnostic-rendered-ansi --crate-type bin --emit=dep-info,link -C embed-bitcode=no -C debuginfo=2 -C metadata=b6fe60e222dc389a -C extra-filename=-b6fe60e222dc389a --out-dir /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps --target /Users/tim/cortex-m-quickstart/thumbv7m-unknown-eabi.json -C incremental=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/incremental -L dependency=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps -L dependency=/Users/tim/cortex-m-quickstart/target/debug/deps --extern 'noprelude:alloc=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/liballoc-8c9ec352989a5f35.rlib' --extern 'noprelude:compiler_builtins=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libcompiler_builtins-0851db5ec8bb1a25.rlib' --extern 'noprelude:core=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libcore-f11f9c4b8f6340f7.rlib' --extern 'noprelude:panic_unwind=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libpanic_unwind-e981032e31382246.rlib' --extern 'noprelude:proc_macro=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libproc_macro-be91720a901aa031.rlib' --extern 'noprelude:std=/Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libstd-22fb39c90a0b0c7b.rlib' -Z unstable-options -L /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/build/cortex-m-quickstart-1a85fd60572a4cc2/out`
error[E0463]: can't find crate for `panic_abort`

error: aborting due to previous error

Ok weird, maybe I need to add panic-abort = "0.3.2" to my dependencies? But then I get these errors:

error: the crate `panic_abort` is not a panic runtime

error: duplicate lang item in crate `panic_abort`: `panic_impl`.
  |
  = note: the lang item is first defined in crate `std` (which `cortex_m_quickstart` depends on)
  = note: first definition in `std` loaded from /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libstd-22fb39c90a0b0c7b.rlib
  = note: second definition in `panic_abort` loaded from /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/libpanic_abort-501bea4b917c9dfc.rlib

error[E0658]: use of unstable library feature 'restricted_std'
  |
  = help: add `#![feature(restricted_std)]` to the crate attributes to enable

error: aborting due to 3 previous errors

Does anyone know what is going on here? It seems to me like std provides its own panic handler, but then I can't figure out why something is trying to find the panic_abort crate. It doesn't help that it doesn't tell me what is trying to find panic_abort. :-/

There's a similar thread here but it seems like they solved it by adding panic-abort as a dependency.

Try readding panic-halt = "0.2.0" to the dependencies - that's what the template does.

Try readding panic-halt

Ah yeah I forgot to say I did try that but it just results in the same can't find crate for panic_abort error.

I am pretty sure you can't currently compile std for Cortex-M3.

There's no fundamental reason for that though, so it should be possible with some work.

Ok I did a bit of debugging. First you can get more info by setting RUSTC_LOG=info. Without the panic-abort dependency you get:

INFO rustc_metadata::creader panic runtime not found -- loading panic_abort
INFO rustc_metadata::creader resolving crate `panic_abort`
INFO rustc_metadata::creader falling back to a load
INFO rustc_metadata::locator lib candidate: /Users/tim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_abort-14c6721c1e3ddac4.rlib
INFO rustc_metadata::locator rlib reading metadata from: /Users/tim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_abort-14c6721c1e3ddac4.rlib
INFO rustc_metadata::locator Rejecting via proc macro: expected true got false
INFO rustc_metadata::locator metadata mismatch

It's trying to use the x86_64-apple-darwin version of libpanic_abort.rlib which is clearly wrong. This code comes from creader.rs, which seems to suggest that we can override std's own panic-abort handler.

However when we try we get the panic-abort isn't a panic runtime error - I think it needs #![panic_runtime] in it (which the std implementation has), but it doesn't have that. But then I don't understand how this works with no_std.

So there are two mysteries remaining:

  1. Why doesn't the panic-abort on crates.io have #![panic_runtime] and why does it work on no_std without it?
  2. Why is rustc trying to load the host version of libpanic_abort.rlib instead of the target version?

The second one is particularly weird because it does build libpanic_abort.rlib for the target, and it even successfully loads other crates from the same place:

INFO rustc_metadata::creader resolving crate `rustc_demangle`
INFO rustc_metadata::creader falling back to a load
INFO rustc_metadata::locator lib candidate: /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/librustc_demangle-bf58fb3a631e7b6d.rlib
INFO rustc_metadata::locator lib candidate: /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/librustc_demangle-bf58fb3a631e7b6d.rmeta
INFO rustc_metadata::locator rmeta reading metadata from: /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/librustc_demangle-bf58fb3a631e7b6d.rmeta
INFO rustc_metadata::creader register crate `rustc_demangle` (cnum = 11. private_dep = false)
INFO rustc_metadata::creader resolving dep crate rustc_std_workspace_core hash: `bd21d81d2dfb0df7` extra filename: `-486c7a3a171d61f4`
INFO rustc_metadata::creader resolving crate `rustc_std_workspace_core`
INFO rustc_metadata::creader resolving dep crate core hash: `d201c55fbf20f1be` extra filename: `-f11f9c4b8f6340f7`
INFO rustc_metadata::creader resolving crate `core`
INFO rustc_metadata::creader resolving dep crate compiler_builtins hash: `96e1c2e0df928dd2` extra filename: `-0851db5ec8bb1a25`
INFO rustc_metadata::creader resolving crate `compiler_builtins`
INFO rustc_metadata::creader panic runtime not found -- loading panic_abort
INFO rustc_metadata::creader resolving crate `panic_abort`
INFO rustc_metadata::creader falling back to a load
INFO rustc_metadata::locator lib candidate: /Users/tim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_abort-14c6721c1e3ddac4.rlib
INFO rustc_metadata::locator rlib reading metadata from: /Users/tim/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib/libpanic_abort-14c6721c1e3ddac4.rlib
INFO rustc_metadata::locator Rejecting via proc macro: expected true got false
INFO rustc_metadata::locator metadata mismatch
error[E0463]: can't find crate for `panic_abort`

Note that it loads /Users/tim/cortex-m-quickstart/target/thumbv7m-unknown-eabi/debug/deps/librustc_demangle-bf58fb3a631e7b6d.rlib fine, but for some reason it doesn't try to find panic_abort in the same place:

$ ls target/thumbv7m-unknown-eabi/debug/deps/libpanic_abort*
target/thumbv7m-unknown-eabi/debug/deps/libpanic_abort-4df2d936555c768e.rlib
target/thumbv7m-unknown-eabi/debug/deps/libpanic_abort-4df2d936555c768e.rmeta

Try depending on panic-abort but compiling with Nightly maybe.

I am compiling with nightly.

I followed your instructions to modify the template but I don't get this error at all. Could you share the entire project with your modifications?

Very weird! Sure I forked cortex-m-quickstart and my changes are in this commit.

To test do this:

git clone https://github.com/Timmmm/cortex-m-quickstart.git
cd cortex-m-quickstart
cargo +nightly build -Z build-std

Let me know if that works for you!

1 Like

I tried it and got the same error as you did. After thinking about it I do agree with @Karsten - std requires an operating system and I don't think many are supported by that CPU.

I don't think std requires an OS. As far as I can see it just requires an implementation of the sys crate, which you can do without an OS (WASM is the obvious example; let's not get into what the definition of "OS" is!). Since I set the target_os to "none" it should use the unsupported implementation which basically fails every operation. Sadly you can't just implement your own sys out-of-tree, per this comment:

//! In the future it would be desirable for the independent
//! implementations of this module to be extracted to their own crates
//! that `std` can link to, thus enabling their implementation
//! out-of-tree via crate replacement. Though due to the complex
//! inter-dependencies within `std` that will be a challenging goal to
//! achieve.

But I should at least be able to replace the allocator.

In any case I don't think that is what is causing this error. Maybe I should start from the WASM target and make it compile for ARM rather than starting from the ARM target and making it compile std.

So it seems like this might actually be an issue with build-std. I cloned the wasm-pack-template repo and tried to build it but I get exactly the same error!

$ cargo +nightly build -Z build-std --target wasm32-unknown-unknown
...
   Compiling wasm-pack-template v0.1.0 (/Users/tim/wasm-pack-template)
error[E0463]: can't find crate for `panic_abort`
1 Like

@Timmmm had the same problem and found a related issue: Error when building with panic = "abort" and -Z build-std · Issue #80685 · rust-lang/rust · GitHub

Apparently, you need to add panic_abort to the list of crates in build-std (e.g -Z build-std=panic_abort,std)

Ah yeah I forgot to say I asked in a github issue and was pointed to the exact same solution.

By the way it totally worked and I was able to build and run some code that used std::vec::Vec for a Cortex-M3!

1 Like