From 0c1c1acb7cadba929809faea57d114ebebde60e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 5 Jul 2026 20:17:49 +0000 Subject: [PATCH] Fix Moonshine Linux release link error on older glibc The release build failed to link on the ubuntu-22.04 runners (glibc 2.35): rust-lld: error: undefined symbol: __isoc23_strtol / __isoc23_strtoll / __isoc23_strtoull >>> ... in archive libort_sys (onnxruntime static lib) The prebuilt ONNX Runtime static library (pyke, via ort's download-binaries) is compiled against glibc >= 2.38, which redirects strtol/strtoul/... to __isoc23_* symbols that don't exist on glibc 2.35, so the static link fails. Add a tiny C shim (compiled by build.rs for the moonshine feature on Linux) that provides the __isoc23_* symbols by forwarding to the classic libc functions. This keeps the binary linkable and runnable on older glibc, preserving the AppImage's low glibc floor rather than raising it by building on ubuntu-24.04. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GpXWVxBBJvtRgkdMWasSH6 --- Cargo.lock | 1 + crates/voxctrl-inference/Cargo.toml | 6 +++ crates/voxctrl-inference/build.rs | 20 +++++++++ crates/voxctrl-inference/src/isoc23_compat.c | 45 ++++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 crates/voxctrl-inference/build.rs create mode 100644 crates/voxctrl-inference/src/isoc23_compat.c diff --git a/Cargo.lock b/Cargo.lock index 86d19df..13029f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9476,6 +9476,7 @@ name = "voxctrl-inference" version = "0.3.0" dependencies = [ "anyhow", + "cc", "crossbeam-channel", "dirs 5.0.1", "ort", diff --git a/crates/voxctrl-inference/Cargo.toml b/crates/voxctrl-inference/Cargo.toml index 7cd7c9b..9e51a62 100644 --- a/crates/voxctrl-inference/Cargo.toml +++ b/crates/voxctrl-inference/Cargo.toml @@ -22,6 +22,12 @@ whisper-rs = { version = "0.16" } [dev-dependencies] tempfile = { workspace = true } +# Used by build.rs to compile the glibc __isoc23_* shim for the Moonshine +# backend on Linux. `cc` is already in the build graph (whisper-rs-sys), so this +# adds nothing to compile. +[build-dependencies] +cc = "1" + [features] default = [] cuda = ["whisper-rs/cuda"] diff --git a/crates/voxctrl-inference/build.rs b/crates/voxctrl-inference/build.rs new file mode 100644 index 0000000..5605f47 --- /dev/null +++ b/crates/voxctrl-inference/build.rs @@ -0,0 +1,20 @@ +fn main() { + // The Moonshine backend statically links a prebuilt ONNX Runtime (via + // `ort` + `download-binaries`) that is built against glibc >= 2.38 and so + // references __isoc23_strtol/strtoll/... symbols. Linking that archive on an + // older-glibc host (our ubuntu-22.04 release runners ship glibc 2.35) fails + // with "undefined symbol". Compile and link a tiny shim that provides those + // symbols by forwarding to the classic libc functions, keeping the binary + // linkable and runnable on older glibc. Linux + `moonshine` feature only. + let moonshine = std::env::var_os("CARGO_FEATURE_MOONSHINE").is_some(); + let linux = std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("linux"); + + println!("cargo:rerun-if-changed=src/isoc23_compat.c"); + println!("cargo:rerun-if-changed=build.rs"); + + if moonshine && linux { + cc::Build::new() + .file("src/isoc23_compat.c") + .compile("voxctrl_isoc23_compat"); + } +} diff --git a/crates/voxctrl-inference/src/isoc23_compat.c b/crates/voxctrl-inference/src/isoc23_compat.c new file mode 100644 index 0000000..1b092f1 --- /dev/null +++ b/crates/voxctrl-inference/src/isoc23_compat.c @@ -0,0 +1,45 @@ +/* + * glibc __isoc23_* compatibility shims for the Moonshine backend. + * + * The prebuilt ONNX Runtime static library (pyke, pulled in by `ort` with + * `download-binaries`) is compiled against glibc >= 2.38. Under C23, glibc + * redirects strtol/strtoul/... to __isoc23_* symbols, so the static archive + * references e.g. __isoc23_strtol. Our release runners are ubuntu-22.04 + * (glibc 2.35), which has no such symbols, and the static link fails with + * "undefined symbol: __isoc23_strtol". + * + * These forwarders provide the symbols by calling the classic libc functions, + * so the binary links and runs on older glibc while keeping the AppImage's low + * glibc floor. The only C23 difference is that base 0 also accepts a "0b" + * binary prefix; ONNX Runtime's integer config parsing does not depend on that, + * so forwarding to the classic functions is safe. + * + * Compiled and linked only for the `moonshine` feature on Linux (see build.rs). + */ + +#include +#include + +long __isoc23_strtol(const char *nptr, char **endptr, int base) { + return strtol(nptr, endptr, base); +} + +long long __isoc23_strtoll(const char *nptr, char **endptr, int base) { + return strtoll(nptr, endptr, base); +} + +unsigned long __isoc23_strtoul(const char *nptr, char **endptr, int base) { + return strtoul(nptr, endptr, base); +} + +unsigned long long __isoc23_strtoull(const char *nptr, char **endptr, int base) { + return strtoull(nptr, endptr, base); +} + +intmax_t __isoc23_strtoimax(const char *nptr, char **endptr, int base) { + return strtoimax(nptr, endptr, base); +} + +uintmax_t __isoc23_strtoumax(const char *nptr, char **endptr, int base) { + return strtoumax(nptr, endptr, base); +}