aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/algorithm.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-02-14 08:39:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-02-14 08:39:58 +0200
commit53b6896e48aaa6ee2b414bd36275263c57b490f8 (patch)
tree823488269e1a9d586e64fdc06d24435f2a134c5e /libbuild2/algorithm.cxx
parent3d39584285e4b39e7290bea9b2e4006cd1cf8a10 (diff)
Avoid duplicate fsdir{} in inject_fsdir(), match_prerequisite*() call sequences
Diffstat (limited to 'libbuild2/algorithm.cxx')
-rw-r--r--libbuild2/algorithm.cxx31
1 files changed, 27 insertions, 4 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 87217f7..26fad23 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -1723,12 +1723,25 @@ namespace build2
{
auto& pts (t.prerequisite_targets[a]);
+ size_t i (pts.size ()); // Index of the first to be added.
+
+ // Avoid duplicating fsdir{} that may have already been injected by
+ // inject_fsdir() (in which case it is expected to be first).
+ //
+ const target* dir (nullptr);
+ if (i != 0)
+ {
+ const prerequisite_target& pt (pts.front ());
+
+ if (pt.target != nullptr && pt.adhoc () && pt.target->is_a<fsdir> ())
+ dir = pt.target;
+ }
+
// Start asynchronous matching of prerequisites. Wait with unlocked phase
// to allow phase switching.
//
wait_guard wg (t.ctx, t.ctx.count_busy (), t[a].task_count, true);
- size_t i (pts.size ()); // Index of the first to be added.
for (auto&& p: forward<R> (r))
{
// Ignore excluded.
@@ -1742,7 +1755,9 @@ namespace build2
? ms (a, t, p, pi)
: prerequisite_target (&search (t, p), pi));
- if (pt.target == nullptr || (s != nullptr && !pt.target->in (*s)))
+ if (pt.target == nullptr ||
+ pt.target == dir ||
+ (s != nullptr && !pt.target->in (*s)))
continue;
match_async (a, *pt.target, t.ctx.count_busy (), t[a].task_count);
@@ -1905,6 +1920,10 @@ namespace build2
const fsdir*
inject_fsdir (action a, target& t, bool match, bool prereq, bool parent)
{
+ auto& pts (t.prerequisite_targets[a]);
+
+ assert (!prereq || pts.empty ()); // This prerequisite target must be first.
+
const fsdir* r (inject_fsdir_impl (t, prereq, parent));
if (r != nullptr)
@@ -1915,7 +1934,7 @@ namespace build2
// Make it ad hoc so that it doesn't end up in prerequisite_targets
// after execution.
//
- t.prerequisite_targets[a].emplace_back (r, include_type::adhoc);
+ pts.emplace_back (r, include_type::adhoc);
}
return r;
@@ -1924,12 +1943,16 @@ namespace build2
const fsdir*
inject_fsdir_direct (action a, target& t, bool prereq, bool parent)
{
+ auto& pts (t.prerequisite_targets[a]);
+
+ assert (!prereq || pts.empty ()); // This prerequisite target must be first.
+
const fsdir* r (inject_fsdir_impl (t, prereq, parent));
if (r != nullptr)
{
match_direct_sync (a, *r);
- t.prerequisite_targets[a].emplace_back (r, include_type::adhoc);
+ pts.emplace_back (r, include_type::adhoc);
}
return r;