aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/prerequisite.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/prerequisite.cxx')
-rw-r--r--libbuild2/prerequisite.cxx120
1 files changed, 120 insertions, 0 deletions
diff --git a/libbuild2/prerequisite.cxx b/libbuild2/prerequisite.cxx
new file mode 100644
index 0000000..7355323
--- /dev/null
+++ b/libbuild2/prerequisite.cxx
@@ -0,0 +1,120 @@
+// file : libbuild2/prerequisite.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <libbuild2/prerequisite.hxx>
+
+#include <libbuild2/scope.hxx>
+#include <libbuild2/target.hxx>
+#include <libbuild2/context.hxx>
+#include <libbuild2/diagnostics.hxx>
+
+using namespace std;
+
+namespace build2
+{
+ // prerequisite_key
+ //
+ ostream&
+ operator<< (ostream& os, const prerequisite_key& pk)
+ {
+ if (pk.proj)
+ os << *pk.proj << '%';
+ //
+ // Don't print scope if we are project-qualified or the prerequisite's
+ // directory is absolute. In both these cases the scope is not used to
+ // resolve it to target.
+ //
+ else if (!pk.tk.dir->absolute ())
+ {
+ // Avoid printing './' in './:...', similar to what we do for the
+ // directory in target_key.
+ //
+ const dir_path& s (pk.scope->out_path ());
+
+ if (stream_verb (os).path < 1)
+ {
+ const string& r (diag_relative (s, false));
+
+ if (!r.empty ())
+ os << r << ':';
+ }
+ else
+ os << s << ':';
+ }
+
+ return os << pk.tk;
+ }
+
+ // prerequisite
+ //
+ static inline optional<string>
+ to_ext (const string* e)
+ {
+ return e != nullptr ? optional<string> (*e) : nullopt;
+ }
+
+ prerequisite::
+ prerequisite (const target_type& t)
+ : proj (nullopt),
+ type (t.type ()),
+ dir (t.dir),
+ out (t.out), // @@ If it's empty, then we treat as undetermined?
+ name (t.name),
+ ext (to_ext (t.ext ())),
+ scope (t.base_scope ()),
+ target (&t),
+ vars (false /* global */)
+ {
+ }
+
+ bool prerequisite::
+ belongs (const target_type& t) const
+ {
+ const auto& p (t.prerequisites ());
+ return !(p.empty () || this < &p.front () || this > &p.back ());
+ }
+
+ value& prerequisite::
+ append (const variable& var, const target_type& t)
+ {
+ if (value* r = vars.find_to_modify (var).first)
+ return *r;
+
+ value& r (assign (var)); // NULL.
+
+ // Note: pretty similar logic to target::append().
+ //
+ lookup l (t.find_original (var).first);
+
+ if (l.defined ())
+ r = *l; // Copy value (and type) from the target/outer scope.
+
+ return r;
+ }
+
+ // include()
+ //
+ include_type
+ include_impl (action a,
+ const target& t,
+ const string& v,
+ const prerequisite& p,
+ const target* m)
+ {
+ include_type r (false);
+
+ if (v == "false") r = include_type::excluded;
+ else if (v == "adhoc") r = include_type::adhoc;
+ else if (v == "true") r = include_type::normal;
+ else
+ fail << "invalid " << var_include->name << " variable value "
+ << "'" << v << "' specified for prerequisite " << p;
+
+ // Call the meta-operation override, if any (currently used by dist).
+ //
+ return current_mif->include == nullptr
+ ? r
+ : current_mif->include (a, t, prerequisite_member {p, m}, r);
+ }
+}