rust-lang/rust · error
LLVM bitcode object in C static library (LTO not supported)
Error message
LLVM bitcode object in C static library (LTO not supported)
What it means
Returned by add_c_staticlib_symbols when scanning a native C static library (.a) to collect exported symbols and it encounters an archive member whose first bytes are the raw LLVM bitcode magic (BC 0xC0 0xDE). This means the .a was built with clang -flto, so its members are bitcode rather than machine object files. Rust's symbol-collector cannot parse bitcode and cannot feed such objects to the native linker for LTO, so it refuses the library.
Source
Thrown at compiler/rustc_codegen_ssa/src/back/link.rs:2813
out: &mut Vec<SymbolExport>,
) -> io::Result<()> {
let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess);
let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? };
let archive = object::read::archive::ArchiveFile::parse(&*archive_map)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
for member in archive.members() {
let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
let data = member
.data(&*archive_map)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
// clang LTO: raw LLVM bitcode
if data.starts_with(b"BC\xc0\xde") {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"LLVM bitcode object in C static library (LTO not supported)",
));
}
let object = object::File::parse(&*data)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
// gcc / clang ELF / Mach-O LTO
if object.sections().any(|s| {
s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false)
}) {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"LTO object in C static library is not supported",
));
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Rebuild the C static library without -flto (plain relocatable objects) and link that instead.
- If you need LTO across the C code, use the same Clang/LLVM toolchain and enable Rust-side -Clinker-plugin-lto so the linker handles bitcode, rather than passing the .a as a plain native lib.
- Vendor a non-LTO build of the dependency (e.g. via a build script that compiles sources with cc::Build without lto).
Example fix
# before: C lib built with LTO clang -flto -c lib.c -o lib.o && ar rcs libfoo.a lib.o # after: relocatable objects, no LTO clang -c lib.c -o lib.o && ar rcs libfoo.a lib.o
Defensive patterns
Strategy: fallback
Validate before calling
use std::process::Command;
// Returns true if the static archive embeds LLVM bitcode sections.
fn archive_contains_llvm_bitcode(path: &str) -> bool {
// Bitcode magic: 'BC' 0xC0 0xDE, or a wrapped __bitcode section.
let out = Command::new("nm").args([path]).output();
match out {
Ok(o) => String::from_utf8_lossy(&o.stdout)
.lines()
.any(|l| l.contains("BC") || l.contains("__bitcode") || l.contains("__llvmbc")),
Err(_) => false,
}
}
// caller: if archive_contains_llvm_bitcode("libfoo.a") { rebuild_without_lto()?; } Type guard
fn is_machine_code_only_archive(path: &str) -> bool {
!archive_contains_llvm_bitcode(path)
} Try / catch
let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("LLVM bitcode object in C static library") {
// Fallback: rebuild the C lib without -flto, then relink.
rebuild_c_lib_no_lto()?;
return retry_link();
} Prevention
- Build C/C++ dependencies with machine code, not `-emit-llvm`/`-flto=thin` bitcode, when shipping a `.a`.
- Ship two artifacts: a bitcode variant for LTO consumers and a plain `.a` for normal links.
- Detect bitcode magic (`BC\xC0\xDE`) or `__bitcode` sections before adding the lib to `cargo:rustc-link-lib=static`.
When it happens
Trigger: Linking a C/C++ static library compiled with `clang -flto` (or `-flto=thin`) into a Rust crate via #[link(name=...)] / -L native search. The member object is raw LLVM bitcode rather than a relocatable .o.
Common situations: A system or vendored C library shipped pre-built with LTO enabled (common in some distro packages). A build.rs or Makefile that adds -flto to CFLAGS for the C dependency. Mixing a clang-LTO-built C lib into a Rust project that does not use matching LLVM LTO.
Related errors
- LTO object in C static library is not supported
- staticlibs not supported
- failed to open LTO bitcode file `{}`: {}
- failed to mmap LTO bitcode file `{}`: {}
- couldn't open rlib
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/e7ec1d37c646bb5a.json.
Report an issue: GitHub.