V2: WASI, -r flag, CI pipeline, examples & tests cleanup
WASI / wasm32 target support
- Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32")
- Skip -march/-mtune for wasm (clang rejects them)
- Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj
-D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync)
- .wasm output extension in expectedOutputFor and link command
- EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html +
runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL
set in the templated index.html so a single shim handles any output name
-r run flag in the CLI: build then exec the artifact (host targets only;
rejects libraries; auto .exe/.wasm extension handling)
CI pipeline (.forgejo/workflows/ci.yaml)
- Triggers: PR/push to master + manual dispatch
- Single arch-latest container job: install deps, bootstrap, self-rebuild,
run tests, cross-compile mingw, package both archives, upload artifacts
- Rolling 'latest' release published only on push/dispatch to master
mingw cross-compile from Linux now works end-to-end:
- ExternalDependency cache key includes target so per-target glslang builds
don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends
'd' to lib names and breaks linking); cross-compile cmake flags
(CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...)
- project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic
and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh
link pulls pthread which mingw doesn't link by default)
- mingw compile uses -femulated-tls so std::__once_callable etc reference
the same emutls symbols libstdc++ provides
- mingw link auto-adds -lstdc++exp -lpthread
GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux
+ Windows) now both use it instead of duplicating the resolution.
Examples reorg: hello-world, library, with-module, wasi, tests — each with
its own README. Tests reorg: per-test directory with inner/ fixture, no
shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
|
|
|
name: CI
|
|
|
|
|
|
|
|
|
|
on:
|
|
|
|
|
pull_request:
|
|
|
|
|
branches: [master]
|
|
|
|
|
push:
|
|
|
|
|
branches: [master]
|
|
|
|
|
workflow_dispatch:
|
|
|
|
|
|
|
|
|
|
jobs:
|
|
|
|
|
build-test-release:
|
|
|
|
|
runs-on: arch-latest
|
2026-04-28 23:57:43 +02:00
|
|
|
env:
|
|
|
|
|
# x86-64-v2 = SSE4.2 baseline; runs on the CI SBC (Intel N5105 / Tremont,
|
|
|
|
|
# no AVX) and on essentially every x86_64 CPU since ~2011. v3 is out —
|
|
|
|
|
# it requires AVX2 the SBC doesn't have, so the bootstrap binary
|
|
|
|
|
# wouldn't even run there. mtune=generic keeps codegen balanced across
|
|
|
|
|
# consumer CPUs.
|
|
|
|
|
CRAFTER_BUILD_MARCH: x86-64-v2
|
|
|
|
|
CRAFTER_BUILD_MTUNE: generic
|
V2: WASI, -r flag, CI pipeline, examples & tests cleanup
WASI / wasm32 target support
- Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32")
- Skip -march/-mtune for wasm (clang rejects them)
- Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj
-D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync)
- .wasm output extension in expectedOutputFor and link command
- EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html +
runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL
set in the templated index.html so a single shim handles any output name
-r run flag in the CLI: build then exec the artifact (host targets only;
rejects libraries; auto .exe/.wasm extension handling)
CI pipeline (.forgejo/workflows/ci.yaml)
- Triggers: PR/push to master + manual dispatch
- Single arch-latest container job: install deps, bootstrap, self-rebuild,
run tests, cross-compile mingw, package both archives, upload artifacts
- Rolling 'latest' release published only on push/dispatch to master
mingw cross-compile from Linux now works end-to-end:
- ExternalDependency cache key includes target so per-target glslang builds
don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends
'd' to lib names and breaks linking); cross-compile cmake flags
(CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...)
- project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic
and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh
link pulls pthread which mingw doesn't link by default)
- mingw compile uses -femulated-tls so std::__once_callable etc reference
the same emutls symbols libstdc++ provides
- mingw link auto-adds -lstdc++exp -lpthread
GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux
+ Windows) now both use it instead of duplicating the resolution.
Examples reorg: hello-world, library, with-module, wasi, tests — each with
its own README. Tests reorg: per-test directory with inner/ fixture, no
shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
|
|
|
steps:
|
|
|
|
|
- name: Install build dependencies
|
|
|
|
|
run: |
|
2026-04-28 23:40:27 +02:00
|
|
|
# The slim archlinux:latest image arrives without a populated
|
|
|
|
|
# pacman keyring AND without a local pacman master key, so:
|
|
|
|
|
# 1. --init generates the local signing key (needed when pacman
|
|
|
|
|
# itself rewrites the keyring during package upgrades)
|
|
|
|
|
# 2. --populate archlinux imports the upstream master keys so
|
|
|
|
|
# currently-shipping signatures verify
|
|
|
|
|
# After that we can refresh archlinux-keyring to pick up keys for
|
|
|
|
|
# packagers added after the image's snapshot, then -Syu the rest.
|
|
|
|
|
pacman-key --init
|
|
|
|
|
pacman-key --populate archlinux
|
|
|
|
|
pacman -Sy --noconfirm --needed archlinux-keyring
|
2026-04-28 23:36:51 +02:00
|
|
|
pacman -Syu --noconfirm --needed \
|
V2: WASI, -r flag, CI pipeline, examples & tests cleanup
WASI / wasm32 target support
- Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32")
- Skip -march/-mtune for wasm (clang rejects them)
- Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj
-D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync)
- .wasm output extension in expectedOutputFor and link command
- EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html +
runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL
set in the templated index.html so a single shim handles any output name
-r run flag in the CLI: build then exec the artifact (host targets only;
rejects libraries; auto .exe/.wasm extension handling)
CI pipeline (.forgejo/workflows/ci.yaml)
- Triggers: PR/push to master + manual dispatch
- Single arch-latest container job: install deps, bootstrap, self-rebuild,
run tests, cross-compile mingw, package both archives, upload artifacts
- Rolling 'latest' release published only on push/dispatch to master
mingw cross-compile from Linux now works end-to-end:
- ExternalDependency cache key includes target so per-target glslang builds
don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends
'd' to lib names and breaks linking); cross-compile cmake flags
(CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...)
- project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic
and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh
link pulls pthread which mingw doesn't link by default)
- mingw compile uses -femulated-tls so std::__once_callable etc reference
the same emutls symbols libstdc++ provides
- mingw link auto-adds -lstdc++exp -lpthread
GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux
+ Windows) now both use it instead of duplicating the resolution.
Examples reorg: hello-world, library, with-module, wasi, tests — each with
its own README. Tests reorg: per-test directory with inner/ fixture, no
shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
|
|
|
base-devel git zip tar \
|
|
|
|
|
clang lld libc++ cmake \
|
|
|
|
|
mingw-w64-gcc \
|
|
|
|
|
wasi-libc wasi-libc++ wasi-libc++abi wasi-compiler-rt \
|
|
|
|
|
nodejs
|
|
|
|
|
# The container runs as root and the workspace may be owned by a
|
|
|
|
|
# different uid; tell git not to refuse operations on it.
|
|
|
|
|
git config --global --add safe.directory '*'
|
|
|
|
|
|
|
|
|
|
- name: Checkout
|
|
|
|
|
uses: actions/checkout@v4
|
|
|
|
|
with:
|
|
|
|
|
# Persist the auth token so the 'Update rolling latest tag' step
|
|
|
|
|
# below can push the tag back via the implicit GITHUB_TOKEN.
|
|
|
|
|
persist-credentials: true
|
|
|
|
|
|
|
|
|
|
- name: Cache glslang clone+build
|
|
|
|
|
uses: actions/cache@v4
|
|
|
|
|
with:
|
|
|
|
|
path: |
|
|
|
|
|
~/.cache/crafter.build/external
|
|
|
|
|
key: glslang-${{ runner.os }}-v1
|
|
|
|
|
|
|
|
|
|
- name: Bootstrap (build.sh)
|
|
|
|
|
run: ./build.sh
|
|
|
|
|
|
|
|
|
|
- name: Self-rebuild via crafter-build (Linux)
|
|
|
|
|
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build
|
|
|
|
|
|
|
|
|
|
- name: Run tests
|
|
|
|
|
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build test
|
|
|
|
|
|
|
|
|
|
- name: Cross-compile for Windows (mingw32)
|
|
|
|
|
run: CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build --target=x86_64-w64-mingw32
|
|
|
|
|
|
|
|
|
|
- name: Package artifacts
|
|
|
|
|
run: |
|
|
|
|
|
set -eux
|
|
|
|
|
mkdir -p dist
|
|
|
|
|
|
|
|
|
|
# Linux: bin/, lib/, share/ at archive root
|
|
|
|
|
stage_lin=$(mktemp -d)
|
|
|
|
|
mkdir -p "$stage_lin/bin" "$stage_lin/lib"
|
|
|
|
|
cp bin/crafter-build "$stage_lin/bin/"
|
|
|
|
|
cp lib/libcrafter-build.a "$stage_lin/lib/"
|
|
|
|
|
cp -r share "$stage_lin/"
|
|
|
|
|
tar czf dist/crafter-build-linux-x86_64.tar.gz -C "$stage_lin" .
|
|
|
|
|
|
|
|
|
|
# Windows: bin/ contents (exe + auto-bundled mingw DLLs) and share/
|
|
|
|
|
stage_win=$(mktemp -d)
|
|
|
|
|
mkdir -p "$stage_win/bin"
|
|
|
|
|
cp bin/crafter.build-exe-x86_64-w64-mingw32-native/* "$stage_win/bin/"
|
|
|
|
|
cp -r share "$stage_win/"
|
|
|
|
|
(cd "$stage_win" && zip -r "$GITHUB_WORKSPACE/dist/crafter-build-windows-x86_64.zip" .)
|
|
|
|
|
|
|
|
|
|
ls -la dist/
|
|
|
|
|
|
|
|
|
|
- name: Upload workflow artifacts
|
2026-04-28 23:57:43 +02:00
|
|
|
# v4+ uses a GHES-only upload API Forgejo Actions doesn't implement;
|
|
|
|
|
# v3 stays on the older API that works on Forgejo.
|
|
|
|
|
uses: actions/upload-artifact@v3
|
V2: WASI, -r flag, CI pipeline, examples & tests cleanup
WASI / wasm32 target support
- Auto-detect /usr/share/wasi-sysroot on Linux when target starts_with("wasm32")
- Skip -march/-mtune for wasm (clang rejects them)
- Apply -fno-exceptions -fno-c++-static-destructors -mllvm -wasm-enable-sjlj
-D_WASI_EMULATED_SIGNAL to wasm builds (compile + std PCM, kept in sync)
- .wasm output extension in expectedOutputFor and link command
- EnableWasiBrowserRuntime(cfg): opt-in helper that drops index.html +
runtime.js next to the .wasm; runtime.js reads window.CRAFTER_WASM_URL
set in the templated index.html so a single shim handles any output name
-r run flag in the CLI: build then exec the artifact (host targets only;
rejects libraries; auto .exe/.wasm extension handling)
CI pipeline (.forgejo/workflows/ci.yaml)
- Triggers: PR/push to master + manual dispatch
- Single arch-latest container job: install deps, bootstrap, self-rebuild,
run tests, cross-compile mingw, package both archives, upload artifacts
- Rolling 'latest' release published only on push/dispatch to master
mingw cross-compile from Linux now works end-to-end:
- ExternalDependency cache key includes target so per-target glslang builds
don't collide; CMAKE_BUILD_TYPE=Release pinned (otherwise glslang appends
'd' to lib names and breaks linking); cross-compile cmake flags
(CMAKE_SYSTEM_NAME=Windows, CMAKE_*_COMPILER_TARGET=...)
- project.cpp accepts --target=<triple>; Linux-only -Wl,--export-dynamic
and -ldl are gated; mingw glslang skips the standalone exe (its libgcc_eh
link pulls pthread which mingw doesn't link by default)
- mingw compile uses -femulated-tls so std::__once_callable etc reference
the same emutls symbols libstdc++ provides
- mingw link auto-adds -lstdc++exp -lpthread
GetCrafterBuildHome() exposed from the Platform module; LoadProject (Linux
+ Windows) now both use it instead of duplicating the resolution.
Examples reorg: hello-world, library, with-module, wasi, tests — each with
its own README. Tests reorg: per-test directory with inner/ fixture, no
shared tests/fixtures/ tree. New Wasi test verifies .wasm magic bytes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 23:24:46 +02:00
|
|
|
with:
|
|
|
|
|
name: crafter-build
|
|
|
|
|
path: dist/
|
|
|
|
|
if-no-files-found: error
|
|
|
|
|
|
|
|
|
|
- name: Update rolling 'latest' tag
|
|
|
|
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
|
|
|
|
|
run: |
|
|
|
|
|
git config user.email "ci@catcrafts.net"
|
|
|
|
|
git config user.name "Crafter Build CI"
|
|
|
|
|
git tag -f latest
|
|
|
|
|
git push origin latest --force
|
|
|
|
|
|
|
|
|
|
- name: Publish rolling 'latest' release
|
|
|
|
|
if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
|
|
|
|
|
uses: https://code.forgejo.org/actions/forgejo-release@v2
|
|
|
|
|
with:
|
|
|
|
|
direction: upload
|
|
|
|
|
url: ${{ github.server_url }}
|
|
|
|
|
repo: ${{ github.repository }}
|
|
|
|
|
tag: latest
|
|
|
|
|
title: Latest main build
|
|
|
|
|
prerelease: true
|
|
|
|
|
override: true
|
|
|
|
|
release-dir: dist
|
|
|
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|