aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-02-14 09:56:42 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-02-14 14:53:51 +0200
commit8a7b3bb944ca08d240fc778a9269c6db0f9746f8 (patch)
tree750e1ae74d9fdd3989871f92b71df4b0feb3b3f1
parentcc2b346d96bc2877efc9719507ceaa4fefbc9668 (diff)
Modify library mate-information protocol not to use lib{} group
-rw-r--r--build2/algorithm6
-rw-r--r--build2/algorithm.cxx10
-rw-r--r--build2/bin/rule.cxx38
-rw-r--r--build2/bin/target3
-rw-r--r--build2/bin/target.cxx9
-rw-r--r--build2/cc/compile.cxx26
-rw-r--r--build2/cc/link.cxx22
-rw-r--r--build2/target6
-rw-r--r--build2/target.cxx7
9 files changed, 48 insertions, 79 deletions
diff --git a/build2/algorithm b/build2/algorithm
index 33da884..18f2fce 100644
--- a/build2/algorithm
+++ b/build2/algorithm
@@ -86,7 +86,9 @@ namespace build2
match (slock&, action, target&);
// Note that calling this function only makes sense if the target itself
- // doesn't have its own dependents.
+ // doesn't have its own dependents (since they will not be unmatched) or
+ // if you know for sure that someone else will match and execute this
+ // target for real.
//
void
unmatch (action, target&);
@@ -98,7 +100,7 @@ namespace build2
match_only (slock&, action, target&);
// Match a "delegate rule" from withing another rules' apply() function
- // skipping recursive matches (thus the third argument). Return recipe and
+ // avoiding recursive matches (thus the third argument). Return recipe and
// recipe action (if any). Note that unlike match(), this call doesn't
// increment the dependents count. See also the companion
// execute_delegate().
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index 0aad5b6..7239f3e 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -98,12 +98,12 @@ namespace build2
{
pair<const rule*, match_result> r (nullptr, false);
- // By default, clear the resolved targets list before calling
- // match(). The rule is free to modify this list in match()
- // (provided that it matches) in order to, for example, prepare
- // it for apply().
+ // Clear the resolved targets list before calling match(). The rule is
+ // free to modify this list in match() (provided that it matches) in order
+ // to, for example, prepare it for apply().
//
- t.reset (a);
+ t.clear_data ();
+ t.prerequisite_targets.clear ();
// If this is a nested operation, first try the outer operation.
// This allows a rule to implement a "precise match", that is,
diff --git a/build2/bin/rule.cxx b/build2/bin/rule.cxx
index ea84971..075af0e 100644
--- a/build2/bin/rule.cxx
+++ b/build2/bin/rule.cxx
@@ -46,7 +46,7 @@ namespace build2
"insufficient space");
match_result lib_rule::
- match (slock& ml, action act, target& xt, const string&) const
+ match (slock&, action act, target& xt, const string&) const
{
lib& t (xt.as<lib> ());
@@ -64,30 +64,6 @@ namespace build2
fail << "unknown library type: " << type <<
info << "'static', 'shared', or 'both' expected";
- // Search and pre-match the members. The pre-match here is part
- // of the "library meta-information protocol" that could be used
- // by the module that actually builds the members. The idea is
- // that pre-matching members may populate our prerequisite_targets
- // with prerequisite libraries from which others can extract the
- // meta-information about the library, such as the options to use
- // when linking it, etc.
- //
- if (a)
- {
- if (t.a == nullptr)
- t.a = &search<liba> (t.dir, t.out, t.name, nullptr, nullptr);
-
- match_only (ml, act, *t.a);
- }
-
- if (s)
- {
- if (t.s == nullptr)
- t.s = &search<libs> (t.dir, t.out, t.name, nullptr, nullptr);
-
- match_only (ml, act, *t.s);
- }
-
t.data (match_data {type}); // Save in the target's auxilary storage.
match_result mr (true);
@@ -112,13 +88,21 @@ namespace build2
bool a (type == "static" || type == "both");
bool s (type == "shared" || type == "both");
- // Now we do full match.
- //
if (a)
+ {
+ if (t.a == nullptr)
+ t.a = &search<liba> (t.dir, t.out, t.name, nullptr, nullptr);
+
build2::match (ml, act, *t.a);
+ }
if (s)
+ {
+ if (t.s == nullptr)
+ t.s = &search<libs> (t.dir, t.out, t.name, nullptr, nullptr);
+
build2::match (ml, act, *t.s);
+ }
return &perform;
}
diff --git a/build2/bin/target b/build2/bin/target
index 0108f09..4157f67 100644
--- a/build2/bin/target
+++ b/build2/bin/target
@@ -94,9 +94,6 @@ namespace build2
const_ptr<liba> a = nullptr;
const_ptr<libs> s = nullptr;
- virtual void
- reset (action_type) override;
-
public:
static const target_type static_type;
diff --git a/build2/bin/target.cxx b/build2/bin/target.cxx
index caef8e0..ea0a1ac 100644
--- a/build2/bin/target.cxx
+++ b/build2/bin/target.cxx
@@ -201,15 +201,6 @@ namespace build2
// lib
//
- void lib::
- reset (action_type)
- {
- clear_data ();
-
- // Don't clear prerequisite_targets since it is "given" to our
- // members to implement "library meta-information protocol".
- }
-
static pair<target*, optional<string>>
lib_factory (const target_type&,
dir_path d,
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index c8394a9..3039f00 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -213,7 +213,9 @@ namespace build2
const scope& bs (t.base_scope ());
const scope& rs (*bs.root_scope ());
+
otype ct (compile_type (t));
+ lorder lo (link_order (bs, ct));
// Derive file name from target name.
//
@@ -286,16 +288,24 @@ namespace build2
{
if (a.operation () == update_id)
{
- // Handle imported libraries. We know that for such libraries
- // we don't need to do match() in order to get options (if
- // any, they would be set by search_library()).
+ // Handle imported libraries. We know that for such libraries we
+ // don't need to do match() in order to get options (if any, they
+ // would be set by search_library()).
//
- if (!p.proj () ||
- search_library (
- sys_lib_dirs, usr_lib_dirs, p.prerequisite) == nullptr)
+ if (p.proj ())
{
- match_only (ml, a, p.search ());
+ if (search_library (sys_lib_dirs,
+ usr_lib_dirs,
+ p.prerequisite) != nullptr)
+ continue;
}
+
+ target* pt (&p.search ());
+
+ if (lib* l = pt->is_a<lib> ())
+ pt = &link_member (*l, lo);
+
+ match_only (ml, a, *pt);
}
continue;
@@ -316,8 +326,6 @@ namespace build2
//
if (a == perform_update_id)
{
- lorder lo (link_order (bs, ct));
-
// The cached prerequisite target should be the same as what is in
// t.prerequisite_targets since we used standard search() and match()
// above.
diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx
index 0aef9f0..269b11f 100644
--- a/build2/cc/link.cxx
+++ b/build2/cc/link.cxx
@@ -126,7 +126,7 @@ namespace build2
// Set the library type.
//
- t.vars.assign (c_type) = string (x);
+ t.vars.assign (c_type) = string (x); //@@ move to apply()?
// If we have any prerequisite libraries, search/import and pre-match
// them to implement the "library meta-information protocol". Don't do
@@ -140,8 +140,8 @@ namespace build2
op != install_id && oop != install_id &&
op != uninstall_id && oop != uninstall_id)
{
- if (t.group != nullptr)
- t.group->prerequisite_targets.clear (); // lib{}'s
+ const scope& bs (t.base_scope ());
+ lorder lo (link_order (bs, lt));
optional<dir_paths> usr_lib_dirs; // Extract lazily.
@@ -159,15 +159,13 @@ namespace build2
if (pt == nullptr)
{
pt = &p.search ();
+
+ if (lib* l = pt->is_a<lib> ())
+ pt = &link_member (*l, lo);
+
match_only (ml, a, *pt);
}
- // If the prerequisite came from the lib{} group, then also
- // add it to lib's prerequisite_targets.
- //
- if (!p.prerequisite.belongs (t))
- t.group->prerequisite_targets.push_back (pt);
-
t.prerequisite_targets.push_back (pt);
}
}
@@ -486,8 +484,10 @@ namespace build2
// altogether. So we are going to use the target's project.
//
- // @@ Why are we creating the obj{} group if the source came from a
- // group?
+ // If the source came from the lib{} group, then create the obj{}
+ // group and add the source as a prerequisite of the obj{} group,
+ // not the obj?{} member. This way we only need one prerequisite
+ // for, say, both liba{} and libs{}.
//
bool group (!p.prerequisite.belongs (t)); // Group's prerequisite.
diff --git a/build2/target b/build2/target
index 90709db..27d6947 100644
--- a/build2/target
+++ b/build2/target
@@ -245,12 +245,6 @@ namespace build2
public:
using action_type = build2::action;
- // Reset the target before matching it to a rule. The default
- // implementation clears the auxilary data and prerequisite_targets.
- //
- virtual void
- reset (action_type);
-
// You should not call this function directly; rather use
// resolve_group_members() from <build2/algorithm>.
//
diff --git a/build2/target.cxx b/build2/target.cxx
index 5389ec9..9f5d94b 100644
--- a/build2/target.cxx
+++ b/build2/target.cxx
@@ -131,13 +131,6 @@ namespace build2
dependents = 0; //@@ MT: either relax or use as match flag?
}
- void target::
- reset (action_type)
- {
- clear_data ();
- prerequisite_targets.clear ();
- }
-
group_view target::
group_members (action_type)
{