From 8a7b3bb944ca08d240fc778a9269c6db0f9746f8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 14 Feb 2017 09:56:42 +0200 Subject: Modify library mate-information protocol not to use lib{} group --- build2/algorithm | 6 ++++-- build2/algorithm.cxx | 10 +++++----- build2/bin/rule.cxx | 38 +++++++++++--------------------------- build2/bin/target | 3 --- build2/bin/target.cxx | 9 --------- build2/cc/compile.cxx | 26 +++++++++++++++++--------- build2/cc/link.cxx | 22 +++++++++++----------- build2/target | 6 ------ build2/target.cxx | 7 ------- 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 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 ()); @@ -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 (t.dir, t.out, t.name, nullptr, nullptr); - - match_only (ml, act, *t.a); - } - - if (s) - { - if (t.s == nullptr) - t.s = &search (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 (t.dir, t.out, t.name, nullptr, nullptr); + build2::match (ml, act, *t.a); + } if (s) + { + if (t.s == nullptr) + t.s = &search (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 a = nullptr; const_ptr 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> 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 ()) + 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 usr_lib_dirs; // Extract lazily. @@ -159,15 +159,13 @@ namespace build2 if (pt == nullptr) { pt = &p.search (); + + if (lib* l = pt->is_a ()) + 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 . // 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) { -- cgit v1.1