From 82e25e8b69e5722fee39182a6d5d27e7ac3ccb6c Mon Sep 17 00:00:00 2001 From: Ryan Kuester Date: Thu, 2 Jul 2026 15:41:08 -0500 Subject: [PATCH 1/2] docs(readme): pin esp toolchain to 1.93.0.0 esp toolchains 1.94.x and 1.95.x ship LLVM 21, which fails to compile release builds for the Xtensa target. Version 1.93.0.0, the last release on LLVM 20, builds correctly. Pin the espup install step to 1.93.0.0 and note the reason. --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2386915..d117007 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,16 @@ RUSTUP_TOOLCHAIN=stable cargo install espup --locked ``` ```bash -espup install +espup install --toolchain-version 1.93.0.0 ``` +Pin the toolchain to 1.93.0.0. Newer esp toolchains (1.94.x, 1.95.x) +ship LLVM 21, whose Xtensa backend miscompiles optimized builds and +aborts with `rustc-LLVM ERROR: Cannot select ... XtensaISD::PCREL_WRAPPER`. +1.93.0.0 (LLVM 20) is the last known-good version. `build.rs` refuses to +build on the affected toolchains, so an accidental `espup update` fails +fast with the same instructions instead of a cryptic backend crash. + ### Install flashing tools ```bash cargo install cargo-espflash espflash --locked From b553d8983ce45a58745d43ea1088d9fbe4514f2e Mon Sep 17 00:00:00 2001 From: Ryan Kuester Date: Thu, 2 Jul 2026 15:41:08 -0500 Subject: [PATCH 2/2] build: reject esp toolchains with broken LLVM 21 esp toolchains 1.94.x and 1.95.x ship LLVM 21, which fails to compile release builds for the Xtensa target with the error `rustc-LLVM ERROR: Cannot select`. Version 1.93.0.0, the last release on LLVM 20, builds correctly. Check the LLVM version in the build script and stop the build with instructions to install 1.93.0.0 when it is 21 or newer, catching an accidental toolchain update. --- build.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/build.rs b/build.rs index f164761..ba33913 100644 --- a/build.rs +++ b/build.rs @@ -1,10 +1,48 @@ fn main() { linker_be_nice(); + check_llvm_version(); println!("cargo:rustc-link-arg=-Tdefmt.x"); // make sure linkall.x is the last linker script (otherwise might cause problems with flip-link) println!("cargo:rustc-link-arg=-Tlinkall.x"); } +// esp toolchains built on LLVM 21 (Xtensa Rust 1.94.x / 1.95.x) fail to +// compile release builds for the Xtensa target: the backend can't select +// XtensaISD::PCREL_WRAPPER for a constant-pool string reference and aborts +// with `rustc-LLVM ERROR: Cannot select`. LLVM 20 (Xtensa Rust 1.93.0.0) is +// the last good version. Turn that cryptic crash into an actionable message. +// Revisit the version bound once esp-rs ships a fixed LLVM 21. +fn check_llvm_version() { + let rustc = std::env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); + let output = match std::process::Command::new(&rustc) + .args(["--version", "--verbose"]) + .output() + { + Ok(output) => output, + // Can't probe rustc; don't block the build over it. + Err(_) => return, + }; + + let major = String::from_utf8_lossy(&output.stdout) + .lines() + .find_map(|line| line.strip_prefix("LLVM version:")) + .and_then(|version| version.trim().split('.').next()) + .and_then(|major| major.parse::().ok()); + + if let Some(major) = major { + if major >= 21 { + eprintln!(); + eprintln!("This esp toolchain bundles LLVM {major}, which miscompiles optimized"); + eprintln!("Xtensa builds (XtensaISD::PCREL_WRAPPER cannot be selected). Install the"); + eprintln!("last known-good toolchain:"); + eprintln!(); + eprintln!(" espup install --toolchain-version 1.93.0.0"); + eprintln!(); + std::process::exit(1); + } + } +} + fn linker_be_nice() { let args: Vec = std::env::args().collect(); if args.len() > 1 {