From 0d275db1433dec9bc7b4fcf5fcd28b42da3b6166 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 6 Sep 2018 19:20:01 +0200 Subject: Fix issues with interaction between binless logic and Windows DLLs --- build2/cc/common.cxx | 7 +++---- build2/cc/link-rule.cxx | 26 ++++++++++++++++---------- build2/cc/pkgconfig.cxx | 35 +++++++++++++++++++++++++---------- build2/cc/windows-rpath.cxx | 4 ++-- 4 files changed, 46 insertions(+), 26 deletions(-) diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx index 6a1698e..ae125a5 100644 --- a/build2/cc/common.cxx +++ b/build2/cc/common.cxx @@ -614,9 +614,7 @@ namespace build2 libs* s (nullptr); pair pc; // pkg-config .pc file paths. - - path f; // Reuse the buffer. - const dir_path* pd (nullptr); + path f; // Reuse the buffer. auto search =[&a, &s, &pc, &an, &ae, @@ -670,7 +668,7 @@ namespace build2 // but valid timestamp (aka "trust me, it's there"). // s->mtime (mt); - s->path (path ()); + s->path (empty_path); } } else @@ -787,6 +785,7 @@ namespace build2 if (!usrd) usrd = extract_library_dirs (*p.scope); + const dir_path* pd (nullptr); for (const dir_path& d: *usrd) { if (search (d)) diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx index a2f2381..138ae9d 100644 --- a/build2/cc/link-rule.cxx +++ b/build2/cc/link-rule.cxx @@ -1238,6 +1238,12 @@ namespace build2 // Linking a library to a shared library or executable. // + // Note: on Windows shared library could be the DLL with unknown + // location (empty path). See search_library() for details. + // + if (l->path ().empty () && l->member != nullptr) // Binless. + return; + // On Windows a shared library is a DLL with the import library as // a first ad hoc group member. MinGW though can link directly to // DLLs (see search_library() for details). @@ -1247,9 +1253,6 @@ namespace build2 tclass == "windows") l = &l->member->as (); - if (l->path ().empty ()) // Binless. - return; - string p (relative (l->path ()).string ()); if (f & lflag_whole) @@ -1349,6 +1352,16 @@ namespace build2 if (d.li.type == otype::a && !lu) return; + // Note: on Windows shared library could be the DLL with unknown + // location (empty path). See search_library() for details. + // + if (l->path ().empty () && l->member != nullptr) // Binless. + return; + + // Check if this library renders us out of date. + // + d.update = d.update || l->newer (d.mt); + // On Windows a shared library is a DLL with the import library as a // first ad hoc group member. MinGW though can link directly to DLLs // (see search_library() for details). @@ -1358,13 +1371,6 @@ namespace build2 tclass == "windows") l = &l->member->as (); - if (l->path ().empty ()) // Binless. - return; - - // Check if this library renders us out of date. - // - d.update = d.update || l->newer (d.mt); - d.cs.append (f); hash_path (d.cs, l->path (), d.out_root); } diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index b0634fb..cbc4c50 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -549,30 +549,38 @@ namespace build2 // struct data { - pair r; + path a; + path s; bool common; - } d {{}, common}; + } d {path (), path (), common}; auto check = [&d, &search_dir] (dir_path&& p) -> bool { // First look for static/shared-specific files. // - d.r.first = search_dir (p, ".static"); - d.r.second = search_dir (p, ".shared"); + d.a = search_dir (p, ".static"); + d.s = search_dir (p, ".shared"); - if (!d.r.first.empty () || !d.r.second.empty ()) + if (!d.a.empty () || !d.s.empty ()) return false; // Then the common. // if (d.common) - d.r.first = d.r.second = search_dir (p, string ()); + d.a = d.s = search_dir (p, ""); - return d.r.first.empty (); + return d.a.empty (); }; - pkgconfig_search (libd, check); - return d.r; + pair r; + + if (pkgconfig_search (libd, check)) + { + r.first = move (d.a); + r.second = move (d.s); + } + + return r; }; bool common:: @@ -1084,7 +1092,14 @@ namespace build2 // the saving logic). // pkgconf& ipc (sp.empty () ? apc : spc); // Interface package info. - bool ibl ((sp.empty () ? at->path () : st->path ()).empty ()); // Binless. + bool ibl (sp.empty () // Binless. + ? at->path ().empty () + // + // On Windows the shared library could be a DLL with an empty + // path (unknown location) and an ad hoc member that is the + // import library. See search_library() for details. + // + : st->path ().empty () && st->member != nullptr); bool pa (at != nullptr && !ap.empty ()); if (pa || sp.empty ()) diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx index 507395c..e9fd680 100644 --- a/build2/cc/windows-rpath.cxx +++ b/build2/cc/windows-rpath.cxx @@ -77,7 +77,7 @@ namespace build2 { // This can be an "undiscovered" DLL (see search_library()). // - if (!l->is_a () || l->path ().empty ()) // Covers binless. + if (!l->is_a () || l->path ().empty ()) // Also covers binless. return; } else @@ -152,7 +152,7 @@ namespace build2 if (l != nullptr) { - if (l->is_a () && !l->path ().empty ()) // Covers binless. + if (l->is_a () && !l->path ().empty ()) // Also covers binless. { // Get .pdb if there is one. // -- cgit v1.1