From 2dbac9c6d08697e28af28178b2ce041140164842 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 7 Feb 2022 14:02:11 +0300 Subject: Introduce package_skeleton for evaluating dependency clauses --- bpkg/package-skeleton.hxx | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 bpkg/package-skeleton.hxx (limited to 'bpkg/package-skeleton.hxx') 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 +#include + +#include + +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 db_; + reference_wrapper available_; + strings config_vars_; + + bool loaded_ = false; + bool dirty_ = false; + + strings reflect_; + }; +} + +#endif // BPKG_PACKAGE_SKELETON_HXX -- cgit v1.1