From a84ff43b183181e0a12c6d5e31c1f366d39ce2fe Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 31 Jul 2017 18:42:47 +0200 Subject: Experimental (and probably broken) pkg-config generation support --- build2/cc/link.cxx | 120 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 49 deletions(-) (limited to 'build2/cc/link.cxx') diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index 1cb3a11..08b5314 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -19,6 +19,7 @@ #include #include +#include #include // c #include @@ -142,34 +143,33 @@ namespace build2 } auto link:: - derive_libs_paths (file& ls) const -> libs_paths + derive_libs_paths (file& ls, const char* pfx, const char* sfx) const + -> libs_paths { const char* ext (nullptr); - const char* pfx (nullptr); - const char* sfx (nullptr); bool win (tclass == "windows"); if (win) { if (tsys == "mingw32") - pfx = "lib"; + { + if (pfx == nullptr) + pfx = "lib"; + } ext = "dll"; } - else if (tclass == "macos") - { - pfx = "lib"; - ext = "dylib"; - } else { - pfx = "lib"; - ext = "so"; - } + if (pfx == nullptr) + pfx = "lib"; - if (auto l = ls["bin.lib.prefix"]) pfx = cast (l).c_str (); - if (auto l = ls["bin.lib.suffix"]) sfx = cast (l).c_str (); + if (tclass == "macos") + ext = "dylib"; + else + ext = "so"; + } // First sort out which extension we are using. // @@ -315,14 +315,6 @@ namespace build2 // Derive file name(s) and add ad hoc group members. // - - // Add if necessary and lock an ad hoc group member. - // - auto add_adhoc = [act, &bs] (target& t, const char* type) -> target_lock - { - return add_adhoc_member (act, t, *bs.find_target_type (type)); - }; - { target_lock libi; // Have to hold until after PDB member addition. @@ -391,6 +383,11 @@ namespace build2 } else { + if (auto l = t[ot == otype::e ? "bin.exe.prefix" : "bin.lib.prefix"]) + p = cast (l).c_str (); + if (auto l = t[ot == otype::e ? "bin.exe.suffix" : "bin.lib.suffix"]) + s = cast (l).c_str (); + switch (ot) { case otype::e: @@ -400,9 +397,6 @@ namespace build2 else e = ""; - if (auto l = t["bin.exe.prefix"]) p = cast (l).c_str (); - if (auto l = t["bin.exe.suffix"]) s = cast (l).c_str (); - t.derive_path (e, p, s); break; } @@ -412,13 +406,10 @@ namespace build2 e = "lib"; else { - p = "lib"; + if (p == nullptr) p = "lib"; e = "a"; } - if (auto l = t["bin.lib.prefix"]) p = cast (l).c_str (); - if (auto l = t["bin.lib.suffix"]) s = cast (l).c_str (); - t.derive_path (e, p, s); break; } @@ -428,9 +419,9 @@ namespace build2 // the DLL and we add libi{} import library as its member. // if (tclass == "windows") - libi = add_adhoc (t, "libi"); + libi = add_adhoc_member (act, t); - t.data (derive_libs_paths (t)); // Cache in target. + t.data (derive_libs_paths (t, p, s)); // Cache in target. if (libi) match_recipe (libi, group_recipe); // Set recipe and unlock. @@ -438,26 +429,57 @@ namespace build2 break; } } - } - // PDB - // - if (!lt.static_library () && - cid == compiler_id::msvc && - (find_option ("/DEBUG", t, c_loptions, true) || - find_option ("/DEBUG", t, x_loptions, true))) - { - // Add after the import library if any. + // Add VC's .pdb. // - target_lock pdb ( - add_adhoc (t.member == nullptr ? t : *t.member, "pdb")); + if (ot != otype::a && + cid == compiler_id::msvc && + (find_option ("/DEBUG", t, c_loptions, true) || + find_option ("/DEBUG", t, x_loptions, true))) + { + // Note: add after the import library if any. + // + target_lock pdb ( + add_adhoc_member (act, t, *bs.find_target_type ("pdb"))); + + // We call it foo.{exe,dll}.pdb rather than just foo.pdb because + // we can have both foo.exe and foo.dll in the same directory. + // + pdb.target->as ().derive_path (t.path (), "pdb"); + + match_recipe (pdb, group_recipe); // Set recipe and unlock. + } - // We call it foo.{exe,dll}.pdb rather than just foo.pdb because we - // can have both foo.exe and foo.dll in the same directory. + // Add pkg-config's .pc file. // - pdb.target->as ().derive_path (t.path (), "pdb"); + // Note that we do it here regardless of whether we are installing + // or not for two reasons. Firstly, it is not easy to detect this + // situation in apply() since the action may (and is) overridden to + // unconditional install. Secondly, always having the member takes + // care of cleanup automagically. The actual generation happens in + // the install rule. + // + if (ot != otype::e) + { + target_lock pc ( + add_adhoc_member ( + act, t, + ot == otype::a + ? pkgconfig::pca::static_type + : pkgconfig::pcs::static_type)); + + // Note that here we always use the lib name prefix, even on + // Windows with VC. The reason is the user needs a consistent name + // across platforms by which they can refere to the library. This + // is also the reason why we use the static/shared suffixes rather + // that a./.lib/.so/.dylib/.dll. + // + pc.target->as ().derive_path (nullptr, + (p == nullptr ? "lib" : p), + s); - match_recipe (pdb, group_recipe); // Set recipe and unlock. + match_recipe (pc, group_recipe); // Set recipe and unlock. + } } } @@ -1164,12 +1186,12 @@ namespace build2 { tracer trace (x, "link::perform_update"); - const file& t (xt.as ()); - const path& tp (t.path ()); - auto oop (act.outer_operation ()); bool for_install (oop == install_id || oop == uninstall_id); + const file& t (xt.as ()); + const path& tp (t.path ()); + const scope& bs (t.base_scope ()); const scope& rs (*bs.root_scope ()); -- cgit v1.1