musl host support: bootstrap and run on Alpine (x86_64-alpine-linux-musl)
The Linux host code paths were gated on the x86_64_pc_linux_gnu target define alone, and LoadProject hardcoded --target=x86_64-pc-linux-gnu when compiling project.cpp and the module PCMs. Both break on musl hosts: the glibc release launcher cannot run there at all (no glibc loader; gcompat lacks libgcc_s and the __isoc23_* symbols), and a musl-built launcher would still compile project.cpp for the wrong libc. - The host gates test clang's __linux__ instead of one triple's define: they mean "Linux host", whatever the libc (or, later, the CPU). - LoadProject derives the host triple from HostTarget() (clang's -print-target-triple), which is also more correct on glibc distros whose triple isn't x86_64-pc-linux-gnu. - project.cpp / the cmake libc++ flags treat any *-linux-gnu or *-linux-musl target as Linux. - build.sh targets the host toolchain's triple (CRAFTER_BUILD_TARGET overrides) and derives the per-target define from it. On Arch this is byte-for-byte the previous behaviour. - CI: a release-musl job bootstraps on alpine:edge, runs the tests, and attaches crafter-build-linux-x86_64-musl-v2.tar.gz to the rolling latest release (via the API, so the glibc assets survive). Dynamic against musl libc++: the launcher dlopens project.so, so it cannot be fully static. First consumer: imsd's package CI, which cross-compiles for aarch64 from an Alpine container. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
802caac1c2
commit
dc239f4257
7 changed files with 131 additions and 22 deletions
|
|
@ -186,3 +186,76 @@ jobs:
|
|||
override: true
|
||||
release-dir: dist
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# musl build for Alpine / postmarketOS hosts: the glibc launcher above cannot
|
||||
# run there (musl has no glibc loader and gcompat lacks libgcc_s + the
|
||||
# __isoc23_* symbols). Bootstrap natively on alpine:edge and ship the
|
||||
# bootstrap output — the same thing the Arch PKGBUILD installs. Dynamic
|
||||
# against musl libc++ (crafter-build dlopens project.so, so it cannot be
|
||||
# fully static); consumers need `apk add clang lld libc++-dev llvm-runtimes`.
|
||||
release-musl:
|
||||
needs: build-test-release
|
||||
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
|
||||
runs-on: arch-latest
|
||||
container:
|
||||
image: alpine:edge
|
||||
env:
|
||||
CRAFTER_BUILD_MARCH: x86-64-v2
|
||||
CRAFTER_BUILD_MTUNE: generic
|
||||
steps:
|
||||
- name: Install build dependencies
|
||||
# nodejs: actions/checkout is a Node action. build-base: gcc's
|
||||
# libgcc_s + crt objects, which clang's musl driver links against, plus
|
||||
# make/binutils for the glslang cmake build (python3: its generators).
|
||||
# clang-dev + llvm-dev: the libclang header Crafter.Build-Lint includes
|
||||
# lives under llvm-config --includedir here, not /usr/include. llvm:
|
||||
# llvm-ar for the LTO static archives the self-host/test builds write.
|
||||
run: |
|
||||
apk add -q nodejs git curl jq tar clang clang-dev lld libc++-dev \
|
||||
llvm-libunwind-dev llvm-runtimes llvm llvm-dev cmake build-base python3
|
||||
git config --global --add safe.directory '*'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Bootstrap (build.sh)
|
||||
run: ./build.sh
|
||||
|
||||
- name: Run tests
|
||||
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build test
|
||||
|
||||
- name: Package artifact
|
||||
run: |
|
||||
set -eux
|
||||
file bin/crafter-build || true
|
||||
mkdir -p dist
|
||||
stage=$(mktemp -d)
|
||||
mkdir -p "$stage/bin" "$stage/lib"
|
||||
cp bin/crafter-build "$stage/bin/"
|
||||
cp lib/libcrafter-build.a "$stage/lib/"
|
||||
cp -r share "$stage/"
|
||||
tar czf dist/crafter-build-linux-x86_64-musl-v2.tar.gz -C "$stage" .
|
||||
ls -la dist/
|
||||
|
||||
- name: Upload musl artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with: { name: crafter-build-linux-x86_64-musl-v2, path: dist/crafter-build-linux-x86_64-musl-v2.tar.gz, if-no-files-found: error }
|
||||
|
||||
# Add the asset to the rolling 'latest' release the first job just
|
||||
# (re)published, via the API rather than forgejo-release: that action's
|
||||
# override mode would drop the other job's assets.
|
||||
- name: Attach to rolling 'latest' release
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
run: |
|
||||
set -eu
|
||||
asset=crafter-build-linux-x86_64-musl-v2.tar.gz
|
||||
rel=$(curl -fsS -H "Authorization: token $TOKEN" "$API/releases/tags/latest")
|
||||
id=$(printf '%s' "$rel" | jq -r .id)
|
||||
for old in $(printf '%s' "$rel" | jq -r --arg n "$asset" '.assets[] | select(.name==$n) | .id'); do
|
||||
curl -fsS -X DELETE -H "Authorization: token $TOKEN" "$API/releases/$id/assets/$old"
|
||||
done
|
||||
curl -fsS -H "Authorization: token $TOKEN" -F "attachment=@dist/$asset" \
|
||||
"$API/releases/$id/assets?name=$asset" > /dev/null
|
||||
echo "attached $asset to release $id"
|
||||
|
|
|
|||
Loading…
Reference in a new issue