diff options
-rw-r--r-- | build2/cxx/link.cxx | 50 | ||||
-rw-r--r-- | build2/cxx/module.cxx | 7 | ||||
-rw-r--r-- | build2/target | 14 | ||||
-rw-r--r-- | build2/target.cxx | 54 |
4 files changed, 88 insertions, 37 deletions
diff --git a/build2/cxx/link.cxx b/build2/cxx/link.cxx index 7a527e0..6bfc1bf 100644 --- a/build2/cxx/link.cxx +++ b/build2/cxx/link.cxx @@ -578,6 +578,8 @@ namespace build2 scope& bs (t.base_scope ()); scope& rs (*bs.root_scope ()); + + const string& cid (cast<string> (rs["cxx.id"])); const string& tsys (cast<string> (rs["cxx.target.system"])); const string& tclass (cast<string> (rs["cxx.target.class"])); @@ -679,31 +681,47 @@ namespace build2 t.derive_path (e, p); } - // On Windows add the DLL as an ad hoc group member. + // Add ad hoc group members. // - if (so && tclass == "windows") + auto add_adhoc = [a, &bs] (target& t, const char* type) -> file& { - file* dll (nullptr); - - // Registered by cxx module's init(). - // - const target_type& tt (*bs.find_target_type ("dll")); + const target_type& tt (*bs.find_target_type (type)); if (t.member != nullptr) // Might already be there. - { assert (t.member->type () == tt); - dll = static_cast<file*> (t.member); - } else + t.member = &search (tt, t.dir, t.out, t.name, nullptr, nullptr); + + file& r (static_cast<file&> (*t.member)); + r.recipe (a, group_recipe); + return r; + }; + + if (tclass == "windows") + { + // DLL + // + if (so) { - t.member = dll = static_cast<file*> ( - &search (tt, t.dir, t.out, t.name, nullptr, nullptr)); + file& dll (add_adhoc (t, "dll")); + + if (dll.path ().empty ()) + dll.derive_path ("dll", tsys == "mingw32" ? "lib" : nullptr); } - if (dll->path ().empty ()) - dll->derive_path ("dll", tsys == "mingw32" ? "lib" : nullptr); + // PDB + // + if (lt != type::a && + cid == "msvc" && + find_option ("/DEBUG", t, "cxx.loptions", true)) + { + // Add after the DLL if any. + // + file& pdb (add_adhoc (t.member == nullptr ? t : *t.member, "pdb")); - dll->recipe (a, group_recipe); + if (pdb.path ().empty ()) + pdb.derive_path (t.path (), "pdb"); + } } t.prerequisite_targets.clear (); // See lib pre-match in match() above. @@ -1649,7 +1667,7 @@ namespace build2 // // Clean up .ilk in case the user enabled incremental linking. // - e = {"+.d", "/+.dlls", "+.manifest", ".ilk", "+.pdb"}; + e = {"+.d", "/+.dlls", "+.manifest", ".ilk"}; } } else diff --git a/build2/cxx/module.cxx b/build2/cxx/module.cxx index a4afe44..6a5469c 100644 --- a/build2/cxx/module.cxx +++ b/build2/cxx/module.cxx @@ -365,6 +365,13 @@ namespace build2 { const target_type& dll (b.derive_target_type<file> ("dll").first); install_path (dll, b, dir_path ("bin")); + + if (cid == "msvc") + { + const target_type& pdb (b.derive_target_type<file> ("pdb").first); + install_path (pdb, b, dir_path ("bin")); + install_mode (pdb, b, "644"); + } } return true; diff --git a/build2/target b/build2/target index 3207778..955c2f9 100644 --- a/build2/target +++ b/build2/target @@ -1025,11 +1025,23 @@ namespace build2 // Finally, if the path was already assigned to this target, then this // function verifies that the two are the same. // - void + const path_type& derive_path (const char* default_ext = nullptr, const char* name_prefix = nullptr, const char* name_suffix = nullptr); + // This version can be used to derive the path from another target's path + // by adding another extension. + // + const path_type& + derive_path (path_type base, const char* default_ext = nullptr); + + // As above but only derives (and returns) the extension (empty means no + // extension used). + // + const string& + derive_extension (const char* default_ext = nullptr); + public: static const target_type static_type; diff --git a/build2/target.cxx b/build2/target.cxx index deeee4f..a8fae39 100644 --- a/build2/target.cxx +++ b/build2/target.cxx @@ -307,21 +307,10 @@ namespace build2 // path_target // - void path_target:: - derive_path (const char* de, const char* np, const char* ns) + const string& path_target:: + derive_extension (const char* de) { - string n; - - if (np != nullptr) - n += np; - - n += name; - - if (ns != nullptr) - n += ns; - - // Update the extension. See also search_existing_file() if updating - // anything here. + // See also search_existing_file() if updating anything here. // assert (de == nullptr || type ().extension != nullptr); @@ -344,23 +333,48 @@ namespace build2 } } - // Add the extension. + return *ext; + } + + const path& path_target:: + derive_path (const char* de, const char* np, const char* ns) + { + string n; + + if (np != nullptr) + n += np; + + n += name; + + if (ns != nullptr) + n += ns; + + return derive_path (dir / path_type (move (n)), de); + } + + const path& path_target:: + derive_path (path_type p, const char* de) + { + // Derive and add the extension if any. // + derive_extension (de); + if (!ext->empty ()) { - n += '.'; - n += *ext; + p += '.'; + p += *ext; } - path_type p (dir / path_type (move (n))); const path_type& ep (path ()); if (ep.empty ()) - path (p); + path (move (p)); else if (p != ep) fail << "path mismatch for target " << *this << - info << "assigned '" << ep << "'" << + info << "existing '" << ep << "'" << info << "derived '" << p << "'"; + + return path (); } // file_target |