rust-lang/rust · critical

staticlibs not supported

Error message

staticlibs not supported

What it means

Thrown by link_staticlib_by_name on the LlbcLinker, which is the self-contained LLVM-bitcode linker used for -C linker-flavor=llbc (typically emscripten/wasm LTO linking). This linker can only consume bitcode/object files passed by path and has no mechanism to resolve a static library by name against a search path, so asking it to link a named staticlib is unsupported and panics.

Source

Thrown at compiler/rustc_codegen_ssa/src/back/linker.rs:1940

    cmd: Command,
    sess: &'a Session,
}

impl<'a> Linker for LlbcLinker<'a> {
    fn cmd(&mut self) -> &mut Command {
        &mut self.cmd
    }

    fn set_output_kind(
        &mut self,
        _output_kind: LinkOutputKind,
        _crate_type: CrateType,
        _out_filename: &Path,
    ) {
    }

    fn link_staticlib_by_name(&mut self, _name: &str, _verbatim: bool, _whole_archive: bool) {
        panic!("staticlibs not supported")
    }

    fn link_staticlib_by_path(&mut self, path: &Path, _whole_archive: bool) {
        self.link_or_cc_arg(path);
    }

    fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
        match strip {
            Strip::None => {
                self.link_arg("--debug");
            }
            Strip::Debuginfo | Strip::Symbols => {}
        }
    }

    fn optimize(&mut self) {
        self.link_arg(match self.sess.opts.optimize {
            OptLevel::No => "-O0",

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Link the static library by path instead of by name: pass the full .a path via cargo:rustc-link-lib=static:<path> or -C link-arg=<path.a>, which routes through link_staticlib_by_path (supported).
  2. Avoid -C linker-flavor=llbc if the build genuinely needs named static libraries; use a linker flavor that supports library search.
  3. If the dependency is optional, gate or remove the cargo:rustc-link-lib=static=... directive for llbc builds.

Example fix

// build.rs before (named static lib, unsupported by llbc)
println!("cargo:rustc-link-lib=static=foo");
// after (link by path so LlbcLinker::link_staticlib_by_path handles it)
println!("cargo:rustc-link-lib=static:+whole-archive={}",
         out_dir.join("libfoo.a").display());
Defensive patterns

Strategy: fallback

Validate before calling

fn target_supports_staticlibs(target: &str) -> bool {
    // wasm32-unknown-unknown and a few bare-metal targets reject `staticlib`.
    !(target.starts_with("wasm32-") && target.contains("unknown"))
        && !target.starts_with("bpfel-")
        && !target.starts_with("nvptx")
}

// caller: if !target_supports_staticlibs(&target) { use_cdylib_instead()?; }

Type guard

fn target_allows_staticlib(target: &str) -> bool {
    target_supports_staticlibs(target)
}

Try / catch

let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("staticlibs not supported") {
    // Fallback: switch crate-type from `staticlib` to `cdylib` for this target.
    rebuild_with_crate_types(&["cdylib"])?;
}

Prevention

When it happens

Trigger: Invoked when the LLBC linker is in use and the build requests linking a static library by name (e.g. -l static=foo or #[link(name="foo", kind="static")]) rather than by explicit path. The LLBC flavor simply does not implement name-based staticlib resolution.

Common situations: Setting -C linker-flavor=llbc (or a target whose default flavor is llbc) while a dependency requests a named static library. Mixing native -l static dependencies into a wasm/emscripten LTO build. A build script emitting cargo:rustc-link-lib=static=... under an llbc toolchain.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/73cfd4530a928a89.json. Report an issue: GitHub.