From 57b10c06925d0bdf6ffb38488ee908f085109e95 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 4 Jul 2019 19:12:15 +0300 Subject: Move config, dist, test, and install modules into library --- libbuild2/dist/rule.cxx | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 libbuild2/dist/rule.cxx (limited to 'libbuild2/dist/rule.cxx') diff --git a/libbuild2/dist/rule.cxx b/libbuild2/dist/rule.cxx new file mode 100644 index 0000000..357d70e --- /dev/null +++ b/libbuild2/dist/rule.cxx @@ -0,0 +1,88 @@ +// file : libbuild2/dist/rule.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include + +using namespace std; + +namespace build2 +{ + namespace dist + { + bool rule:: + match (action, target&, const string&) const + { + return true; // We always match. + } + + recipe rule:: + apply (action a, target& t) const + { + const dir_path& out_root (t.root_scope ().out_path ()); + + // If we can, go inside see-through groups. + // + for (prerequisite_member p: + group_prerequisite_members (a, t, members_mode::maybe)) + { + // Note: no exclusion tests, we want all of them (and see also the + // dist_include() override). + + // Skip prerequisites imported from other projects. + // + if (p.proj ()) + continue; + + // We used to always search and match but that resulted in the + // undesirable behavior in case one of the "source" files is + // missing. In this case we would enter a target as "output", this + // rule would match it, and then dist_execute() would ignore it by + // default. + // + // So now if this is a file target (we still want to always "see + // through" other targets like aliases), we will only match it if (1) + // it exists in src or (2) it exists as a target. It feels like we + // don't need the stronger "... and not implied" condition since if it + // is mentioned as a target, then it is in out (we don't do the same + // target in both src/out). + // + // @@ Note that this is still an issue in a custom dist rule. + // + const target* pt (nullptr); + if (p.is_a ()) + { + pt = p.load (); + + if (pt == nullptr) + { + // Search for an existing target or existing file in src. + // + const prerequisite_key& k (p.key ()); + pt = k.tk.type->search (t, k); + + if (pt == nullptr) + fail << "prerequisite " << k << " is not existing source file " + << "nor known output target" << endf; + + search_custom (p.prerequisite, *pt); // Cache. + } + } + else + pt = &p.search (t); + + // Don't match targets that are outside of our project. + // + if (pt->dir.sub (out_root)) + build2::match (a, *pt); + } + + return noop_recipe; // We will never be executed. + } + } +} -- cgit v1.1