diff options
Diffstat (limited to 'build/config')
-rw-r--r-- | build/config/module | 26 | ||||
-rw-r--r-- | build/config/module.cxx | 90 | ||||
-rw-r--r-- | build/config/operation | 19 | ||||
-rw-r--r-- | build/config/operation.cxx | 455 | ||||
-rw-r--r-- | build/config/utility | 128 | ||||
-rw-r--r-- | build/config/utility.cxx | 92 | ||||
-rw-r--r-- | build/config/utility.ixx | 17 | ||||
-rw-r--r-- | build/config/utility.txx | 45 |
8 files changed, 0 insertions, 872 deletions
diff --git a/build/config/module b/build/config/module deleted file mode 100644 index 3e43c7b..0000000 --- a/build/config/module +++ /dev/null @@ -1,26 +0,0 @@ -// file : build/config/module -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD_CONFIG_MODULE -#define BUILD_CONFIG_MODULE - -#include <build/types> -#include <build/utility> - -#include <build/module> - -namespace build -{ - namespace config - { - extern "C" void - config_boot (scope&, const location&, unique_ptr<module>&); - - extern "C" bool - config_init ( - scope&, scope&, const location&, unique_ptr<module>&, bool, bool); - } -} - -#endif // BUILD_CONFIG_MODULE diff --git a/build/config/module.cxx b/build/config/module.cxx deleted file mode 100644 index c9139ed..0000000 --- a/build/config/module.cxx +++ /dev/null @@ -1,90 +0,0 @@ -// file : build/config/module.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build/config/module> - -#include <butl/filesystem> - -#include <build/file> -#include <build/rule> -#include <build/scope> -#include <build/diagnostics> - -#include <build/config/operation> - -using namespace std; -using namespace butl; - -namespace build -{ - namespace config - { - //@@ Same as in operation.cxx - // - static const path config_file ("build/config.build"); - - extern "C" void - config_boot (scope& root, const location&, unique_ptr<module>&) - { - tracer trace ("config::boot"); - - const dir_path& out_root (root.out_path ()); - level5 ([&]{trace << "for " << out_root;}); - - // Register meta-operations. - // - root.meta_operations.insert (configure_id, configure); - root.meta_operations.insert (disfigure_id, disfigure); - - // Load config.build if one exists. - // - // Note that we have to do this during bootstrap since the order in - // which the modules will be initialized is unspecified. So it is - // possible that some module which needs the configuration will get - // called first. - // - path f (out_root / config_file); - - if (file_exists (f)) - source (f, root, root); - } - - extern "C" bool - config_init (scope& root, - scope&, - const location& l, - std::unique_ptr<module>&, - bool first, - bool) - { - tracer trace ("config::init"); - - if (!first) - { - warn (l) << "multiple config module initializations"; - return true; - } - - level5 ([&]{trace << "for " << root.out_path ();}); - - // Register alias and fallback rule for the configure meta-operation. - // - { - // We need this rule for out-of-any-project dependencies (e.g., - // libraries imported from /usr/lib). - // - global_scope->rules.insert<file> ( - configure_id, 0, "config.file", file_rule::instance); - - auto& r (root.rules); - - r.insert<target> (configure_id, 0, "config", fallback_rule::instance); - r.insert<file> (configure_id, 0, "config.file", fallback_rule::instance); - r.insert<alias> (configure_id, 0, "config.alias", alias_rule::instance); - } - - return true; - } - } -} diff --git a/build/config/operation b/build/config/operation deleted file mode 100644 index ee5161d..0000000 --- a/build/config/operation +++ /dev/null @@ -1,19 +0,0 @@ -// file : build/config/operation -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD_CONFIG_OPERATION -#define BUILD_CONFIG_OPERATION - -#include <build/operation> - -namespace build -{ - namespace config - { - extern meta_operation_info configure; - extern meta_operation_info disfigure; - } -} - -#endif // BUILD_CONFIG_OPERATION diff --git a/build/config/operation.cxx b/build/config/operation.cxx deleted file mode 100644 index abe4e22..0000000 --- a/build/config/operation.cxx +++ /dev/null @@ -1,455 +0,0 @@ -// file : build/config/operation.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build/config/operation> - -#include <fstream> - -#include <butl/filesystem> - -#include <build/file> -#include <build/scope> -#include <build/target> -#include <build/context> -#include <build/algorithm> -#include <build/diagnostics> - -using namespace std; -using namespace butl; - -namespace build -{ - namespace config - { - static const path config_file ("build/config.build"); - - // configure - // - static operation_id - configure_operation_pre (operation_id o) - { - // Don't translate default to update. In our case unspecified - // means configure everything. - // - return o; - } - - static void - save_src_root (const dir_path& out_root, const dir_path& src_root) - { - path f (out_root / src_root_file); - - if (verb) - text << (verb >= 2 ? "config::save_src_root " : "save ") << f; - - try - { - ofstream ofs (f.string ()); - if (!ofs.is_open ()) - fail << "unable to open " << f; - - ofs.exceptions (ofstream::failbit | ofstream::badbit); - - //@@ TODO: quote path - // - ofs << "# Created automatically by the config module." << endl - << "#" << endl - << "src_root = " << src_root << endl; - } - catch (const ofstream::failure&) - { - fail << "unable to write " << f; - } - } - - static void - save_config (scope& root) - { - const dir_path& out_root (root.out_path ()); - path f (out_root / config_file); - - if (verb) - text << (verb >= 2 ? "config::save_config " : "save ") << f; - - try - { - ofstream ofs (f.string ()); - if (!ofs.is_open ()) - fail << "unable to open " << f; - - ofs.exceptions (ofstream::failbit | ofstream::badbit); - - ofs << "# Created automatically by the config module, but" << endl - << "# feel free to edit." << endl - << "#" << endl; - - if (auto l = root.vars["amalgamation"]) - { - const dir_path& d (as<dir_path> (*l)); - - ofs << "# Base configuration inherited from " << d << endl - << "#" << endl; - } - - // Save all the variables in the config namespace that are set - // on the project's root scope. - // - for (auto p (root.vars.find_namespace ("config")); - p.first != p.second; - ++p.first) - { - const variable& var (p.first->first); - const value& val (p.first->second); - const string& n (var.name); - - // Skip special variables. - // - 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<bool> (val)) - continue; - } - - // Warn the user if the value that we are saving differs - // from the one they specified on the command line. - // - auto l ((*global_scope)[var]); - if (l.defined () && *l != val) - { - warn << "variable " << var.name << " configured value " - << "differs from command line value" << - info << "reconfigure the project to use command line value"; - } - - if (val) - { - ofs << var.name << " = " << val.data_ << endl; - //text << var.name << " = " << val.data_; - } - else - { - ofs << var.name << " = #[null]" << endl; // @@ TODO: [null] - //text << var.name << " = [null]"; - } - } - } - catch (const ofstream::failure&) - { - fail << "unable to write " << f; - } - } - - static void - configure_project (action a, scope& root) - { - tracer trace ("configure_project"); - - const dir_path& out_root (root.out_path ()); - const dir_path& src_root (root.src_path ()); - - // Make sure the directories exist. - // - if (out_root != src_root) - { - mkdir_p (out_root); - mkdir (out_root / build_dir); - mkdir (out_root / bootstrap_dir); - } - - // We distinguish between a complete configure and operation- - // specific. - // - if (a.operation () == default_id) - { - level5 ([&]{trace << "completely configuring " << out_root;}); - - // Save src-root.build unless out_root is the same as src. - // - if (out_root != src_root) - save_src_root (out_root, src_root); - - // Save config.build. - // - save_config (root); - } - else - { - } - - // Configure subprojects that have been loaded. - // - if (auto l = root.vars["subprojects"]) - { - for (auto p: as<subprojects> (*l)) - { - const dir_path& pd (p.second); - dir_path out_nroot (out_root / pd); - scope& nroot (scopes.find (out_nroot)); - - // @@ Strictly speaking we need to check whether the config - // module was loaded for this subproject. - // - if (nroot.out_path () != out_nroot) // This subproject not loaded. - continue; - - configure_project (a, nroot); - } - } - } - - static void - configure_match (action, action_targets&) - { - // Don't match anything -- see execute (). - } - - 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) - { - 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); - } - } - - meta_operation_info configure { - "configure", - "configure", - "configuring", - "is configured", - nullptr, // meta-operation pre - &configure_operation_pre, - &load, // normal load - &search, // normal search - &configure_match, - &configure_execute, - nullptr, // operation post - nullptr // meta-operation post - }; - - // disfigure - // - static operation_id - disfigure_operation_pre (operation_id o) - { - // Don't translate default to update. In our case unspecified - // means disfigure everything. - // - return o; - } - - static void - disfigure_load (const path& bf, - scope&, - const dir_path&, - const dir_path&, - const location&) - { - tracer trace ("disfigure_load"); - level6 ([&]{trace << "skipping " << bf;}); - } - - static void - disfigure_search (scope& root, - const target_key&, - const location&, - action_targets& ts) - { - tracer trace ("disfigure_search"); - level6 ([&]{trace << "collecting " << root.out_path ();}); - ts.push_back (&root); - } - - static void - disfigure_match (action, action_targets&) {} - - static bool - disfigure_project (action a, scope& root) - { - tracer trace ("disfigure_project"); - - bool m (false); // Keep track of whether we actually did anything. - - const dir_path& out_root (root.out_path ()); - const dir_path& src_root (root.src_path ()); - - // Disfigure subprojects. Since we don't load buildfiles during - // disfigure, we do it for all known subprojects. - // - if (auto l = root.vars["subprojects"]) - { - for (auto p: as<subprojects> (*l)) - { - const dir_path& pd (p.second); - - // Create and bootstrap subproject's root scope. - // - dir_path out_nroot (out_root / pd); - - // The same logic for src_root as in create_bootstrap_inner(). - // - scope& nroot (create_root (out_nroot, dir_path ())); - bootstrap_out (nroot); - - value& val (nroot.assign ("src_root")); - - if (!val) - val = is_src_root (out_nroot) ? out_nroot : (src_root / pd); - - setup_root (nroot); - - bootstrap_src (nroot); - - m = disfigure_project (a, nroot) || m; - - // We use mkdir_p() to create the out_root of a subproject - // which means there could be empty parent directories left - // behind. Clean them up. - // - if (!pd.simple () && out_root != src_root) - { - for (dir_path d (pd.directory ()); - !d.empty (); - d = d.directory ()) - { - rmdir_status s (rmdir (out_root / d)); - - if (s == rmdir_status::not_empty) - break; // No use trying do remove parent ones. - - m = (s == rmdir_status::success) || m; - } - } - } - } - - // We distinguish between a complete disfigure and operation- - // specific. - // - if (a.operation () == default_id) - { - level5 ([&]{trace << "completely disfiguring " << out_root;}); - - m = rmfile (out_root / config_file) || m; - - if (out_root != src_root) - { - m = rmfile (out_root / src_root_file) || m; - - // Clean up the directories. - // - m = rmdir (out_root / bootstrap_dir) || m; - m = rmdir (out_root / build_dir) || m; - - switch (rmdir (out_root)) - { - case rmdir_status::not_empty: - { - warn << "directory " << out_root << " is " - << (out_root == work - ? "current working directory" - : "not empty") << ", not removing"; - break; - } - case rmdir_status::success: - m = true; - default: - break; - } - } - } - else - { - } - - return m; - } - - static void - disfigure_execute (action a, const action_targets& ts, bool quiet) - { - tracer trace ("disfigure_execute"); - - for (void* v: ts) - { - scope& root (*static_cast<scope*> (v)); - - if (!disfigure_project (a, root)) - { - // Create a dir{$out_root/} target to signify the project's - // root in diagnostics. Not very clean but seems harmless. - // - target& t ( - targets.insert ( - dir::static_type, root.out_path (), "", nullptr, trace).first); - - if (!quiet) - info << diag_done (a, t); - } - } - } - - static void - disfigure_meta_operation_post () - { - tracer trace ("disfigure_meta_operation_post"); - - // Reset the dependency state since anything that could have been - // loaded earlier using a previous configuration is now invalid. - // - level6 ([&]{trace << "resetting dependency state";}); - reset (); - } - - meta_operation_info disfigure { - "disfigure", - "disfigure", - "disfiguring", - "is disfigured", - nullptr, // meta-operation pre - &disfigure_operation_pre, - &disfigure_load, - &disfigure_search, - &disfigure_match, - &disfigure_execute, - nullptr, // operation post - &disfigure_meta_operation_post - }; - } -} diff --git a/build/config/utility b/build/config/utility deleted file mode 100644 index ee5f50b..0000000 --- a/build/config/utility +++ /dev/null @@ -1,128 +0,0 @@ -// file : build/config/utility -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD_CONFIG_UTILITY -#define BUILD_CONFIG_UTILITY - -#include <string> -#include <utility> // pair -#include <functional> // reference_wrapper - -#include <build/types> -#include <build/variable> -#include <build/diagnostics> - -namespace build -{ - class scope; - - namespace config - { - // Set, if necessary, a required config.* variable. - // - // If override is true and the variable doesn't come from this root - // scope or from the command line, then its value is "overridden" - // for this root scope. - // - // Return the reference to the value as well as the indication of - // whether the variable has actually been set. - // - template <typename T> - std::pair<std::reference_wrapper<const value>, bool> - required (scope& root, - const variable&, - const T& default_value, - bool override = false); - - template <typename T> - inline std::pair<std::reference_wrapper<const value>, bool> - required (scope& root, - const std::string& name, - const T& default_value, - bool override = false) - { - return required (root, var_pool.find (name), default_value, override); - } - - inline std::pair<std::reference_wrapper<const value>, bool> - required (scope& root, - const std::string& name, - const char* default_value, - bool override = false) - { - return required (root, name, std::string (default_value), override); - } - - // Set, if necessary, an optional config.* variable. In particular, - // an unspecified variable is set to NULL which is used to distinguish - // between the "configured as unspecified" and "not yet configured" - // cases. - // - // Return the value, which can be NULL. - // - const value& - optional (scope& root, const variable&); - - inline const value& - optional (scope& root, const std::string& var) - { - return optional (root, var_pool.find (var)); - } - - // As above but assumes the value is dir_path and makes it - // absolute if the value specified on the command line is - // relative. - // - const value& - optional_absolute (scope& root, const variable&); - - inline const value& - optional_absolute (scope& root, const std::string& var) - { - 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. - // - // 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); - - // @@ Why are these here? - // - - // Add all the values from a variable to the C-string list. T is - // either target or scope. The variable is expected to be of type - // strings. - // - template <typename T> - void - append_options (cstrings& args, T& s, const char* var); - - // As above but from the strings value directly. - // - void - append_options (cstrings& args, const const_strings_value&); - - // Check if a specified option is present in the variable value. - // T is either target or scope. - // - template <typename T> - bool - find_option (const char* option, T& s, const char* var); - } -} - -#include <build/config/utility.txx> -#include <build/config/utility.ixx> - -#endif // BUILD_CONFIG_UTILITY diff --git a/build/config/utility.cxx b/build/config/utility.cxx deleted file mode 100644 index b81cb04..0000000 --- a/build/config/utility.cxx +++ /dev/null @@ -1,92 +0,0 @@ -// file : build/config/utility.cxx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build/config/utility> - -#include <build/context> - -using namespace std; - -namespace build -{ - namespace config - { - const value& - optional (scope& root, const variable& var) - { - auto l (root[var]); - - return l.defined () - ? l.belongs (*global_scope) ? (root.assign (var) = *l) : *l - : root.assign (var); // NULL - } - - const value& - optional_absolute (scope& root, const variable& var) - { - auto l (root[var]); - - if (!l.defined ()) - return root.assign (var); // NULL - - if (!l.belongs (*global_scope)) // Value from (some) root scope. - return *l; - - // Make the command-line value absolute. This is necessary to avoid - // a warning issued by the config module about global/root scope - // value mismatch. - // - value& v (const_cast<value&> (*l)); - - if (v && !v.empty ()) - { - dir_path& d (as<dir_path> (v)); - - if (d.relative ()) - { - d = work / d; - d.normalize (); - } - } - - return root.assign (var) = v; - } - - bool - specified (scope& r, const string& ns) - { - // Search all outer scopes for any value in this namespace. - // - for (scope* s (&r); s != nullptr; s = s->parent_scope ()) - { - 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; - } - - void - append_options (cstrings& args, const const_strings_value& sv) - { - if (!sv.empty ()) - { - args.reserve (args.size () + sv.size ()); - - for (const string& s: sv) - args.push_back (s.c_str ()); - } - } - } -} diff --git a/build/config/utility.ixx b/build/config/utility.ixx deleted file mode 100644 index 4e32119..0000000 --- a/build/config/utility.ixx +++ /dev/null @@ -1,17 +0,0 @@ -// file : build/config/utility.ixx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -namespace build -{ - namespace config - { - template <typename T> - inline void - append_options (cstrings& args, T& s, const char* var) - { - if (auto l = s[var]) - append_options (args, as<strings> (*l)); - } - } -} diff --git a/build/config/utility.txx b/build/config/utility.txx deleted file mode 100644 index 06cb2eb..0000000 --- a/build/config/utility.txx +++ /dev/null @@ -1,45 +0,0 @@ -// file : build/config/utility.txx -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#include <build/scope> - -namespace build -{ - namespace config - { - template <typename T> - std::pair<std::reference_wrapper<const value>, bool> - required (scope& root, const variable& var, const T& def_value, bool ovr) - { - using result = std::pair<std::reference_wrapper<const value>, bool>; - - if (auto l = root[var]) - { - if (l.belongs (*global_scope)) - return result (root.assign (var) = *l, true); - - if (!ovr || l.belongs (root)) - return result (*l, false); - } - - return result (root.assign (var) = def_value, true); - } - - template <typename T> - bool - find_option (const char* option, T& s, const char* var) - { - if (auto l = s[var]) - { - for (const std::string& s: as<strings> (*l)) - { - if (s == option) - return true; - } - } - - return false; - } - } -} |