[M7] lockfile carries full recipe (find_package, targets, pkg_config_module, brute_force_*)
This commit is contained in:
@@ -92,6 +92,11 @@ auto merge_lockfile(const manifest::Manifest& m,
|
|||||||
.nixpkgs_attr = std::move(attr),
|
.nixpkgs_attr = std::move(attr),
|
||||||
.nixpkgs_rev = std::move(rev),
|
.nixpkgs_rev = std::move(rev),
|
||||||
.linkdb_source = rec.source,
|
.linkdb_source = rec.source,
|
||||||
|
.find_package = rec.find_package,
|
||||||
|
.targets = rec.targets,
|
||||||
|
.pkg_config_module = rec.pkg_config_module,
|
||||||
|
.brute_force_libs = rec.brute_force_libs,
|
||||||
|
.brute_force_includes = rec.brute_force_includes,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
for (std::size_t i = 0; i < m.dependencies.size(); ++i) {
|
for (std::size_t i = 0; i < m.dependencies.size(); ++i) {
|
||||||
@@ -176,11 +181,45 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release,
|
|||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lockfile::Lockfile prior;
|
||||||
|
if (std::error_code ec; std::filesystem::exists(project_root / "Cargoxx.lock", ec)) {
|
||||||
|
if (auto r = lockfile::parse(project_root / "Cargoxx.lock"); r) {
|
||||||
|
prior = std::move(*r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto recipe_from_lock = [&](const std::string& name, const std::string& version)
|
||||||
|
-> std::optional<linkdb::Recipe> {
|
||||||
|
for (const auto& p : prior.packages) {
|
||||||
|
if (p.name != name || p.version != version) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!p.find_package || p.targets.empty()) {
|
||||||
|
if (p.brute_force_libs.empty() && p.brute_force_includes.empty()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return linkdb::Recipe{
|
||||||
|
.nixpkgs_attr = p.nixpkgs_attr.value_or(""),
|
||||||
|
.find_package = p.find_package.value_or(""),
|
||||||
|
.targets = p.targets,
|
||||||
|
.source = p.linkdb_source.value_or(""),
|
||||||
|
.pkg_config_module = p.pkg_config_module,
|
||||||
|
.brute_force_libs = p.brute_force_libs,
|
||||||
|
.brute_force_includes = p.brute_force_includes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
auto resolve_list = [&](const std::vector<manifest::Dependency>& deps)
|
auto resolve_list = [&](const std::vector<manifest::Dependency>& deps)
|
||||||
-> util::Result<std::vector<linkdb::Recipe>> {
|
-> util::Result<std::vector<linkdb::Recipe>> {
|
||||||
std::vector<linkdb::Recipe> out;
|
std::vector<linkdb::Recipe> out;
|
||||||
out.reserve(deps.size());
|
out.reserve(deps.size());
|
||||||
for (const auto& dep : deps) {
|
for (const auto& dep : deps) {
|
||||||
|
if (auto cached = recipe_from_lock(dep.name, dep.version_spec); cached) {
|
||||||
|
out.push_back(std::move(*cached));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto r = db->resolve(dep.name, dep.version_spec, dep.components);
|
auto r = db->resolve(dep.name, dep.version_spec, dep.components);
|
||||||
if (!r && r.error().code == util::ErrorCode::LinkdbUnknownPackage) {
|
if (!r && r.error().code == util::ErrorCode::LinkdbUnknownPackage) {
|
||||||
if (auto resolved = auto_resolve(dep.name, dep.version_spec,
|
if (auto resolved = auto_resolve(dep.name, dep.version_spec,
|
||||||
@@ -205,13 +244,6 @@ auto cmd_build(const fs::path& project_root, bool no_build, bool release,
|
|||||||
if (!dev_recipes) {
|
if (!dev_recipes) {
|
||||||
return std::unexpected(dev_recipes.error());
|
return std::unexpected(dev_recipes.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
lockfile::Lockfile prior;
|
|
||||||
if (std::error_code ec; std::filesystem::exists(project_root / "Cargoxx.lock", ec)) {
|
|
||||||
if (auto r = lockfile::parse(project_root / "Cargoxx.lock"); r) {
|
|
||||||
prior = std::move(*r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto lock = merge_lockfile(*m, *recipes, *dev_recipes, prior);
|
auto lock = merge_lockfile(*m, *recipes, *dev_recipes, prior);
|
||||||
|
|
||||||
codegen::GenerateInputs in{
|
codegen::GenerateInputs in{
|
||||||
|
|||||||
@@ -79,6 +79,33 @@ auto parse_package(const toml::table& tbl, const std::filesystem::path& path)
|
|||||||
if (auto v = tbl["linkdb_source"].value<std::string>()) {
|
if (auto v = tbl["linkdb_source"].value<std::string>()) {
|
||||||
pkg.linkdb_source = *v;
|
pkg.linkdb_source = *v;
|
||||||
}
|
}
|
||||||
|
if (auto v = tbl["find_package"].value<std::string>()) {
|
||||||
|
pkg.find_package = *v;
|
||||||
|
}
|
||||||
|
if (const auto* arr = tbl["targets"].as_array()) {
|
||||||
|
auto r = extract_string_array(*arr, "targets", path);
|
||||||
|
if (!r) {
|
||||||
|
return std::unexpected(r.error());
|
||||||
|
}
|
||||||
|
pkg.targets = std::move(*r);
|
||||||
|
}
|
||||||
|
if (auto v = tbl["pkg_config_module"].value<std::string>()) {
|
||||||
|
pkg.pkg_config_module = *v;
|
||||||
|
}
|
||||||
|
if (const auto* arr = tbl["brute_force_libs"].as_array()) {
|
||||||
|
auto r = extract_string_array(*arr, "brute_force_libs", path);
|
||||||
|
if (!r) {
|
||||||
|
return std::unexpected(r.error());
|
||||||
|
}
|
||||||
|
pkg.brute_force_libs = std::move(*r);
|
||||||
|
}
|
||||||
|
if (const auto* arr = tbl["brute_force_includes"].as_array()) {
|
||||||
|
auto r = extract_string_array(*arr, "brute_force_includes", path);
|
||||||
|
if (!r) {
|
||||||
|
return std::unexpected(r.error());
|
||||||
|
}
|
||||||
|
pkg.brute_force_includes = std::move(*r);
|
||||||
|
}
|
||||||
|
|
||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
@@ -149,6 +176,33 @@ auto write(const Lockfile& lock, const std::filesystem::path& path) -> util::Res
|
|||||||
if (p.linkdb_source) {
|
if (p.linkdb_source) {
|
||||||
tbl.insert_or_assign("linkdb_source", *p.linkdb_source);
|
tbl.insert_or_assign("linkdb_source", *p.linkdb_source);
|
||||||
}
|
}
|
||||||
|
if (p.find_package) {
|
||||||
|
tbl.insert_or_assign("find_package", *p.find_package);
|
||||||
|
}
|
||||||
|
if (!p.targets.empty()) {
|
||||||
|
toml::array arr;
|
||||||
|
for (const auto& t : p.targets) {
|
||||||
|
arr.push_back(t);
|
||||||
|
}
|
||||||
|
tbl.insert_or_assign("targets", std::move(arr));
|
||||||
|
}
|
||||||
|
if (p.pkg_config_module) {
|
||||||
|
tbl.insert_or_assign("pkg_config_module", *p.pkg_config_module);
|
||||||
|
}
|
||||||
|
if (!p.brute_force_libs.empty()) {
|
||||||
|
toml::array arr;
|
||||||
|
for (const auto& l : p.brute_force_libs) {
|
||||||
|
arr.push_back(l);
|
||||||
|
}
|
||||||
|
tbl.insert_or_assign("brute_force_libs", std::move(arr));
|
||||||
|
}
|
||||||
|
if (!p.brute_force_includes.empty()) {
|
||||||
|
toml::array arr;
|
||||||
|
for (const auto& i : p.brute_force_includes) {
|
||||||
|
arr.push_back(i);
|
||||||
|
}
|
||||||
|
tbl.insert_or_assign("brute_force_includes", std::move(arr));
|
||||||
|
}
|
||||||
packages.push_back(std::move(tbl));
|
packages.push_back(std::move(tbl));
|
||||||
}
|
}
|
||||||
root.insert_or_assign("package", std::move(packages));
|
root.insert_or_assign("package", std::move(packages));
|
||||||
|
|||||||
@@ -9,10 +9,15 @@ export namespace cargoxx::lockfile {
|
|||||||
struct LockfilePackage {
|
struct LockfilePackage {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string version;
|
std::string version;
|
||||||
std::vector<std::string> dependencies; // "<name> <version>" entries; non-empty for the root
|
std::vector<std::string> dependencies;
|
||||||
std::optional<std::string> nixpkgs_attr;
|
std::optional<std::string> nixpkgs_attr;
|
||||||
std::optional<std::string> nixpkgs_rev;
|
std::optional<std::string> nixpkgs_rev;
|
||||||
std::optional<std::string> linkdb_source;
|
std::optional<std::string> linkdb_source;
|
||||||
|
std::optional<std::string> find_package;
|
||||||
|
std::vector<std::string> targets;
|
||||||
|
std::optional<std::string> pkg_config_module;
|
||||||
|
std::vector<std::string> brute_force_libs;
|
||||||
|
std::vector<std::string> brute_force_includes;
|
||||||
|
|
||||||
bool operator==(const LockfilePackage&) const = default;
|
bool operator==(const LockfilePackage&) const = default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,6 +70,54 @@ TEST_CASE("write round-trips a lockfile with deps", "[lockfile]") {
|
|||||||
REQUIRE(round_trip(l) == l);
|
REQUIRE(round_trip(l) == l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("write round-trips lockfile recipe fields", "[lockfile]") {
|
||||||
|
Lockfile l{
|
||||||
|
1,
|
||||||
|
{
|
||||||
|
LockfilePackage{
|
||||||
|
.name = "fmt",
|
||||||
|
.version = "10.2.1",
|
||||||
|
.dependencies = {},
|
||||||
|
.nixpkgs_attr = "fmt_10",
|
||||||
|
.nixpkgs_rev = std::nullopt,
|
||||||
|
.linkdb_source = "conan",
|
||||||
|
.find_package = "fmt CONFIG REQUIRED",
|
||||||
|
.targets = {"fmt::fmt"},
|
||||||
|
.pkg_config_module = std::nullopt,
|
||||||
|
.brute_force_libs = {},
|
||||||
|
.brute_force_includes = {},
|
||||||
|
},
|
||||||
|
LockfilePackage{
|
||||||
|
.name = "sqlite",
|
||||||
|
.version = "*",
|
||||||
|
.dependencies = {},
|
||||||
|
.nixpkgs_attr = "sqlite",
|
||||||
|
.nixpkgs_rev = std::nullopt,
|
||||||
|
.linkdb_source = "pkg-config",
|
||||||
|
.find_package = "PkgConfig REQUIRED",
|
||||||
|
.targets = {"PkgConfig::SQLITE3"},
|
||||||
|
.pkg_config_module = "sqlite3",
|
||||||
|
.brute_force_libs = {},
|
||||||
|
.brute_force_includes = {},
|
||||||
|
},
|
||||||
|
LockfilePackage{
|
||||||
|
.name = "obscure",
|
||||||
|
.version = "*",
|
||||||
|
.dependencies = {},
|
||||||
|
.nixpkgs_attr = "obscure",
|
||||||
|
.nixpkgs_rev = std::nullopt,
|
||||||
|
.linkdb_source = "brute-force",
|
||||||
|
.find_package = "",
|
||||||
|
.targets = {"obscure::obscure"},
|
||||||
|
.pkg_config_module = std::nullopt,
|
||||||
|
.brute_force_libs = {"/nix/store/abc/lib/libobscure.a"},
|
||||||
|
.brute_force_includes = {"/nix/store/abc/include"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
REQUIRE(round_trip(l) == l);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Lockfile::nixpkgs_rev returns the shared rev", "[lockfile]") {
|
TEST_CASE("Lockfile::nixpkgs_rev returns the shared rev", "[lockfile]") {
|
||||||
Lockfile l{
|
Lockfile l{
|
||||||
1,
|
1,
|
||||||
|
|||||||
Reference in New Issue
Block a user