From d3ef150c45d9325bc075d33a00c8cf0a6b1bf954 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 20 Jul 2023 10:17:03 +0200 Subject: Consider unmatched prerequisites in updated_during_match() check --- libbuild2/adhoc-rule-buildscript.cxx | 24 +++++++++++++++++++++--- libbuild2/build/script/parser.cxx | 5 +++++ libbuild2/dyndep.cxx | 18 ++++++++++-------- libbuild2/target.hxx | 11 +++++++++-- 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 (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 $ (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 (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 (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 (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; -- cgit v1.1