Crafter.Build/packaging/flatpak/net.catcrafts.CrafterBuild.metainfo.xml

126 lines
17 KiB
XML
Raw Permalink Normal View History

<?xml version="1.0" encoding="UTF-8"?>
<!-- SPDX-License-Identifier: CC0-1.0 -->
<component type="console-application">
<id>net.catcrafts.CrafterBuild</id>
<name>Crafter Build</name>
<summary>C++26 modules build system</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>LGPL-3.0-only</project_license>
<developer id="net.catcrafts">
<name>Catcrafts</name>
</developer>
<description>
<p>
A build system for C++26 modules. Project descriptions are C++: a
project.cpp constructs a Configuration and returns it, and crafter-build
compiles, loads and executes it. The Flatpak carries its own LLVM, so
every machine builds with the same clang, lld, libc++ and WASI sysroot.
</p>
</description>
<url type="homepage">https://forgejo.catcrafts.net/Catcrafts/Crafter.Build</url>
<url type="bugtracker">https://forgejo.catcrafts.net/Catcrafts/Crafter.Build/issues</url>
<url type="vcs-browser">https://forgejo.catcrafts.net/Catcrafts/Crafter.Build</url>
<provides>
<binary>crafter-build</binary>
</provides>
<content_rating type="oars-1.1"/>
<releases>
<release version="6.0.0" date="2026-11-02">
<description>
<p>New</p>
<ul>
<li>The Flatpak carries lldb, with <code>lldb-server</code>, <code>lldb-dap</code> and <code>lldb-mcp</code>, from the same LLVM build as the compiler, so programs that <code>-r</code> and the test runner start can be debugged inside the sandbox they run in. The README's new Debugging section says how, including <code>flatpak enter</code> to reach a program that is already running.</li>
<li>The Flatpak carries the Khronos Vulkan validation layer, the Vulkan SDK release of the runtime's own loader. <code>VK_INSTANCE_LAYERS</code> or <code>VK_LOADER_LAYERS_ENABLE</code> turns it on from the environment, and <code>VK_KHRONOS_VALIDATION_GPUAV_ENABLE=1</code> adds GPU-assisted validation. A layer installed on the host cannot stand in: <code>flatpak run</code> clears <code>VK_LAYER_PATH</code> and <code>VK_ADD_LAYER_PATH</code>.</li>
<li>The Flatpak carries the SPIRV-Tools programs (<code>spirv-val</code>, <code>spirv-opt</code>, <code>spirv-dis</code> and the rest), so a test that requires <code>tool:spirv-val</code> runs inside it instead of being skipped.</li>
<li>The alias in the README's install commands passes <code>--die-with-parent</code>, which ends the sandbox when its <code>flatpak run</code> process dies and, for a command typed at a bash or zsh prompt, when that shell does. Without it, killing <code>flatpak run</code> leaves a build writing into <code>bin/</code> and <code>build/</code> and a program started with <code>-r</code> running. An alias set up from an earlier README does not have it.</li>
</ul>
<p>Fixes</p>
<ul>
<li>The <code>.flatpakref</code> attached to a release carries the repository's signing key. Releases 2.0.0 to 5.0.0 attach one with a placeholder in its place, and installing from it fails with <code>GPG: Unable to export keys</code>; the one on flatpak.catcrafts.net has the key.</li>
</ul>
<p>Breaking</p>
<ul>
<li>Master has no builds of its own any more: the beta branch gets no new builds and the rolling "Latest master build" release is gone, and every change reaches users as a release on the stable branch. Beta's last build is marked end-of-life, and the next <code>flatpak update</code> of a beta installation says so: install stable with <code>flatpak install catcrafts net.catcrafts.CrafterBuild//stable</code> and remove beta with <code>flatpak uninstall net.catcrafts.CrafterBuild//beta</code>.</li>
</ul>
</description>
</release>
<release version="5.0.0" date="2026-10-31">
<description>
<p>Fixes</p>
<ul>
<li>A mingw build no longer sees the Linux system's headers and libraries. Inside the Flatpak the mingw-w64 prefix is the host's /usr, and it was clang's <code>--sysroot</code>, so clang searched /usr/include and /usr/lib for the Windows build as well: libstdc++ found glibc's <code>sys/single_threaded.h</code> and had <code>shared_ptr</code> read <code>__libc_single_threaded</code>, and every program that used one failed to link. <code>CRAFTER_MINGW_DIR=/usr</code> did the same outside the Flatpak. A prefix that also holds a Linux system (the host's /usr, or any prefix whose include/ has a C library's features.h) now reaches clang through a view of its mingw-w64 directories in the cache, and compiler messages still name its headers where they are installed. A prefix that holds mingw-w64 alone is the sysroot as before, so Windows libraries installed into its include/ and lib/ are found (#43).</li>
<li>Units that import a std module rebuilt in place, after a libc++ update or a mingw-w64 update under the same compiler, are compiled again. They used to be relinked unchanged.</li>
<li>A CMake external whose configure inputs changed, such as another compiler or <code>--sysroot</code>, is built again from an empty build directory. It used to be reconfigured in place, keeping the objects and check results of the old configure, so a mingw external built by 4.0.0 would have kept failing to link after the fix above.</li>
<li>Configurations that compile the std module differently no longer share one. Two that differed only in <code>-mtune</code> (a project built with <code>CRAFTER_BUILD_MTUNE</code> set, next to its own project.cpp) or only in sysroot took turns rebuilding it, and every module built against it, on every run.</li>
<li><code>crafter-build lint</code> fails, and says why, when a configuration's compile command cannot be assembled or its std module cannot be built. Its files used to pass every rule that needs an AST as if they were clean.</li>
</ul>
<p>Breaking</p>
<ul>
<li><code>Toolchain::mingwSysroot</code> is now <code>mingwPrefix</code>, beside <code>mingwPrefixIsSystem</code>, because clang no longer always gets the prefix itself. A project.cpp that passes the mingw sysroot to a command of its own calls <code>MingwSysroot()</code>; passing <code>mingwPrefix</code> brings the bug above back for a prefix like /usr.</li>
<li>The std module's cache directory is now keyed on every flag it is compiled with, and every build directory on the std module it imports, so the first build of each project after updating starts in fresh directories and compiles everything, as after a compiler update. <code>crafter-build clean</code> removes the old build directories; the old std module directories stay in the cache until it is cleared by hand.</li>
</ul>
</description>
</release>
<release version="4.0.0" date="2026-10-31">
<description>
<p>New</p>
<ul>
<li>A project keeps its agent instructions in <code>AGENTS.template.md</code>, and <code>crafter-build</code> and <code>crafter-build test</code> write <code>AGENTS.md</code> from it with the dependencies' notes merged in: after the template's text, or between its marker lines. <code>AGENTS.md</code> is build output, so it goes into .gitignore, and a fresh clone has none until its first build. A project with a committed <code>AGENTS.md</code> moves over with <code>git mv AGENTS.md AGENTS.template.md</code> and <code>echo /AGENTS.md &gt;&gt; .gitignore</code>. An <code>AGENTS.md</code> no build wrote, such as a committed one still beside a new template, is never replaced; every build warns until it is deleted.</li>
</ul>
<p>Fixes</p>
<ul>
<li>A build no longer changes a file the project commits. The dependency notes lived in a section of the committed <code>AGENTS.md</code>, so a dependency that edited its notes, an unpinned one that moved on, or a flag that pulled one in showed up in the project's diff as a change nobody made.</li>
</ul>
<p>Breaking</p>
<ul>
<li>Without an <code>AGENTS.template.md</code>, a build leaves <code>AGENTS.md</code> alone. A section 3.0.0 kept in it is no longer updated, and every build warns about it until the file is moved to the template or the section is deleted.</li>
</ul>
</description>
</release>
<release version="3.0.0" date="2026-10-31">
<description>
<p>New</p>
<ul>
<li>C++ exceptions work in WebAssembly builds. Every <code>wasm32-wasip1</code> unit and the std module are compiled with WebAssembly exception handling in its standardized form (exnref), against the exception-enabled libc++ the sysroot ships under <code>lib/&lt;triple&gt;/eh/</code>, and <code>-lunwind</code> and <code>-lsetjmp</code> are linked automatically, so throw and catch, libc++'s own throws, setjmp and longjmp all work. The Flatpak's WASI sysroot is built with those libraries. A page from <code>EnableWasiBrowserRuntime</code> probes for the feature and names what an older browser lacks instead of failing with a CompileError.</li>
<li>Scripts. A project.cpp can push a name and a C++ callback onto <code>cfg.scripts</code>; <code>crafter-build run &lt;name&gt; [args...]</code> runs it with everything after the name handed over untouched, a bare <code>run</code> lists the scripts, and the callback's return value is the exit status. <code>ScriptContext</code> gives it the project, the project directory, the arguments and <code>Run(command)</code>, which runs a shell command with the terminal attached. <code>Crafter::ShellQuote</code> is exported. Only the scripts of the project crafter-build was pointed at can be run, never a dependency's.</li>
<li>Dependency notes for agents. A library ships an <code>AGENTS.consumer.md</code> beside its project.cpp; <code>crafter-build</code> and <code>crafter-build test</code> keep its dependencies' notes in a marked section of a consumer's <code>AGENTS.md</code>, when the consumer has one, and never create the file. <code>cfg.dependencyNotes</code> picks the dependencies: <code>Transitive</code> (the default), <code>Direct</code> or <code>None</code>, which also removes the section.</li>
<li>In a page from <code>EnableWasiBrowserRuntime</code>, <code>exit</code> and <code>_Exit</code> end the program without running any of its code on the way out, no destructor and no <code>catch (...)</code>, with the status in <code>window.crafter_wasi.exitCode</code>. A program that hands the thread to the browser for good and goes on serving calls imports <code>crafter_runtime.park</code> instead, which never returns and leaves main's locals valid for the calls that follow.</li>
<li>The mingw target is found where it is: by the <code>x86_64-w64-mingw32-gcc</code> on PATH, through <code>CRAFTER_MINGW_DIR</code> naming another prefix, and inside the Flatpak through the host's /usr when it has mingw-w64. Its std module comes from the toolchain's own libstdc++.modules.json, and a toolchain that is not there is a build error saying where it looked, not std::terminate.</li>
</ul>
<p>Fixes</p>
<ul>
<li>A program that holds two builds of one module is refused before anything compiles, with both paths and what tells the builds apart. A sibling project that two paths loaded with different arg lists used to be built twice, every consumer took whichever build clang found first, and the program built cleanly and then read garbage or crashed (#41).</li>
<li>An external dependency shared by the configurations of one build is fetched and built once per build pass instead of once per configuration, and each clone's fetch and build hold a file lock. The tests of a project that copies its externalDependencies into each test pulled the same clone side by side and broke its FETCH_HEAD, which failed every test (#34); they now wait for one fetch.</li>
<li>Incremental builds pick up more of what changed. A shader rebuilds when a file it includes or one of its settings (stage, entry point, defines, include directories) changes, not only its own source. An executable relinks when its link command changed, such as a new link flag or a dependency's library that moved to another cache directory, not only when an object is newer.</li>
<li>Submodules are checked out at the revisions the fetched commit records, after every clone, switch, checkout and pull, so a pinned commit builds against its own submodules and not the default branch's.</li>
<li>A project that loads the same sibling as one of its <code>#pragma crafter dependency</code> tools, with the same args, got the tool's copy back: host tooling with -march=native and -fPIC, whose BMI clang then refused. Host tooling and everything it loads are now kept apart in the project cache.</li>
<li><code>crafter-build format clean</code> formats the rules matching "clean"; it used to delete bin/ and build/ and exit 0.</li>
<li><code>--</code> ends crafter-build's options, as the help has advertised: every later word is an operand of the verb. It used to be forwarded as a project arg and change the variant hash, and the words after it were still read as options.</li>
<li><code>ProjectDependency()</code> works from a static initialiser of a project file; it used to find nothing there and terminate the process.</li>
</ul>
<p>Breaking</p>
<ul>
<li>A wasm build needs a sysroot that ships the exception-enabled libc++ and libunwind (wasi-sdk 33 or later; the Flatpak's does), and stops with one line saying so without one. It refuses <code>-fno-exceptions</code>, <code>-flto</code> in compileFlags or linkFlags, and shared libraries, each with a message that says why; there is no switch back to building without exceptions. The result runs on engines with exnref: Chrome 137, Firefox 131, Safari 18.4 and wasmtime 47 or newer (the bundled one qualifies; an older wasmtime needs <code>-W exceptions=y</code>). An exception that escapes main ends the program as an uncaught WebAssembly exception without calling std::terminate, so catch it in main to report it. The flags are part of the variant hash, so the first wasm build after updating starts in a fresh directory.</li>
<li>A sibling loaded through <code>GitProject</code> or <code>LocalProject</code> without <code>.args</code> now receives the args its loading project.cpp was given, so <code>--target=</code>, <code>--march=</code>, <code>--debug</code> and the project's own flags reach every sibling down the chain; releases up to 2.2.0 forwarded nothing. Set <code>.args = {}</code> to keep the old behaviour, and give every sibling the same list: a project that two paths load with different lists now stops the build. The default is read when the spec is made, so make it inside <code>CrafterBuildProject</code>; a spec made at namespace scope forwards nothing. A <code>#pragma crafter dependency</code> still gets none of the project's args.</li>
</ul>
</description>
</release>
<release version="2.2.0" date="2026-10-16">
<description>
<p>A Shader entry can carry defines, spelled like the compiler's -D (NAME is defined to 1, NAME=VALUE to VALUE), and a variant that names its output, so one source compiles into several outputs: ui.comp.glsl with variant sets becomes ui.comp.sets.spv. A configuration in which two entries share an output name is refused with both named, as are a malformed define and a variant with a path separator.</p>
<p>Compiles with a sysroot now use the sysroot's own libc++ headers instead of the bundled toolchain's, which fixes cross builds against a musl sysroot that include a standard header textually and stops glibc sysroot builds from silently compiling against the wrong libc++ release. The project.so stamp hashes every part of the host build, so a changed declaration recompiles it. The vendored json.hpp is gone.</p>
</description>
</release>
<release version="2.1.0" date="2026-10-03">
<description>
<p>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.</p>
<p>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.</p>
</description>
</release>
<release version="2.0.0" date="2026-10-03">
<description>
<p>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.</p>
</description>
</release>
</releases>
</component>