-flto in a wasm configuration's compileFlags or linkFlags reached the link, where LTO code generation runs without the backend options that keep exception handling: every landing pad was dropped, and the build succeeded with throws that escaped their catch blocks. -fno-exceptions there made every `import std;` fail on the std module built with exceptions, and a wasm shared library failed to link against the eh/ libc++, which is static archives built without -fPIC. Build() refuses all three now, each with a line that says why, before it makes a directory or starts a thread. The sysroot check sat in BuildStdPcm, which the linter calls as well. There the error only dropped the compile command, so lint ran no AST rule on a wasm configuration and reported it clean. It also refused static libraries, which never link, fired after the shader and external threads had started, and called a missing sysroot, or one without the target, "no C++ exception support". It is part of the same early check now, which first says when the sysroot or the target's directory is missing, and asks for libunwind only where something links. C sources got only the signal.h define. setjmp.h refused to compile in C, and a C object given -wasm-enable-sjlj through compileFlags used the legacy exception encoding next to C++ objects in the standard one, a mix engines refuse to load. They get WasmCompileFlags now, like the C++ units, a variant pass's flags included. The baseline probes include simd: V8 and SpiderMonkey switch SIMD off on x86 CPUs without SSE4.1, which virtual machines often present, and such an engine passed the exception-handling probe only to fail compiling the module; the manifest tests expect it on every entry. The Flatpak pins WASI_SDK_EXCEPTIONS=DUAL, which wasi-sdk 34 defaults to only with clang 23 or newer, and checks that the eh/ libunwind got installed: the wasm tests skip without it, so CI would otherwise pass a Flatpak whose every wasm build fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
261 lines
12 KiB
YAML
261 lines
12 KiB
YAML
# SPDX-License-Identifier: LGPL-3.0-only
|
|
# SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
#
|
|
# crafter-build as a Flatpak. The runtime is the Freedesktop *Sdk*, not the
|
|
# Platform: a build tool needs glibc's headers and crt objects, gcc's
|
|
# libgcc_s, cmake, ninja, make, git and python at run time. Everything
|
|
# compiler-shaped is ours and lives under /app: clang, lld, libclang, libc++,
|
|
# compiler-rt (native and wasm32) and the WASI sysroot, all built from one
|
|
# LLVM source tree so the modules crafter-build builds and the compiler that
|
|
# consumes them can never drift apart.
|
|
app-id: net.catcrafts.CrafterBuild
|
|
runtime: org.freedesktop.Sdk
|
|
runtime-version: '26.08'
|
|
sdk: org.freedesktop.Sdk
|
|
command: crafter-build
|
|
finish-args:
|
|
# git dependencies, and the local web server `-r` starts for browser builds
|
|
- --share=network
|
|
- --socket=ssh-auth
|
|
# projects live anywhere; user sysroots too
|
|
- --filesystem=host
|
|
# so `-r` can launch what it built, games included
|
|
- --share=ipc
|
|
- --socket=wayland
|
|
- --socket=fallback-x11
|
|
- --socket=pulseaudio
|
|
- --device=all
|
|
# gdb and friends from the Sdk
|
|
- --allow=devel
|
|
- --env=PATH=/app/bin:/usr/bin
|
|
cleanup:
|
|
- /share/man
|
|
- /share/doc
|
|
modules:
|
|
- name: llvm
|
|
buildsystem: cmake-ninja
|
|
builddir: true
|
|
subdir: llvm
|
|
build-options:
|
|
# flatpak-builder's default CFLAGS carry -g. For all of LLVM that is a
|
|
# 30 GB build tree and a multi-gigabyte .Debug extension, so build
|
|
# without debug info, strip, and skip the split. The hardening flags
|
|
# from the defaults stay.
|
|
no-debuginfo: true
|
|
strip: true
|
|
cflags: -O2 -pipe -fexceptions -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
|
|
cflags-override: true
|
|
cxxflags: -O2 -pipe -fexceptions -fasynchronous-unwind-tables -fstack-protector-strong -fstack-clash-protection -fcf-protection
|
|
cxxflags-override: true
|
|
config-opts:
|
|
- -DCMAKE_BUILD_TYPE=Release
|
|
- -DLLVM_ENABLE_ASSERTIONS=OFF
|
|
- -DLLVM_ENABLE_PROJECTS=clang;lld
|
|
- -DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind
|
|
- -DLLVM_TARGETS_TO_BUILD=X86;AArch64;WebAssembly
|
|
# Classic layout: libc++ in lib/ and include/c++/v1, not under a
|
|
# per-target subdirectory, the same shape as a distro install.
|
|
# crafter-build adds -L and an rpath for <prefix>/lib itself, since
|
|
# clang searches only its per-target directory and the system paths.
|
|
- -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF
|
|
# One shared LLVM and one shared clang library instead of a statically
|
|
# linked copy per tool: a fraction of the install size.
|
|
- -DLLVM_BUILD_LLVM_DYLIB=ON
|
|
- -DLLVM_LINK_LLVM_DYLIB=ON
|
|
- -DCLANG_LINK_CLANG_DYLIB=ON
|
|
- -DCLANG_DEFAULT_CXX_STDLIB=libc++
|
|
- -DCLANG_DEFAULT_LINKER=lld
|
|
- -DLIBCXX_INSTALL_MODULES=ON
|
|
- -DLLVM_INCLUDE_TESTS=OFF
|
|
- -DLLVM_INCLUDE_EXAMPLES=OFF
|
|
- -DLLVM_INCLUDE_DOCS=OFF
|
|
- -DLLVM_INCLUDE_BENCHMARKS=OFF
|
|
- -DLLVM_INSTALL_UTILS=OFF
|
|
- -DCLANG_INCLUDE_TESTS=OFF
|
|
- -DCOMPILER_RT_INCLUDE_TESTS=OFF
|
|
# The Sdk links with binutils' ld; two libLLVM-sized links at a time
|
|
# fit the CX53's memory with room to spare.
|
|
- -DLLVM_PARALLEL_LINK_JOBS=2
|
|
cleanup:
|
|
- /include/llvm
|
|
- /include/llvm-c
|
|
- /include/clang
|
|
- /include/clang-tidy
|
|
- /include/lld
|
|
- /lib/cmake
|
|
- /lib/*.a
|
|
- /share/opt-viewer
|
|
- /share/scan-build
|
|
- /share/scan-view
|
|
- /bin/clang-check
|
|
- /bin/clang-extdef-mapping
|
|
- /bin/clang-import-test
|
|
- /bin/clang-linker-wrapper
|
|
- /bin/clang-nvlink-wrapper
|
|
- /bin/clang-offload-bundler
|
|
- /bin/clang-offload-packager
|
|
- /bin/clang-refactor
|
|
- /bin/clang-rename
|
|
- /bin/clang-repl
|
|
- /bin/clang-sycl-linker
|
|
- /bin/diagtool
|
|
- /bin/git-clang-format
|
|
- /bin/hmaptool
|
|
- /bin/llvm-exegesis
|
|
- /bin/scan-build*
|
|
- /bin/scan-view
|
|
sources:
|
|
- type: archive
|
|
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-23.1.2/llvm-project-23.1.2.src.tar.xz
|
|
sha256: c98bbef08a2b4c2613cd50e9aa9ae7b69b1fe6c16b2c40373bc0ab6116fdf78a
|
|
|
|
- name: wasi-sysroot
|
|
# wasi-sdk's sysroot-only mode, driven by the clang built above:
|
|
# wasi-libc, compiler-rt builtins (installed into our clang's resource
|
|
# dir, where the wasm32 driver looks for them) and libc++ for wasip1 and
|
|
# wasip1-threads. The llvm-project tree is the same release as above so
|
|
# the wasm libc++ matches the native one.
|
|
buildsystem: cmake-ninja
|
|
builddir: true
|
|
build-options:
|
|
no-debuginfo: true
|
|
# flatpak-builder's default CFLAGS/LDFLAGS are x86-64 hardening flags
|
|
# (-fcf-protection, -z relro) that the nested wasm32 builds inherit
|
|
# through the environment and clang rejects for that target.
|
|
cflags: ""
|
|
cflags-override: true
|
|
cxxflags: ""
|
|
cxxflags-override: true
|
|
ldflags: ""
|
|
ldflags-override: true
|
|
strip: true
|
|
config-opts:
|
|
- -DCMAKE_TOOLCHAIN_FILE=/run/build/wasi-sysroot/wasi-host-toolchain.cmake
|
|
- -DWASI_SDK_BUILD_TOOLCHAIN=OFF
|
|
- -DWASI_SDK_INSTALL_TO_CLANG_RESOURCE_DIR=ON
|
|
- -DWASI_SDK_TARGETS=wasm32-wasip1;wasm32-wasip1-threads
|
|
- -DWASI_SDK_INCLUDE_TESTS=OFF
|
|
# crafter-build compiles every wasm unit with C++ exceptions and links
|
|
# the libc++ and libunwind built with them, from lib/<triple>/eh. The
|
|
# default is DUAL only when the driving clang is 23 or newer and OFF
|
|
# below that; said outright, an LLVM downgrade cannot quietly ship a
|
|
# sysroot that no wasm build links against.
|
|
- -DWASI_SDK_EXCEPTIONS=DUAL
|
|
- -DCMAKE_INSTALL_PREFIX=/app
|
|
post-install:
|
|
# wasi-sdk installs into <prefix>/share/wasi-sysroot; crafter-build
|
|
# looks there (Crafter.Build:Toolchain), so nothing to move.
|
|
- test -f /app/share/wasi-sysroot/share/libc++/v1/std.cppm
|
|
# The wasm tests skip when these are missing, as on a distro sysroot,
|
|
# so the Flatpak checks for them itself: without them its CI would
|
|
# pass while every wasm build failed.
|
|
- test -f /app/share/wasi-sysroot/lib/wasm32-wasip1/eh/libunwind.a
|
|
- test -f /app/share/wasi-sysroot/lib/wasm32-wasip1-threads/eh/libunwind.a
|
|
sources:
|
|
- type: git
|
|
url: https://github.com/WebAssembly/wasi-sdk.git
|
|
tag: wasi-sdk-34
|
|
disable-submodules: true
|
|
# The compiler-rt sub-build gets the C target but not the ASM target, so
|
|
# its two wasm/*.S stubs come out as host objects when the driving clang
|
|
# does not default to wasm32. Reported upstream; drop once wasi-sdk has it.
|
|
- type: patch
|
|
path: wasi-sdk-asm-target.patch
|
|
- type: git
|
|
url: https://github.com/WebAssembly/wasi-libc.git
|
|
commit: 2e6fb9d8ee0cdf9e431fbcabe8af3115de000a13
|
|
dest: src/wasi-libc
|
|
# A git checkout, where the llvm module above unpacks the release
|
|
# tarball of the same tag: wasi-sdk treats src/llvm-project as the
|
|
# submodule it is upstream. It patches the tree with `git apply` before
|
|
# building libc++, and records `git rev-parse HEAD` in the sysroot's
|
|
# VERSION file. Unpacked from a tarball the directory is a plain
|
|
# subdirectory of the wasi-sdk checkout, where git treats the patched
|
|
# paths as outside the current directory, skips every one of them and
|
|
# exits 0. LLVM 22 happened to build without the patches; LLVM 23's
|
|
# libc++ does not compile for WASI without one of them.
|
|
- type: git
|
|
url: https://github.com/llvm/llvm-project.git
|
|
tag: llvmorg-23.1.2
|
|
commit: 85ac560262434c9ccfc0c183ec22d4138ed647fb
|
|
dest: src/llvm-project
|
|
- type: file
|
|
path: wasi-host-toolchain.cmake
|
|
|
|
- name: wasmtime
|
|
# The runner for wasm32-wasi tests and `-r` on a non-browser wasm build.
|
|
buildsystem: simple
|
|
build-commands:
|
|
- install -Dm755 wasmtime /app/bin/wasmtime
|
|
sources:
|
|
- type: archive
|
|
url: https://github.com/bytecodealliance/wasmtime/releases/download/v49.0.2/wasmtime-v49.0.2-x86_64-linux.tar.xz
|
|
sha256: a4d6e9e3a5a60f527cf7793d674c48930c80c2e8977995b8a275cad3254b9322
|
|
|
|
- name: libcxx-22-modules
|
|
# The std module source of the libc++ release before the bundled one, for
|
|
# cross sysroots that carry that libc++ without it: Alpine packages the
|
|
# headers and the library but not share/libc++/v1, and a module source
|
|
# only compiles against the headers of its own release. crafter-build
|
|
# picks <major>/std.cppm here by the sysroot's _LIBCPP_VERSION
|
|
# (SysrootStdModule in Crafter.Build:Toolchain). Add a module like this
|
|
# one per release worth supporting; the bundled clang has to be able to
|
|
# compile that release's headers.
|
|
buildsystem: simple
|
|
build-commands:
|
|
# Configure only. The cxx-modules component is std.cppm as configure
|
|
# generates it plus the .inc files straight from the source tree, so
|
|
# nothing is compiled, and libc++'s own install rule stays the one
|
|
# place that knows what a module source install consists of.
|
|
- cmake -S runtimes -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/app/bin/clang -DCMAKE_CXX_COMPILER=/app/bin/clang++ "-DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi" -DLIBCXXABI_USE_LLVM_UNWINDER=OFF -DLIBCXX_INSTALL_MODULES=ON
|
|
# Staged, not installed to /app: the component also writes
|
|
# lib/libc++.modules.json, which would replace the bundled libc++'s.
|
|
- cmake --install build --component cxx-modules --prefix "$PWD/stage"
|
|
- grep -q "_LIBCPP_VERSION 22" libcxx/include/__config
|
|
- mkdir -p /app/share/crafter-build/libc++-modules
|
|
- cp -r stage/share/libc++/v1 /app/share/crafter-build/libc++-modules/22
|
|
sources:
|
|
- type: archive
|
|
url: https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/llvm-project-22.1.8.src.tar.xz
|
|
sha256: 922f1817a0df7b1489272d18134ee0087a8b068828f87ac63b9861b1a9965888
|
|
|
|
- name: crafter-build
|
|
buildsystem: simple
|
|
build-options:
|
|
# The self-host build fetches Crafter.Math, Crafter.Asset,
|
|
# Crafter.LintRules and glslang from git; they are unpinned on purpose
|
|
# (sibling repos tracking their default branch, see AGENTS.md).
|
|
build-args:
|
|
- --share=network
|
|
# On this module, not at the top of the manifest: top-level build
|
|
# options are part of every module's cache key, and the version changes
|
|
# with every commit, which made flatpak-builder rebuild LLVM each run.
|
|
env:
|
|
CRAFTER_BUILD_LLVM_DIR: /app
|
|
# The shipped binary runs on any x86_64 from the last decade; user
|
|
# projects still build with -march=native by default.
|
|
CRAFTER_BUILD_MARCH: x86-64-v2
|
|
CRAFTER_BUILD_MTUNE: generic
|
|
# CI replaces this with the version; a local build is a development
|
|
# build.
|
|
CRAFTER_BUILD_VERSION: 0.0.0-dev
|
|
build-commands:
|
|
# Bootstrap by hand, then let the result build itself: only the
|
|
# self-hosted binary has asset support and ThinLTO.
|
|
- ./build.sh
|
|
- ./bin/crafter-build
|
|
- CRAFTER_BUILD_HOME=$PWD/share/crafter-build ./bin/crafter-build test
|
|
- install -Dm755 bin/crafter.build-exe-*/crafter-build /app/bin/crafter-build
|
|
- install -Dm644 bin/crafter.build-lib-*/libcrafter-build.a /app/lib/libcrafter-build.a
|
|
- mkdir -p /app/share && cp -r share/crafter-build /app/share/
|
|
- install -Dm644 LICENSE LICENSE.GPL -t /app/share/licenses/net.catcrafts.CrafterBuild/
|
|
- install -Dm644 packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml -t /app/share/metainfo/
|
|
sources:
|
|
- type: dir
|
|
path: ../..
|
|
skip:
|
|
- .git
|
|
- bin
|
|
- build
|
|
- lib/libcrafter-build.a
|
|
- share/crafter-build
|