import std; import Crafter.Build; namespace fs = std::filesystem; using namespace Crafter; extern "C" Configuration CrafterBuildProject(std::span args) { std::vector depArgs(args.begin(), args.end()); // Local-mode resolution for the Crafter.Math/Crafter.Asset deps that the // self-host pass links in (so `cfg.assets` calls CompressAsset → Crafter.Asset // in-process). `--local` points at sibling working trees instead of git; // useful during cross-repo development so edits in ../Crafter.Asset are // picked up without commit-and-pull. bool useLocal = false; for (std::string_view a : args) { if (a == "--local") { useLocal = true; break; } } auto resolveDep = [&](std::string_view name, std::string_view gitUrl) -> Configuration* { if (useLocal) { return LocalProject({ .projectFile = fs::path("../") / name / "project.cpp", .args = depArgs, }); } return GitProject({ .source = { .url = std::string(gitUrl) }, .args = depArgs, }); }; static auto crafterBuildLib = std::make_unique(); crafterBuildLib->path = "./"; crafterBuildLib->name = "crafter.build-lib"; crafterBuildLib->outputName = "crafter-build"; ApplyStandardArgs(*crafterBuildLib, args); // Windows builds (native msvc via build.cmd or cross-compiled mingw from // Linux) need a DLL + import lib + launcher exe so LoadProject can // compile project.cpp against a stable ABI boundary. Linux is monolithic. crafterBuildLib->type = (crafterBuildLib->target == "x86_64-w64-mingw32" || crafterBuildLib->target == "x86_64-pc-windows-msvc") ? ConfigurationType::LibraryDynamic : ConfigurationType::LibraryStatic; // Self-host pass links Crafter.Asset (and its Crafter.Math dep) into the // crafter-build binary so cfg.assets can call CompressAsset in-process. // The bootstrap (build.sh) defines no such dep — its impl unit takes the // stub branch and cfg.assets errors at runtime until a self-host rebuild. Configuration* math = resolveDep("Crafter.Math", "https://forgejo.catcrafts.net/Catcrafts/Crafter.Math.git"); Configuration* asset = resolveDep("Crafter.Asset", "https://forgejo.catcrafts.net/Catcrafts/Crafter.Asset.git"); crafterBuildLib->dependencies = { math, asset }; crafterBuildLib->defines.push_back({"CRAFTER_BUILD_HAS_ASSET", ""}); { std::array interfaces = { "interfaces/Crafter.Build", "interfaces/Crafter.Build-Shader", "interfaces/Crafter.Build-Platform", "interfaces/Crafter.Build-Interface", "interfaces/Crafter.Build-Implementation", "interfaces/Crafter.Build-External", "interfaces/Crafter.Build-Clang", "interfaces/Crafter.Build-Test", "interfaces/Crafter.Build-Progress", "interfaces/Crafter.Build-Asset", }; std::array implementations = { "implementations/Crafter.Build-Shader", "implementations/Crafter.Build-Platform", "implementations/Crafter.Build-Interface", "implementations/Crafter.Build-Implementation", "implementations/Crafter.Build-External", "implementations/Crafter.Build-Clang", "implementations/Crafter.Build-Test", "implementations/Crafter.Build-Progress", "implementations/Crafter.Build-Asset", }; crafterBuildLib->GetInterfacesAndImplementations(interfaces, implementations); } ExternalDependency& glslang = crafterBuildLib->externalDependencies.emplace_back(); glslang.name = "glslang"; glslang.source.url = "https://github.com/KhronosGroup/glslang.git"; glslang.source.branch = "main"; glslang.builder = ExternalBuilder::CMake; glslang.options = { "-DENABLE_OPT=OFF" }; // mingw cross-build: skip the standalone executable. We only consume the // libraries, and glslang.exe pulls in libgcc_eh which needs pthread that // mingw-w64 doesn't link by default. if (crafterBuildLib->target == "x86_64-w64-mingw32") { glslang.options.push_back("-DENABLE_GLSLANG_BINARIES=OFF"); } glslang.includeDirs = { "" }; glslang.libs = { "SPIRV", "GenericCodeGen", "glslang", "OSDependent", "MachineIndependent", "glslang-default-resource-limits" }; Configuration cfg; cfg.path = "./"; cfg.name = "crafter.build-exe"; cfg.outputName = "crafter-build"; ApplyStandardArgs(cfg, args); cfg.type = ConfigurationType::Executable; cfg.dependencies = { crafterBuildLib.get() }; { std::array interfaces = {}; std::array implementations = { "implementations/main" }; cfg.GetInterfacesAndImplementations(interfaces, implementations); } if (cfg.target == "x86_64-pc-linux-gnu") { cfg.linkFlags.push_back("-Wl,--export-dynamic"); cfg.linkFlags.push_back("-ldl"); } return cfg; }