From c3baad41eebc54f1c67f0b487997821f79ef8a79 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 24 Aug 2017 11:04:21 +0200 Subject: See through bmi*{} in order to install mxx{} --- build2/cc/install.cxx | 53 ++++++++++++++++++++++++++++++++++++++------------- build2/cc/install.hxx | 2 +- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/build2/cc/install.cxx b/build2/cc/install.cxx index 050ab1e..1280c73 100644 --- a/build2/cc/install.cxx +++ b/build2/cc/install.cxx @@ -30,12 +30,31 @@ namespace build2 // NOTE: see also alias_install::filter() below if changing anything // here. - if (t.is_a ()) + otype ot (link_type (t).type); + + // Don't install executable's prerequisite headers. + // + if (t.is_a () && x_header (p)) + return nullptr; + + // Here is a problem: if the user spells the obj*/bmi*{} targets + // explicitly, then the source files, including headers/modules may be + // specified as preprequisites of those targets and not of this target. + // While this can be worked around for headers by also listing them as + // prerequisites of this target, this won't work for modules (since they + // are compiled). So what we are going to do here is detect bmi*{} and + // translate them to their mxx{} (this doesn't quite work for headers + // since there would normally be several of them). + // + if (p.is_a () || p.is_a (compile_types (ot).bmi)) { - // Don't install executable's prerequisite headers. - // - if (x_header (p)) - return nullptr; + const target& mt (p.search (t)); + + for (prerequisite_member mp: group_prerequisite_members (a, mt)) + { + if (mp.is_a (*x_mod)) + return t.is_a () ? nullptr : file_rule::filter (a, mt, mp); + } } // If this is a shared library prerequisite, install it as long as it @@ -56,8 +75,7 @@ namespace build2 // link. For libu{} we want to the "see through" logic. // if (const libx* l = pt->is_a ()) - pt = &link_member ( - *l, a, link_info (t.base_scope (), link_type (t).type)); + pt = &link_member (*l, a, link_info (t.base_scope (), ot)); if ((st && pt->is_a ()) || (at && pt->is_a ())) return pt->in (t.weak_scope ()) ? pt : nullptr; @@ -175,11 +193,21 @@ namespace build2 // The "see through" semantics that should be parallel to file_install // above. In particular, here we use libue/libua/libus{} as proxies for // exe/liba/libs{} there. - // - if (t.is_a ()) + + otype ot (link_type (t).type); + + if (t.is_a () && x_header (p)) + return nullptr; + + if (p.is_a () || p.is_a (compile_types (ot).bmi)) { - if (x_header (p)) - return nullptr; + const target& mt (p.search (t)); + + for (prerequisite_member mp: group_prerequisite_members (a, mt)) + { + if (mp.is_a (*x_mod)) + return t.is_a () ? nullptr : alias_rule::filter (a, mt, mp); + } } bool st (t.is_a () || t.is_a ()); // Target needs shared. @@ -191,8 +219,7 @@ namespace build2 const target* pt (&p.search (t)); if (const libx* l = pt->is_a ()) - pt = &link_member ( - *l, a, link_info (t.base_scope (), link_type (t).type)); + pt = &link_member (*l, a, link_info (t.base_scope (), ot)); if ((st && pt->is_a ()) || (at && pt->is_a ())) return pt->in (t.weak_scope ()) ? pt : nullptr; diff --git a/build2/cc/install.hxx b/build2/cc/install.hxx index a846fc8..28a0a94 100644 --- a/build2/cc/install.hxx +++ b/build2/cc/install.hxx @@ -19,7 +19,7 @@ namespace build2 { class link; - // Installation rule for exe, liba{}, and libs{}. + // Installation rule for exe{}, lib*{}, etc. // class file_install: public install::file_rule, virtual common { -- cgit v1.1