ci(release): add musl static Linux builds (glibc-independent)

The gnu Linux binaries are glibc-floored (2.35 after #74), so they still
won't run on Amazon Linux 2023 / RHEL 9 (glibc 2.34), Alpine, or anything
older. Add fully static musl builds that run on ANY Linux regardless of
glibc.

Adds x86_64-unknown-linux-musl and aarch64-unknown-linux-musl to the build
matrix, built with cargo-zigbuild (zig as the C/C++ cross-compiler for
BoringSSL). Build scripts (bindgen) run as the glibc host so libclang loads,
and the linked output is fully static. A native Alpine build can't do this —
its static build scripts can't dlopen libclang.

musl assets ship ALONGSIDE the gnu ones (gnu stays default; musl is the
runs-anywhere fallback). The release job globs *.tar.gz, so the new assets
are checksummed + uploaded automatically; the docker/homebrew jobs enumerate
gnu targets explicitly and are unaffected.

Validated in Docker: cargo-zigbuild produced a fully static aarch64-musl
webclaw-mcp (ldd: not a dynamic executable) that answered an MCP handshake on
Alpine, Debian 11 (glibc 2.31), Debian 12, Amazon Linux 2023 (2.34), and
Ubuntu 24.04 — everywhere, including where the gnu builds fail.

Closes #73

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Valerio 2026-06-27 13:49:40 +02:00
parent 07c105b5cb
commit 77fe3b52e2

View file

@ -46,6 +46,14 @@ jobs:
os: ubuntu-22.04
- target: aarch64-unknown-linux-gnu
os: ubuntu-22.04
# musl static builds: glibc-independent, run on ANY Linux (Alpine,
# Amazon Linux 2023, RHEL 9, old distros) where the gnu builds can't.
# cargo-zigbuild links statically, so the host glibc is irrelevant —
# ubuntu-latest is fine. See #73.
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
- target: aarch64-unknown-linux-musl
os: ubuntu-latest
- target: x86_64-pc-windows-msvc
os: windows-latest
@ -84,8 +92,30 @@ jobs:
choco install nasm -y
echo "C:\Program Files\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# musl static builds use zig as the C/C++ cross-compiler for BoringSSL,
# driven by cargo-zigbuild. Build scripts (bindgen) still run as the glibc
# host so libclang loads fine; the linked output is fully static and runs
# on any Linux regardless of glibc. (A native Alpine build can't do this —
# its static build scripts can't dlopen libclang.)
- name: Setup zig + cargo-zigbuild (musl)
if: contains(matrix.target, 'musl')
run: |
python3 -m pip install --user --break-system-packages ziglang
mkdir -p "$HOME/.local/bin"
printf '#!/bin/sh\nexec python3 -m ziglang "$@"\n' > "$HOME/.local/bin/zig"
chmod +x "$HOME/.local/bin/zig"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
"$HOME/.local/bin/zig" version
cargo install cargo-zigbuild --locked
- name: Build
run: cargo build --release --target ${{ matrix.target }}
shell: bash
run: |
if [[ "${{ matrix.target }}" == *-musl ]]; then
cargo zigbuild --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi
- name: Package
shell: bash