aboutsummaryrefslogtreecommitdiff
path: root/build/dist/operation.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build/dist/operation.cxx')
-rw-r--r--build/dist/operation.cxx459
1 files changed, 0 insertions, 459 deletions
diff --git a/build/dist/operation.cxx b/build/dist/operation.cxx
deleted file mode 100644
index 28a64fa..0000000
--- a/build/dist/operation.cxx
+++ /dev/null
@@ -1,459 +0,0 @@
-// file : build/dist/operation.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <build/dist/operation>
-
-#include <cassert>
-
-#include <butl/process>
-#include <butl/filesystem>
-
-#include <build/file>
-#include <build/dump>
-#include <build/scope>
-#include <build/target>
-#include <build/context>
-#include <build/algorithm>
-#include <build/diagnostics>
-
-using namespace std;
-using namespace butl;
-
-namespace build
-{
- namespace dist
- {
- static void
- dist_meta_operation_pre ()
- {
- // Reset the dependency state so that we don't end up with stray
- // files from previous batches.
- //
- // @@ This is called too late, after we have bootstrapped the
- // project.
- //
- //reset ();
- }
-
- static operation_id
- dist_operation_pre (operation_id o)
- {
- if (o != default_id)
- fail << "explicit operation specified for dist meta-operation";
-
- return o;
- }
-
- static void
- dist_match (action, action_targets&)
- {
- // Don't match anything -- see execute ().
- }
-
- // install -d <dir>
- //
- static void
- install (const string& cmd, const dir_path&);
-
- // install <file> <dir>
- //
- static void
- install (const string& cmd, file&, const dir_path&);
-
- // cd <root> && tar|zip ... <pkg>.<ext> <pkg>
- //
- static void
- archive (const dir_path& root, const string& pkg, const string& ext);
-
- static void
- dist_execute (action, const action_targets& ts, bool)
- {
- tracer trace ("dist_execute");
-
- // For now we assume all the targets are from the same project.
- //
- target& t (*static_cast<target*> (ts[0]));
- scope* rs (t.base_scope ().root_scope ());
-
- if (rs == nullptr)
- fail << "out of project target " << t;
-
- const dir_path& out_root (rs->out_path ());
- const dir_path& src_root (rs->src_path ());
-
- if (out_root == src_root)
- fail << "in-tree distribution of target " << t <<
- info << "distribution requires out-of-tree build";
-
- // Make sure we have the necessary configuration before
- // we get down to business.
- //
- auto l (rs->vars["dist.root"]);
-
- if (!l || l->empty ())
- fail << "unknown root distribution directory" <<
- info << "did you forget to specify config.dist.root?";
-
- const dir_path& dist_root (as<dir_path> (*l));
-
- if (!dir_exists (dist_root))
- fail << "root distribution directory " << dist_root
- << " does not exist";
-
- l = rs->vars["dist.package"];
-
- if (!l || l->empty ())
- fail << "unknown distribution package name" <<
- info << "did you forget to set dist.package?";
-
- const string& dist_package (as<string> (*l));
- const string& dist_cmd (as<string> (*rs->vars["dist.cmd"]));
-
- // Get the list of operations supported by this project. Skip
- // default_id.
- //
- for (operations::size_type id (default_id + 1);
- id < rs->operations.size ();
- ++id)
- {
- const operation_info* oi (rs->operations[id]);
- if (oi == nullptr)
- continue;
-
- // Note that we are not calling operation_pre/post() callbacks
- // here since the meta operation is dist and we know what we
- // are doing.
- //
- current_inner_oif = oi;
- current_outer_oif = nullptr;
- current_mode = oi->mode;
- dependency_count = 0;
-
- action a (dist_id, id);
-
- if (verb >= 6)
- dump (a);
-
- for (void* v: ts)
- {
- target& t (*static_cast<target*> (v));
-
- if (rs != t.base_scope ().root_scope ())
- fail << "out of project target " << t;
-
- level5 ([&]{trace << diag_doing (a, t);});
-
- match (a, t);
- }
-
- if (verb >= 6)
- dump (a);
- }
-
- // Add buildfiles that are not normally loaded as part of the
- // project, for example, the export stub. They will still be
- // ignored on the next step if the user explicitly marked them
- // nodist.
- //
- auto add_adhoc = [&src_root, &trace] (const dir_path& d, const char* f)
- {
- path p (d / path (f));
- if (file_exists (p))
- {
- const char* e (p.extension ());
- targets.insert<buildfile> (
- p.directory (),
- p.leaf ().base ().string (),
- &extension_pool.find (e == nullptr ? "" : e), // Specified.
- trace);
- }
- };
-
- add_adhoc (src_root, "build/export.build");
-
- // The same for subprojects that have been loaded.
- //
- if (auto l = rs->vars["subprojects"])
- {
- for (auto p: as<subprojects> (*l))
- {
- const dir_path& pd (p.second);
- dir_path out_nroot (out_root / pd);
- scope& nrs (scopes.find (out_nroot));
-
- if (nrs.out_path () != out_nroot) // This subproject not loaded.
- continue;
-
- const dir_path& src_nroot (nrs.src_path ());
-
- if (!src_nroot.sub (src_root)) // Not a strong amalgamation.
- continue;
-
- add_adhoc (src_nroot, "build/export.build");
- }
- }
-
- // Collect the files. We want to take the snapshot of targets
- // since updating some of them may result in more targets being
- // entered.
- //
- action_targets files;
- const variable& dist_var (var_pool.find ("dist"));
-
- for (const auto& pt: targets)
- {
- file* ft (pt->is_a<file> ());
-
- if (ft == nullptr) // Not a file.
- continue;
-
- if (ft->dir.sub (src_root))
- {
- // Include unless explicitly excluded.
- //
- auto l ((*ft)[dist_var]);
-
- if (l && !as<bool> (*l))
- level5 ([&]{trace << "excluding " << *ft;});
- else
- files.push_back (ft);
-
- continue;
- }
-
- if (ft->dir.sub (out_root))
- {
- // Exclude unless explicitly included.
- //
- auto l ((*ft)[dist_var]);
-
- if (l && as<bool> (*l))
- {
- level5 ([&]{trace << "including " << *ft;});
- files.push_back (ft);
- }
-
- continue;
- }
- }
-
- // Make sure what we need to distribute is up to date.
- //
- {
- if (perform.meta_operation_pre != nullptr)
- perform.meta_operation_pre ();
-
- current_mif = &perform;
-
- if (perform.operation_pre != nullptr)
- perform.operation_pre (update_id);
-
- current_inner_oif = &update;
- current_outer_oif = nullptr;
- current_mode = update.mode;
- dependency_count = 0;
-
- action a (perform_id, update_id);
-
- perform.match (a, files);
- perform.execute (a, files, true); // Run quiet.
-
- if (perform.operation_post != nullptr)
- perform.operation_post (update_id);
-
- if (perform.meta_operation_post != nullptr)
- perform.meta_operation_post ();
- }
-
- dir_path td (dist_root / dir_path (dist_package));
-
- // Clean up the target directory.
- //
- // @@ Not for incremental dist?
- //
- if (build::rmdir_r (td) == rmdir_status::not_empty)
- fail << "unable to clean target directory " << td;
-
- install (dist_cmd, td);
-
- // Copy over all the files.
- //
- for (void* v: files)
- {
- file& t (*static_cast<file*> (v));
-
- // Figure out where this file is inside the target directory.
- //
- dir_path d (td);
- d /= t.dir.sub (src_root)
- ? t.dir.leaf (src_root)
- : t.dir.leaf (out_root);
-
- if (!dir_exists (d))
- install (dist_cmd, d);
-
- install (dist_cmd, t, d);
- }
-
- // Archive if requested.
- //
- if (auto l = rs->vars["dist.archives"])
- {
- for (const string& e: as<strings> (*l))
- archive (dist_root, dist_package, e);
- }
- }
-
- // install -d <dir>
- //
- static void
- install (const string& cmd, const dir_path& d)
- {
- path reld (relative (d));
-
- cstrings args {cmd.c_str (), "-d"};
-
- args.push_back ("-m");
- args.push_back ("755");
- args.push_back (reld.string ().c_str ());
- args.push_back (nullptr);
-
- if (verb >= 2)
- print_process (args);
- else if (verb)
- text << "dist -d " << d;
-
- try
- {
- process pr (args.data ());
-
- if (!pr.wait ())
- throw failed ();
- }
- catch (const process_error& e)
- {
- error << "unable to execute " << args[0] << ": " << e.what ();
-
- if (e.child ())
- exit (1);
-
- throw failed ();
- }
- }
-
- // install <file> <dir>
- //
- static void
- install (const string& cmd, file& t, const dir_path& d)
- {
- path reld (relative (d));
- path relf (relative (t.path ()));
-
- cstrings args {cmd.c_str ()};
-
- // Preserve timestamps. This could becomes important if, for
- // example, we have pre-generated sources. Note that the
- // install-sh script doesn't support this option, while both
- // Linux and BSD install's do.
- //
- args.push_back ("-p");
-
- // Assume the file is executable if the owner has execute
- // permission, in which case we make it executable for
- // everyone.
- //
- args.push_back ("-m");
- args.push_back (
- (path_permissions (t.path ()) & permissions::xu) == permissions::xu
- ? "755"
- : "644");
-
- args.push_back (relf.string ().c_str ());
- args.push_back (reld.string ().c_str ());
- args.push_back (nullptr);
-
- if (verb >= 2)
- print_process (args);
- else if (verb)
- text << "dist " << t;
-
- try
- {
- process pr (args.data ());
-
- if (!pr.wait ())
- throw failed ();
- }
- catch (const process_error& e)
- {
- error << "unable to execute " << args[0] << ": " << e.what ();
-
- if (e.child ())
- exit (1);
-
- throw failed ();
- }
- }
-
- static void
- archive (const dir_path& root, const string& pkg, const string& e)
- {
- string a (pkg + '.' + e);
-
- // Delete old archive for good measure.
- //
- path ap (root / path (a));
- if (file_exists (ap))
- rmfile (ap);
-
- // Use zip for .zip archives. Everything else goes to tar in the
- // auto-compress mode (-a).
- //
- cstrings args;
- if (e == "zip")
- args = {"zip", "-rq", a.c_str (), pkg.c_str (), nullptr};
- else
- args = {"tar", "-a", "-cf", a.c_str (), pkg.c_str (), nullptr};
-
- if (verb >= 2)
- print_process (args);
- else if (verb)
- text << args[0] << " " << ap;
-
- try
- {
- // Change child's working directory to dist_root.
- //
- process pr (root.string ().c_str (), args.data ());
-
- if (!pr.wait ())
- throw failed ();
- }
- catch (const process_error& e)
- {
- error << "unable to execute " << args[0] << ": " << e.what ();
-
- if (e.child ())
- exit (1);
-
- throw failed ();
- }
- }
-
- meta_operation_info dist {
- "dist",
- "distribute",
- "distributing",
- "has nothing to distribute", // We cannot "be distributed".
- &dist_meta_operation_pre,
- &dist_operation_pre,
- &load, // normal load
- &search, // normal search
- &dist_match,
- &dist_execute,
- nullptr, // operation post
- nullptr // meta-operation post
- };
- }
-}