From 183329b89ddf810e2df5c250ae5b97d8ebcbba74 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 3 Mar 2017 14:33:54 +0200 Subject: Fix cli distribution via group --- build2/algorithm | 7 ++++--- build2/algorithm.cxx | 24 +++++++++++++----------- build2/algorithm.ixx | 13 ++++++++----- build2/buildfile | 14 ++++++-------- build2/cli/init.cxx | 28 ++++++++++++++-------------- build2/cli/target.cxx | 7 +++---- build2/dist/init.cxx | 5 ++--- build2/dist/operation.cxx | 4 +++- build2/dist/rule | 7 +++++++ build2/operation | 12 ++++++------ 10 files changed, 66 insertions(+), 55 deletions(-) (limited to 'build2') diff --git a/build2/algorithm b/build2/algorithm index 2fa9fe4..dfe8c42 100644 --- a/build2/algorithm +++ b/build2/algorithm @@ -162,12 +162,13 @@ namespace build2 // Match a "delegate rule" from withing another rules' apply() function // 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 + // recipe action (if any). Unless fail is false, fail if not rule is found. + // Otherwise return empty recipe. Note that unlike match(), this function + // does not increment the dependents count. See also the companion // execute_delegate(). // pair - match_delegate (action, target&, const rule&); + match_delegate (action, target&, const rule&, bool fail = true); // The standard prerequisite search and match implementations. They call // search() and then match() for each prerequisite in a loop omitting out of diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index d981af0..e44d610 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -245,8 +245,8 @@ namespace build2 // Return the matching rule and the recipe action. // - pair>&, action> - match_impl (action a, target& t, const rule* skip) + pair>*, action> + match_impl (action a, target& t, const rule* skip, bool f) { // Clear the resolved targets list before calling match(). The rule is // free to modify this list in match() (provided that it matches) in order @@ -393,9 +393,7 @@ namespace build2 } if (!ambig) - return pair< - const pair>&, - action> {r, m.recipe_action}; + return make_pair (&r, m.recipe_action); else dr << info << "use rule hint to disambiguate this match"; } @@ -404,13 +402,17 @@ namespace build2 } } - diag_record dr; - dr << fail << "no rule to " << diag_do (a, t); + if (f) + { + diag_record dr; + dr << fail << "no rule to " << diag_do (a, t); - if (verb < 4) - dr << info << "re-run with --verbose 4 for more information"; + if (verb < 4) + dr << info << "re-run with --verbose 4 for more information"; + } - dr << endf; + return pair>*, + action> {nullptr, a}; } recipe @@ -451,7 +453,7 @@ namespace build2 // Match. // auto mr (match_impl (a, t, nullptr)); - t.rule = &mr.first; + t.rule = mr.first; t.action = mr.second; // In case overriden. l.offset = target::offset_matched; diff --git a/build2/algorithm.ixx b/build2/algorithm.ixx index 83aa050..e1f8ddc 100644 --- a/build2/algorithm.ixx +++ b/build2/algorithm.ixx @@ -129,8 +129,8 @@ namespace build2 return r; } - pair>&, action> - match_impl (action, target&, const rule* skip); + pair>*, action> + match_impl (action, target&, const rule* skip, bool fail = true); recipe apply_impl (target&, @@ -220,11 +220,14 @@ namespace build2 } inline pair - match_delegate (action a, target& t, const rule& r) + match_delegate (action a, target& t, const rule& r, bool fail) { assert (phase == run_phase::match); - auto mr (match_impl (a, t, &r)); - return make_pair (apply_impl (t, mr.first, mr.second), mr.second); + auto mr (match_impl (a, t, &r, fail)); + return make_pair (mr.first != nullptr + ? apply_impl (t, *mr.first, mr.second) + : empty_recipe, + mr.second); } group_view diff --git a/build2/buildfile b/build2/buildfile index a946bc7..a1c3d3d 100644 --- a/build2/buildfile +++ b/build2/buildfile @@ -110,10 +110,10 @@ if ($cxx.target.class != "windows") # Generated options parser. # -{hxx ixx cxx}{b-options}: cli{b} - if $cli.configured { + cli.cxx{b-options}: cli{b} + cli.options += -I $src_root --include-with-brackets --include-prefix build2 \ --guard-prefix BUILD2 --cxx-prologue "#include " \ --cli-namespace build2::cl --generate-file-scanner --generate-parse \ @@ -123,10 +123,8 @@ if $cli.configured # cli.options += --suppress-undocumented --long-usage --ansi-color \ --page-usage 'build2::print_$name$_' --option-length 20 -} -# Include generated cli files into the distribution. -# -hxx{*-options}: dist = true -ixx{*-options}: dist = true -cxx{*-options}: dist = true + # Include generated cli files into the distribution. + # + cli.cxx{*}: dist = true +} diff --git a/build2/cli/init.cxx b/build2/cli/init.cxx index 1cf248d..590d434 100644 --- a/build2/cli/init.cxx +++ b/build2/cli/init.cxx @@ -300,23 +300,23 @@ namespace build2 { auto& r (bs.rules); - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); - - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); + auto reg = [&r] (meta_operation_id mid, operation_id oid) + { + r.insert (mid, oid, "cli.compile", compile_); + r.insert (mid, oid, "cli.compile", compile_); + r.insert (mid, oid, "cli.compile", compile_); + r.insert (mid, oid, "cli.compile", compile_); + }; - r.insert (perform_update_id, "cli.compile", compile_); - r.insert (perform_clean_id, "cli.compile", compile_); + reg (perform_id, update_id); + reg (perform_id, clean_id); - // Other rules (e.g., cxx::compile) may need to have the group - // members resolved. Looks like a general pattern: groups should - // resolve on configure(update). + // Other rules (e.g., cxx::compile) may need to have the group members + // resolved/linked up. Looks like a general pattern: groups should + // resolve on *(update). // - r.insert (configure_update_id, "cli.compile", compile_); + reg (configure_id, update_id); + reg (dist_id, update_id); } return true; diff --git a/build2/cli/target.cxx b/build2/cli/target.cxx index 51f58aa..015c034 100644 --- a/build2/cli/target.cxx +++ b/build2/cli/target.cxx @@ -50,10 +50,9 @@ namespace build2 { tracer trace ("cli::cli_cxx_factory"); - // Pre-enter (potential) members as targets. The main purpose - // of doing this is to avoid searching for existing files in - // src_base if the buildfile mentions some of them explicitly - // as prerequisites. + // Pre-enter (potential) members as targets. The main purpose of doing + // this is to avoid searching for existing files in src_base if the + // buildfile mentions some of them explicitly as prerequisites. // targets.insert (d, o, n, trace); targets.insert (d, o, n, trace); diff --git a/build2/dist/init.cxx b/build2/dist/init.cxx index 98f8a9a..be7b381 100644 --- a/build2/dist/init.cxx +++ b/build2/dist/init.cxx @@ -84,9 +84,8 @@ namespace build2 assert (config_hints.empty ()); // We don't known any hints. - // Register our wildcard rule. Do it explicitly for the alias - // to prevent something like insert(dist_id, test_id) - // taking precedence. + // Register our wildcard rule. Do it explicitly for the alias to prevent + // something like insert(dist_id, test_id) taking precedence. // rs.rules.insert (dist_id, 0, "dist", rule_); rs.rules.insert (dist_id, 0, "dist.alias", rule_); diff --git a/build2/dist/operation.cxx b/build2/dist/operation.cxx index 6b50c14..027452f 100644 --- a/build2/dist/operation.cxx +++ b/build2/dist/operation.cxx @@ -123,7 +123,9 @@ namespace build2 // set_current_oif (*oif); - match (action (dist_id, oif->id), ts); // Standard (perform) match. + // Use standard (perform) match. + // + match (action (dist_id, oif->id), ts); } } diff --git a/build2/dist/rule b/build2/dist/rule index db8e731..0a5cc3a 100644 --- a/build2/dist/rule +++ b/build2/dist/rule @@ -16,6 +16,13 @@ namespace build2 { namespace dist { + // This is the default rule that simply matches all the prerequisites. + // + // A custom rule (usually the same as perform_update) may be necessary to + // enter ad hoc prerequisites (like generated test input/output) or + // establishing group links (so that we see the dist variable set on a + // group). + // class rule: public build2::rule { public: diff --git a/build2/operation b/build2/operation index 7eb6325..e6c34d6 100644 --- a/build2/operation +++ b/build2/operation @@ -109,12 +109,12 @@ namespace build2 // that no operation was explicitly specified by the user. If adding // something here remember to update the man page. // - const operation_id default_id = 1; // Shall be first. - const operation_id update_id = 2; // Shall be second. - const operation_id clean_id = 3; - const operation_id test_id = 4; - const operation_id install_id = 5; - const operation_id uninstall_id = 6; + const operation_id default_id = 1; // Shall be first. + const operation_id update_id = 2; // Shall be second. + const operation_id clean_id = 3; + const operation_id test_id = 4; + const operation_id install_id = 5; + const operation_id uninstall_id = 6; const action_id perform_update_id = (perform_id << 4) | update_id; const action_id perform_clean_id = (perform_id << 4) | clean_id; -- cgit v1.1