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); +}