aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-08-12 09:27:24 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-08-12 09:27:24 +0200
commit7382e4bf15d11b9200d6220b2a89e1f82b220c5e (patch)
tree1d3614f58ed7fe5e2154fa9ea189b7bd01557352
parent037e5e9224648fdc9f3956d612fb476966847f5c (diff)
Avoid duplication in Libs/Libs.private in generated .pc files
-rw-r--r--libbuild2/cc/common.cxx2
-rw-r--r--libbuild2/cc/link-rule.hxx51
-rw-r--r--libbuild2/cc/pkgconfig.cxx39
3 files changed, 69 insertions, 23 deletions
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index d9afd21..934ea38 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -305,7 +305,9 @@ namespace build2
//
if (impl && !c_e_libs.defined () && !x_e_libs.defined ())
{
+#if 0
assert (top_li); // Must pick a member if implementation (see above).
+#endif
for (const prerequisite_target& pt: l.prerequisite_targets[a])
{
diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx
index 23f7167..3d801d6 100644
--- a/libbuild2/cc/link-rule.hxx
+++ b/libbuild2/cc/link-rule.hxx
@@ -81,11 +81,10 @@ namespace build2
class appended_libraries: public small_vector<appended_library, 128>
{
public:
- // Find existing or append new entry. If appending new, use the second
- // argument as the begin value.
+ // Find existing entry, if any.
//
- appended_library&
- append (const file& l, size_t b)
+ appended_library*
+ find (const file& l)
{
auto i (find_if (begin (), end (),
[&l] (const appended_library& al)
@@ -93,19 +92,11 @@ namespace build2
return al.l2 == nullptr && al.l1 == &l;
}));
- if (i != end ())
- return *i;
-
- push_back (appended_library {&l, nullptr, b, appended_library::npos});
- return back ();
+ return i != end () ? &*i : nullptr;
}
- // Return NULL if no duplicate tracking can be performed for this
- // library.
- //
appended_library*
- append (const small_vector<reference_wrapper<const string>, 2>& ns,
- size_t b)
+ find (const small_vector<reference_wrapper<const string>, 2>& ns)
{
size_t n (ns.size ());
@@ -125,8 +116,36 @@ namespace build2
: al.l1 == nullptr);
}));
- if (i != end ())
- return &*i;
+ return i != end () ? &*i : nullptr;
+ }
+
+ // Find existing or append new entry. If appending new, use the second
+ // argument as the begin value.
+ //
+ appended_library&
+ append (const file& l, size_t b)
+ {
+ if (appended_library* r = find (l))
+ return *r;
+
+ push_back (appended_library {&l, nullptr, b, appended_library::npos});
+ return back ();
+ }
+
+ // Return NULL if no duplicate tracking can be performed for this
+ // library.
+ //
+ appended_library*
+ append (const small_vector<reference_wrapper<const string>, 2>& ns,
+ size_t b)
+ {
+ size_t n (ns.size ());
+
+ if (n > 2)
+ return nullptr;
+
+ if (appended_library* r = find (ns))
+ return r;
push_back (appended_library {
n == 2 ? &ns[1].get () : nullptr, &ns[0].get (),
diff --git a/libbuild2/cc/pkgconfig.cxx b/libbuild2/cc/pkgconfig.cxx
index 9177dbb..3fcfb9a 100644
--- a/libbuild2/cc/pkgconfig.cxx
+++ b/libbuild2/cc/pkgconfig.cxx
@@ -1642,9 +1642,10 @@ namespace build2
struct data
{
ofdstream& os;
- appended_libraries& ls;
+ appended_libraries* pls; // Previous.
+ appended_libraries* ls; // Current.
strings& args;
- } d {os, ls, args};
+ } d {os, nullptr, &ls, args};
auto imp = [&priv] (const target&, bool la) {return priv && la;};
@@ -1656,17 +1657,31 @@ namespace build2
{
const file* l (lc != nullptr ? &(*lc)->as<file> () : nullptr);
+ // Suppress duplicates from the previous run (Libs/Libs.private
+ // split).
+ //
+ if (d.pls != nullptr)
+ {
+ // Doesn't feel like we can prune here: we may have seen this
+ // interface library but not its implementation dependencies.
+ //
+ if ((l != nullptr
+ ? d.pls->find (*l)
+ : d.pls->find (ns)) != nullptr)
+ return true;
+ }
+
// Suppress duplicates (see append_libraries() for details).
//
// Note that we use the original name for duplicate tracking.
//
appended_library* al (l != nullptr
- ? &d.ls.append (*l, d.args.size ())
- : d.ls.append (ns, d.args.size ()));
+ ? &d.ls->append (*l, d.args.size ())
+ : d.ls->append (ns, d.args.size ()));
if (al != nullptr && al->end != appended_library::npos)
{
- d.ls.hoist (d.args, *al);
+ d.ls->hoist (d.args, *al);
return true;
}
@@ -1697,9 +1712,12 @@ namespace build2
//@@ TODO: how will the Libs/Libs.private work?
//@@ TODO: remember to use escape()
+ if (d.pls != nullptr && d.pls->find (l) != nullptr)
+ return true;
+
// See link_rule::append_libraries().
- if (d.ls.append (l, d.args.size ()).end != appended_library::npos)
+ if (d.ls->append (l, d.args.size ()).end != appended_library::npos)
return true;
return true;
@@ -1723,9 +1741,16 @@ namespace build2
{
os << "Libs.private:";
- ls.clear ();
args.clear ();
priv = true;
+
+ // Use previous appended_libraries to weed out entries that are
+ // already in Libs.
+ //
+ appended_libraries als;
+ d.pls = d.ls;
+ d.ls = &als;
+
process_libraries (a, bs, li, sys_lib_dirs,
l, la, 0, // Link flags.
imp, lib, opt, false /* self */, &lib_cache);