diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-07-20 07:44:36 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-07-20 07:44:36 +0200 |
commit | b61e0de250d522ec9a8e16146ef979a65c181db1 (patch) | |
tree | 93cf8e451a5c605f9d0159c6474e77d47b6f2de4 /libbuild2/install | |
parent | 7aabdc2ccfea23c93e3b94290df59708aa179104 (diff) |
Change inner rule/prerequisites match order in install::file_rule
The old order messed up the for-install signaling logic. See the long comment
in install::file_rule::apply_impl() for background and details.
Diffstat (limited to 'libbuild2/install')
-rw-r--r-- | libbuild2/install/rule.cxx | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/libbuild2/install/rule.cxx b/libbuild2/install/rule.cxx index 20a4bc3..4dd11e8 100644 --- a/libbuild2/install/rule.cxx +++ b/libbuild2/install/rule.cxx @@ -378,11 +378,36 @@ namespace build2 // (actual update). We used to do this after matching the prerequisites // but the inner rule may provide some rule-specific information (like // the target extension for exe{}) that may be required during the - // prerequisite search (like the base name for in{}). + // prerequisite search (like the base name for in{}; this no longer + // reproduces likely due to the changes to exe{} extension derivation + // but a contrived arrangement can still be made to trigger this). // + // But then we discovered that doing this before the prerequisites messes + // up with the for-install signaling. Specifically, matching the + // prerequisites may signal that they are being updated for install, + // for example, for a library via a metadata library used in a moc + // recipe. While matching the inner rule may trigger updating during + // match of such prerequisites, for example, a source file generated by + // that moc recipe that depends on this metadata library. If we match + // prerequisites before, then the library that is pulled by the metadata + // library will be updated before we had a chance to signal that it + // should be updated for install. + // + // To try to accommodate both cases (as best as we can) we now split the + // inner rule match into two steps: we do the match before and apply + // after. This allows rules that deal with tricky prerequisites like + // in{} to assign the target path in match() instead of apply() (see + // in::rule, for example). + // +#if 0 optional<bool> unchanged; if (a.operation () == update_id) unchanged = match_inner (a, t, unmatch::unchanged).first; +#else + action ia (a.inner_action ()); + if (a.operation () == update_id) + match_only_sync (ia, t); +#endif optional<const scope*> is; // Installation scope (resolve lazily). @@ -454,6 +479,12 @@ namespace build2 pts.push_back (prerequisite_target (pt, pi)); } +#if 1 + optional<bool> unchanged; + if (a.operation () == update_id) + unchanged = match_sync (ia, t, unmatch::unchanged).first; +#endif + if (a.operation () == update_id) { return *unchanged |