diff --git a/AGENTS.md b/AGENTS.md index 574abeb..091807a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -110,7 +110,7 @@ Beyond the rules: - There is no host-platform preprocessor split: the host is Linux. Target differences (mingw, wasm) branch on `cfg.target` strings at runtime, in the library as well as in `project.cpp` and tests. - A build step fails when its command exits nonzero, never because it printed. Use `RunBuildCommand` or `RunCommandChecked`; warnings go to `Progress::Diagnostic`. - Every output path goes through `Configuration::BinDir()`, `BuildDir()` and `PcmDir()`. Hand-rolled `path / "bin" / ...` clobbered variants before; do not add new ones. -- Anything that changes what gets compiled or bundled belongs in `VariantId()`. It already hashes type, debug, sysroot, defines, compile flags, wasm variant flags, uninterpreted project args and the toolchain (`Toolchain::Key()`). +- Anything that changes what gets compiled or bundled belongs in `VariantId()`. It already hashes type, debug, sysroot, defines, compile flags, wasm variant flags and uninterpreted project args. ## Design rules @@ -170,4 +170,4 @@ To release: add a `` to `packaging/flatpak/net.catcrafts.CrafterBuild.m - 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 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//`, one `libcxx--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---*/` rather than predicting the hash. The hash includes the compiler, so after a toolchain update the previous variant's directories stay in `bin/` and `build/` until `clean`, and such a glob matches both. +- `VariantId()` names the output directory, so CI globs `bin/crafter.build-exe---*/` rather than predicting the hash. diff --git a/README.md b/README.md index 07ae901..c195fb2 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ extern "C" Configuration CrafterBuildProject(std::span a } ``` -Run `crafter-build` in that directory; outputs land at `bin/myapp----/myapp` and intermediates at `build/myapp----/`. The hash covers everything that changes what is compiled (build type, defines, flags, sysroot, the compiler itself), so two such builds never share a directory. After a compiler update, a new crafter-build release included, the first build starts a fresh directory and recompiles; `crafter-build clean` removes the ones left behind. Add `-r` to run the produced executable straight after a successful build. +Run `crafter-build` in that directory; outputs land at `bin/myapp--/myapp` and intermediates at `build/myapp--/`. Add `-r` to run the produced executable straight after a successful build. ## Dependencies diff --git a/interfaces/Crafter.Build-Clang.cppm b/interfaces/Crafter.Build-Clang.cppm index 8a306be..1149661 100644 --- a/interfaces/Crafter.Build-Clang.cppm +++ b/interfaces/Crafter.Build-Clang.cppm @@ -7,7 +7,6 @@ import :Shader; import :Interface; import :Implementation; import :External; -import :Toolchain; namespace fs = std::filesystem; export namespace Crafter { @@ -489,21 +488,10 @@ export namespace Crafter { void AddAstLintRule(std::string name, std::function check); // Suffix that uniquely identifies this Configuration's compile state. // target+march+mtune are spelled out for readability; the rest - // (type, debug, sysroot, defines, compileFlags, the toolchain) - // collapse into a short hash so two Configurations sharing a path but - // with different compile state can't clobber each other's outputs. - std::string VariantId() const { return VariantId(GetToolchain()); } - // The variant under an explicit toolchain; VariantId() is this for - // the running one. The compiler is compile state like any flag: a - // PCM can only be read by the clang release that wrote it, and - // staleness is decided by mtimes, which a compiler update does not - // touch. Before the toolchain was hashed, a project built with clang - // 22 kept its PCMs when crafter-build moved to clang 23, and the - // first edit afterwards failed with "module file ... uses an older - // format that is no longer supported" until the project was cleaned. - // Keyed here, an update starts an empty directory and rebuilds; the - // old one stays until `crafter-build clean`. - std::string VariantId(const Toolchain& toolchain) const { + // (type, debug, sysroot, defines, compileFlags) collapse into a short + // hash so two Configurations sharing a path but with different + // compile state can't clobber each other's outputs. + std::string VariantId() const { std::string compileKey; compileKey += std::to_string(static_cast(type)); compileKey += '|'; @@ -533,8 +521,6 @@ export namespace Crafter { compileKey += "|A:"; compileKey += a; } - compileKey += "|T:"; - compileKey += toolchain.Key(); std::size_t configHash = std::hash{}(compileKey); return std::format("{}-{}-{}-{}-{:08x}", name, target, march, mtune, configHash); } diff --git a/packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml b/packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml index e63ee54..afe8428 100644 --- a/packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml +++ b/packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml @@ -25,12 +25,6 @@ - - -

The bundled toolchain is now LLVM 23.1.2. Build outputs are kept per compiler, so the first build after updating recompiles each project into a fresh directory and nothing has to be cleaned by hand.

-

Cross builds pick the std module source that matches the sysroot's libc++ release. The source for libc++ 22 ships beside the bundled 23 for sysroots that carry libc++ without one, such as Alpine, and a sysroot nothing matches fails with one line naming both releases. crafter-build --version prints the libc++ release in use.

-
-

First release distributed as a Flatpak, with a bundled LLVM 22 toolchain and WASI sysroot. Windows host support is removed; crafter-build gains --version and resolves its compiler from one place.

diff --git a/tests/VariantId/main.cpp b/tests/VariantId/main.cpp index e4d2a36..022b0d6 100644 --- a/tests/VariantId/main.cpp +++ b/tests/VariantId/main.cpp @@ -133,33 +133,6 @@ int main() { Check(a.BuildDir() != b.BuildDir(), "different VariantId yields different BuildDir"); Check(a.BinDir() != b.BinDir(), "different VariantId yields different BinDir"); } - { - // The compiler is compile state as much as any flag: a PCM can only - // be read by the clang release that wrote it, and nothing in a - // project's sources changes when the compiler does. With the - // toolchain left out of the id, a project built with clang 22 kept - // its PCMs after crafter-build moved to clang 23; the build after - // the update found nothing stale, and the first edit failed with - // "module file ... uses an older format that is no longer supported" - // until the project was cleaned by hand. - Configuration cfg = MakeBase(); - Toolchain older; - older.clangxx = "/app/bin/clang++"; - older.clangVersion = "clang version 22.1.8"; - Toolchain newer = older; - newer.clangVersion = "clang version 23.1.2"; - Check(cfg.VariantId(older) != cfg.VariantId(newer), "a compiler update at the same path perturbs VariantId"); - Check(cfg.VariantId(older) == cfg.VariantId(older), "VariantId under one toolchain is deterministic"); - - // Two installs of one release are still two toolchains: their - // libc++ need not be the same build. - Toolchain elsewhere = older; - elsewhere.clangxx = "/usr/bin/clang++"; - Check(cfg.VariantId(older) != cfg.VariantId(elsewhere), "the same release installed elsewhere perturbs VariantId"); - - Check(cfg.VariantId() == cfg.VariantId(GetToolchain()), "VariantId() is the variant under the running toolchain"); - Check(cfg.BuildDir().filename() == cfg.VariantId(GetToolchain()), "BuildDir is named for the running toolchain's variant"); - } if (Failures > 0) { std::println(std::cerr, "{} assertions failed", Failures);