aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-07-20 10:18:54 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-07-20 10:18:54 +0200
commit317e2cb68753c7b89783a3c829ba53889a370f8c (patch)
tree04b803c94b95645130dc7942cdf53aa9a0357672 /libbuild2
parentd3ef150c45d9325bc075d33a00c8cf0a6b1bf954 (diff)
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.
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/adhoc-rule-buildscript.cxx14
-rw-r--r--libbuild2/adhoc-rule-buildscript.hxx7
-rw-r--r--libbuild2/build/script/script.cxx20
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 <libbuild2/target.hxx>
+#include <libbuild2/adhoc-rule-buildscript.hxx> // include_unmatch*
+
#include <libbuild2/script/timeout.hxx>
#include <libbuild2/build/script/parser.hxx>
@@ -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<target_type*> (p.data)
+ : nullptr)
+ {
+ pt->as_name (ns);
+ }
}
assign (var_ps) = move (ns);