From 9b6086440aa261fc376c8293df2345050658dd2b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 7 Oct 2021 22:36:01 +0300 Subject: Allow building build module in multiple configurations if they belong to different configuration clusters --- bpkg/database.cxx | 33 +++++++++++++++++++++++++++++++++ bpkg/database.hxx | 8 +++++++- bpkg/pkg-build.cli | 2 +- bpkg/pkg-build.cxx | 38 ++++++++++++++++++++++++++------------ tests/pkg-build.testscript | 21 +++++++++++++++++++++ 5 files changed, 88 insertions(+), 14 deletions(-) diff --git a/bpkg/database.cxx b/bpkg/database.cxx index dd6790a..4f3b102 100644 --- a/bpkg/database.cxx +++ b/bpkg/database.cxx @@ -936,6 +936,39 @@ namespace bpkg empty_string /* type */); } + linked_databases database:: + cluster_configs (bool sys_rep) + { + linked_databases r; + + // If the database is not in the resulting list, then add it and its + // dependent and dependency configurations, recursively. + // + auto add = [&r, sys_rep] (database& db, const auto& add) + { + if (std::find (r.begin (), r.end (), db) != r.end ()) + return; + + r.push_back (db); + + { + linked_databases cs (db.dependency_configs ()); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (*i, add); + } + + { + linked_databases cs (db.dependent_configs (sys_rep)); + for (auto i (cs.begin_linked ()); i != cs.end (); ++i) + add (*i, add); + } + }; + + add (*this, add); + + return r; + } + database& database:: find_attached (uint64_t id, bool s) { diff --git a/bpkg/database.hxx b/bpkg/database.hxx index c9ef590..cfd2645 100644 --- a/bpkg/database.hxx +++ b/bpkg/database.hxx @@ -214,7 +214,7 @@ namespace bpkg // // Note that we skip dangling links without any warning since they can be // quite common. Think of a shared host configuration with a bunch of - // implicitly linked configurations, which are removed and potentially + // implicitly linked configurations which are removed and potentially // recreated later during the host configuration lifetime. Note however, // that we remove the dangling implicit links during migration (see // migrate() on details). @@ -297,6 +297,12 @@ namespace bpkg linked_databases dependent_configs (bool sys_rep = false); + // Return configurations of the linked cluster which the current + // configuration belongs to. + // + linked_databases + cluster_configs (bool sys_rep = false); + // The following find_*() functions assume that the main database has been // created with the pre_attach flag set to true. // diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli index f9cee12..b1415fe 100644 --- a/bpkg/pkg-build.cli +++ b/bpkg/pkg-build.cli @@ -412,7 +412,7 @@ namespace bpkg "", "Assume current configuration is in rather than in the current working directory. Repeat this option to specify multiple current - configurations. If multiple configurations are specified, they must + configurations. If multiple configurations are specified, they need not belong to the same linked configuration cluster." } }; diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index 51bd224..dd48440 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -6218,15 +6218,18 @@ namespace bpkg verify_dependencies); // Now, verify that none of the build2 modules may simultaneously be - // built in multiple configurations, accross all (potentially - // unrelated) dependency trees. + // built in multiple configurations which belong to the same linked + // configuration cluster. // // For that we use the `package_prereqs` map: its key set refers to // all the packages potentially involved into the build (explicitly // or implicitly). // { - map build2_mods; + // List of module packages together with the linked configuration + // clusters they belong to. + // + vector> build2_mods; for (const auto& pp: package_prereqs) { @@ -6249,22 +6252,33 @@ namespace bpkg continue; } - auto i (build2_mods.emplace (cp.name, cp.db)); - - if (!i.second) + // Make sure the module's database doesn't belong to any other + // cluster this module is also configured in. + // + for (const auto& m: build2_mods) { - database& db (i.first->second); + if (m.first.name != cp.name) + continue; // The `package_prereqs` map can only contain the same package // twice if databases differ. // - assert (db != cp.db); + assert (m.first.db != cp.db); + + const linked_databases& lcc (m.second); - fail << "building build system module " << cp.name << " in " - << "multiple configurations" << - info << db.config_orig << - info << cp.db.config_orig; + if (find (lcc.begin (), lcc.end (), cp.db) != lcc.end ()) + { + fail << "building build system module " << cp.name + << " in multiple configurations" << + info << m.first.db.config_orig << + info << cp.db.config_orig; + } } + + // Add the module and its cluster to the list. + // + build2_mods.emplace_back (cp, cp.db.cluster_configs ()); } } } diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index 4da7747..48fea7b 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -6465,6 +6465,27 @@ else libbaz configured 1.0.0 EOO } + + : build2-module-different-clusters + : + : Test that the same module can successfully be built in 2 configurations + : if they belong to different linked configuration clusters. + : + { + $cfg_create -d cfg --uuid $cfg_uuid &cfg/***; + $cfg_create -d cfg2 --uuid $cfg2_uuid &cfg2/***; + + test.arguments += -d cfg2; # Now refers 2 current dirs: cfg/ and cfg2/. + + $* "libbiz@$rep/t7a" +{ --config-uuid $cfg_uuid } \ + "libbuz@$rep/t7a" +{ --config-uuid $cfg2_uuid } --yes --trust-yes 2>>~%EOE% + %(added|fetching) .+%{4} + %(fetched|unpacked) .+%{26} + %configured .+%{13} + %info: .+ is up to date%{2} + %updated .+%{2} + EOE + } } : system -- cgit v1.1