From 9d45f82f821f0663a7c21c69c26d93fa0613d48a Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 4 May 2021 12:32:07 +0200 Subject: Handle duplicate suppression of multi-element libraries (-l foo) See GitHub issue #114 for context. --- libbuild2/cc/link-rule.hxx | 60 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) (limited to 'libbuild2/cc/link-rule.hxx') diff --git a/libbuild2/cc/link-rule.hxx b/libbuild2/cc/link-rule.hxx index baccf8d..33a4f1c 100644 --- a/libbuild2/cc/link-rule.hxx +++ b/libbuild2/cc/link-rule.hxx @@ -58,8 +58,14 @@ namespace build2 { 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). + // Each appended_library represents either a library target or a + // library name fragment up to 2 elements long: + // + // target | name + // -------------------------------------------------- + const void* l1; // library target | library name[1] or NULL + const void* l2; // NULL | library name[0] + size_t begin; // First arg belonging to this library. size_t end; // Past last arg belonging to this library. }; @@ -73,38 +79,52 @@ namespace build2 appended_library& append (const file& l, size_t b) { - auto p (reinterpret_cast (&l)); auto i (find_if (begin (), end (), - [p] (const appended_library& al) + [&l] (const appended_library& al) { - return al.l == p; + return al.l2 == nullptr && al.l1 == &l; })); if (i != end ()) return *i; - push_back (appended_library {p, b, appended_library::npos}); + push_back (appended_library {&l, nullptr, b, appended_library::npos}); return back (); } - appended_library& - append (const string& l, size_t b) + // Return NULL if no duplicate tracking can be performed for this + // library. + // + appended_library* + append (const small_vector, 2>& ns, + size_t b) { - auto i (find_if (begin (), end (), - [&l] (const appended_library& al) - { - return (al.l & 1) != 0 && - l == *reinterpret_cast ( - al.l & ~uintptr_t (1)); - })); + size_t n (ns.size ()); + + if (n > 2) + return nullptr; + + auto i ( + find_if ( + begin (), end (), + [&ns, n] (const appended_library& al) + { + return al.l2 != nullptr && + *static_cast (al.l2) == ns[0].get () && + (n == 2 + ? (al.l1 != nullptr && + *static_cast (al.l1) == ns[1].get ()) + : al.l1 == nullptr); + })); if (i != end ()) - return *i; + return &*i; - push_back ( - appended_library { - reinterpret_cast (&l) | 1, b, appended_library::npos}); - return back (); + push_back (appended_library { + n == 2 ? &ns[1].get () : nullptr, &ns[0].get (), + b, appended_library::npos}); + + return &back (); } }; -- cgit v1.1