From 29f8159583d2b02efa2afeaa58082f57222c943d Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 3 Dec 2015 14:37:22 +0200 Subject: Add ability for module to remember that it is unconfigured A module can set and then check the config.*.configured special variable to false. --- build/cli/module.cxx | 40 ++++++++++++++++++++++++++++------------ build/config/operation.cxx | 15 +++++++++++++-- build/config/utility | 17 ++++++++++------- build/config/utility.cxx | 15 ++++++++++++--- build/variable | 2 ++ 5 files changed, 65 insertions(+), 24 deletions(-) (limited to 'build') diff --git a/build/cli/module.cxx b/build/cli/module.cxx index 7ce4235..c44d670 100644 --- a/build/cli/module.cxx +++ b/build/cli/module.cxx @@ -65,6 +65,8 @@ namespace build // if (first) { + var_pool.find ("config.cli.configured", bool_type); + var_pool.find ("config.cli", string_type); //@@ VAR type var_pool.find ("config.cli.options", strings_type); @@ -73,17 +75,26 @@ namespace build // Configure. // - // The plan is as follows: try to configure the module. If this - // fails with the default values and the module is optional, - // leave it unconfigured. + // The plan is as follows: try to configure the module. If this fails, + // we are using default values, and the module is optional, leave it + // unconfigured. // - bool r (true); // We will only honor optional if the user didn't specify any cli // configuration explicitly. // optional = optional && !config::specified (root, "config.cli"); + // Don't re-run tests if the configuration says we are unconfigured. + // + if (optional) + { + auto l (root["config.cli.configured"]); + + if (l && !as (*l)) + return false; + } + // config.cli // if (first) @@ -148,10 +159,15 @@ namespace build if (ver.empty ()) { - r = false; + // Note that we are unconfigured so that we don't keep re-testing + // this on each run. + // + root.assign ("config.cli.configured") = false; if (verb >= 2) text << cli << " not found, leaving cli module unconfigured"; + + return false; } else { @@ -175,6 +191,10 @@ namespace build } } + // Clear the unconfigured flag, if any. + // + root.assign ("config.cli.configured") = true; + if (!ver.empty () && verb >= 2) text << cli << " " << ver; } @@ -185,15 +205,11 @@ namespace build // cli.* variables. See the cxx module for more information on // this merging semantics and some of its tricky aspects. // - if (r) - { - if (const value& v = config::optional (root, "config.cli.options")) - base.assign ("cli.options") += as (v); - } + if (const value& v = config::optional (root, "config.cli.options")) + base.assign ("cli.options") += as (v); // Register our rules. // - if (r) { auto& rs (base.rules); @@ -216,7 +232,7 @@ namespace build rs.insert (configure_id, update_id, "cli", compile_); } - return r; + return true; } } } diff --git a/build/config/operation.cxx b/build/config/operation.cxx index 295a38a..abe4e22 100644 --- a/build/config/operation.cxx +++ b/build/config/operation.cxx @@ -101,13 +101,24 @@ namespace build { const variable& var (p.first->first); const value& val (p.first->second); + const string& n (var.name); // Skip special variables. // - if (var.name == "config.loaded" || - var.name == "config.configured") + if (n == "config.loaded" || + n == "config.configured") continue; + // We will only write config.*.configured if it is false + // (true is implied by its absence). + // + if (n.size () > 11 && + n.compare (n.size () - 11, 11, ".configured") == 0) + { + if (val == nullptr || as (val)) + continue; + } + // Warn the user if the value that we are saving differs // from the one they specified on the command line. // diff --git a/build/config/utility b/build/config/utility index ece7a88..ee5f50b 100644 --- a/build/config/utility +++ b/build/config/utility @@ -83,13 +83,16 @@ namespace build return optional_absolute (root, var_pool.find (var)); } - // Check whether there are any variables specified from the - // config namespace. The idea is that we can check if there - // are any, say, config.install.* values. If there are none, - // then we can assume this functionality is not (yet) used - // and omit writing a whole bunch of NULL config.install.* - // values to the config.build file . We call it omitted/ - // delayed configuration. + // Check whether there are any variables specified from the config + // namespace. The idea is that we can check if there are any, say, + // config.install.* values. If there are none, then we can assume + // this functionality is not (yet) used and omit writing a whole + // bunch of NULL config.install.* values to the config.build file. + // We call it omitted/delayed configuration. + // + // Note that this function detects and ignores the special + // config.*.configured variable which may be used by a module to + // "remember" that it is unconfigured. // bool specified (scope& root, const std::string& ns); diff --git a/build/config/utility.cxx b/build/config/utility.cxx index c9d7c66..b81cb04 100644 --- a/build/config/utility.cxx +++ b/build/config/utility.cxx @@ -60,9 +60,18 @@ namespace build // for (scope* s (&r); s != nullptr; s = s->parent_scope ()) { - auto p (s->vars.find_namespace (ns)); - if (p.first != p.second) - return true; + for (auto p (s->vars.find_namespace (ns)); + p.first != p.second; + ++p.first) + { + const variable& var (p.first->first); + + // Ignore config.*.configured. + // + if (var.name.size () < 11 || + var.name.compare (var.name.size () - 11, 11, ".configured") != 0) + return true; + } } return false; diff --git a/build/variable b/build/variable index 5d0b175..51d748d 100644 --- a/build/variable +++ b/build/variable @@ -119,6 +119,8 @@ namespace build bool empty () const {return state_ == state_type::empty;} explicit operator bool () const {return !null ();} + bool operator== (std::nullptr_t) const {return null ();} + bool operator!= (std::nullptr_t) const {return !null ();} // Raw data read interface. // -- cgit v1.1