aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc/windows-rpath.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-05-04 12:32:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-05-04 12:32:07 +0200
commit9d45f82f821f0663a7c21c69c26d93fa0613d48a (patch)
tree19e221c41cc0f43bf3621a8f1a2a21b62470851d /libbuild2/cc/windows-rpath.cxx
parent8bae6cd94035cd5999ff2d767d91e176939ba203 (diff)
Handle duplicate suppression of multi-element libraries (-l foo)
See GitHub issue #114 for context.
Diffstat (limited to 'libbuild2/cc/windows-rpath.cxx')
-rw-r--r--libbuild2/cc/windows-rpath.cxx95
1 files changed, 52 insertions, 43 deletions
diff --git a/libbuild2/cc/windows-rpath.cxx b/libbuild2/cc/windows-rpath.cxx
index 70eef73..7b572df 100644
--- a/libbuild2/cc/windows-rpath.cxx
+++ b/libbuild2/cc/windows-rpath.cxx
@@ -58,10 +58,11 @@ namespace build2
//
auto imp = [] (const target&, bool) {return true;};
- auto lib = [&r] (const target* const* lc,
- const string& f,
- lflags,
- bool sys)
+ auto lib = [&r] (
+ const target* const* lc,
+ const small_vector<reference_wrapper<const string>, 2>& ns,
+ lflags,
+ bool sys)
{
const file* l (lc != nullptr ? &(*lc)->as<file> () : nullptr);
@@ -76,8 +77,13 @@ namespace build2
{
// This can be an "undiscovered" DLL (see search_library()).
//
- if (!l->is_a<libs> () || l->path ().empty ()) // Also covers binless.
- return;
+ if (l->is_a<libs> () && !l->path ().empty ()) // Also covers binless.
+ {
+ timestamp t (l->load_mtime ());
+
+ if (t > r)
+ r = t;
+ }
}
else
{
@@ -91,20 +97,19 @@ namespace build2
//
// Though this can happen on MinGW with direct DLL link...
//
- size_t p (path::traits_type::find_extension (f));
-
- if (p == string::npos || icasecmp (f.c_str () + p + 1, "dll") != 0)
- return;
- }
+ for (const string& f: ns)
+ {
+ size_t p (path::traits_type::find_extension (f));
- // Ok, this is a DLL.
- //
- timestamp t (l != nullptr
- ? l->load_mtime ()
- : mtime (f.c_str ()));
+ if (p != string::npos && icasecmp (f.c_str () + p + 1, "dll") == 0)
+ {
+ timestamp t (mtime (f.c_str ()));
- if (t > r)
- r = t;
+ if (t > r)
+ r = t;
+ }
+ }
+ }
};
for (const prerequisite_target& pt: t.prerequisite_targets[a])
@@ -139,10 +144,11 @@ namespace build2
auto imp = [] (const target&, bool) {return true;};
- auto lib = [&r, &bs] (const target* const* lc,
- const string& f,
- lflags,
- bool sys)
+ auto lib = [&r, &bs] (
+ const target* const* lc,
+ const small_vector<reference_wrapper<const string>, 2>& ns,
+ lflags,
+ bool sys)
{
const file* l (lc != nullptr ? &(*lc)->as<file> () : nullptr);
@@ -161,7 +167,7 @@ namespace build2
: nullptr);
r.insert (
windows_dll {
- f,
+ ns[0],
pdb != nullptr ? &pdb->as<file> ().path ().string () : nullptr,
string ()
});
@@ -169,35 +175,38 @@ namespace build2
}
else
{
- size_t p (path::traits_type::find_extension (f));
-
- if (p != string::npos && icasecmp (f.c_str () + p + 1, "dll") == 0)
+ for (const string& f: ns)
{
- // See if we can find a corresponding .pdb.
- //
- windows_dll wd {f, nullptr, string ()};
- string& pdb (wd.pdb_storage);
-
- // First try "our" naming: foo.dll.pdb.
- //
- pdb = f;
- pdb += ".pdb";
+ size_t p (path::traits_type::find_extension (f));
- if (!exists (path (pdb)))
+ if (p != string::npos && icasecmp (f.c_str () + p + 1, "dll") == 0)
{
- // Then try the usual naming: foo.pdb.
+ // See if we can find a corresponding .pdb.
//
- pdb.assign (f, 0, p);
+ windows_dll wd {f, nullptr, string ()};
+ string& pdb (wd.pdb_storage);
+
+ // First try "our" naming: foo.dll.pdb.
+ //
+ pdb = f;
pdb += ".pdb";
if (!exists (path (pdb)))
- pdb.clear ();
- }
+ {
+ // Then try the usual naming: foo.pdb.
+ //
+ pdb.assign (f, 0, p);
+ pdb += ".pdb";
- if (!pdb.empty ())
- wd.pdb = &pdb;
+ if (!exists (path (pdb)))
+ pdb.clear ();
+ }
- r.insert (move (wd));
+ if (!pdb.empty ())
+ wd.pdb = &pdb;
+
+ r.insert (move (wd));
+ }
}
}
};