Skip to content

build(linux): default ggml CPU features to a portable build - #2

Open
luislobo wants to merge 1 commit into
Nikish-codes:linuxfrom
luislobo:linux-portable-ggml-flags
Open

build(linux): default ggml CPU features to a portable build#2
luislobo wants to merge 1 commit into
Nikish-codes:linuxfrom
luislobo:linux-portable-ggml-flags

Conversation

@luislobo

@luislobo luislobo commented Sep 1, 2026

Copy link
Copy Markdown

Hi @Nikish-codes — offering this to andrewyng#470 rather than competing with it.

I had a parallel Linux packaging PR upstream (andrewyng#551). Having gone through yours properly, andrewyng#470 is the better base — your resource_dir() sidecar resolution is correct where mine wasn't, and your deps script is distro-aware where mine hard-exits on anything without apt-get. I'm closing mine and bringing over the one piece of it that yours doesn't already have.

What this adds

build_linux.sh currently lets ggml tune whisper.cpp for the build host. For a distributable bundle that's wrong twice over: a host-tuned artifact can SIGILL on an older user CPU, and ggml's feature probe trusts each CPU flag independently.

The second failure mode isn't theoretical. On a clean Ubuntu 24.04 VM that advertised avx2 but not fma, ggml enabled its AVX2 path anyway and the build died outright:

error: inlining failed in call to 'always_inline' '_mm256_fmadd_ps': target specific option mismatch

This patch defaults the GGML_* features OFF so the shipped binary runs anywhere, and leaves every flag overridable from the environment for anyone who wants a host-optimised local build.

I think this matters most for the CI job andrewyng#470 adds — a runner whose CPU flags differ from the target host would otherwise emit artifacts that fail on user machines, or fail to build at all. That's a hard class of bug to diagnose from a CI log.

Verification

Built today on Ubuntu (rustc 1.93.1, node 22.21.1, Python 3.10.12): packaging/build_linux.sh appimage completed and produced a 146 MB OpenWorker_0.2.1_amd64.AppImage. The GGML defaults did not interfere with the AppImage bundling path.

One caveat I'd rather state than have you discover: I have not yet run this against your CI workflow, and I have not tested the .deb or rpm targets with these flags set. If you'd prefer this shaped differently — a single GGML_PORTABLE=1 toggle, or scoped only to the CI invocation rather than every local build — I'm happy to rework it.

Also worth a look if you haven't seen them: andrewyng#19 (@rmanicardi) un-gates voice input via a runtime cpal probe and replaces the Linux keep-awake no-op with systemd-inhibit, and @marbetschar's Fedora 44 report is in your #1. Between andrewyng#470, andrewyng#19 and that testing there's a fairly complete Linux story, which is roughly the argument I'm about to make on andrewyng#171.

whisper.cpp (via whisper-rs-sys) compiles its CPU backend during `tauri build`,
and ggml tunes for the build host by default. For a distributable bundle that is
wrong twice over: a host-tuned artifact can SIGILL on an older user CPU, and the
feature probe trusts each flag independently.

The second one is not theoretical. A clean Ubuntu 24.04 VM advertised `avx2` but
not `fma`; ggml enabled its AVX2 path regardless and the build failed on an FMA
intrinsic:

    error: inlining failed in call to 'always_inline' '_mm256_fmadd_ps':
    target specific option mismatch

Default the GGML_* feature flags OFF so the shipped binary runs anywhere, while
leaving every one of them overridable from the environment for builders who want
a host-optimised local package.

This matters most for the CI job this PR adds: a runner whose CPU flags differ
from the target host would otherwise produce artifacts that fail on user
machines, or fail to build at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@luislobo

luislobo commented Sep 1, 2026

Copy link
Copy Markdown
Author

One incidental thing I hit while testing this branch, unrelated to the patch itself: linux is behind main and predates andrewyng#416, so coworker/config.py here still has the bare import tomllib. On a machine where python3 is 3.10 — which setup_dev_env.sh will happily build a venv from — the server then dies at import with ModuleNotFoundError: No module named 'tomllib'. main now has the tomli fallback, so a rebase picks it up for free.

Only mentioning it because it presents as "the sidecar won't start", which is easy to misread as a packaging bug when you're testing packaging.

Separately, while running the AppImage from andrewyng#551 I confirmed the failure mode your resource_dir() approach avoids: the artifact exec'd .../src-tauri/../../../.venv/bin/openworker-server, i.e. the CARGO_MANIFEST_DIR path baked in at compile time, pointing into my own home directory. Details are on andrewyng#171. Worth knowing that it's invisible on the build machine — that path exists there, so the AppImage looks fine locally and only fails elsewhere. Might be worth having someone who didn't build it test your artifacts before this lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant