diff options
-rw-r--r-- | libbuild2/bash/rule.cxx | 5 | ||||
-rw-r--r-- | libbuild2/cc/install-rule.cxx | 5 | ||||
-rw-r--r-- | libbuild2/cc/link-rule.hxx | 34 | ||||
-rw-r--r-- | libbuild2/install/rule.cxx | 11 | ||||
-rw-r--r-- | libbuild2/install/rule.hxx | 6 |
5 files changed, 43 insertions, 18 deletions
diff --git a/libbuild2/bash/rule.cxx b/libbuild2/bash/rule.cxx index 82c06c7..1138227 100644 --- a/libbuild2/bash/rule.cxx +++ b/libbuild2/bash/rule.cxx @@ -400,7 +400,10 @@ namespace build2 recipe install_rule:: apply (action a, target& t) const { - recipe r (file_rule::apply (a, t)); + recipe r (file_rule::apply_impl (a, t)); + + if (r == nullptr) + return noop_recipe; if (a.operation () == update_id) { diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx index 3e62d59..59acaf7 100644 --- a/libbuild2/cc/install-rule.cxx +++ b/libbuild2/cc/install-rule.cxx @@ -165,7 +165,10 @@ namespace build2 recipe install_rule:: apply (action a, target& t) const { - recipe r (file_rule::apply (a, t)); + recipe r (file_rule::apply_impl (a, t)); + + if (r == nullptr) + return noop_recipe; if (a.operation () == update_id) { diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx index 0fc1790..655d36a 100644 --- a/libbuild2/cc/link-rule.hxx +++ b/libbuild2/cc/link-rule.hxx @@ -278,22 +278,28 @@ namespace build2 // have already been executed, then it was for install. // // This has an interesting implication: it means that this rule cannot - // be used to update targets during match. Specifically, we cannot be - // executed for group resolution purposes (not a problem) nor as part - // of the generated source update. The latter case can be a problem: - // imagine a code generator that itself may need to be updated before - // it can be used to re-generate some out-of-date source code. As an - // aside, note that even if we were somehow able to communicate the - // "for install" in this case, the result of such an update may not - // actually be "usable" (e.g., not runnable because of the missing + // be used to update targets to be installed during match (since we + // would notice that they are for install too late). Specifically, we + // cannot be executed for group resolution purposes (should not be a + // problem) nor as part of the generated source update. The latter + // case can be a problem: imagine a source code generator that itself + // may need to be updated before it can be used to re-generate some + // out-of-date source code (or, worse, both the generator and the + // target to be installed depend on the same library). + // + // As an aside, note that even if we were somehow able to communicate + // the "for install" in this case, the result of such an update may + // not actually be "usable" (e.g., not runnable because of the missing // rpaths). There is another prominent case where the result may not - // be usable: cross-compilation. + // be usable: cross-compilation (in fact, if you think about it, "for + // install" is quite similar to cross-compilation: we are building for + // a foreign "environment" and thus cannot execute the results of the + // build). // - // So the current (admittedly fuzzy) thinking is that a project shall - // not try to use its own build for update since it may not be usable - // (because of cross-compilations, being "for install", etc). Instead, - // it should rely on another, "usable" build of itself (this, BTW, is - // related to bpkg's build-time vs run-time dependencies). + // So the current thinking is that a project shall not try to use its + // own "for install" (or, naturally, cross-compilation) build for + // update since it may not be usable. Instead, it should rely on + // another, "usable" build. // optional<bool> for_install; diff --git a/libbuild2/install/rule.cxx b/libbuild2/install/rule.cxx index 3543286..b4b4a01 100644 --- a/libbuild2/install/rule.cxx +++ b/libbuild2/install/rule.cxx @@ -298,6 +298,13 @@ namespace build2 recipe file_rule:: apply (action a, target& t) const { + recipe r (apply_impl (a, t)); + return r != nullptr ? r : noop_recipe; + } + + recipe file_rule:: + apply_impl (action a, target& t) const + { tracer trace ("install::file_rule::apply"); // Note that we are called both as the outer part during the update-for- @@ -307,10 +314,10 @@ namespace build2 // In both cases we first determine if the target is installable and // return noop if it's not. Otherwise, in the first case (update-for- // un/install) we delegate to the normal update and in the second - // (un/install) -- perform the test. + // (un/install) -- perform the install. // if (!lookup_install<path> (t, "install")) - return noop_recipe; + return empty_recipe; // In both cases, the next step is to search, match, and collect all the // installable prerequisites. diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx index 2ed162e..61c0ae9 100644 --- a/libbuild2/install/rule.hxx +++ b/libbuild2/install/rule.hxx @@ -133,6 +133,12 @@ namespace build2 virtual recipe apply (action, target&) const override; + // Implementation of apply() that returns empty_recipe if the target is + // not installable. + // + recipe + apply_impl (action, target&) const; + static target_state perform_update (action, const target&); |