This commit is contained in:
parent
a25b0a1ded
commit
8892154b28
70 changed files with 2780 additions and 596 deletions
|
|
@ -1,5 +1,5 @@
|
|||
//SPDX-License-Identifier: LGPL-3.0-only
|
||||
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
||||
|
||||
module Crafter.Build:External_impl;
|
||||
import std;
|
||||
|
|
@ -175,10 +175,7 @@ std::string ConfigureCMake(const fs::path& cloneDir, const fs::path& cmakeBuildD
|
|||
|
||||
if (!fs::exists(cmakeBuildDir)) fs::create_directories(cmakeBuildDir);
|
||||
|
||||
std::string cmd = std::format("cmake -S {} -B {}{}",
|
||||
ShellQuote(fs::absolute(cloneDir).string()),
|
||||
ShellQuote(fs::absolute(cmakeBuildDir).string()),
|
||||
BuildInjectedCMakeFlags(cmakeBuildDir, target));
|
||||
std::string cmd = std::format("cmake -S {} -B {}{}", ShellQuote(fs::absolute(cloneDir).string()), ShellQuote(fs::absolute(cmakeBuildDir).string()), BuildInjectedCMakeFlags(cmakeBuildDir, target));
|
||||
if (!options.empty()) {
|
||||
cmd += " ";
|
||||
cmd += optionsKey;
|
||||
|
|
@ -198,9 +195,8 @@ std::string BuildCMake(const fs::path& cmakeBuildDir) {
|
|||
// unit at a time, leaving every core but one idle. Pass an explicit job
|
||||
// count (a bare --parallel maps to an unbounded `make -j` fork bomb on the
|
||||
// Makefiles generator) so deps like DPP/msquic/glslang compile ~N× faster.
|
||||
unsigned jobs = std::max(1u, std::thread::hardware_concurrency());
|
||||
std::string cmd = std::format("cmake --build {} --parallel {}",
|
||||
ShellQuote(fs::absolute(cmakeBuildDir).string()), jobs);
|
||||
std::uint32_t jobs = std::max(1u, std::thread::hardware_concurrency());
|
||||
std::string cmd = std::format("cmake --build {} --parallel {}", ShellQuote(fs::absolute(cmakeBuildDir).string()), jobs);
|
||||
CommandResult r = RunCommandChecked(cmd);
|
||||
if (r.exitCode != 0) {
|
||||
return std::format("cmake --build failed (exit {}): {}", r.exitCode, r.output);
|
||||
|
|
@ -210,10 +206,7 @@ std::string BuildCMake(const fs::path& cmakeBuildDir) {
|
|||
|
||||
} // namespace
|
||||
|
||||
ExternalBuildResult Crafter::BuildExternal(
|
||||
const ExternalDependency& dep,
|
||||
std::string_view target,
|
||||
std::atomic<bool>& cancelled) {
|
||||
ExternalBuildResult Crafter::BuildExternal(const ExternalDependency& dep, std::string_view target, std::atomic<bool>& cancelled) {
|
||||
ExternalBuildResult result;
|
||||
|
||||
if (cancelled.load(std::memory_order_relaxed)) return result;
|
||||
|
|
@ -234,8 +227,7 @@ ExternalBuildResult Crafter::BuildExternal(
|
|||
}
|
||||
}
|
||||
|
||||
std::string keyMaterial = std::format("{}|{}|{}|{}|{}",
|
||||
dep.source.url, dep.source.branch, dep.source.commit, JoinOptions(dep.options), target);
|
||||
std::string keyMaterial = std::format("{}|{}|{}|{}|{}", dep.source.url, dep.source.branch, dep.source.commit, JoinOptions(dep.options), target);
|
||||
std::size_t key = std::hash<std::string>{}(keyMaterial);
|
||||
fs::path cloneDir = externalRoot / std::format("{}-{:016x}", name, key);
|
||||
|
||||
|
|
@ -303,8 +295,8 @@ ExternalBuildResult Crafter::BuildExternal(
|
|||
}
|
||||
|
||||
namespace {
|
||||
std::mutex projectCacheMutex;
|
||||
std::unordered_map<std::string, std::unique_ptr<Configuration>> projectCache;
|
||||
std::mutex ProjectCacheMutex;
|
||||
std::unordered_map<std::string, std::unique_ptr<Configuration>> ProjectCache;
|
||||
|
||||
// Run the dep's project.cpp from its own directory so its relative paths
|
||||
// (cfg.path = "./", interfaces/, lib/, ...) resolve against the dep
|
||||
|
|
@ -342,8 +334,7 @@ Configuration* Crafter::GitProject(const GitProjectSpec& spec) {
|
|||
// how the dep's project.cpp interprets them at runtime), while the
|
||||
// in-memory Configuration is keyed by the full spec so each (args)
|
||||
// permutation gets its own Configuration object.
|
||||
std::string srcKey = std::format("git|{}|{}|{}|{}",
|
||||
spec.source.url, spec.source.branch, spec.source.commit, spec.projectFile.string());
|
||||
std::string srcKey = std::format("git|{}|{}|{}|{}", spec.source.url, spec.source.branch, spec.source.commit, spec.projectFile.string());
|
||||
std::string srcHash = std::format("{:016x}", std::hash<std::string>{}(srcKey));
|
||||
|
||||
std::string fullKey = srcKey;
|
||||
|
|
@ -354,8 +345,8 @@ Configuration* Crafter::GitProject(const GitProjectSpec& spec) {
|
|||
std::string fullHash = std::format("{:016x}", std::hash<std::string>{}(fullKey));
|
||||
|
||||
{
|
||||
std::lock_guard lock(projectCacheMutex);
|
||||
if (auto it = projectCache.find(fullHash); it != projectCache.end()) {
|
||||
std::lock_guard lock(ProjectCacheMutex);
|
||||
if (auto it = ProjectCache.find(fullHash); it != ProjectCache.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
}
|
||||
|
|
@ -379,38 +370,34 @@ Configuration* Crafter::GitProject(const GitProjectSpec& spec) {
|
|||
|
||||
fs::path projectPath = cloneDir / spec.projectFile;
|
||||
if (!fs::exists(projectPath)) {
|
||||
throw std::runtime_error(std::format(
|
||||
"GitProject({}): {} not found in clone", spec.source.url, spec.projectFile.string()));
|
||||
throw std::runtime_error(std::format("GitProject({}): {} not found in clone", spec.source.url, spec.projectFile.string()));
|
||||
}
|
||||
|
||||
std::vector<std::string_view> argViews(spec.args.begin(), spec.args.end());
|
||||
Configuration cfg = LoadProjectFromRoot(projectPath, cloneDir, argViews);
|
||||
|
||||
std::lock_guard lock(projectCacheMutex);
|
||||
if (auto it = projectCache.find(fullHash); it != projectCache.end()) {
|
||||
std::lock_guard lock(ProjectCacheMutex);
|
||||
if (auto it = ProjectCache.find(fullHash); it != ProjectCache.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
auto stored = std::make_unique<Configuration>(std::move(cfg));
|
||||
Configuration* ptr = stored.get();
|
||||
projectCache.emplace(std::move(fullHash), std::move(stored));
|
||||
ProjectCache.emplace(std::move(fullHash), std::move(stored));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
fs::path Crafter::GitFetch(const GitSource& source) {
|
||||
std::string name = DeriveName(source);
|
||||
if (name.empty()) {
|
||||
throw std::runtime_error(std::format(
|
||||
"GitFetch: could not derive name from URL '{}'", source.url));
|
||||
throw std::runtime_error(std::format("GitFetch: could not derive name from URL '{}'", source.url));
|
||||
}
|
||||
fs::path externalRoot = GetCacheDir() / "external";
|
||||
std::error_code ec;
|
||||
fs::create_directories(externalRoot, ec);
|
||||
if (ec) {
|
||||
throw std::runtime_error(std::format(
|
||||
"GitFetch: failed to create {}: {}", externalRoot.string(), ec.message()));
|
||||
throw std::runtime_error(std::format("GitFetch: failed to create {}: {}", externalRoot.string(), ec.message()));
|
||||
}
|
||||
std::string keyMaterial = std::format("git|{}|{}|{}",
|
||||
source.url, source.branch, source.commit);
|
||||
std::string keyMaterial = std::format("git|{}|{}|{}", source.url, source.branch, source.commit);
|
||||
std::size_t key = std::hash<std::string>{}(keyMaterial);
|
||||
fs::path cloneDir = externalRoot / std::format("{}-{:016x}", name, key);
|
||||
|
||||
|
|
@ -439,8 +426,8 @@ Configuration* Crafter::LocalProject(const LocalProjectSpec& spec) {
|
|||
std::string fullHash = std::format("{:016x}", std::hash<std::string>{}(fullKey));
|
||||
|
||||
{
|
||||
std::lock_guard lock(projectCacheMutex);
|
||||
if (auto it = projectCache.find(fullHash); it != projectCache.end()) {
|
||||
std::lock_guard lock(ProjectCacheMutex);
|
||||
if (auto it = ProjectCache.find(fullHash); it != ProjectCache.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
}
|
||||
|
|
@ -449,12 +436,12 @@ Configuration* Crafter::LocalProject(const LocalProjectSpec& spec) {
|
|||
std::vector<std::string_view> argViews(spec.args.begin(), spec.args.end());
|
||||
Configuration cfg = LoadProjectFromRoot(canonical, depRoot, argViews);
|
||||
|
||||
std::lock_guard lock(projectCacheMutex);
|
||||
if (auto it = projectCache.find(fullHash); it != projectCache.end()) {
|
||||
std::lock_guard lock(ProjectCacheMutex);
|
||||
if (auto it = ProjectCache.find(fullHash); it != ProjectCache.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
auto stored = std::make_unique<Configuration>(std::move(cfg));
|
||||
Configuration* ptr = stored.get();
|
||||
projectCache.emplace(std::move(fullHash), std::move(stored));
|
||||
ProjectCache.emplace(std::move(fullHash), std::move(stored));
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue