// SPDX-License-Identifier: LGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® export module Crafter.Build:Clang; import std; import :Shader; import :Interface; import :Implementation; import :External; import :Toolchain; import :Agents; namespace fs = std::filesystem; namespace Crafter { // What every wasm32 C++ translation unit is compiled with, and the std // module it imports. A BMI cannot be loaded by a unit whose options differ // from the ones that wrote it, so GetCompileCommand and BuildStdPcm both // take the set from here (through WasmCompileFlags), and VariantId and // StdPcmDir hash it so that a crafter-build which changes it never reuses // what the old set compiled. // // -fwasm-exceptions compiles C++ exceptions to WebAssembly exception // handling. It also selects the sysroot's include//eh and // lib//eh, the libc++ built with exceptions that wasi-sdk 33 and // later ship next to the noeh/ one, so it has to reach the link too; the // link reuses this command line, so it does. Those libraries use the // standardized form of the proposal (try_table, exnref), while LLVM 23 // still defaults to the legacy one: wasmtime refuses to load that, and it // would mix two encodings in one binary. -wasm-use-legacy-eh=false asks // for the standard form, for setjmp as well. wasi-libc's setjmp.h does // not compile without -wasm-enable-sjlj, which lowers setjmp to the same // exception handling, and signal.h needs the emulation define. inline constexpr std::string_view WasmBaselineFlags = "-fwasm-exceptions -mllvm -wasm-use-legacy-eh=false -msimd128 -fno-c++-static-destructors -mllvm -wasm-enable-sjlj -D_WASI_EMULATED_SIGNAL"; // The wasi-runtime/runtime.js probes an engine has to pass to run anything // built with WasmBaselineFlags; EnableWasiBrowserRuntime puts them on every // entry of variants.json. Exception handling with exnref is the newest // feature those flags need (Chrome 137, Firefox 131, Safari 18.4), so an // engine that has it has SIMD128 and the rest as well. inline constexpr auto WasmBaselineProbes = std::to_array({"exception-handling"}); } export namespace Crafter { struct BuildResult { std::string result; bool repack; // Sets in order: the commands they go into are compared with the ones // recorded last time, so they come out the same however the // dependency threads that fill them happen to finish. std::set libs; // Compile flags (typically -I include paths) the dep wants its // consumers to see — sourced from its external dependencies' include // dirs so headers a dep exposes in its public modules are reachable // when a consumer #includes them directly. Propagates transitively. std::set publicCompileFlags; }; struct Define { std::string name; std::string value; }; // A browser-wasm codegen variant. The same wasm32 target is compiled more // than once, each pass adding `flags` to every translation unit, so newer // ISA features (relaxed SIMD today; threads, future SIMD revisions, … later) // can be adopted without dropping engines that lack them. Each non-empty // `label` emits an additional `outputName.