aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-08-29 08:14:27 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-08-29 08:14:27 +0200
commit2a9d673f298b623db061ee85d397563d644c8268 (patch)
tree7fa40a9d364f710e3aa7438e273287f14eace725
parentfd689eb883655dcb29e505b041cd02fac01f0bac (diff)
New configure meta-operation implementation
Now we search and match (but do not execute) a rule for every operation supported by the project.
-rw-r--r--build/bin/module.cxx14
-rw-r--r--build/cli/module.cxx4
-rw-r--r--build/cli/rule.cxx2
-rw-r--r--build/config/module.cxx8
-rw-r--r--build/config/operation.cxx45
-rw-r--r--build/cxx/compile.cxx11
-rw-r--r--build/cxx/link.cxx2
-rw-r--r--build/cxx/module.cxx9
-rw-r--r--build/dist/module.cxx2
-rw-r--r--build/rule14
-rw-r--r--build/rule.cxx4
11 files changed, 88 insertions, 27 deletions
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<obj> (perform_id, update_id, "bin.obj", obj_);
- rs.insert<obj> (perform_id, clean_id, "bin.obj", obj_);
+ rs.insert<obj> (perform_id, update_id, "bin", obj_);
+ rs.insert<obj> (perform_id, clean_id, "bin", obj_);
- rs.insert<lib> (perform_id, update_id, "bin.lib", lib_);
- rs.insert<lib> (perform_id, clean_id, "bin.lib", lib_);
+ rs.insert<lib> (perform_id, update_id, "bin", lib_);
+ rs.insert<lib> (perform_id, clean_id, "bin", lib_);
+
+ // Configure members.
+ //
+ rs.insert<lib> (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<lib> (perform_id, install_id, "bin.lib", lib_);
+ rs.insert<lib> (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<cxx::ixx> (perform_id, update_id, "cli", compile_);
rs.insert<cxx::ixx> (perform_id, clean_id, "cli", compile_);
+
+ // We may need to resolve group members.
+ //
+ rs.insert<cli_cxx> (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 <butl/filesystem>
-#include <build/scope>
#include <build/file>
+#include <build/rule>
+#include <build/scope>
#include <build/diagnostics>
#include <build/config/operation>
@@ -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<alias> (configure_id, 0, "alias", alias_rule::instance);
+ r.rules.insert<target> (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 <build/scope>
#include <build/target>
#include <build/context>
+#include <build/algorithm>
#include <build/diagnostics>
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<scope*> (v));
- configure_project (a, root);
+ target& t (*static_cast<target*> (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<libso> (perform_id, update_id, "cxx", link::instance);
rs.insert<libso> (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<obja> (configure_id, update_id, "cxx", compile::instance);
+ rs.insert<objso> (configure_id, update_id, "cxx", compile::instance);
+ rs.insert<exe> (configure_id, update_id, "cxx", link::instance);
+ rs.insert<liba> (configure_id, update_id, "cxx", link::instance);
+ rs.insert<libso> (configure_id, update_id, "cxx", link::instance);
+
//@@ Should we check if install module was loaded (see bin)?
//
rs.insert<exe> (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<target> (dist_id, 0, "dist", rule_);
- r.rules.insert<alias> (dist_id, 0, "dist", rule_);
+ r.rules.insert<alias> (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;
}