aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-08-24 11:04:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-08-24 14:50:13 +0200
commitc3baad41eebc54f1c67f0b487997821f79ef8a79 (patch)
treecc7b70cb8379b45c500582cdb4b2a44aa3fff09a
parent0f8f04a993fdc756f331f8bf8b471c9c6854b84c (diff)
See through bmi*{} in order to install mxx{}
-rw-r--r--build2/cc/install.cxx53
-rw-r--r--build2/cc/install.hxx2
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<exe> ())
+ otype ot (link_type (t).type);
+
+ // Don't install executable's prerequisite headers.
+ //
+ if (t.is_a<exe> () && 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<bmi> () || 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<exe> () ? 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<libx> ())
- 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<libs> ()) || (at && pt->is_a<liba> ()))
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<libue> ())
+
+ otype ot (link_type (t).type);
+
+ if (t.is_a<libue> () && x_header (p))
+ return nullptr;
+
+ if (p.is_a<bmi> () || 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<libue> () ? nullptr : alias_rule::filter (a, mt, mp);
+ }
}
bool st (t.is_a<libue> () || t.is_a<libus> ()); // Target needs shared.
@@ -191,8 +219,7 @@ namespace build2
const target* pt (&p.search (t));
if (const libx* l = pt->is_a<libx> ())
- 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<libs> ()) || (at && pt->is_a<liba> ()))
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
{