aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-02-16 16:48:25 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-02-16 16:48:25 +0200
commit114fb345a5223ea513851f57c8c002abc1496c4a (patch)
tree4b433f67ca0b0cb74a7b33183000d2f2ac007e79
parent6293ede7a742866a713050737cc2b43d51161b6f (diff)
Perform ad hoc group resolution instead of resolve_group() in module search
-rw-r--r--build2/cc/compile-rule.cxx20
-rw-r--r--build2/target.hxx7
2 files changed, 22 insertions, 5 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index 632a9bf..17f9b72 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -3524,12 +3524,22 @@ namespace build2
// need to get hold of the corresponding mxx{} (unlikely but possible
// for bmi{} to have a different name).
//
+ // While we want to use group_prerequisite_members() below, we cannot
+ // call resolve_group() since we will be doing it "speculatively" for
+ // modules that we may use but also for modules that may use us. This
+ // quickly leads to deadlocks. So instead we are going to perform an
+ // ad hoc group resolution.
+ //
+ const target* pg;
if (p.is_a<bmi> ())
+ {
+ pg = pt != nullptr ? pt : &p.search (t);
pt = &search (t, mtt, p.key ()); // Same logic as in picking obj*{}.
+ }
else if (p.is_a (mtt))
{
- if (pt == nullptr)
- pt = &p.search (t);
+ pg = &search (t, bmi::static_type, p.key ());
+ if (pt == nullptr) pt = &p.search (t);
}
else
continue;
@@ -3537,14 +3547,14 @@ namespace build2
// Find the mxx{} prerequisite and extract its "file name" for the
// fuzzy match unless the user specified the module name explicitly.
//
- resolve_group (a, *pt);
- for (prerequisite_member p: group_prerequisite_members (a, *pt))
+ for (prerequisite_member p:
+ prerequisite_members (a, t, group_prerequisites (*pt, pg)))
{
if (p.is_a (*x_mod))
{
// Check for an explicit module name. Only look for an existing
// target (which means the name can only be specified on the
- // target itself, no target type/pattern-spec).
+ // target itself, not target type/pattern-spec).
//
const target* t (p.search_existing ());
const string* n (t != nullptr
diff --git a/build2/target.hxx b/build2/target.hxx
index e783ee4..5ba3905 100644
--- a/build2/target.hxx
+++ b/build2/target.hxx
@@ -711,6 +711,13 @@ namespace build2
t_.group->prerequisites ().empty ()
? nullptr : t_.group) {}
+ explicit
+ group_prerequisites (const target& t, const target* g)
+ : t_ (t),
+ g_ (g == nullptr ||
+ g->prerequisites ().empty ()
+ ? nullptr : g) {}
+
using prerequisites_type = target::prerequisites_type;
using base_iterator = prerequisites_type::const_iterator;