aboutsummaryrefslogtreecommitdiff
path: root/build/config/operation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build/config/operation.cxx')
-rw-r--r--build/config/operation.cxx455
1 files changed, 0 insertions, 455 deletions
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
- };
- }
-}