{"id":"76edd8027086261d","repo":"rust-lang/rust","slug":"cannot-load-libgccjit-so","errorCode":null,"errorMessage":"Cannot load libgccjit.so: {}","messagePattern":"Cannot load libgccjit\\.so: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_codegen_gcc/src/lib.rs","lineNumber":189,"sourceCode":"\n#[derive(Clone)]\npub struct GccCodegenBackend {\n    target_info: LockedTargetInfo,\n    lto_supported: Arc<AtomicBool>,\n}\n\nfn load_libgccjit_if_needed(libgccjit_target_lib_file: &Path) {\n    if gccjit::is_loaded() {\n        // Do not load a libgccjit second time.\n        return;\n    }\n\n    let path = libgccjit_target_lib_file.to_str().expect(\"libgccjit path\");\n\n    let string = CString::new(path).expect(\"string to libgccjit path\");\n\n    if let Err(error) = gccjit::load(&string) {\n        panic!(\"Cannot load libgccjit.so: {}\", error);\n    }\n}\n\nimpl CodegenBackend for GccCodegenBackend {\n    fn name(&self) -> &'static str {\n        \"gcc\"\n    }\n\n    fn init(&self, sess: &Session) {\n        fn file_path(sysroot_path: &Path, sess: &Session) -> PathBuf {\n            let rustlib_path =\n                rustc_target::relative_target_rustlib_path(sysroot_path, &sess.host.llvm_target);\n            sysroot_path\n                .join(rustlib_path)\n                .join(\"codegen-backends\")\n                .join(\"lib\")\n                .join(sess.target.llvm_target.as_ref())\n                .join(\"libgccjit.so\")","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/lib.rs#L171-L207","documentation":"`panic!(\"Cannot load libgccjit.so: {}\")` in `load_libgccjit_if_needed`, reached when `gccjit::load(&path)` returns `Err`. The backend located a candidate `libgccjit.so` under `<sysroot>/rustlib/codegen-backends/lib/<target>/libgccjit.so` and tried to dlopen it, but loading failed. The formatted `{}` is the underlying load error (missing symbol, ABI mismatch, missing transitive shared library, corrupt file).","triggerScenarios":"Using `-Ccodegen-backend=gcc` (or a rustc configured with the GCC backend as default) when the discovered libgccjit.so fails to dlopen: e.g. built against libstdc++.so.N that is not installed, or built for a different libgccjit soname, or compiled with a conflicting `-Ctarget-cpu`/ABI.","commonSituations":"A rustc_codegen_gcc toolchain installed without its runtime dependency libraries; a system upgrade that removed or bumped libstdc++/libgmp; a manually copied libgccjit.so with a broken DT_NEEDED; cross-target sysroot pointing at the wrong triplet.","solutions":["Run `ldd <sysroot>/.../libgccjet.so` to find the missing transitive dependency and install it.","Reinstall the rustc_codegen_gcc toolchain (or `rustup component add`-equivalent) so the bundled libgccjit and its deps match.","Confirm the file is not corrupt: `file libgccjit.so` and `nm -D libgccjit.so | grep gccjit_create_context`.","If you set `--sysroot`, point it at the toolchain root that actually ships libgccjit.so for your target."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate libgccjit.so is loadable BEFORE invoking the GCC backend\nuse std::path::Path;\n\nfn libgccjit_loadable(sysroot: &str, host_triple: &str, target_triple: &str) -> Result<(), String> {\n    // The backend looks for: sysroot/lib/rustlib/{host}/codegen-backends/lib/{target}/libgccjit.so\n    let candidate = format!(\n        \"{}/lib/rustlib/{}/codegen-backends/lib/{}/libgccjit.so\",\n        sysroot, host_triple, target_triple\n    );\n    if Path::new(&candidate).exists() {\n        // Verify it is actually dlopen-able (not a broken symlink)\n        let probe = std::process::Command::new(\"sh\")\n            .args([\"-c\", &format!(\"ldd '{}' 2>&1\", candidate)])\n            .output()\n            .map_err(|e| format!(\"Cannot run ldd: {}\", e))?;\n        let out = String::from_utf8_lossy(&probe.stdout);\n        if out.contains(\"not found\") {\n            return Err(format!(\"libgccjit.so exists at {} but has unresolved dependencies: {}\", candidate, out));\n        }\n        return Ok(());\n    }\n    // Fall back to system-wide ldconfig lookup\n    let ldc = std::process::Command::new(\"sh\")\n        .args([\"-c\", \"ldconfig -p 2>/dev/null | grep libgccjit\"])\n        .output()\n        .map_err(|e| format!(\"Cannot run ldconfig: {}\", e))?;\n    if ldc.stdout.is_empty() {\n        return Err(\"libgccjit.so not found. Install libgccjit-dev (apt) or gccjit-devel (dnf), or set GCC_BACKEND_PATH.\".into());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"// Catch libgccjit load failure at the build-script / CI level and fall back\nuse std::process::Command;\n\nfn compile_with_gcc_or_fallback(crate_path: &str) -> Result<(), String> {\n    let gcc_result = Command::new(\"rustc\")\n        .args([\"-Z\", \"codegen-backend=gcc\"])\n        .arg(crate_path)\n        .output()\n        .map_err(|e| format!(\"Failed to invoke rustc: {}\", e))?;\n    if !gcc_result.status.success() {\n        let stderr = String::from_utf8_lossy(&gcc_result.stderr);\n        if stderr.contains(\"Cannot load libgccjit\") {\n            eprintln!(\"Warning: GCC backend unavailable, falling back to LLVM\");\n            let llvm_result = Command::new(\"rustc\")\n                .arg(crate_path)\n                .output()\n                .map_err(|e| e.to_string())?;\n            if !llvm_result.status.success() {\n                return Err(String::from_utf8_lossy(&llvm_result.stderr).to_string());\n            }\n        } else {\n            return Err(stderr.to_string());\n        }\n    }\n    Ok(())\n}","preventionTips":["Install the libgccjit development package: apt install libgccjit-dev (Debian/Ubuntu) or dnf install gccjit-devel (Fedora)","Verify with: ldd $(rustc --print sysroot)/lib/rustlib/*/codegen-backends/*/*/libgccjit.so to check for unresolved dependencies","Pin a GCC version compatible with your rustc build — libgccjit ABI changes between major GCC releases","In CI, add a pre-build step that runs: rustc -Z codegen-backend=gcc --version as a smoke test before the real compilation"],"tags":["rustc-codegen-gcc","libgccjit","dlopen","shared-library","toolchain","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}