aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-09-13 17:00:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-09-13 17:00:08 +0200
commit2958f39350a067795e4e13080f78b9df394b298c (patch)
tree8fb9f84102a27354ad4a72a6d99d6f502f142efd
parentb9ea935ac2e31144db8ebdc2a98ebfc3f94357cc (diff)
Consistently install prerequisites from any scope by defaultinstall-scope
-rw-r--r--libbuild2/bash/rule.cxx15
-rw-r--r--libbuild2/bash/rule.hxx11
-rw-r--r--libbuild2/cc/install-rule.cxx24
-rw-r--r--libbuild2/cc/install-rule.hxx6
-rw-r--r--libbuild2/install/rule.cxx39
-rw-r--r--libbuild2/install/rule.hxx21
-rw-r--r--libbuild2/install/utility.hxx10
7 files changed, 67 insertions, 59 deletions
diff --git a/libbuild2/bash/rule.cxx b/libbuild2/bash/rule.cxx
index d378227..82c06c7 100644
--- a/libbuild2/bash/rule.cxx
+++ b/libbuild2/bash/rule.cxx
@@ -420,20 +420,5 @@ namespace build2
return r;
}
-
- const target* install_rule::
- filter (action a, const target& t, const prerequisite& p) const
- {
- // If this is a module prerequisite, install it as long as it is in the
- // same amalgamation as we are.
- //
- if (p.is_a<bash> ())
- {
- const target& pt (search (t, p));
- return pt.in (t.weak_scope ()) ? &pt : nullptr;
- }
- else
- return file_rule::filter (a, t, p);
- }
}
}
diff --git a/libbuild2/bash/rule.hxx b/libbuild2/bash/rule.hxx
index 81c4604..c54b07c 100644
--- a/libbuild2/bash/rule.hxx
+++ b/libbuild2/bash/rule.hxx
@@ -61,12 +61,8 @@ namespace build2
const string&) const;
};
- // Installation rule for bash scripts (exe{}) and modules (bash{}). Here
- // we do:
- //
- // 1. Signal to in_rule that this is update for install.
- //
- // 2. Custom filtering of prerequisites.
+ // Installation rule for bash scripts (exe{}) and modules (bash{}) that
+ // signals to in_rule that this is update for install.
//
class LIBBUILD2_BASH_SYMEXPORT install_rule: public install::file_rule
{
@@ -79,9 +75,6 @@ namespace build2
virtual recipe
apply (action, target&) const override;
- virtual const target*
- filter (action, const target&, const prerequisite&) const override;
-
protected:
const in_rule& in_;
};
diff --git a/libbuild2/cc/install-rule.cxx b/libbuild2/cc/install-rule.cxx
index dc10543..3e62d59 100644
--- a/libbuild2/cc/install-rule.cxx
+++ b/libbuild2/cc/install-rule.cxx
@@ -25,14 +25,15 @@ namespace build2
: common (move (d)), link_ (l) {}
const target* install_rule::
- filter (action a, const target& t, prerequisite_iterator& i) const
+ filter (const scope* is,
+ action a, const target& t, prerequisite_iterator& i) const
{
// NOTE: see libux_install_rule::filter() if changing anything here.
const prerequisite& p (i->prerequisite);
- // If this is a shared library prerequisite, install it as long as it
- // is in the same amalgamation as we are.
+ // If this is a shared library prerequisite, install it as long as it is
+ // in the installation scope.
//
// Less obvious: we also want to install a static library prerequisite
// of a library (since it could be referenced from its .pc file, etc).
@@ -61,7 +62,7 @@ namespace build2
// Note: not redundant since we are returning a member.
//
if ((st && pt->is_a<libs> ()) || (at && pt->is_a<liba> ()))
- return pt->in (t.weak_scope ()) ? pt : nullptr;
+ return is == nullptr || pt->in (*is) ? pt : nullptr;
// See through to libu*{} members. Note that we are always in the same
// project (and thus amalgamation).
@@ -72,7 +73,7 @@ namespace build2
// The rest of the tests only succeed if the base filter() succeeds.
//
- const target* pt (file_rule::filter (a, t, p));
+ const target* pt (file_rule::filter (is, a, t, p));
if (pt == nullptr)
return pt;
@@ -137,7 +138,7 @@ namespace build2
{
pt = t.is_a<exe> ()
? nullptr
- : file_rule::filter (a, *pt, pm.prerequisite);
+ : file_rule::filter (is, a, *pt, pm.prerequisite);
break;
}
}
@@ -279,8 +280,11 @@ namespace build2
: common (move (d)), link_ (l) {}
const target* libux_install_rule::
- filter (action a, const target& t, prerequisite_iterator& i) const
+ filter (const scope* is,
+ action a, const target& t, prerequisite_iterator& i) const
{
+ using file_rule = install::file_rule;
+
const prerequisite& p (i->prerequisite);
// The "see through" semantics that should be parallel to install_rule
@@ -301,13 +305,13 @@ namespace build2
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;
+ return is == nullptr || pt->in (*is) ? pt : nullptr;
if (pt->is_a<libux> ())
return pt;
}
- const target* pt (install::file_rule::instance.filter (a, t, p));
+ const target* pt (file_rule::instance.filter (is, a, t, p));
if (pt == nullptr)
return pt;
@@ -349,7 +353,7 @@ namespace build2
{
pt = t.is_a<libue> ()
? nullptr
- : install::file_rule::instance.filter (a, *pt, pm.prerequisite);
+ : file_rule::instance.filter (is, a, *pt, pm.prerequisite);
break;
}
}
diff --git a/libbuild2/cc/install-rule.hxx b/libbuild2/cc/install-rule.hxx
index 5856352..acd1bd8 100644
--- a/libbuild2/cc/install-rule.hxx
+++ b/libbuild2/cc/install-rule.hxx
@@ -35,7 +35,8 @@ namespace build2
install_rule (data&&, const link_rule&);
virtual const target*
- filter (action, const target&, prerequisite_iterator&) const override;
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&) const override;
virtual bool
match (action, target&, const string&) const override;
@@ -67,7 +68,8 @@ namespace build2
libux_install_rule (data&&, const link_rule&);
virtual const target*
- filter (action, const target&, prerequisite_iterator&) const override;
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&) const override;
virtual bool
match (action, target&, const string&) const override;
diff --git a/libbuild2/install/rule.cxx b/libbuild2/install/rule.cxx
index 388400a..9f8fbf7 100644
--- a/libbuild2/install/rule.cxx
+++ b/libbuild2/install/rule.cxx
@@ -54,16 +54,19 @@ namespace build2
}
const target* alias_rule::
- filter (action a, const target& t, prerequisite_iterator& i) const
+ filter (const scope* is,
+ action a, const target& t, prerequisite_iterator& i) const
{
assert (i->member == nullptr);
- return filter (a, t, i->prerequisite);
+ return filter (is, a, t, i->prerequisite);
}
const target* alias_rule::
- filter (action, const target& t, const prerequisite& p) const
+ filter (const scope* is,
+ action, const target& t, const prerequisite& p) const
{
- return &search (t, p);
+ const target& pt (search (t, p));
+ return is == nullptr || pt.in (*is) ? &pt : nullptr;
}
recipe alias_rule::
@@ -75,8 +78,9 @@ namespace build2
//
// @@ Shouldn't we do match in parallel (here and below)?
//
- auto& pts (t.prerequisite_targets[a]);
+ optional<const scope*> is; // Installation scope (resolve lazily).
+ auto& pts (t.prerequisite_targets[a]);
auto pms (group_prerequisite_members (a, t, members_mode::never));
for (auto i (pms.begin ()), e (pms.end ()); i != e; ++i)
{
@@ -100,7 +104,10 @@ namespace build2
// Note: we assume that if the filter enters the group, then it
// iterates over all its members.
//
- const target* pt (filter (a, t, i));
+ if (!is)
+ is = install_scope (t);
+
+ const target* pt (filter (*is, a, t, i));
if (pt == nullptr)
{
l5 ([&]{trace << "ignoring " << p << " (filtered out)";});
@@ -217,7 +224,6 @@ namespace build2
if (gv.members != nullptr)
{
auto& pts (t.prerequisite_targets[a]);
-
for (size_t i (0); i != gv.count; ++i)
{
const target* m (gv.members[i]);
@@ -271,17 +277,19 @@ namespace build2
}
const target* file_rule::
- filter (action a, const target& t, prerequisite_iterator& i) const
+ filter (const scope* is,
+ action a, const target& t, prerequisite_iterator& i) const
{
assert (i->member == nullptr);
- return filter (a, t, i->prerequisite);
+ return filter (is, a, t, i->prerequisite);
}
const target* file_rule::
- filter (action, const target& t, const prerequisite& p) const
+ filter (const scope* is,
+ action, const target& t, const prerequisite& p) const
{
const target& pt (search (t, p));
- return pt.in (t.root_scope ()) ? &pt : nullptr;
+ return is == nullptr || pt.in (*is) ? &pt : nullptr;
}
recipe file_rule::
@@ -314,8 +322,9 @@ namespace build2
if (a.operation () == update_id)
unchanged = match_inner (a, t, unmatch::unchanged).first;
- auto& pts (t.prerequisite_targets[a]);
+ optional<const scope*> is; // Installation scope (resolve lazily).
+ auto& pts (t.prerequisite_targets[a]);
auto pms (group_prerequisite_members (a, t, members_mode::never));
for (auto i (pms.begin ()), e (pms.end ()); i != e; ++i)
{
@@ -339,7 +348,11 @@ namespace build2
// Note: we assume that if the filter enters the group, then it
// iterates over all its members.
//
- const target* pt (filter (a, t, i));
+ if (!is)
+ is = install_scope (t);
+
+ const target* pt (filter (*is, a, t, i));
+
if (pt == nullptr)
{
l5 ([&]{trace << "ignoring " << p << " (filtered out)";});
diff --git a/libbuild2/install/rule.hxx b/libbuild2/install/rule.hxx
index 73f2486..ce60bb9 100644
--- a/libbuild2/install/rule.hxx
+++ b/libbuild2/install/rule.hxx
@@ -25,7 +25,9 @@ namespace build2
match (action, target&, const string&) const override;
// Return NULL if this prerequisite should be ignored and pointer to its
- // target otherwise. The default implementation allows all prerequsites.
+ // target otherwise. The default implementation ignores prerequsites
+ // that are outside of the installation scope (see install_scope() for
+ // details).
//
// The prerequisite is passed as an iterator allowing the filter to
// "see" inside groups.
@@ -34,10 +36,11 @@ namespace build2
prerequisite_members_range<group_prerequisites>::iterator;
virtual const target*
- filter (action, const target&, prerequisite_iterator&) const;
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&) const;
virtual const target*
- filter (action, const target&, const prerequisite&) const;
+ filter (const scope*, action, const target&, const prerequisite&) const;
virtual recipe
apply (action, target&) const override;
@@ -103,11 +106,8 @@ namespace build2
// Return NULL if this prerequisite should be ignored and pointer to its
// target otherwise. The default implementation ignores prerequsites
- // that are outside of this target's project.
- //
- // @@ I wonder why we do weak amalgamation for alias but project for
- // file? And then override this for prerequisite libraries/modules
- // in cc::install_rule and bash::install_rule...
+ // that are outside of the installation scope (see install_scope() for
+ // details).
//
// The prerequisite is passed as an iterator allowing the filter to
// "see" inside groups.
@@ -116,10 +116,11 @@ namespace build2
prerequisite_members_range<group_prerequisites>::iterator;
virtual const target*
- filter (action, const target&, prerequisite_iterator&) const;
+ filter (const scope*,
+ action, const target&, prerequisite_iterator&) const;
virtual const target*
- filter (action, const target&, const prerequisite&) const;
+ filter (const scope*, action, const target&, const prerequisite&) const;
virtual recipe
apply (action, target&) const override;
diff --git a/libbuild2/install/utility.hxx b/libbuild2/install/utility.hxx
index 2c0ca56..0104a1c 100644
--- a/libbuild2/install/utility.hxx
+++ b/libbuild2/install/utility.hxx
@@ -56,6 +56,16 @@ namespace build2
return install_mode (s, T::static_type, move (m));
}
+ // Return the "installation scope". We do not install prerequisites (for
+ // example, shared libraries) of targets (for example, executables) that
+ // are outside of this scope. If it's NULL, install all prerequisites.
+ //
+ inline const scope*
+ install_scope (const target&)
+ {
+ return nullptr;
+ }
+
// Resolve relative installation directory path (e.g., include/libfoo) to
// its absolute directory path (e.g., /usr/include/libfoo). If the
// resolution encountered an unknown directory, issue diagnostics and fail