Description
The bevy setup guide recommends using cranelift. In general, it sounds to me (everywhere cranelift is mentioned on the internet) like cranelift is suggested for debug builds because it builds the code quickly, but for release builds we should still use LLVM.
Problem Description
The current bevy setup docs make it sound like cranelift is clearly the better option for debug builds.
It took me roughly a year to realize that cranelift is the reason why the debugger is neither working in vscode, nor in rust-rover, nor with plain lldb in the terminal. At some point I just accepted that debugging seems not to work with dynamic linking. But I have now finally verified that the dynamic linking itself is not the issue!
- Dynamic linking with the following
.cargo/config.toml
works: Hitting a breakpoint, stepping, viewing local variables.
# https://bevyengine.org/learn/quick-start/getting-started/setup/#installing-os-dependencies
# Faster builds by 30%, they say.
#
# This enables faster compiles for your binary, but builds Bevy and other dependencies with the more-optimized LLVM backend.
#
# While cranelift is very fast to compile, the generated binaries are not optimized for speed. Additionally, it is generally still immature, so you may run into issues with it. Notably, Wasm builds do not work yet.
#
# When shipping your game, you should still compile it with LLVM.
#[unstable]
#codegen-backend = true
#
#[profile.dev]
#codegen-backend = "cranelift"
#
#[profile.dev.package."*"]
#codegen-backend = "llvm"
# Faster linking by using lld instead of rust compiler
# for Linux
[target.x86_64-unknown-linux-gnu]
linker = "clang"
rustflags = ["-C", "link-arg=-fuse-ld=lld",
# (Nightly) Make the current crate share its generic instantiations
"-Zshare-generics=y",
]
# for Windows
[target.x86_64-pc-windows-msvc]
linker = "rust-lld.exe"
- dynamic linking with the cranelift settings commented back in instead works for breakpoints and stepping but not for viewing variables.
"Variables are not available"
.
- Static linking is broken in the same way. We can even remove bevy fully and observe the same problematic behavior.
- Whether the lld settings are present or not does not change anything
Reproducible Example
// src/main.rs
fn main() {
let a = 1;
// set a breakpoint here and try to view the value of `a`
let b = 2;
println!("Hello! {}+{}={}", a, b, a+b);
}
# Cargo.toml
[package]
name = "rustq-bevyerror"
version = "0.1.0"
edition = "2021"
[dependencies]
# No optimization in the dev profile.
[profile.dev]
opt-level = 0
debug = "full"
# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]
opt-level = 3
# ./.cargo/config.toml
[unstable]
codegen-backend = true
[profile.dev]
# This is the problematic setting
codegen-backend = "cranelift"
[profile.dev.package."*"]
codegen-backend = "llvm"
# rust-toolchain.toml
# This gives access to the latest performance improvements and "unstable" optimizations, including generic sharing.
[toolchain]
channel = "nightly"
$ rustup --version
rustup 1.28.2 (e4f3ad6f8 2025-04-28)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.90.0-nightly (f26e58023 2025-06-30)`
$ cat /proc/version
Linux version 6.12.33+deb13-amd64 (debian-kernel@lists.debian.org) (x86_64-linux-gnu-gcc-14 (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44) #1 SMP PREEMPT_DYNAMIC Debian 6.12.33-1 (2025-06-19)
Action
I am unsure whether this issue should be reported to cranelift (where is their issue-tracker even? Is it the same as wasmtime?) or lldb.
But I am not really a user of either, I am only hearing about them because of my use of bevy. As such, I think it would make sense that the bevy setup guide would mention the tradeoff that using cranelift for faster debug builds will break the debugger.