aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-03-03 14:33:54 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-03-03 15:25:32 +0200
commit183329b89ddf810e2df5c250ae5b97d8ebcbba74 (patch)
treebf1e174ffe0929a9ec78ac642b351cbc5a23b78b
parentbcb5045dff9e87decbad3a785eb1fe42f4fc1410 (diff)
Fix cli distribution via group
-rw-r--r--build2/algorithm7
-rw-r--r--build2/algorithm.cxx24
-rw-r--r--build2/algorithm.ixx13
-rw-r--r--build2/buildfile14
-rw-r--r--build2/cli/init.cxx28
-rw-r--r--build2/cli/target.cxx7
-rw-r--r--build2/dist/init.cxx5
-rw-r--r--build2/dist/operation.cxx4
-rw-r--r--build2/dist/rule7
-rw-r--r--build2/operation12
10 files changed, 66 insertions, 55 deletions
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<recipe, action>
- 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<const pair<const string, reference_wrapper<const rule>>&, action>
- match_impl (action a, target& t, const rule* skip)
+ pair<const pair<const string, reference_wrapper<const rule>>*, 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<const string, reference_wrapper<const rule>>&,
- 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<const pair<const string, reference_wrapper<const rule>>*,
+ 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<const pair<const string, reference_wrapper<const rule>>&, action>
- match_impl (action, target&, const rule* skip);
+ pair<const pair<const string, reference_wrapper<const rule>>*, action>
+ match_impl (action, target&, const rule* skip, bool fail = true);
recipe
apply_impl (target&,
@@ -220,11 +220,14 @@ namespace build2
}
inline pair<recipe, action>
- 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 <build2/types-parsers>" \
--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<cli_cxx> (perform_update_id, "cli.compile", compile_);
- r.insert<cli_cxx> (perform_clean_id, "cli.compile", compile_);
-
- r.insert<cxx::hxx> (perform_update_id, "cli.compile", compile_);
- r.insert<cxx::hxx> (perform_clean_id, "cli.compile", compile_);
-
- r.insert<cxx::cxx> (perform_update_id, "cli.compile", compile_);
- r.insert<cxx::cxx> (perform_clean_id, "cli.compile", compile_);
+ auto reg = [&r] (meta_operation_id mid, operation_id oid)
+ {
+ r.insert<cli_cxx> (mid, oid, "cli.compile", compile_);
+ r.insert<cxx::hxx> (mid, oid, "cli.compile", compile_);
+ r.insert<cxx::cxx> (mid, oid, "cli.compile", compile_);
+ r.insert<cxx::ixx> (mid, oid, "cli.compile", compile_);
+ };
- r.insert<cxx::ixx> (perform_update_id, "cli.compile", compile_);
- r.insert<cxx::ixx> (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<cli_cxx> (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<cxx::hxx> (d, o, n, trace);
targets.insert<cxx::cxx> (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<target>(dist_id, test_id)
- // taking precedence.
+ // Register our wildcard rule. Do it explicitly for the alias to prevent
+ // something like insert<target>(dist_id, test_id) taking precedence.
//
rs.rules.insert<target> (dist_id, 0, "dist", rule_);
rs.rules.insert<alias> (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;