test(win32): drop the __libc_single_threaded stand-in, which crafter-build 5.0.0 made unneeded

Tests
- Win32Link linked under the Flatpak only with a C file defining
  __libc_single_threaded. crafter-build gave clang the host's /usr as
  the MinGW sysroot, which put glibc's headers on the include path, and
  libstdc++'s shared_ptr, inlined from nlohmann/json in Crafter.Asset's
  GLB loader, then read the symbol. crafter-build 5.0.0 shows clang only
  the mingw-w64 parts of /usr (Catcrafts/Crafter.Build#43), so nothing
  references it any more. Under 5.0.0 Win32Link links without it, and so
  does examples/HelloUI, which no stand-in covered. The native
  crafter-build on the host, which never had the problem, still builds
  PointerWin32, TextWin32 and Win32Link and runs them under Wine.

Docs
- AGENTS.template.md and AGENTS.consumer.md: linking for Win32 under the
  Flatpak needs crafter-build 5.0.0, and the workaround is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-11-01 00:37:41 +01:00
commit 8c9a588083
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
4 changed files with 4 additions and 18 deletions

View file

@ -6,7 +6,7 @@ The Crafter engine's graphics library: a C++ module, `import Crafter.Graphics;`,
- The library's `project.cpp` needs crafter-build 3.0.0 or later; older ones fail to compile it, for every target.
- The target picks the backend, in the library and in your code. Any `wasm32-*` target builds the DOM + WebGPU library; everything else builds Vulkan, with Wayland on Linux (there is no X11 backend) or Win32 on `x86_64-w64-mingw32`. The library defines `CRAFTER_GRAPHICS_WINDOW_WAYLAND`, `_WIN32` or `_DOM` for its own units only, so a wasm consumer sets `cfg.target = "wasm32-wasip1"`, `cfg.defines.push_back({"CRAFTER_GRAPHICS_WINDOW_DOM", ""})`, `cfg.compileFlags.push_back("-msimd128")` (the dependency PCMs were compiled with it) and `EnableWasiBrowserRuntime(cfg)`, as `examples/HelloUI/project.cpp` does. Portable code `#ifdef CRAFTER_GRAPHICS_WINDOW_DOM`s at the few sites where the backends differ; the library has no shared signatures that are no-ops on one side.
- The library's link flags (the Vulkan loader, `wayland-client`, `xkbcommon`, `udev`, or the Win32 libraries) come with the dependency. On `x86_64-w64-mingw32` that includes an import library for `vulkan-1.dll`, so linking for Win32 needs no Vulkan SDK. The library makes it at configure time with the `llvm-dlltool` beside crafter-build's `llvm-ar`, from the loader's own export list (Vulkan-Loader's `loader/vulkan-1.def`, fetched unpinned). Under the Flatpak a Win32 executable still fails to link on `__libc_single_threaded` (Crafter.Build #43). Until that is fixed, add a C file defining `char __libc_single_threaded = 0;` to the executable, as the library's `Win32Link` test does. Its shaders (`ui-*.comp.spv` and `ui-*.comp.sets.spv`) and, for wasm, `dom-env.js` and `dom-webgpu.js` are copied into your executable's bin directory, as are your `cfg.shaders` outputs (`<name>.spv` from `<name>.glsl`) and `cfg.files`. Paths are resolved against the working directory at runtime, so run from the bin directory, as `crafter-build -r` does.
- The library's link flags (the Vulkan loader, `wayland-client`, `xkbcommon`, `udev`, or the Win32 libraries) come with the dependency. On `x86_64-w64-mingw32` that includes an import library for `vulkan-1.dll`, so linking for Win32 needs no Vulkan SDK. The library makes it at configure time with the `llvm-dlltool` beside crafter-build's `llvm-ar`, from the loader's own export list (Vulkan-Loader's `loader/vulkan-1.def`, fetched unpinned). Under the Flatpak, linking for Win32 needs crafter-build 5.0.0 or later: an older one puts the host's glibc headers on the MinGW include path, and the link fails on `__libc_single_threaded` (Crafter.Build #43). Its shaders (`ui-*.comp.spv` and `ui-*.comp.sets.spv`) and, for wasm, `dom-env.js` and `dom-webgpu.js` are copied into your executable's bin directory, as are your `cfg.shaders` outputs (`<name>.spv` from `<name>.glsl`) and `cfg.files`. Paths are resolved against the working directory at runtime, so run from the bin directory, as `crafter-build -r` does.
- Your own shaders: `cfg.shaders.emplace_back(fs::path("raygen.glsl"), std::string("main"), ShaderType::RayGen)`, with `Compute`, `RayGen`, `Miss`, `ClosestHit`, `AnyHit`, `Intersect` and `Callable`. A compute shader for the UI heap is registered twice, see "Custom compute shaders". WGSL for the DOM build ships through `cfg.files` and is loaded at runtime.
- Project args the library understands, passed through your `args`: `--local` (sibling checkouts of Crafter.Event, Crafter.Math and Crafter.Asset instead of clones), `--timing` (meant to add frame timing counters; the build does not compile with it at the moment, issue #178), `--no-webgpu` (wasm: a DOM-only page without the WebGPU bridge, which otherwise requests a GPU adapter on every load and replaces the page body with an error where WebGPU is missing).
- Needs at runtime: Vulkan 1.3 (1.4 is used where the GPU has it), a presentable surface, and the features the library's own shaders use. `VK_EXT_descriptor_heap` and ray tracing are optional groups, see "Device and features". Mesa's llvmpipe runs the compute/UI path, and recent Mesa advertises the heap.

View file

@ -86,7 +86,7 @@ Conventions the existing tests follow:
A bug fix ships with a test that fails before the fix and passes after it. A change to a UI kernel keeps `UIFallbackParity` green: the heap and descriptor-set builds of one source must stay pixel-identical. A category drawn fused must also match the same category drawn standalone. `TextAntialiasing` compares the two for text, and keeps the text's edge ramp at one screen pixel; for quads, circles and images no test does (`UIFusedShader` only pins the push-constant layout): check those by eye, or add the comparison.
Cross targets: the Win32 tests run under Wine from the native crafter-build on the host, which has `wine` on its `PATH` and finds the host's mingw-w64 itself: `WINEPREFIX=<scratch prefix> crafter-build test --target=x86_64-w64-mingw32 PointerWin32 TextWin32 Win32Link`. The Flatpak has no `wine`, so there `PointerWin32` and `TextWin32` skip and only `Win32Link`'s link is checked. Under the Flatpak a Win32 executable also links only with `tests/Win32Link/libc-single-threaded.c`. The MinGW sysroot the Flatpak picks is the host's `/usr`, which puts glibc's headers on the MinGW include path, and libstdc++'s `shared_ptr`, inlined from nlohmann/json in Crafter.Asset's GLB loader, then reads glibc's `__libc_single_threaded` (Crafter.Build #43). For an aarch64 device, `crafter-build test --target=...` tries qemu, which has no Vulkan: build with the sysroot, copy the test's whole bin directory (binary, `*.spv`, `*.sets.spv`, fonts) to the device and run it there, unlocked and with the window visible, since a locked phone's compositor sends no frame callbacks and the FIFO present then blocks forever.
Cross targets: the Win32 tests run under Wine from the native crafter-build on the host, which has `wine` on its `PATH` and finds the host's mingw-w64 itself: `WINEPREFIX=<scratch prefix> crafter-build test --target=x86_64-w64-mingw32 PointerWin32 TextWin32 Win32Link`. The Flatpak has no `wine`, so there `PointerWin32` and `TextWin32` skip and only `Win32Link`'s link is checked. A Flatpak before crafter-build 5.0.0 links no Win32 executable: it gave clang the host's `/usr` as the MinGW sysroot, which put glibc's headers on the MinGW include path, and libstdc++'s `shared_ptr`, inlined from nlohmann/json in Crafter.Asset's GLB loader, then read glibc's `__libc_single_threaded` (Crafter.Build #43). For an aarch64 device, `crafter-build test --target=...` tries qemu, which has no Vulkan: build with the sysroot, copy the test's whole bin directory (binary, `*.spv`, `*.sets.spv`, fonts) to the device and run it there, unlocked and with the window visible, since a locked phone's compositor sends no frame callbacks and the FIFO present then blocks forever.
## Code style

View file

@ -428,11 +428,8 @@ extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> a
// no Wine, run it as --runner=cmd:true, which builds it and runs
// nothing; no requires_, since that would skip the build too.
// Under Wine it also runs, opening a window and closing it, which
// needs a Vulkan device. libc-single-threaded.c stands in for
// Crafter.Build #43 and goes with it.
Test win32LinkTest = LibraryTest("Win32Link");
win32LinkTest.config.cFiles.push_back("tests/Win32Link/libc-single-threaded");
cfg.tests.push_back(std::move(win32LinkTest));
// needs a Vulkan device.
cfg.tests.push_back(LibraryTest("Win32Link"));
}
// Regression test for issue #32: the Wayland scroll-wheel chain

View file

@ -1,11 +0,0 @@
//SPDX-License-Identifier: LGPL-3.0-only
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
// Stands in for Crafter.Build #43, and goes when that is fixed, with its line
// in project.cpp. In the Flatpak the MinGW sysroot is the host's /usr, which
// puts glibc's headers on the include path, so the libstdc++ shared_ptr that
// nlohmann/json inlines into Crafter.Asset's GLB loader reads glibc's
// __libc_single_threaded, which no Windows library defines. Zero means "not
// single-threaded", so the reference counts stay atomic, as they would be
// without the leak.
char __libc_single_threaded = 0;