diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-11-18 11:38:44 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-11-18 11:38:44 +0200 |
commit | bbf670d03ee587b0794f77a39db801bad6459ca5 (patch) | |
tree | f7e144fc5a1ca83c4ee6d7a1f21039c657ef3718 | |
parent | 462afa615e9f2fdff12a0ee7a36eb431ee07e141 (diff) |
Only install runtime part of static library prerequisites of share libraries (GH issue #448)HEADmaster
-rw-r--r-- | libbuild2/bin/init.cxx | 8 | ||||
-rw-r--r-- | libbuild2/bin/rule.cxx | 13 | ||||
-rw-r--r-- | libbuild2/bin/rule.hxx | 21 | ||||
-rw-r--r-- | libbuild2/cc/install-rule.cxx | 22 | ||||
-rw-r--r-- | libbuild2/install/rule.hxx | 2 |
5 files changed, 58 insertions, 8 deletions
diff --git a/libbuild2/bin/init.cxx b/libbuild2/bin/init.cxx index 610082e..f01adfb 100644 --- a/libbuild2/bin/init.cxx +++ b/libbuild2/bin/init.cxx @@ -12,7 +12,6 @@ #include <libbuild2/test/module.hxx> -#include <libbuild2/install/rule.hxx> #include <libbuild2/install/utility.hxx> #include <libbuild2/bin/rule.hxx> @@ -31,6 +30,7 @@ namespace build2 static const obj_rule obj_; static const libul_rule libul_; static const lib_rule lib_; + static const install_lib_rule install_lib_; static const def_rule def_; // Default config.bin.*.lib values. @@ -631,10 +631,8 @@ namespace build2 // if (install_loaded) { - auto& gr (install::group_rule::instance); - - r.insert<lib> (perform_install_id, "bin.lib", gr); - r.insert<lib> (perform_uninstall_id, "bin.lib", gr); + r.insert<lib> (perform_install_id, "bin.lib", install_lib_); + r.insert<lib> (perform_uninstall_id, "bin.lib", install_lib_); } if (const test::module* m = rs.find_module<test::module> ("test")) diff --git a/libbuild2/bin/rule.cxx b/libbuild2/bin/rule.cxx index c7147bf..1fea558 100644 --- a/libbuild2/bin/rule.cxx +++ b/libbuild2/bin/rule.cxx @@ -218,5 +218,18 @@ namespace build2 const target* m[] = {t.a, t.s}; return execute_members (a, t, m); } + + // install_lib_rule + // + pair<const target*, uint64_t> install_lib_rule:: + filter (const scope* is, + action a, const target& t, const prerequisite& p, + match_extra& me) const + { + if (p.is_a<lib> ()) + return pair<const target*, uint64_t> (nullptr, 0); + + return install::group_rule::filter (is, a, t, p, me); + } } } diff --git a/libbuild2/bin/rule.hxx b/libbuild2/bin/rule.hxx index 9dd1d14..74f4301 100644 --- a/libbuild2/bin/rule.hxx +++ b/libbuild2/bin/rule.hxx @@ -10,6 +10,7 @@ #include <libbuild2/rule.hxx> #include <libbuild2/dist/rule.hxx> +#include <libbuild2/install/rule.hxx> #include <libbuild2/bin/export.hxx> @@ -78,6 +79,26 @@ namespace build2 static target_state perform (action, const target&); }; + + // Install rule for lib{} group. + // + // The only difference compared to the standard install::group_rule is + // that it ignores the lib{} prerequisites, instead expecting the correct + // things to be installed via the liba{}/libs{} members. This is important + // due to the presence of match options (see lib{} target for details). + // + class LIBBUILD2_BIN_SYMEXPORT install_lib_rule: public install::group_rule + { + public: + install_lib_rule () {} + + virtual pair<const target*, uint64_t> + filter (const scope*, + action, const target&, const prerequisite&, + match_extra&) const override; + + using install::group_rule::filter; // "Unhide" to make Clang happy. + }; } } diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx index 3fede89..46764a6 100644 --- a/libbuild2/cc/install-rule.cxx +++ b/libbuild2/cc/install-rule.cxx @@ -109,7 +109,21 @@ namespace build2 // This is a library prerequisite of a library target and // runtime-only begets runtime-only. // - if (me.cur_options == lib::option_install_runtime) + // @@ But it goes further: while an interface prerequisite should + // match the target's options, it feels an implementation can be + // runtime-only, at least for shared library targets (for static + // the consumer would still need to link the prerequisite + // explicitly, which means it is more like buildtime). We could + // probably distinguish between interface/implementation by + // examining the *.export.libs variable and looking for the + // prerequisite (or its group). Feels hairy, though. So for now we + // only do this for target-shared/prerequisite-static case where + // we can assume the prerequisite is always implementation. See GH + // issue #448. See also apply_posthoc() as well as + // libux_install_rule below. + // + if (me.cur_options == lib::option_install_runtime || + (t.is_a<libs> () && pt->is_a<liba> ())) options = lib::option_install_runtime; } } @@ -315,6 +329,9 @@ namespace build2 p.match_options = lib::option_install_runtime; else { + // @@ Hm, maybe runtime should be unconditional here since a + // plugin is always an implementation dependency? + // if (me.cur_options == lib::option_install_runtime) p.match_options = lib::option_install_runtime; } @@ -493,7 +510,8 @@ namespace build2 options = lib::option_install_runtime; else { - if (me.cur_options == lib::option_install_runtime) + if (me.cur_options == lib::option_install_runtime || + (t.is_a<libus> () && pt->is_a<liba> ())) options = lib::option_install_runtime; } } diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx index b023af5..3dbb68d 100644 --- a/libbuild2/install/rule.hxx +++ b/libbuild2/install/rule.hxx @@ -119,7 +119,7 @@ namespace build2 virtual recipe apply (action, target&, match_extra&) const override; - group_rule (bool sto): see_through_only (sto) {} + group_rule (bool sto = false): see_through_only (sto) {} static const group_rule instance; bool see_through_only; |