import std; import Crafter.Build; namespace fs = std::filesystem; using namespace Crafter; extern "C" Configuration CrafterBuildProject(std::span args) { constexpr std::array networkInterfaces = { "interfaces/Crafter.Network", "interfaces/Crafter.Network-ClientTCP", "interfaces/Crafter.Network-ListenerTCP", "interfaces/Crafter.Network-ClientHTTP", "interfaces/Crafter.Network-ListenerHTTP", "interfaces/Crafter.Network-HTTP", "interfaces/Crafter.Network-HTTP3", "interfaces/Crafter.Network-ClientQUIC", "interfaces/Crafter.Network-ListenerQUIC", "interfaces/Crafter.Network-WebTransport", }; std::vector depArgs(args.begin(), args.end()); Configuration* thread = GitProject({ .source = { .url = "https://forgejo.catcrafts.net/Catcrafts/Crafter.Thread.git" }, .args = depArgs, }); Configuration cfg; cfg.path = "./"; cfg.name = "crafter-network"; cfg.outputName = "crafter-network"; cfg.type = ConfigurationType::LibraryStatic; ApplyStandardArgs(cfg, args); cfg.dependencies = { thread }; // Browser path: any wasm32-* target gets the browser network stack // (fetch + WebTransport via JS glue). msquic and the POSIX socket // backends are skipped; the listener / TCP partitions stub to empty // modules via #ifdef CRAFTER_NETWORK_BROWSER in their interface files. // HTTP3 (varint / frame / QPACK codec) is dropped entirely — it threw // exceptions for protocol errors, which the wasm build's -fno-exceptions // forbids, and the browser's fetch() handles HTTP-layer framing itself. bool browser = cfg.target.find("wasm") != std::string::npos; if (browser) { cfg.defines.push_back({"CRAFTER_NETWORK_BROWSER", ""}); std::array browserIfaces = { "interfaces/Crafter.Network", "interfaces/Crafter.Network-ClientTCP", "interfaces/Crafter.Network-ListenerTCP", "interfaces/Crafter.Network-ClientHTTP", "interfaces/Crafter.Network-ListenerHTTP", "interfaces/Crafter.Network-HTTP", "interfaces/Crafter.Network-ClientQUIC", "interfaces/Crafter.Network-ListenerQUIC", "interfaces/Crafter.Network-WebTransport", }; std::array browserImpls = { "implementations/Crafter.Network-ClientHTTP-Browser", "implementations/Crafter.Network-ClientQUIC-Browser", }; cfg.GetInterfacesAndImplementations(browserIfaces, browserImpls); // JS glue shipped alongside the .wasm. The consuming executable's // wasi-browser runtime merges this into the env import object // before instantiation (mirrors Crafter.Graphics/dom-env.js). cfg.files.emplace_back(fs::path("additional/network-env.js")); return cfg; } constexpr std::array networkImplementations = { "implementations/Crafter.Network-ClientTCP", "implementations/Crafter.Network-ListenerTCP", "implementations/Crafter.Network-ClientHTTP", "implementations/Crafter.Network-ListenerHTTP", "implementations/Crafter.Network-ClientQUIC", "implementations/Crafter.Network-ListenerQUIC", "implementations/Crafter.Network-WebTransport", }; // msquic — provides the QUIC transport used by ClientQUIC / ListenerQUIC. // Cloned + built via CMake into the per-project external cache; no system // package required. Submodules (quictls / clog / etc.) come via the // recursive clone Crafter.Build performs. We disable msquic's own tests, // tools and perf binaries since we only need the library. ExternalDependency& msquic = cfg.externalDependencies.emplace_back(); msquic.name = "msquic"; msquic.source.url = "https://github.com/microsoft/msquic.git"; msquic.source.branch = "main"; msquic.builder = ExternalBuilder::CMake; msquic.options = { "-DQUIC_TLS_LIB=quictls", "-DQUIC_BUILD_TEST=OFF", "-DQUIC_BUILD_TOOLS=OFF", "-DQUIC_BUILD_PERF=OFF", "-DQUIC_BUILD_SHARED=ON", }; msquic.includeDirs = { "src/inc" }; // msquic's CMakeLists overrides CMAKE_LIBRARY_OUTPUT_DIRECTORY with // QUIC_OUTPUT_DIR (defaults to bin/$), so libmsquic.so lands in // a subdir of the cmake build dir rather than at its root. Point the // linker at the actual output location. msquic.libDirs = { "bin/Release" }; msquic.libs = { "msquic" }; std::array ifaces; std::ranges::copy(networkInterfaces, ifaces.begin()); std::array impls; std::ranges::copy(networkImplementations, impls.begin()); cfg.GetInterfacesAndImplementations(ifaces, impls); return cfg; }