docs: describe how a sysroot build finds its std module source
All checks were successful
Flatpak / flatpak (push) Successful in 1h30m57s
All checks were successful
Flatpak / flatpak (push) Successful in 1h30m57s
The README said a cross build precompiles the sysroot's own std.cppm, which was never the whole story for sysroots that do not ship one. It now states the order (the sysroot's, the toolchain's for the same major release, the sources crafter-build carries for other releases), what the failure looks like when nothing matches and how to resolve it, and lists the new directory in the install layout. AGENTS.md records the rule for the next LLVM bump: the release the bundled toolchain leaves behind stays available as a module-source module, because stable distros remain on it long after. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
4159ee4117
commit
4e5d17b9e9
2 changed files with 5 additions and 2 deletions
|
|
@ -21,7 +21,7 @@ crafter-build is a C++26 modules build system. A project is described by a `proj
|
||||||
|
|
||||||
Partitions and what they own:
|
Partitions and what they own:
|
||||||
|
|
||||||
- `:Toolchain` resolves the compiler once per process (`GetToolchain`): clang++, clang, llvm-ar, libclang, libc++'s std module source and the default sysroots, from `CRAFTER_BUILD_LLVM_DIR`, else a toolchain installed beside crafter-build, else PATH. It also holds the version baked in at build time.
|
- `:Toolchain` resolves the compiler once per process (`GetToolchain`): clang++, clang, llvm-ar, libclang, libc++'s std module source and the default sysroots, from `CRAFTER_BUILD_LLVM_DIR`, else a toolchain installed beside crafter-build, else PATH. It also holds the version baked in at build time. `SysrootStdModule` picks the std module source for a sysroot build by the sysroot's libc++ release.
|
||||||
- `:Clang` holds `Configuration`, `Build()`, `VariantId()`, `ApplyStandardArgs`, `HostTarget`, the CLI entry point `Crafter::Run`, and the lint and test data types.
|
- `:Clang` holds `Configuration`, `Build()`, `VariantId()`, `ApplyStandardArgs`, `HostTarget`, the CLI entry point `Crafter::Run`, and the lint and test data types.
|
||||||
- `:Platform` runs commands, implements `LoadProject` (compile and load `project.cpp`), the host PCM cache, `#pragma crafter dependency`, and all OS-specific code.
|
- `:Platform` runs commands, implements `LoadProject` (compile and load `project.cpp`), the host PCM cache, `#pragma crafter dependency`, and all OS-specific code.
|
||||||
- `:Interface` and `:Implementation` model module units, their staleness checks and their compiles.
|
- `:Interface` and `:Implementation` model module units, their staleness checks and their compiles.
|
||||||
|
|
@ -169,4 +169,5 @@ To release: add a `<release>` to `packaging/flatpak/net.catcrafts.CrafterBuild.m
|
||||||
- `crafter-build clean` leaves a pragma dependency's build alone; it lives with the clone in the cache.
|
- `crafter-build clean` leaves a pragma dependency's build alone; it lives with the clone in the cache.
|
||||||
- The bootstrap binary is compiled without `CRAFTER_BUILD_HAS_ASSET`, so `cfg.assets` only works in the self-hosted binary. Changing asset extensions means updating two maps in `Crafter.Build-Clang.cpp`: `assetOutput` and the transitive copy loop.
|
- The bootstrap binary is compiled without `CRAFTER_BUILD_HAS_ASSET`, so `cfg.assets` only works in the self-hosted binary. Changing asset extensions means updating two maps in `Crafter.Build-Clang.cpp`: `assetOutput` and the transitive copy loop.
|
||||||
- A warning is printed only when its unit actually recompiles. A build with nothing to do is silent, which is not evidence that a warning is gone.
|
- A warning is printed only when its unit actually recompiles. A build with nothing to do is silent, which is not evidence that a warning is gone.
|
||||||
|
- A std module source only compiles against the headers of its own libc++ release, and a sysroot does not always ship one (Alpine). The Flatpak therefore carries the sources of the release next to the bundled one under `share/crafter-build/libc++-modules/<major>/`, one `libcxx-<major>-modules` manifest module each. When the bundled LLVM is bumped, keep the release it leaves behind as such a module: sysroots on the stable distro stay on it for months. The native loop has no such directory; stage one by hand under `share/crafter-build/` to test against a foreign sysroot.
|
||||||
- `VariantId()` names the output directory, so CI globs `bin/crafter.build-exe-<target>-<march>-*/` rather than predicting the hash.
|
- `VariantId()` names the output directory, so CI globs `bin/crafter.build-exe-<target>-<march>-*/` rather than predicting the hash.
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,8 @@ Inside the Flatpak:
|
||||||
/app/bin/clang++ lld llvm-ar wasmtime # the bundled toolchain the executable resolves first
|
/app/bin/clang++ lld llvm-ar wasmtime # the bundled toolchain the executable resolves first
|
||||||
/app/lib/libcrafter-build.a # static archive for downstream consumers
|
/app/lib/libcrafter-build.a # static archive for downstream consumers
|
||||||
/app/share/crafter-build/*.cppm # module sources (rebuilt on the user's machine on first run)
|
/app/share/crafter-build/*.cppm # module sources (rebuilt on the user's machine on first run)
|
||||||
|
/app/share/crafter-build/libc++-modules/<major>/
|
||||||
|
# std module sources of other libc++ releases, for sysroots without their own
|
||||||
/app/share/wasi-sysroot/ # WASI sysroot for wasm32 targets
|
/app/share/wasi-sysroot/ # WASI sysroot for wasm32 targets
|
||||||
~/.var/app/net.catcrafts.CrafterBuild/cache/crafter.build/<target>-<march>-<clang>-<hash>/
|
~/.var/app/net.catcrafts.CrafterBuild/cache/crafter.build/<target>-<march>-<clang>-<hash>/
|
||||||
# std.pcm + Crafter.Build*.pcm, built locally per toolchain
|
# std.pcm + Crafter.Build*.pcm, built locally per toolchain
|
||||||
|
|
@ -174,7 +176,7 @@ TestRunner::Cmd("wine") // local exec via prefix co
|
||||||
|
|
||||||
For elaborate setups (rsync, ssh ControlMaster, env vars on the spawn, `QEMU_LD_PREFIX` for sysroots), construct `TestRunner` directly — `copy`/`exec`/`cleanup`/`probe` are public string fields with `{bundle}`, `{remote_bundle}`, `{bin}`, `{bin_name}`, `{args}` placeholders.
|
For elaborate setups (rsync, ssh ControlMaster, env vars on the spawn, `QEMU_LD_PREFIX` for sysroots), construct `TestRunner` directly — `copy`/`exec`/`cleanup`/`probe` are public string fields with `{bundle}`, `{remote_bundle}`, `{bin}`, `{bin_name}`, `{args}` placeholders.
|
||||||
|
|
||||||
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 `<sysroot>/usr/share/libc++/v1/std.cppm` is precompiled instead of the host's. 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 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. 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. 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. 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.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue