From 77fe3b52e2767d756b4f0069751c8d2aec40b4b5 Mon Sep 17 00:00:00 2001 From: Valerio Date: Sat, 27 Jun 2026 13:49:40 +0200 Subject: [PATCH] ci(release): add musl static Linux builds (glibc-independent) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .github/workflows/release.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b44b5b4..52c6c52 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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