diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-02-16 16:48:25 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-02-16 16:48:25 +0200 |
commit | 114fb345a5223ea513851f57c8c002abc1496c4a (patch) | |
tree | 4b433f67ca0b0cb74a7b33183000d2f2ac007e79 | |
parent | 6293ede7a742866a713050737cc2b43d51161b6f (diff) |
Perform ad hoc group resolution instead of resolve_group() in module search
-rw-r--r-- | build2/cc/compile-rule.cxx | 20 | ||||
-rw-r--r-- | build2/target.hxx | 7 |
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; |