aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-10-07 22:36:01 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-10-08 16:23:51 +0300
commit9b6086440aa261fc376c8293df2345050658dd2b (patch)
tree8f632c035566a469c9eca32b34659bc48ef6a4b2
parentaa2df902257cb939a36a515e34b0559cd3c24462 (diff)
Allow building build module in multiple configurations if they belong to different configuration clusters
-rw-r--r--bpkg/database.cxx33
-rw-r--r--bpkg/database.hxx8
-rw-r--r--bpkg/pkg-build.cli2
-rw-r--r--bpkg/pkg-build.cxx38
-rw-r--r--tests/pkg-build.testscript21
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
"<dir>",
"Assume current configuration is in <dir> 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<package_name, database&> build2_mods;
+ // List of module packages together with the linked configuration
+ // clusters they belong to.
+ //
+ vector<pair<config_package, linked_databases>> 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