aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/cxx/link.cxx50
-rw-r--r--build2/cxx/module.cxx7
-rw-r--r--build2/target14
-rw-r--r--build2/target.cxx54
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