rust-lang/rust · error
Failed to spawn `as`.
Error message
Failed to spawn `as`.
What it means
This fires in Cranelift codegen's `compile_global_asm` when the environment variable `CG_CLIF_FORCE_GNU_AS` is set. The code spawns the system assembler (`as`, path from `config.assembler`) via `Command::new(&config.assembler).spawn().expect(...)`. If the assembler binary cannot be found in PATH, lacks execute permission, or the OS refuses to spawn it (resource limits, fork failure), the panic fires.
Source
Thrown at compiler/rustc_codegen_cranelift/src/global_asm.rs:233
) -> Result<(), String> {
assert!(!global_asm.is_empty());
// Remove all LLVM style comments
let mut global_asm = global_asm
.lines()
.map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line })
.collect::<Vec<_>>()
.join("\n");
global_asm.push('\n');
// Assemble `global_asm`
if option_env!("CG_CLIF_FORCE_GNU_AS").is_some() {
let mut child = Command::new(&config.assembler)
.arg("-o")
.arg(&global_asm_object_file)
.stdin(Stdio::piped())
.spawn()
.expect("Failed to spawn `as`.");
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
let status = child.wait().expect("Failed to wait for `as`.");
if !status.success() {
return Err(format!("Failed to assemble `{}`", global_asm));
}
} else {
// Escape { and }
let global_asm = global_asm.replace('{', "{{").replace('}', "}}");
let mut child = Command::new(std::env::current_exe().unwrap())
// Avoid a warning about the jobserver fd not being passed
.env_remove("CARGO_MAKEFLAGS")
.arg("--target")
.arg(&config.target)
.arg("--crate-type")
.arg("staticlib")
.arg("--emit")
.arg("obj")View on GitHub (pinned to 7088e4b63a)
Solutions
- Install binutils: `apt-get install binutils` (Debian/Ubuntu) or `apk add binutils` (Alpine).
- Remove the `CG_CLIF_FORCE_GNU_AS` environment variable — without it, cg_clif uses rustc+LLVM to assemble global asm instead of spawning `as` directly.
- Verify the assembler is in PATH: `which as`.
- If cross-compiling, install the cross-assembler (e.g., `gcc-multilib` or the target's binutils).
Example fix
# before (CG_CLIF_FORCE_GNU_AS set but `as` missing → panic) CG_CLIF_FORCE_GNU_AS=1 cargo build # after (install binutils, or remove the env var) # Option A: install binutils apt-get install -y binutils # Option B: unset the flag unset CG_CLIF_FORCE_GNU_AS cargo build
Defensive patterns
Strategy: validation
Validate before calling
// Before building with global_asm! + CG_CLIF_FORCE_GNU_AS, verify
// the assembler exists:
// which as || { echo 'as not found; install binutils'; exit 1; }
// Rust-side check in build.rs:
// fn main() {
// if option_env!("CG_CLIF_FORCE_GNU_AS").is_some() {
// let out = std::process::Command::new("which").arg("as").output();
// if !out.map(|o| o.status.success()).unwrap_or(false) {
// panic!("CG_CLIF_FORCE_GNU_AS set but `as` not found. Install binutils.");
// }
// }
// } Try / catch
// In a build script, handle assembler spawn failure gracefully:
use std::process::Command;
let result = Command::new(&assembler).arg("-o").arg(&outfile).spawn();
match result {
Ok(mut child) => { child.wait().expect("wait failed"); }
Err(e) => {
eprintln!("Failed to spawn assembler: {}. Install binutils or unset CG_CLIF_FORCE_GNU_AS.", e);
std::process::exit(1);
}
} Prevention
- Always have binutils installed when using CG_CLIF_FORCE_GNU_AS.
- Verify 'which as' succeeds before building.
- In Dockerfiles, add binutils to the install list.
- Don't set CG_CLIF_FORCE_GNU_AS unless you specifically need GNU as over the LLVM path.
When it happens
Trigger: Compiling a crate that uses `global_asm!` with the Cranelift backend while `CG_CLIF_FORCE_GNU_AS` is set, and the system assembler (`as`) is not installed or not in PATH. Common on minimal Docker containers, Alpine Linux (uses `as` from binutils), or cross-compilation setups without the target's assembler.
Common situations: Minimal Docker images (e.g., `debian:slim`, Alpine) without `binutils` installed. Cross-compilation where the target's `as` isn't in PATH. Systems where `as` exists but is not executable or the process table is full. Setting `CG_CLIF_FORCE_GNU_AS` to bypass the default LLVM-via-rustc asm path.
Related errors
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/2a347b8709b912f5.
Report an issue: GitHub.