aboutsummaryrefslogtreecommitdiff
path: root/build/config
diff options
context:
space:
mode:
Diffstat (limited to 'build/config')
-rw-r--r--build/config/module26
-rw-r--r--build/config/module.cxx90
-rw-r--r--build/config/operation19
-rw-r--r--build/config/operation.cxx455
-rw-r--r--build/config/utility128
-rw-r--r--build/config/utility.cxx92
-rw-r--r--build/config/utility.ixx17
-rw-r--r--build/config/utility.txx45
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;
- }
- }
-}