aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/algorithm.cxx10
-rw-r--r--libbuild2/target.cxx24
-rw-r--r--libbuild2/target.hxx14
3 files changed, 25 insertions, 23 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index d69ff95..76f7c4c 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1853,6 +1853,7 @@ namespace build2
{
using mode = backlink_mode;
+ context& ctx (t.ctx);
const scope& s (t.base_scope ());
backlinks bls;
@@ -1895,11 +1896,12 @@ namespace build2
// Note that we want to avoid group or tt/patter-spec lookup. And
// since this is an ad hoc member (which means it was either declared
// in the buildfile or added by the rule), we assume that the value,
- // if any, will be set as a rule-specific variable (since setting it
- // as a target-specific wouldn't be MT-safe). @@ Don't think this
- // applies to declared ad hoc members.
+ // if any, will be set as a target or rule-specific variable.
//
- lookup l (mt->state[a].vars[t.ctx.var_backlink]);
+ lookup l (mt->state[a].vars[ctx.var_backlink]);
+
+ if (!l)
+ l = mt->vars[ctx.var_backlink];
optional<mode> bm (l ? backlink_test (*mt, l) : m);
diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx
index c78fc57..41a3273 100644
--- a/libbuild2/target.cxx
+++ b/libbuild2/target.cxx
@@ -158,21 +158,18 @@ namespace build2
{
++r.second;
-#if 1
+ // While we went back to not treating the first member as a group for
+ // variable lookup, let's keep this logic in case one day we end up with
+ // a separate ad hoc group target.
+ //
+#if 0
// In case of an ad hoc group, we may have to look in two groups.
//
if ((g1 = group) != nullptr)
{
auto p (g1->vars.lookup (var));
if (p.first != nullptr)
- {
- if (g1->adhoc_group ())
- fail << "ad hoc group variable lookup " << var <<
- info << "member " << *this <<
- info << "group " << *g1;
-
r.first = lookup_type (*p.first, p.second, g1->vars);
- }
else
{
if ((g2 = g1->group) != nullptr)
@@ -216,17 +213,6 @@ namespace build2
g1 != nullptr ? &g1k : nullptr,
g2 != nullptr ? &g2k : nullptr));
- if (p.first && g1 != nullptr && g1->adhoc_group ())
- {
- for (size_t d (2); d <= p.second; d += 3)
- {
- if (p.second == d)
- fail << "ad hoc group type/pattern variable lookup " << var <<
- info << "member " << *this <<
- info << "group " << *g1;
- }
- }
-
r.first = move (p.first);
r.second = r.first ? r.second + p.second : p.second;
}
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index 038552f..44e8538 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -408,6 +408,10 @@ namespace build2
// - Ad hoc group cannot have sub-groups (of any kind) though an ad hoc
// group can be a sub-group of an explicit group.
//
+ // - Member variable lookup skips the ad hoc group (since the group is the
+ // first member, this is normally what we want). But special semantics
+ // could be arranged; see var_backlink, for example.
+ //
// Note that ad hoc groups can be part of explicit groups. In a sense, we
// have a two-level grouping: an explicit group with its members each of
// which can be an ad hoc group. For example, lib{} contains libs{} which
@@ -416,6 +420,16 @@ namespace build2
// Use add_adhoc_member(), find_adhoc_member() from algorithms to manage
// ad hoc members.
//
+ // One conceptual issue we have with our ad hoc group implementation is
+ // that the behavior could be sensitive to the order in which the members
+ // are specified (due to the primary member logic). For example, unless we
+ // specify the header in the header/source group first, it will not be
+ // installed. Perhaps the solution is to synthesize a separate group
+ // target for the ad hoc members (with a special target type that rules
+ // like install could recognize). See also the variable lookup semantics.
+ // We could also probably support see_through via an attribute or some
+ // such.
+ //
const_ptr<target> adhoc_member = nullptr;
// Return true if this target is an ad hoc group (that is, its primary