aboutsummaryrefslogtreecommitdiff
path: root/bpkg/package-skeleton.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/package-skeleton.hxx')
-rw-r--r--bpkg/package-skeleton.hxx139
1 files changed, 139 insertions, 0 deletions
diff --git a/bpkg/package-skeleton.hxx b/bpkg/package-skeleton.hxx
new file mode 100644
index 0000000..5fcb151
--- /dev/null
+++ b/bpkg/package-skeleton.hxx
@@ -0,0 +1,139 @@
+// file : bpkg/package-skeleton.hxx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BPKG_PACKAGE_SKELETON_HXX
+#define BPKG_PACKAGE_SKELETON_HXX
+
+#include <bpkg/types.hxx>
+#include <bpkg/utility.hxx>
+
+#include <bpkg/package.hxx>
+
+namespace bpkg
+{
+ // A build system skeleton of a package used to evaluate buildfile clauses
+ // during dependency resolution (enable, reflect, require or prefer/accept).
+ //
+ class package_skeleton
+ {
+ public:
+ // Note that the database and available_package are expected to outlive
+ // this object.
+ //
+ // Note also that this creates an "unloaded" skeleton and is therefore
+ // cheap.
+ //
+ // @@ Note that storing the list of configuration variables by reference
+ // complicates its use in pkg-build, where both the configuration and
+ // the optional skeleton are parts of the same copyable/moveable
+ // build_package object. We could probably move the configuration into
+ // the skeleton if create it, complicating an access to the
+ // configuration for the users (if the skeleton is present then get
+ // configuration from it, etc). Let's however keep it simple for now
+ // and just copy the configuration.
+ //
+ package_skeleton (database& db,
+ const available_package& ap,
+ const strings& cvs)
+ : db_ (db), available_ (ap), config_vars_ (cvs) {}
+
+ // Evaluate the enable clause.
+ //
+ // @@ What can we pass as location? Maybe somehow point to manifest in the
+ // skeleton (will need to re-acquire the position somehow)?
+ //
+ bool
+ evaluate_enable (const string&)
+ {
+ // @@ TMP
+ //
+ fail << "conditional dependency for package " << name () <<
+ info << "conditional dependencies are not yet supported";
+
+ load ();
+
+ // TODO
+
+ return true; // @@ TMP
+ }
+
+ // Evaluate the reflect clause.
+ //
+ void
+ evaluate_reflect (const string& r)
+ {
+ load ();
+
+ // TODO
+
+ // @@ DEP For now we assume that the reflection, if present, contains
+ // a single configuration variable that assigns a literal value.
+ //
+ reflect_.push_back (r);
+
+ dirty ();
+ }
+
+ // Return the accumulated reflect values.
+ //
+ strings
+ collect_reflect ()
+ {
+ return reflect_;
+ }
+
+ const package_name&
+ name () const {return available_.get ().id.name;}
+
+ private:
+ // Create the skeleton if necessary and (re)load the build system state.
+ //
+ // Call this function before evaluating every clause.
+ //
+ void
+ load ()
+ {
+ if (loaded_ && !dirty_)
+ return;
+
+ // Plan:
+ //
+ // 0. Create filesystem state if necessary (could have been created by
+ // another instance, e.g., during simulation).
+ //
+ // @@ build/ vs build2/ -- probably doesn't matter unless in the
+ // future we allow specifying additional files.
+ //
+ // 1. If loaded but dirty, save the accumulated reflect state, and
+ // destroy the old state.
+ //
+ // 2. Load the state potentially with accumulated reflect state.
+
+ loaded_ = true;
+ dirty_ = false;
+ }
+
+ // Mark the build system state as needing reloading.
+ //
+ // Call this function after evaluating the reflect clause (since some
+ // computed values in root.build may depend on the new value).
+ //
+ void
+ dirty ()
+ {
+ dirty_ = true;
+ }
+
+ private:
+ reference_wrapper<database> db_;
+ reference_wrapper<const available_package> available_;
+ strings config_vars_;
+
+ bool loaded_ = false;
+ bool dirty_ = false;
+
+ strings reflect_;
+ };
+}
+
+#endif // BPKG_PACKAGE_SKELETON_HXX