aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-02-08 14:32:41 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-02-09 10:19:46 +0200
commit9689e2bafcf9af511df1f357aa3f6ec8545d0010 (patch)
tree0d7c28e6ec9e900b90302e0b6754306f3701865c
parent1cccd7acfa672397b7d5d1a759f803bb0f748224 (diff)
Don't skip empty see-through target groups
-rw-r--r--libbuild2/target.hxx20
-rw-r--r--libbuild2/target.ixx19
-rw-r--r--libbuild2/target.txx33
3 files changed, 34 insertions, 38 deletions
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index 4ce871b..76c01b6 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -1144,10 +1144,19 @@ namespace build2
// See-through group members iteration mode. Ad hoc members must always
// be entered explicitly.
//
+ // Note that if the group is empty, then we see the group itself (rather
+ // than nothing). Failed that, an empty group would never be executed (e.g.,
+ // during clean) since there is no member to trigger the group execution.
+ // Other than that, it feels like seeing the group in this cases should be
+ // harmless (i.e., rules are generally prepared to see prerequisites they
+ // don't recognize).
+ //
enum class members_mode
{
- always, // Iterate over members, assert if not resolvable.
- maybe, // Iterate over members if resolvable, group otherwise.
+ always, // Iterate over members if not empty, group if empty, assert if
+ // not resolvable.
+ maybe, // Iterate over members if resolvable and not empty, group
+ // otherwise.
never // Iterate over group (can still use enter_group()).
};
@@ -1200,9 +1209,10 @@ namespace build2
leave_group ();
// Iterate over this group's members. Return false if the member
- // information is not available. Similar to leave_group(), you should
- // increment the iterator after calling this function (provided it
- // returned true).
+ // information is not available (note: return true if the group is
+ // empty). Similar to leave_group(), you should increment the iterator
+ // after calling this function provided group() returns true (see
+ // below).
//
bool
enter_group ();
diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx
index cfc3847..fddf1b2 100644
--- a/libbuild2/target.ixx
+++ b/libbuild2/target.ixx
@@ -456,6 +456,25 @@ namespace build2
}
template <typename T>
+ inline void prerequisite_members_range<T>::iterator::
+ switch_mode ()
+ {
+ g_ = resolve_members (*i_);
+
+ if (g_.members != nullptr)
+ {
+ // See empty see through groups as groups.
+ //
+ for (j_ = 1; j_ <= g_.count && g_.members[j_ - 1] == nullptr; ++j_) ;
+
+ if (j_ > g_.count)
+ g_.count = 0;
+ }
+ else
+ assert (r_->mode_ != members_mode::always); // Group can't be resolved.
+ }
+
+ template <typename T>
inline auto prerequisite_members_range<T>::iterator::
operator++ () -> iterator&
{
diff --git a/libbuild2/target.txx b/libbuild2/target.txx
index 5b48ad1..1363935 100644
--- a/libbuild2/target.txx
+++ b/libbuild2/target.txx
@@ -8,39 +8,6 @@
namespace build2
{
- // prerequisite_members_range
- //
- template <typename T>
- void prerequisite_members_range<T>::iterator::
- switch_mode ()
- {
- // A group could be empty, so we may have to iterate.
- //
- do
- {
- g_ = resolve_members (*i_);
-
- // Group could not be resolved.
- //
- if (g_.members == nullptr)
- {
- assert (r_->mode_ != members_mode::always);
- return;
- }
-
- // Skip empty see through groups.
- //
- for (j_ = 1; j_ <= g_.count && g_.members[j_ - 1] == nullptr; ++j_) ;
- if (j_ <= g_.count)
- break;
-
- g_.count = 0;
- }
- while (++i_ != r_->e_ && i_->type.see_through);
- }
-
- //
- //
template <const char* ext>
const char*
target_extension_fix (const target_key& tk, const scope*)