aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/link-rule.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-11-23 10:22:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-11-23 10:22:48 +0200
commitb7f4e6154fa3c07ad3472bbd7c871df28d440a64 (patch)
tree124a07cd2050c573eb7b12821db5904264b86957 /libbuild2/cc/link-rule.hxx
parent6a2d1e3062964fc16cfbc43bc69284f854c35dca (diff)
Suppress duplicates when extracting library options (GitHub issue #114)
Diffstat (limited to 'libbuild2/cc/link-rule.hxx')
-rw-r--r--libbuild2/cc/link-rule.hxx60
1 files changed, 58 insertions, 2 deletions
diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx
index a93defc..b369da6 100644
--- a/libbuild2/cc/link-rule.hxx
+++ b/libbuild2/cc/link-rule.hxx
@@ -54,8 +54,62 @@ namespace build2
public:
// Library handling.
//
+ struct appended_library
+ {
+ static const size_t npos = size_t (~0);
+
+ uintptr_t l; // Pointer to library target (last bit 0) or to
+ // library name (-lpthread or path; last bit 1).
+ size_t begin = npos; // First arg belonging to this library.
+ size_t end = npos; // Past last arg belonging to this library.
+ };
+
+ 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.
+ //
+ appended_library&
+ append (const file& l, size_t b)
+ {
+ auto p (reinterpret_cast<uintptr_t> (&l));
+ auto i (find_if (begin (), end (),
+ [p] (const appended_library& al)
+ {
+ return al.l == p;
+ }));
+
+ if (i != end ())
+ return *i;
+
+ push_back (appended_library {p, b, appended_library::npos});
+ return back ();
+ }
+
+ appended_library&
+ append (const string& l, size_t b)
+ {
+ auto i (find_if (begin (), end (),
+ [&l] (const appended_library& al)
+ {
+ return (al.l & 1) != 0 &&
+ l == *reinterpret_cast<const string*> (
+ al.l & ~uintptr_t (1));
+ }));
+
+ if (i != end ())
+ return *i;
+
+ push_back (
+ appended_library {
+ reinterpret_cast<uintptr_t> (&l) | 1, b, appended_library::npos});
+ return back ();
+ }
+ };
+
void
- append_libraries (strings&,
+ append_libraries (appended_libraries&, strings&,
const scope&, action,
const file&, bool, lflags, linfo, bool = true) const;
@@ -64,8 +118,10 @@ namespace build2
const scope&, action,
const file&, bool, lflags, linfo) const;
+ using rpathed_libraries = small_vector<const file*, 256>;
+
void
- rpath_libraries (strings&,
+ rpath_libraries (rpathed_libraries&, strings&,
const scope&,
action, const file&, bool, linfo, bool, bool) const;