aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/adhoc-rule-regex-pattern.cxx1
-rw-r--r--libbuild2/algorithm.cxx7
-rw-r--r--libbuild2/context.cxx1
-rw-r--r--libbuild2/context.hxx4
-rw-r--r--libbuild2/operation.cxx42
5 files changed, 41 insertions, 14 deletions
diff --git a/libbuild2/adhoc-rule-regex-pattern.cxx b/libbuild2/adhoc-rule-regex-pattern.cxx
index c4b4cab..3f207dc 100644
--- a/libbuild2/adhoc-rule-regex-pattern.cxx
+++ b/libbuild2/adhoc-rule-regex-pattern.cxx
@@ -433,6 +433,7 @@ namespace build2
else
{
// @@ TODO: currently this uses type as the ad hoc member identity.
+ // Use inject_adhoc_group_member() variant?
//
add_adhoc_member (
t,
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 966c7a8..cf972e7 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1283,7 +1283,10 @@ namespace build2
throw failed ();
if ((r = g.group_members (a)).members != nullptr)
+ {
+ g.ctx.resolve_count.fetch_add (1, memory_order_relaxed);
break;
+ }
// Unlock and to execute ...
//
@@ -1300,6 +1303,10 @@ namespace build2
// we would have already known the members list) and we really do need
// to execute it now.
//
+ // Note that while it might be tempting to decrement resolve_count
+ // here, there is no guarantee that we were the ones who have matched
+ // this target.
+ //
{
phase_switch ps (g.ctx, run_phase::execute);
execute_direct_sync (a, g);
diff --git a/libbuild2/context.cxx b/libbuild2/context.cxx
index ecf34fc..c0442f0 100644
--- a/libbuild2/context.cxx
+++ b/libbuild2/context.cxx
@@ -850,6 +850,7 @@ namespace build2
dependency_count.store (0, memory_order_relaxed);
target_count.store (0, memory_order_relaxed);
skip_count.store (0, memory_order_relaxed);
+ resolve_count.store (0, memory_order_relaxed);
// Clear accumulated targets with post hoc prerequisites.
//
diff --git a/libbuild2/context.hxx b/libbuild2/context.hxx
index 7574787..a54d010 100644
--- a/libbuild2/context.hxx
+++ b/libbuild2/context.hxx
@@ -405,11 +405,13 @@ namespace build2
// decremented after such recipe has been executed. If such a recipe has
// skipped executing the operation, then it should increment the skip
// count. These two counters are used for progress monitoring and
- // diagnostics.
+ // diagnostics. The resolve count keeps track of the number of targets
+ // matched but not executed as a result of the resolve_members() calls.
//
atomic_count dependency_count;
atomic_count target_count;
atomic_count skip_count;
+ atomic_count resolve_count;
// Build state (scopes, targets, variables, etc).
//
diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx
index e57caa5..f199827 100644
--- a/libbuild2/operation.cxx
+++ b/libbuild2/operation.cxx
@@ -761,26 +761,42 @@ namespace build2
if (fail)
throw failed ();
- // We should have executed every target that we matched, provided we
- // haven't failed (in which case we could have bailed out early).
- //
- assert (ctx.target_count.load (memory_order_relaxed) == 0);
-
#ifndef NDEBUG
- if (ctx.dependency_count.load (memory_order_relaxed) != 0)
+ // For now we disable these checks if we've performed any group member
+ // resolutions that required a match (with apply()) but not execute.
+ //
+ if (ctx.resolve_count.load (memory_order_relaxed) == 0)
{
- diag_record dr;
- dr << info << "detected unexecuted matched targets:";
+ // We should have executed every target that we matched, provided we
+ // haven't failed (in which case we could have bailed out early).
+ //
+ assert (ctx.target_count.load (memory_order_relaxed) == 0);
- for (const auto& pt: ctx.targets)
+ if (ctx.dependency_count.load (memory_order_relaxed) != 0)
{
- const target& t (*pt);
- if (size_t n = t[a].dependents.load (memory_order_relaxed))
- dr << text << t << ' ' << n;
+ diag_record dr;
+ dr << info << "detected unexecuted matched targets:";
+
+ for (const auto& pt: ctx.targets)
+ {
+ const target& t (*pt);
+
+ if (size_t n = t[a].dependents.load (memory_order_relaxed))
+ dr << text << t << ' ' << n;
+
+ if (a.outer ())
+ {
+ action ia (a.inner_action ());
+
+ if (size_t n = t[ia].dependents.load (memory_order_relaxed))
+ dr << text << t << ' ' << n;
+ }
+ }
}
+
+ assert (ctx.dependency_count.load (memory_order_relaxed) == 0);
}
#endif
- assert (ctx.dependency_count.load (memory_order_relaxed) == 0);
}
const meta_operation_info mo_perform {