// 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