Merge main into fix/explicit-homebrew-module-directories

This commit is contained in:
Dean Galvin committed 2026-10-18 17:43:12 +13:00
commit 489c64ecb5
978 files changed
+65125 -4011

No files matched your search

+32 -1
View File
@@ -4,9 +4,15 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
namespace Cli {
bool SameDirectory(const std::filesystem::path& first, const std::filesystem::path& second) {
if (std::filesystem::exists(first) && std::filesystem::exists(second)) return std::filesystem::equivalent(first, second);
return std::filesystem::weakly_canonical(first) == std::filesystem::weakly_canonical(second);
}
NativeModules ReadModules(const std::filesystem::path& inputPath, const std::filesystem::path& sceModulePath, const std::set<std::string>& excludedModules, const std::vector<std::string>& moduleDirectories) {
using namespace Relinker;
const auto root = std::filesystem::absolute(sceModulePath).lexically_normal();
@@ -32,7 +38,7 @@ NativeModules ReadModules(const std::filesystem::path& inputPath, const std::fil
auto directory = (root / relative).lexically_normal();
if (!directory.has_filename()) directory = directory.parent_path();
if (!std::filesystem::is_directory(directory)) throw Domain::RelinkerException("Guest module path is not a directory: " + Io::Utf8Path(directory));
if (std::find(directories.begin(), directories.end(), directory) != directories.end()) throw Domain::RelinkerException("Duplicate guest module directory: " + Io::Utf8Path(directory));
if (std::any_of(directories.begin(), directories.end(), [&](const auto& existing) { return SameDirectory(existing, directory); })) throw Domain::RelinkerException("Duplicate guest module directory: " + Io::Utf8Path(directory));
directories.push_back(directory);
runtimeDirectories.push_back(directory);
}
@@ -72,6 +78,31 @@ NativeModules ReadModules(const std::filesystem::path& inputPath, const std::fil
result.Root = root;
result.RuntimeDirectories = std::move(runtimeDirectories);
for (const auto& path : paths) result.Modules.push_back({path, Io::FileReader().Read(Io::Utf8Path(path))});
std::map<std::size_t, std::string> sonames;
const auto soname = [&](std::size_t index) -> const std::string& {
const auto [found, inserted] = sonames.try_emplace(index);
if (inserted) found->second = GuestImageReader().Read(result.Modules[index].Path, result.Modules[index].Bytes).Soname;
return found->second;
};
std::vector<bool> copies(result.Modules.size());
for (std::size_t copy = 0; copy < result.Modules.size(); ++copy) {
const auto& path = result.Modules[copy].Path;
const auto name = Io::Utf8Path(path.filename());
for (std::size_t original = 0; original < result.Modules.size(); ++original) {
const auto& kept = result.Modules[original].Path;
const auto prefix = Io::Utf8Path(kept.filename());
if (kept.parent_path() != path.parent_path() || prefix.size() >= name.size() || !name.starts_with(prefix)) continue;
if (soname(copy).empty() || soname(copy) != soname(original)) continue;
copies[copy] = true;
std::cout << "Skipping backup copy: " << path.lexically_relative(root).generic_string() << " (same SONAME as "
<< kept.lexically_relative(root).generic_string() << ")\n";
break;
}
}
std::vector<GuestModuleInput> modules;
for (std::size_t index = 0; index < result.Modules.size(); ++index)
if (!copies[index]) modules.push_back(std::move(result.Modules[index]));
result.Modules = std::move(modules);
return result;
}