From 77855794fa1b430635ca6b698a6d177bfc9298db Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 27 Oct 2023 09:58:45 +0200 Subject: WIP: install: fix library selection logic --- libbuild2/cc/install-rule.cxx | 95 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx index 5db19bc..389a9ac 100644 --- a/libbuild2/cc/install-rule.cxx +++ b/libbuild2/cc/install-rule.cxx @@ -70,6 +70,11 @@ namespace build2 uint64_t options (match_extra::all_options); + otype ot (link_type (t).type); + + // @@ TMP: drop eventually. + // +#if 0 // If this is a shared library prerequisite, install it as long as it is // in the installation scope. // @@ -81,7 +86,6 @@ namespace build2 // // Note: we install ad hoc prerequisites by default. // - otype ot (link_type (t).type); // Note: at least one must be true since we only register this rule for // exe{}, and lib[as]{} (this makes sure the following if-condition will @@ -147,6 +151,61 @@ namespace build2 return make_pair (pt, options); } } +#else + // Note that at first it may seem like we don't need to install static + // library prerequisites of executables. But such libraries may still + // have prerequisites that are needed at runtime (say, some data files). + // So we install all libraries as long as they are in the installation + // scope and deal with runtime vs buildtime distiction using match + // options. + // + // Note: for now we assume these prerequisites never come from see- + // through groups. + // + // Note: we install ad hoc prerequisites by default. + // + if (p.is_a () || p.is_a () || p.is_a ()) + { + const target* pt (&search (t, p)); + + // If this is the lib{}/libu*{} group, pick a member which we would + // link. For libu*{} we want the "see through" logic. + // + if (const libx* l = pt->is_a ()) + pt = link_member (*l, a, link_info (t.base_scope (), ot)); + + // Adjust match options. + // + if (a.operation () != update_id) + { + if (t.is_a ()) + options = lib::option_install_runtime; + else + { + // This is a library prerequisite of a library target and + // runtime-only begets runtime-only. + // + if (me.cur_options == lib::option_install_runtime) + options = lib::option_install_runtime; + } + } + + // Note: not redundant since we could be returning a member. + // + if (pt->is_a () || pt->is_a ()) + { + return make_pair (is == nullptr || pt->in (*is) ? pt : nullptr, + options); + } + else // libua{} or libus{} + { + // See through to libu*{} members. Note that we are always in the + // same project (and thus amalgamation). + // + return make_pair (pt, options); + } + } +#endif // The rest of the tests only succeed if the base filter() succeeds. // @@ -453,12 +512,16 @@ namespace build2 uint64_t options (match_extra::all_options); + otype ot (link_type (t).type); + // The "see through" semantics that should be parallel to install_rule // above. In particular, here we use libue/libua/libus{} as proxies for // exe/liba/libs{} there. // - otype ot (link_type (t).type); + // @@ TMP: drop eventually. + // +#if 0 bool st (t.is_a () || t.is_a ()); // Target needs shared. bool at (t.is_a () || t.is_a ()); // Target needs static. assert (st || at); @@ -504,6 +567,34 @@ namespace build2 return make_pair (pt, options); } } +#else + if (p.is_a () || p.is_a () || p.is_a ()) + { + const target* pt (&search (t, p)); + + if (const libx* l = pt->is_a ()) + pt = link_member (*l, a, link_info (t.base_scope (), ot)); + + if (a.operation () != update_id) + { + if (t.is_a ()) + options = lib::option_install_runtime; + else + { + if (me.cur_options == lib::option_install_runtime) + options = lib::option_install_runtime; + } + } + + if (pt->is_a () || pt->is_a ()) + { + return make_pair (is == nullptr || pt->in (*is) ? pt : nullptr, + options); + } + else + return make_pair (pt, options); + } +#endif const target* pt (file_rule::instance.filter (is, a, t, p, me).first); if (pt == nullptr) -- cgit v1.1