From 317e2cb68753c7b89783a3c829ba53889a370f8c Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 20 Jul 2023 10:18:54 +0200 Subject: Don't treat unmatched prerequisites as implicitly ad hoc It was surprising and inconvenient that they didn't end up in $<. Plus, such prerequisites can always be marked as ad hoc explicitly. --- libbuild2/adhoc-rule-buildscript.cxx | 14 ++++++++++---- libbuild2/adhoc-rule-buildscript.hxx | 7 +++++-- libbuild2/build/script/script.cxx | 20 +++++++++++++++++--- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/libbuild2/adhoc-rule-buildscript.cxx b/libbuild2/adhoc-rule-buildscript.cxx index fd0411f..3c42e66 100644 --- a/libbuild2/adhoc-rule-buildscript.cxx +++ b/libbuild2/adhoc-rule-buildscript.cxx @@ -533,7 +533,7 @@ namespace build2 l6 ([&]{trace << "unmatch " << *pt.target << ": " << mr.first;}); // If we managed to unmatch, blank it out so that it's not executed, - // etc. Otherwise, convert it to ad hoc (we also automatically avoid + // etc. Otherwise, leave it as is (but we still automatically avoid // hashing it, updating it during match in exec_depdb_dyndep(), and // making us out of date in execute_update_prerequisites()). // @@ -557,10 +557,16 @@ namespace build2 // treat it as ordinary ad hoc since it has the target pointer in // data). // - pt.include &= ~prerequisite_target::include_adhoc; + // But that makes it impossible to distinguish ad hoc unmatch from + // ordinary unmatch prerequisites later when setting $<. Another + // flag to the rescue. + // + if ((pt.include & prerequisite_target::include_adhoc) != 0) + { + pt.include &= ~prerequisite_target::include_adhoc; + pt.include |= include_unmatch_adhoc; + } } - else - pt.include |= prerequisite_target::include_adhoc; } } } diff --git a/libbuild2/adhoc-rule-buildscript.hxx b/libbuild2/adhoc-rule-buildscript.hxx index 994b18c..336dceb 100644 --- a/libbuild2/adhoc-rule-buildscript.hxx +++ b/libbuild2/adhoc-rule-buildscript.hxx @@ -96,9 +96,12 @@ namespace build2 public: using script_type = build::script::script; - // The prerequisite_target::include bit that indicates update=unmatch. + // The prerequisite_target::include bits that indicate update=unmatch and + // an ad hoc version of that. // - static const uintptr_t include_unmatch = 0x100; + static const uintptr_t include_unmatch = 0x100; + static const uintptr_t include_unmatch_adhoc = 0x200; + script_type script; string checksum; // Script text hash. diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx index 0f31e7f..0d96cc3 100644 --- a/libbuild2/build/script/script.cxx +++ b/libbuild2/build/script/script.cxx @@ -7,6 +7,8 @@ #include +#include // include_unmatch* + #include #include @@ -91,13 +93,25 @@ namespace build2 // much sense, they could be handy to exclude certain prerequisites // from $< while still treating them as such, especially in rule. // + // While initially we treated update=unmatch prerequisites as + // implicitly ad hoc, this turned out to be not quite correct, so + // now we add them unless they are explicitly marked ad hoc. + // names ns; - for (const prerequisite_target& pt: target.prerequisite_targets[a]) + for (const prerequisite_target& p: target.prerequisite_targets[a]) { // See adhoc_buildscript_rule::execute_update_prerequisites(). // - if (pt.target != nullptr && !pt.adhoc ()) - pt.target->as_name (ns); + if (const target_type* pt = + p.target != nullptr ? (p.adhoc () ? nullptr : p.target) : + (p.include & adhoc_buildscript_rule::include_unmatch) != 0 && + (p.include & prerequisite_target::include_adhoc) == 0 && + (p.include & adhoc_buildscript_rule::include_unmatch_adhoc) == 0 + ? reinterpret_cast (p.data) + : nullptr) + { + pt->as_name (ns); + } } assign (var_ps) = move (ns); -- cgit v1.1