aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-12 16:23:37 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-12 17:04:22 +0200
commit83b5af87efef571b707fc1f409f22571a9f5054c (patch)
tree4961218154dbe2237f017b9e068ffe80fa025ed7
parent0fd7815cbc6557811df4f1b6ffb40461474b8534 (diff)
Add support for ordering modules in config.build
-rw-r--r--build2/bin/module.cxx4
-rw-r--r--build2/cc/init.cxx4
-rw-r--r--build2/cc/module.cxx19
-rw-r--r--build2/cli/module.cxx4
-rw-r--r--build2/config/module18
-rw-r--r--build2/config/module.cxx22
-rw-r--r--build2/config/operation.cxx7
-rw-r--r--build2/config/utility5
-rw-r--r--build2/config/utility.cxx10
-rw-r--r--build2/dist/module.cxx6
-rw-r--r--build2/install/module.cxx9
-rw-r--r--build2/test/module.cxx6
-rw-r--r--build2/types2
13 files changed, 97 insertions, 19 deletions
diff --git a/build2/bin/module.cxx b/build2/bin/module.cxx
index 3a3f612..89f20af 100644
--- a/build2/bin/module.cxx
+++ b/build2/bin/module.cxx
@@ -74,6 +74,10 @@ namespace build2
using config::required;
using config::optional;
+ // Adjust module priority (binutils).
+ //
+ config::save_module (r, "bin", 350);
+
// The idea here is as follows: if we already have one of
// the bin.* variables set, then we assume this is static
// project configuration and don't bother setting the
diff --git a/build2/cc/init.cxx b/build2/cc/init.cxx
index 80e5027..5f8e2fb 100644
--- a/build2/cc/init.cxx
+++ b/build2/cc/init.cxx
@@ -87,6 +87,10 @@ namespace build2
//
if (first)
{
+ // Adjust module priority (compiler).
+ //
+ config::save_module (r, "cc", 250);
+
// config.cc.id
//
{
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 4b51905..74c07e2 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -43,6 +43,15 @@ namespace build2
if (first)
{
+ // Adjust module priority (compiler). Also order cc module before us
+ // (we don't want to use priorities for that in case someone manages
+ // to slot in-between).
+ //
+ if (!cc_loaded)
+ config::save_module (r, "cc", 250);
+
+ config::save_module (r, x, 250);
+
const variable& config_c_coptions (var_pool["config.cc.coptions"]);
// config.x
@@ -66,7 +75,15 @@ namespace build2
cast_null<string> (r["cc.pattern"]))
: path (x_default));
- auto p1 (config::required (r, config_x, d));
+ // If this value was hinted, save it as commented out so that if the
+ // user changes the source of the pattern, this one will get updated
+ // as well.
+ //
+ auto p1 (config::required (r,
+ config_x,
+ d,
+ false,
+ cc_loaded ? config::save_commented : 0));
p.first = &p1.first.get ();
p.second = p1.second;
}
diff --git a/build2/cli/module.cxx b/build2/cli/module.cxx
index a9bed86..ef9c2f8 100644
--- a/build2/cli/module.cxx
+++ b/build2/cli/module.cxx
@@ -157,6 +157,10 @@ namespace build2
return string (); // Not found.
};
+ // Adjust module priority (code generator).
+ //
+ config::save_module (rs, "cli", 150);
+
string ver; // Empty means unconfigured.
path cli ("cli"); // Default.
bool nv (false); // New value.
diff --git a/build2/config/module b/build2/config/module
index 7360cf6..21a7e28 100644
--- a/build2/config/module
+++ b/build2/config/module
@@ -5,6 +5,7 @@
#ifndef BUILD2_CONFIG_MODULE
#define BUILD2_CONFIG_MODULE
+#include <map>
#include <algorithm> // find_if()
#include <butl/prefix-map>
@@ -49,15 +50,26 @@ namespace build2
struct saved_modules: butl::prefix_map<string, saved_variables, '.'>
{
- vector<const_iterator> sequence;
+ // Priority order with INT32_MIN being the highest. Modules with the
+ // same priority are saved in the order inserted.
+ //
+ // Generally, the idea is that we want higher-level modules at the top
+ // of the file since that's the configuration that we usualy want to
+ // change. So we have the following priority bands/defaults:
+ //
+ // 101-200/150 - code generators (e.g., yacc, bison)
+ // 201-300/250 - compilers (e.g., C, C++),
+ // 301-400/350 - binutils (ar, ld)
+ //
+ std::multimap<std::int32_t, const_iterator> order;
iterator
- insert (string name)
+ insert (string name, int prio = 0)
{
auto p (emplace (move (name), saved_variables ()));
if (p.second)
- sequence.push_back (p.first);
+ order.emplace (prio, p.first);
return p.first;
}
diff --git a/build2/config/module.cxx b/build2/config/module.cxx
index d4b9b49..de106b7 100644
--- a/build2/config/module.cxx
+++ b/build2/config/module.cxx
@@ -11,6 +11,7 @@
#include <build2/filesystem> // file_exists()
#include <build2/diagnostics>
+#include <build2/config/utility>
#include <build2/config/operation>
using namespace std;
@@ -23,17 +24,17 @@ namespace build2
const string module::name ("config");
void
- boot (scope& root, const location&, unique_ptr<module_base>&)
+ boot (scope& rs, const location&, unique_ptr<module_base>&)
{
tracer trace ("config::boot");
- const dir_path& out_root (root.out_path ());
+ const dir_path& out_root (rs.out_path ());
l5 ([&]{trace << "for " << out_root;});
// Register meta-operations.
//
- root.meta_operations.insert (configure_id, configure);
- root.meta_operations.insert (disfigure_id, disfigure);
+ rs.meta_operations.insert (configure_id, configure);
+ rs.meta_operations.insert (disfigure_id, disfigure);
// Load config.build if one exists.
//
@@ -45,11 +46,11 @@ namespace build2
path f (out_root / config_file);
if (file_exists (f))
- source (f, root, root);
+ source (f, rs, rs);
}
bool
- init (scope& root,
+ init (scope& rs,
scope&,
const location& l,
unique_ptr<module_base>& mod,
@@ -65,7 +66,7 @@ namespace build2
return true;
}
- l5 ([&]{trace << "for " << root.out_path ();});
+ l5 ([&]{trace << "for " << rs.out_path ();});
assert (config_hints.empty ()); // We don't known any hints.
@@ -74,6 +75,11 @@ namespace build2
if (current_mif->id == configure_id)
mod.reset (new module);
+ // Adjust priority for the import pseudo-module so that config.import.*
+ // values come first in config.build.
+ //
+ config::save_module (rs, "import", INT32_MIN);
+
// Register alias and fallback rule for the configure meta-operation.
//
{
@@ -83,7 +89,7 @@ namespace build2
global_scope->rules.insert<file> (
configure_id, 0, "config.file", file_rule::instance);
- auto& r (root.rules);
+ auto& r (rs.rules);
r.insert<target> (configure_id, 0, "config", fallback_rule::instance);
r.insert<file> (configure_id, 0, "config.file", fallback_rule::instance);
diff --git a/build2/config/operation.cxx b/build2/config/operation.cxx
index 89ddcfb..ca2d559 100644
--- a/build2/config/operation.cxx
+++ b/build2/config/operation.cxx
@@ -93,11 +93,10 @@ namespace build2
//
names storage;
- for (const saved_modules::const_iterator& i:
- mod.saved_modules.sequence)
+ for (auto p: mod.saved_modules.order)
{
- const string& sname (i->first);
- const saved_variables& svars (i->second);
+ const string& sname (p.second->first);
+ const saved_variables& svars (p.second->second);
bool first (true); // Separate modules with a blank line.
for (const saved_variable& sv: svars)
diff --git a/build2/config/utility b/build2/config/utility
index 2be2842..d11a38b 100644
--- a/build2/config/utility
+++ b/build2/config/utility
@@ -132,6 +132,11 @@ namespace build2
void
save_variable (scope& root, const variable&, uint64_t flags = 0);
+
+ // Establish module order/priority. See config::module for details.
+ //
+ void
+ save_module (scope& root, const char* name, int prio = 0);
}
}
diff --git a/build2/config/utility.cxx b/build2/config/utility.cxx
index b73e852..45417f1 100644
--- a/build2/config/utility.cxx
+++ b/build2/config/utility.cxx
@@ -170,5 +170,15 @@ namespace build2
assert (j->flags == flags);
}
}
+
+ void
+ save_module (scope& r, const char* name, int prio)
+ {
+ if (current_mif->id != configure_id)
+ return;
+
+ if (module* m = r.modules.lookup<module> (module::name))
+ m->saved_modules.insert (string ("config.") += name, prio);
+ }
}
}
diff --git a/build2/dist/module.cxx b/build2/dist/module.cxx
index eed9562..2da75c4 100644
--- a/build2/dist/module.cxx
+++ b/build2/dist/module.cxx
@@ -91,6 +91,12 @@ namespace build2
//
bool s (config::specified (r, "config.dist"));
+ // Adjust module priority so that the config.dist.* values are saved at
+ // the end of config.build.
+ //
+ if (s)
+ config::save_module (r, "dist", INT32_MAX);
+
// dist.root
//
{
diff --git a/build2/install/module.cxx b/build2/install/module.cxx
index ad2af6c..18ce2ad 100644
--- a/build2/install/module.cxx
+++ b/build2/install/module.cxx
@@ -156,7 +156,6 @@ namespace build2
//
// Note that the set_dir() calls below enter some more.
//
- if (first)
{
auto& v (var_pool);
@@ -177,11 +176,17 @@ namespace build2
// must be explicitly specified or the installer will complain
// if and when we try to install.
//
- if (first)
{
using build2::path;
bool s (config::specified (r, "config.install"));
+
+ // Adjust module priority so that the (numerous) config.install.*
+ // values are saved at the end of config.build.
+ //
+ if (s)
+ config::save_module (r, "install", INT32_MAX);
+
const string& n (cast<string> (r["project"]));
set_dir (s, r, "root", abs_dir_path (), false, "", "755", path ("install"));
diff --git a/build2/test/module.cxx b/build2/test/module.cxx
index 3b5cf7b..83ccf3c 100644
--- a/build2/test/module.cxx
+++ b/build2/test/module.cxx
@@ -74,6 +74,12 @@ namespace build2
//@@ TODO: Need ability to specify extra diff options (e.g.,
// --strip-trailing-cr, now hardcoded).
+ // Adjust module priority so that the config.test.* values are saved at
+ // the end of config.build.
+ //
+ // if (s)
+ // config::save_module (r, "test", INT32_MAX);
+
// Register rules.
//
{
diff --git a/build2/types b/build2/types
index 8ccbd13..e3aa1b1 100644
--- a/build2/types
+++ b/build2/types
@@ -11,7 +11,7 @@
#include <memory> // unique_ptr, shared_ptr
#include <utility> // pair, move()
#include <cstddef> // size_t, nullptr_t
-#include <cstdint> // uint{8,16,32,64}_t
+#include <cstdint> // uint{8,16,32,64}_t, *_MIN, *_MAX
#include <istream>
#include <ostream>
#include <functional> // function, reference_wrapper