Crafter.Build/project.cpp
catbot 86fce525c7
Some checks failed
CI / build-test-release (pull_request) Has been cancelled
pin Crafter.Asset to mingw-rotr64 fix commit so Windows CI builds
The CI's mingw cross-compile (--target=x86_64-w64-mingw32) has been
failing for a while at lib/gdeflate/libdeflate/lib/utils.c, where
libdeflate's compiler_gcc.h defines _rotr* as macros before mingw's
<stdlib.h> can declare them as functions. The fix is in
Catcrafts/Crafter.Asset PR #1 (commit 021ced6); pin to that SHA so
the Windows artifact jobs unblock immediately rather than waiting on
master-tracking + a merge race. Once the upstream PR is merged and
master is confirmed to carry the fix, the pin can be removed.

Adds an optional commit arg to resolveDep so the existing
"track-master" call site for Crafter.Math is unchanged.

Refs Catcrafts/Crafter.Build#6.
2026-05-27 02:32:01 +00:00

118 lines
5.7 KiB
C++

import std;
import Crafter.Build;
namespace fs = std::filesystem;
using namespace Crafter;
extern "C" Configuration CrafterBuildProject(std::span<const std::string_view> args) {
std::vector<std::string> 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, std::string_view commit = "") -> Configuration* {
if (useLocal) {
return LocalProject({
.projectFile = fs::path("../") / name / "project.cpp",
.args = depArgs,
});
}
return GitProject({
.source = { .url = std::string(gitUrl), .commit = std::string(commit) },
.args = depArgs,
});
};
static auto crafterBuildLib = std::make_unique<Configuration>();
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");
// Crafter.Asset is pinned here because the mingw cross-compile needs the
// libdeflate _rotr* / stdlib.h fix from Catcrafts/Crafter.Asset PR #1.
// Once that PR lands on master and we've confirmed master tracks the fix,
// the pin can be dropped back to tip-tracking (third arg removed).
Configuration* asset = resolveDep("Crafter.Asset", "https://forgejo.catcrafts.net/Catcrafts/Crafter.Asset.git",
"021ced683d589fae7dbc7e7fa6108a9ee11bf64c");
crafterBuildLib->dependencies = { math, asset };
crafterBuildLib->defines.push_back({"CRAFTER_BUILD_HAS_ASSET", ""});
{
std::array<fs::path, 10> 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<fs::path, 9> 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<fs::path, 0> interfaces = {};
std::array<fs::path, 1> 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");
}
if (cfg.target == "x86_64-w64-mingw32" || cfg.target == "x86_64-pc-windows-msvc") {
// winsock for the -r wasm port probe (bind/WSAStartup).
crafterBuildLib->linkFlags.push_back("-lws2_32");
}
return cfg;
}