aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-12-04 11:48:55 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-12-04 11:48:55 +0200
commitacfa68e443f2ec694d2716b8437bee1594d004b6 (patch)
tree6cfcaeca074a7ca4ace2d66647e047eeaa64f96e /libbuild2
parent4168cda2363f3d796d0b9922852e249aac3131ba (diff)
Fix bug in installed libraries matching logic
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/bin/target.cxx2
-rw-r--r--libbuild2/bin/target.hxx8
-rw-r--r--libbuild2/cc/common.cxx58
3 files changed, 41 insertions, 27 deletions
diff --git a/libbuild2/bin/target.cxx b/libbuild2/bin/target.cxx
index 94851cd..bf701c9 100644
--- a/libbuild2/bin/target.cxx
+++ b/libbuild2/bin/target.cxx
@@ -53,7 +53,7 @@ namespace build2
const target_type libx::static_type
{
"libx",
- &target::static_type,
+ &mtime_target::static_type,
nullptr,
nullptr,
nullptr,
diff --git a/libbuild2/bin/target.hxx b/libbuild2/bin/target.hxx
index 8be8c23..f8d2dd0 100644
--- a/libbuild2/bin/target.hxx
+++ b/libbuild2/bin/target.hxx
@@ -200,10 +200,14 @@ namespace build2
// Common base for lib{} and libul{} groups.
//
- class LIBBUILD2_BIN_SYMEXPORT libx: public target
+ // Use mtime_target as a base for the "trust me it exists" functionality
+ // which we use, for example, to have installed lib{} prerequisites that
+ // are matched by the fallback file rule.
+ //
+ class LIBBUILD2_BIN_SYMEXPORT libx: public mtime_target
{
public:
- using target::target;
+ using mtime_target::mtime_target;
public:
static const target_type static_type;
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index 2f55dcb..62f0ee0 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -840,36 +840,36 @@ namespace build2
return r;
// If we cannot acquire the lock then this mean the target has already
- // been matched (though not clear by whom) and we assume all of this
- // has already been done.
+ // been matched and we assume all of this has already been done.
//
- target_lock ll (lock (act, *lt));
+ auto lock = [act] (const target* t) -> target_lock
+ {
+ auto l (t != nullptr ? build2::lock (act, *t, true) : target_lock ());
+
+ if (l && l.offset == target::offset_matched)
+ {
+ assert ((*t)[act].rule == &file_rule::rule_match);
+ l.unlock ();
+ }
+
+ return l;
+ };
+
+ target_lock ll (lock (lt));
// Set lib{} group members to indicate what's available. Note that we
// must be careful here since its possible we have already imported some
// of its members.
//
+ timestamp mt (timestamp_nonexistent);
if (ll)
{
- if (a != nullptr) lt->a = a;
- if (s != nullptr) lt->s = s;
+ if (s != nullptr) {lt->s = s; mt = s->mtime ();}
+ if (a != nullptr) {lt->a = a; mt = a->mtime ();}
}
- target_lock al (a != nullptr ? lock (act, *a, true) : target_lock ());
-
- if (al && al.offset == target::offset_matched)
- {
- assert ((*a)[act].rule == &file_rule::rule_match);
- al.unlock ();
- }
-
- target_lock sl (s != nullptr ? lock (act, *s, true) : target_lock ());
-
- if (sl && sl.offset == target::offset_matched)
- {
- assert ((*s)[act].rule == &file_rule::rule_match);
- sl.unlock ();
- }
+ target_lock al (lock (a));
+ target_lock sl (lock (s));
if (!al) a = nullptr;
if (!sl) s = nullptr;
@@ -965,9 +965,9 @@ namespace build2
pkgconfig_load (act, *p.scope, *lt, a, s, pc, *pd, sysd, *usrd);
}
- // If we have the lock (meaning this is the first time), set the
- // traget's rule/recipe. Failed that we will keep re-locking it,
- // updating its members, etc.
+ // If we have the lock (meaning this is the first time), set the matched
+ // rule. Failed that we will keep re-locking it, updating its members,
+ // etc.
//
// For members, use the fallback file rule instead of noop since we may
// need their prerequisites matched (used for modules support; see
@@ -977,7 +977,17 @@ namespace build2
//
if (al) match_rule (al, file_rule::rule_match);
if (sl) match_rule (sl, file_rule::rule_match);
- if (ll) match_recipe (ll, noop_recipe);
+ if (ll)
+ {
+ match_rule (ll, file_rule::rule_match);
+
+ // Also bless the library group with a "trust me it exists" timestamp.
+ // Failed that, if the rule match gets cleared (e.g., because of
+ // multiple operations being executed), then the fallback file rule
+ // won't match.
+ //
+ lt->mtime (mt);
+ }
return r;
}