aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-02-15 15:59:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-02-15 15:59:22 +0200
commit743273bd381a132c272226af00381da0494e8920 (patch)
treeb43f53fa0a1b40c1aa38238e42bbe0e0515afe13
parent84c947319c7300bab12f800088d6b92245388f20 (diff)
Diagnose various misuses of library metadata protocol
-rw-r--r--libbuild2/cc/common.cxx4
-rw-r--r--libbuild2/cc/functions.cxx9
-rw-r--r--libbuild2/target.hxx2
-rw-r--r--libbuild2/target.ixx21
4 files changed, 28 insertions, 8 deletions
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index 09a1752..ccb678c 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -320,6 +320,10 @@ namespace build2
if (pt.adhoc || pt == nullptr)
continue;
+ if (marked (pt))
+ fail << "implicit dependency cycle detected involving library "
+ << l;
+
bool la;
const file* f;
diff --git a/libbuild2/cc/functions.cxx b/libbuild2/cc/functions.cxx
index e05c707..8a48e66 100644
--- a/libbuild2/cc/functions.cxx
+++ b/libbuild2/cc/functions.cxx
@@ -74,6 +74,11 @@ namespace build2
{
name& n (*i), o;
const target& t (to_target (*bs, move (n), move (n.pair ? *++i : o)));
+
+ if (!t.matched (a))
+ fail << t << " is not matched" <<
+ info << "make sure this target is listed as prerequisite";
+
d.f (r, vs, *m, *bs, a, t);
}
@@ -174,6 +179,10 @@ namespace build2
(la = (f = t.is_a<liba> ())) ||
( (f = t.is_a<libs> ())))
{
+ if (!t.matched (a))
+ fail << t << " is not matched" <<
+ info << "make sure this target is listed as prerequisite";
+
d.f (ls, r, vs, *m, *bs, a, *f, la, li);
}
else
diff --git a/libbuild2/target.hxx b/libbuild2/target.hxx
index 809bf8b..5eed0a5 100644
--- a/libbuild2/target.hxx
+++ b/libbuild2/target.hxx
@@ -636,7 +636,7 @@ namespace build2
const opstate& operator[] (action a) const {return state[a];}
// Return true if the target has been matched for the specified action.
- // This function can only be called during execution.
+ // This function can only be called during the match or execute phases.
//
bool
matched (action) const;
diff --git a/libbuild2/target.ixx b/libbuild2/target.ixx
index b1e21ae..05f9698 100644
--- a/libbuild2/target.ixx
+++ b/libbuild2/target.ixx
@@ -158,17 +158,24 @@ namespace build2
inline bool target::
matched (action a) const
{
- assert (ctx.phase == run_phase::execute);
+ assert (ctx.phase == run_phase::match ||
+ ctx.phase == run_phase::execute);
const opstate& s (state[a]);
-
- // Note that while the target could be being executed, we should see at
- // least offset_matched since it must have been "achieved" before the
- // phase switch.
- //
size_t c (s.task_count.load (memory_order_relaxed) - ctx.count_base ());
- return c >= offset_matched;
+ if (ctx.phase == run_phase::match)
+ {
+ return c == offset_applied;
+ }
+ else
+ {
+ // Note that while the target could be being executed, we should see at
+ // least offset_matched since it must have been "achieved" before the
+ // phase switch.
+ //
+ return c >= offset_matched;
+ }
}
LIBBUILD2_SYMEXPORT target_state