aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-07-20 10:17:03 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-07-20 10:17:03 +0200
commitd3ef150c45d9325bc075d33a00c8cf0a6b1bf954 (patch)
tree25ca7cd58d81d8453c6a08f45c0b94ccdfaea03d
parentb61e0de250d522ec9a8e16146ef979a65c181db1 (diff)
Consider unmatched prerequisites in updated_during_match() check
-rw-r--r--libbuild2/adhoc-rule-buildscript.cxx24
-rw-r--r--libbuild2/build/script/parser.cxx5
-rw-r--r--libbuild2/dyndep.cxx18
-rw-r--r--libbuild2/target.hxx11
4 files changed, 45 insertions, 13 deletions
diff --git a/libbuild2/adhoc-rule-buildscript.cxx b/libbuild2/adhoc-rule-buildscript.cxx
index ab5706c..fd0411f 100644
--- a/libbuild2/adhoc-rule-buildscript.cxx
+++ b/libbuild2/adhoc-rule-buildscript.cxx
@@ -543,8 +543,22 @@ namespace build2
// information (e.g., poptions from a library) and those will be
// change-tracked.
//
+ // Note: set the include_target flag for the updated_during_match()
+ // check.
+ //
if (mr.first)
+ {
+ pt.data = reinterpret_cast<uintptr_t> (pt.target);
pt.target = nullptr;
+ pt.include |= prerequisite_target::include_target;
+
+ // Note that this prerequisite could also be ad hoc and we must
+ // clear that flag if we managed to unmatch (failed that we will
+ // treat it as ordinary ad hoc since it has the target pointer in
+ // data).
+ //
+ pt.include &= ~prerequisite_target::include_adhoc;
+ }
else
pt.include |= prerequisite_target::include_adhoc;
}
@@ -828,9 +842,7 @@ namespace build2
// them to the auxiliary data member in prerequisite_target (see
// execute_update_prerequisites() for details).
//
- // @@ This actually messes up with updated_during_match() check. Could
- // we not redo this so that we always keep p.target intact? Can't
- // we just omit p.adhoc() targets from $<?
+ // Note: set the include_target flag for the updated_during_match() check.
//
for (prerequisite_target& p: pts)
{
@@ -840,6 +852,7 @@ namespace build2
{
p.data = reinterpret_cast<uintptr_t> (p.target);
p.target = nullptr;
+ p.include |= prerequisite_target::include_target;
}
}
@@ -1898,6 +1911,7 @@ namespace build2
// !NULL false 1 - normal prerequisite already updated
// !NULL true 0 - ad hoc prerequisite to be updated and blanked
// NULL true !NULL - ad hoc prerequisite already updated and blanked
+ // NULL false !NULL - unmatched prerequisite (ignored by this function)
//
// Note that we still execute already updated prerequisites to keep the
// dependency counts straight. But we don't consider them for the "renders
@@ -1972,10 +1986,14 @@ namespace build2
// Blank out adhoc.
//
+ // Note: set the include_target flag for the updated_during_match()
+ // check.
+ //
if (p.adhoc ())
{
p.data = reinterpret_cast<uintptr_t> (p.target);
p.target = nullptr;
+ p.include |= prerequisite_target::include_target;
}
}
}
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index d449f4b..bb9ff66 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -2591,10 +2591,15 @@ namespace build2
{
prerequisite_target& pt (pts.back ());
+ // Note: set the include_target flag for consistency (the
+ // updated_during_match() check does not apply since it's a
+ // dynamic prerequisite).
+ //
if (pt.adhoc ())
{
pt.data = reinterpret_cast<uintptr_t> (pt.target);
pt.target = nullptr;
+ pt.include |= prerequisite_target::include_target;
}
else
pt.data = 1; // Already updated.
diff --git a/libbuild2/dyndep.cxx b/libbuild2/dyndep.cxx
index c0360f0..e6d0643 100644
--- a/libbuild2/dyndep.cxx
+++ b/libbuild2/dyndep.cxx
@@ -70,19 +70,21 @@ namespace build2
{
const prerequisite_target& p (pts[i]);
- // @@ This currently doesn't cover adhoc targets if matched with
- // buildscript (it stores them in p.data). Probably need to redo
- // things there (see adhoc_buildscript_rule::apply()).
+ // If include_target flag is specified, then p.data contains the
+ // target pointer.
//
- if (p.target != nullptr)
+ if (const target* xt =
+ (p.target != nullptr ? p.target :
+ ((p.include & prerequisite_target::include_target) != 0
+ ? reinterpret_cast<target*> (p.data)
+ : nullptr)))
{
- if (p.target == &pt &&
- (p.include & prerequisite_target::include_udm) != 0)
+ if (xt == &pt && (p.include & prerequisite_target::include_udm) != 0)
return true;
- if (size_t n = p.target->prerequisite_targets[a].size ())
+ if (size_t n = xt->prerequisite_targets[a].size ())
{
- if (updated_during_match (a, *p.target, n, pt))
+ if (updated_during_match (a, *xt, n, pt))
return true;
}
}
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index aa3df7f..79ec9fa 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -111,8 +111,15 @@ namespace build2
// prerequisites that are updated during match should have this bit set
// (see dyndep_rule::*_existing_file() for details).
//
- static const uintptr_t include_adhoc = 0x01;
- static const uintptr_t include_udm = 0x02;
+ // target
+ //
+ // The data member contains the target pointer that has been "blanked
+ // out" for some reason (updated during match, unmatched, etc). See
+ // dyndep_rule::updated_during_match() for details.
+ //
+ static const uintptr_t include_adhoc = 0x01;
+ static const uintptr_t include_udm = 0x02;
+ static const uintptr_t include_target = 0x80;
uintptr_t include;