docs: which mingw prefixes are viewed, and what keys the std module
All checks were successful
Flatpak / flatpak (pull_request) Successful in 7m28s

The README said every prefix reached clang as a view of its
x86_64-w64-mingw32/ and lib/gcc/, in ~/.cache. It now says a prefix is
the sysroot as it is unless it also holds a Linux system, names
lib64/gcc/ as well, gives the view's place inside the Flatpak and the
XDG_RUNTIME_DIR fallback, and says messages name headers by their path
in the prefix.

AGENTS.template.md describes MingwSysroot's two outcomes and
MingwViewToPrefix, has the std PCM keyed on its flags in the cache
rule, lists StdPcmKey among what VariantId hashes, and gains two
gotchas: anything that changes how the std module is compiled goes into
StdPcmFlags, and a CMake external whose recorded configure inputs
differ is built again from an empty directory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-31 22:59:47 +01:00
commit c56d98abba
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
2 changed files with 6 additions and 4 deletions

View file

@ -201,7 +201,7 @@ For elaborate setups (rsync, ssh ControlMaster, env vars on the spawn, `QEMU_LD_
For cross-arch builds, set `cfg.sysroot` on the `Configuration` to point at a sysroot for the target. `BuildStdPcm` and the compile/link commands both consume it: `--sysroot=<path>` is passed to clang, and the std module is precompiled against the sysroot's libc++ headers. Ordinary compiles are pointed at the same headers (`-nostdinc++ -isystem <sysroot>/usr/include/c++/v1`), so a unit that `#include`s a standard header gets the sysroot's libc++ and not the host toolchain's. The module source has to come from the same libc++ release as those headers, so it is taken from `<sysroot>/usr/share/libc++/v1/std.cppm` when the sysroot ships it, else from the toolchain when both are the same major release, else from the sources crafter-build carries for other releases (`share/crafter-build/libc++-modules/<major>/`, `crafter-build --version` lists them). Alpine is the common case for the last two: its `libc++-dev` has the headers and no module source. When nothing matches, the build stops with one line naming both releases, installing that release's `share/libc++/v1` directory into the sysroot resolves it. The cheapest aarch64 sysroot is an extracted [Arch Linux ARM rootfs](http://os.archlinuxarm.org/) plus `libc++` + `libc++abi` + `gcc` installed into it via `pacman --root <rootfs> --config <alarm-pacman.conf> --dbpath <rootfs>/var/lib/pacman -Sy …` (point pacman at ALARM's mirrors via explicit config to avoid pulling host-arch packages).
For `--target=x86_64-w64-mingw32` (Windows from Linux), the pipeline cross-compiles as long as `mingw-w64` is installed, with libstdc++ 15 or newer for its std module. clang finds it by the `x86_64-w64-mingw32-gcc` on `PATH`; `CRAFTER_MINGW_DIR` names another prefix (the directory holding `x86_64-w64-mingw32/` and `lib/gcc/`), and inside the Flatpak the host's `/usr` is used when it has mingw-w64. Without one the build stops with a message saying where it looked. clang is shown only the prefix's `x86_64-w64-mingw32/` and `lib/gcc/`, as links in `~/.cache/crafter.build/mingw-sysroot/`: it searches the `include/` and `lib/` of whatever it gets as the sysroot, and those of a prefix like `/usr` are the Linux system's own, glibc's headers among them. Pair it with `--runner=cmd:wine` to run the result. Only the MinGW ABI is supported, there is no MSVC target and no Windows host. `-fuse-ld=lld` is auto-injected on every link, and `-lstdc++exp` is auto-linked for the mingw target so user projects don't need to declare those flags.
For `--target=x86_64-w64-mingw32` (Windows from Linux), the pipeline cross-compiles as long as `mingw-w64` is installed, with libstdc++ 15 or newer for its std module. clang finds it by the `x86_64-w64-mingw32-gcc` on `PATH`; `CRAFTER_MINGW_DIR` names another prefix (the directory holding `x86_64-w64-mingw32/` and `lib/gcc/`), and inside the Flatpak the host's `/usr` is used when it has mingw-w64. Without one the build stops with a message saying where it looked. The prefix is clang's sysroot as it is, so Windows libraries installed into its `include/` and `lib/` are found, unless it also holds a Linux system: the host's `/usr` in the Flatpak, or any prefix whose `include/` has a C library's `features.h`, as `/usr` does. clang searches a sysroot's `include/` and `lib/`, and in such a prefix those hold glibc's headers and Linux libraries, so clang is shown only its `x86_64-w64-mingw32/`, `lib/gcc/` and `lib64/gcc/`, as links in `mingw-sysroot/` in the cache (`~/.cache/crafter.build/`, in the Flatpak `~/.var/app/net.catcrafts.CrafterBuild/cache/crafter.build/`, or `$XDG_RUNTIME_DIR/crafter.build/` when the cache's filesystem takes no symbolic links). Compiler messages still name those headers by their paths in the prefix. Pair it with `--runner=cmd:wine` to run the result. Only the MinGW ABI is supported, there is no MSVC target and no Windows host. `-fuse-ld=lld` is auto-injected on every link, and `-lstdc++exp` is auto-linked for the mingw target so user projects don't need to declare those flags.
For `--target=wasm32-wasip1`, the WASI sysroot is the one beside the toolchain (the Flatpak bundles one) unless `CRAFTER_BUILD_WASI_SYSROOT` names another, and tests run under `wasmtime`. C++ exceptions work as on the other targets: every unit and the std module are compiled with `-fwasm-exceptions` in the standardized form of WebAssembly exception handling (exnref), against the exception-enabled libc++ in the sysroot's `lib/<triple>/eh/`, and `-lunwind` is linked automatically. A sysroot without that libc++ (wasi-sdk before 33) stops the build with one line saying so. The result runs on engines with that proposal: Chrome 137, Firefox 131 and Safari 18.4 or newer, and the wasmtime the Flatpak bundles. A page from `EnableWasiBrowserRuntime` checks first and names what an older browser lacks in the console, instead of failing to compile the module. An exception that escapes `main` leaves the program as an uncaught WebAssembly exception (wasmtime reports `thrown Wasm exception` and exits 1, a page gets a `WebAssembly.Exception`) without calling `std::terminate`, so a `std::set_terminate` handler does not run and nothing prints the exception's type or `what()`: wasm exception handling unwinds in a single phase, and nothing finds out that no handler is left until the stack is gone. Catch it in `main` to report it.