From 2a9d673f298b623db061ee85d397563d644c8268 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 29 Aug 2015 08:14:27 +0200 Subject: New configure meta-operation implementation Now we search and match (but do not execute) a rule for every operation supported by the project. --- build/bin/module.cxx | 14 +++++++++----- build/cli/module.cxx | 4 ++++ build/cli/rule.cxx | 2 +- build/config/module.cxx | 8 +++++++- build/config/operation.cxx | 45 ++++++++++++++++++++++++++++++++------------- build/cxx/compile.cxx | 11 ++++++----- build/cxx/link.cxx | 2 +- build/cxx/module.cxx | 9 +++++++++ build/dist/module.cxx | 2 +- build/rule | 14 ++++++++++++++ build/rule.cxx | 4 ++++ 11 files changed, 88 insertions(+), 27 deletions(-) (limited to 'build') diff --git a/build/bin/module.cxx b/build/bin/module.cxx index 63f602c..760c90d 100644 --- a/build/bin/module.cxx +++ b/build/bin/module.cxx @@ -57,11 +57,15 @@ namespace build { auto& rs (b.rules); - rs.insert (perform_id, update_id, "bin.obj", obj_); - rs.insert (perform_id, clean_id, "bin.obj", obj_); + rs.insert (perform_id, update_id, "bin", obj_); + rs.insert (perform_id, clean_id, "bin", obj_); - rs.insert (perform_id, update_id, "bin.lib", lib_); - rs.insert (perform_id, clean_id, "bin.lib", lib_); + rs.insert (perform_id, update_id, "bin", lib_); + rs.insert (perform_id, clean_id, "bin", lib_); + + // Configure members. + // + rs.insert (configure_id, update_id, "lib", lib_); //@@ Should we check if the install module was loaded // (by checking if install operation is registered @@ -70,7 +74,7 @@ namespace build // should enforce loading of all operation-defining // modules before all others? // - rs.insert (perform_id, install_id, "bin.lib", lib_); + rs.insert (perform_id, install_id, "bin", lib_); } // Enter module variables. diff --git a/build/cli/module.cxx b/build/cli/module.cxx index efc9ff2..0e81db3 100644 --- a/build/cli/module.cxx +++ b/build/cli/module.cxx @@ -72,6 +72,10 @@ namespace build rs.insert (perform_id, update_id, "cli", compile_); rs.insert (perform_id, clean_id, "cli", compile_); + + // We may need to resolve group members. + // + rs.insert (configure_id, update_id, "cli", compile_); } // Enter module variables. diff --git a/build/cli/rule.cxx b/build/cli/rule.cxx index b3c57f1..8b0ba85 100644 --- a/build/cli/rule.cxx +++ b/build/cli/rule.cxx @@ -172,7 +172,7 @@ namespace build { case perform_update_id: return &perform_update; case perform_clean_id: return &perform_clean; - default: assert (false); return default_recipe; + default: return noop_recipe; // Configure update. } } else diff --git a/build/config/module.cxx b/build/config/module.cxx index fbb51af..5ecf2d3 100644 --- a/build/config/module.cxx +++ b/build/config/module.cxx @@ -6,8 +6,9 @@ #include -#include #include +#include +#include #include #include @@ -49,6 +50,11 @@ namespace build r.meta_operations.insert (configure_id, configure); r.meta_operations.insert (disfigure_id, disfigure); + // Register alias and fallback rule for the configure meta-operation. + // + r.rules.insert (configure_id, 0, "alias", alias_rule::instance); + r.rules.insert (configure_id, 0, "", fallback_rule::instance); + // Load config.build if one exists. // path f (out_root / config_file); diff --git a/build/config/operation.cxx b/build/config/operation.cxx index 80b92dc..b1c6239 100644 --- a/build/config/operation.cxx +++ b/build/config/operation.cxx @@ -12,6 +12,7 @@ #include #include #include +#include #include using namespace std; @@ -187,26 +188,44 @@ namespace build } static void - configure_search (scope& root, - const target_key&, - const location&, - action_targets& ts) + configure_match (action, action_targets&) { - tracer trace ("configure_search"); - level5 ([&]{trace << "collecting " << root.path ();}); - ts.push_back (&root); + // Don't match anything -- see execute (). } static void - configure_match (action, action_targets&) {} - - static void configure_execute (action a, const action_targets& ts, bool) { + // Match rules to configure every operation supported by each + // project. Note that we are not calling operation_pre/post() + // callbacks here since the meta operation is configure and we + // know what we are doing. + // for (void* v: ts) { - scope& root (*static_cast (v)); - configure_project (a, root); + target& t (*static_cast (v)); + scope* rs (t.base_scope ().root_scope ()); + + if (rs == nullptr) + fail << "out of project target " << t; + + for (operations::size_type id (default_id + 1); // Skip default_id + id < rs->operations.size (); + ++id) + { + const operation_info* oi (rs->operations[id]); + if (oi == nullptr) + continue; + + current_inner_oif = oi; + current_outer_oif = nullptr; + current_mode = oi->mode; + dependency_count = 0; + + match (action (configure_id, id), t); + } + + configure_project (a, *rs); } } @@ -218,7 +237,7 @@ namespace build nullptr, // meta-operation pre &configure_operation_pre, &load, // normal load - &configure_search, + &search, // normal search &configure_match, &configure_execute, nullptr, // operation post diff --git a/build/cxx/compile.cxx b/build/cxx/compile.cxx index bb42c30..514c57a 100644 --- a/build/cxx/compile.cxx +++ b/build/cxx/compile.cxx @@ -129,11 +129,12 @@ namespace build t.prerequisite_targets.push_back (&pt); } - // Inject additional prerequisites. We only do it for update - // since chances are we will have to update some of our - // prerequisites in the process (auto-generated source code). + // Inject additional prerequisites. We only do it when + // performing update since chances are we will have to + // update some of our prerequisites in the process (auto- + // generated source code). // - if (a.operation () == update_id) + if (a == perform_update_id) { // The cached prerequisite target should be the same as what // is in t.prerequisite_targets since we used standard @@ -151,7 +152,7 @@ namespace build { case perform_update_id: return &perform_update; case perform_clean_id: return &perform_clean; - default: assert (false); return default_recipe; + default: return noop_recipe; // Configure update. } } diff --git a/build/cxx/link.cxx b/build/cxx/link.cxx index 9602e75..3b628b5 100644 --- a/build/cxx/link.cxx +++ b/build/cxx/link.cxx @@ -722,7 +722,7 @@ namespace build { case perform_update_id: return &perform_update; case perform_clean_id: return &perform_clean; - default: assert (false); return default_recipe; + default: return noop_recipe; // Configure update. } } diff --git a/build/cxx/module.cxx b/build/cxx/module.cxx index c2469d9..7171738 100644 --- a/build/cxx/module.cxx +++ b/build/cxx/module.cxx @@ -79,6 +79,15 @@ namespace build rs.insert (perform_id, update_id, "cxx", link::instance); rs.insert (perform_id, clean_id, "cxx", link::instance); + // Register for configure so that we detect unresolved imports + // during configuration rather that later, e.g., during update. + // + rs.insert (configure_id, update_id, "cxx", compile::instance); + rs.insert (configure_id, update_id, "cxx", compile::instance); + rs.insert (configure_id, update_id, "cxx", link::instance); + rs.insert (configure_id, update_id, "cxx", link::instance); + rs.insert (configure_id, update_id, "cxx", link::instance); + //@@ Should we check if install module was loaded (see bin)? // rs.insert (perform_id, install_id, "cxx", install::instance); diff --git a/build/dist/module.cxx b/build/dist/module.cxx index 7b9b340..ab27df7 100644 --- a/build/dist/module.cxx +++ b/build/dist/module.cxx @@ -52,7 +52,7 @@ namespace build // taking precedence. // r.rules.insert (dist_id, 0, "dist", rule_); - r.rules.insert (dist_id, 0, "dist", rule_); + r.rules.insert (dist_id, 0, "alias", rule_); // Enter module variables. // diff --git a/build/rule b/build/rule index 5339b40..af1bcc8 100644 --- a/build/rule +++ b/build/rule @@ -116,6 +116,20 @@ namespace build static fsdir_rule instance; }; + + // Fallback rule that always matches and does nothing. + // + class fallback_rule: public build::rule + { + public: + virtual match_result + match (action, target& t, const std::string&) const {return t;} + + virtual recipe + apply (action, target&, const match_result&) const {return noop_recipe;} + + static fallback_rule instance; + }; } #endif // BUILD_RULE diff --git a/build/rule.cxx b/build/rule.cxx index b9a989b..0fe5e1a 100644 --- a/build/rule.cxx +++ b/build/rule.cxx @@ -242,4 +242,8 @@ namespace build } fsdir_rule fsdir_rule::instance; + + // fallback_rule + // + fallback_rule fallback_rule::instance; } -- cgit v1.1