aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/bash/rule.cxx5
-rw-r--r--libbuild2/cc/install-rule.cxx5
-rw-r--r--libbuild2/cc/link-rule.hxx34
-rw-r--r--libbuild2/install/rule.cxx11
-rw-r--r--libbuild2/install/rule.hxx6
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&);