diff options
Diffstat (limited to 'libbuild2/dyndep.hxx')
-rw-r--r-- | libbuild2/dyndep.hxx | 112 |
1 files changed, 98 insertions, 14 deletions
diff --git a/libbuild2/dyndep.hxx b/libbuild2/dyndep.hxx index b285704..a0949c4 100644 --- a/libbuild2/dyndep.hxx +++ b/libbuild2/dyndep.hxx @@ -14,16 +14,20 @@ #include <libbuild2/export.hxx> // Additional functionality that is normally only useful for implementing -// rules with dynamic dependencies. +// rules with dynamic dependencies (usually prerequisites, but also target +// group members). // namespace build2 { class LIBBUILD2_SYMEXPORT dyndep_rule { public: - // Update the target during the match phase. Return true if it has changed - // or if the passed timestamp is not timestamp_unknown and is older than - // the target. + // Update the target during the match phase. Return true if the target has + // changed or, if the passed timestamp is not timestamp_unknown, it is + // older than the target. + // + // Note that such a target must still be updated during the execute phase + // in order to keep the dependency counts straight. // static bool update (tracer&, action, const target&, timestamp); @@ -32,7 +36,7 @@ namespace build2 // target. // // Return the indication of whether it has changed or, if the passed - // timestamp is not timestamp_unknown, is older than this timestamp. If + // timestamp is not timestamp_unknown, is newer than this timestamp. If // the prerequisite target does not exists nor can be generated (no rule), // then issue diagnostics and fail if the fail argument is true and return // nullopt otherwise. @@ -53,32 +57,39 @@ namespace build2 bool adhoc = false, uintptr_t data = 0); - // As above but verify the file is matched with noop_recipe and issue - // diagnostics and fail otherwise (regardless of the fail flag). + // As above but verify the file is matched with noop_recipe or was updated + // during match and issue diagnostics and fail otherwise (regardless of + // the fail flag). Pass 0 for pts_n if don't want the "was updated during + // match" part. // // This version (together with verify_existing_file() below) is primarily // useful for handling dynamic dependencies that are produced as a // byproduct of recipe execution (and thus must have all the generated // prerequisites specified statically). // + // Note that this function expects all the static prerequisites of the + // target to already be matched and their number passed in pts_n. + // static optional<bool> inject_existing_file (tracer&, const char* what, - action, target&, + action, target&, size_t pts_n, const file& prerequiste, timestamp, bool fail, bool adhoc = false, uintptr_t data = 0); - // Verify the file is matched with noop_recipe and issue diagnostics and - // fail otherwise. If the file is not matched, then fail if the target is - // not implied (that is, declared in a buildfile). + // Verify the file is matched with noop_recipe or was updated during match + // and issue diagnostics and fail otherwise. If the file is not matched, + // then fail if the target is not implied (that is, declared in a + // buildfile). Pass 0 for pts_n if don't want the "was updated during + // match" part. // // Note: can only be called in the execute phase. // static void verify_existing_file (tracer&, const char* what, - action, const target&, + action, const target&, size_t pts_n, const file& prerequiste); // Reverse-lookup target type(s) from file name/extension. @@ -87,6 +98,10 @@ namespace build2 // and those derived from them are considered. Otherwise, any file-based // type is considered but not the file type itself. // + // It's possible the extension-to-target type mapping is ambiguous (for + // example, because both C and C++-language headers use the same .h + // extension). So this function can return multiple target types. + // static small_vector<const target_type*, 2> map_extension (const scope& base, const string& name, const string& ext, @@ -203,17 +218,86 @@ namespace build2 const srcout_map& = {}); // As above but do not insert the target if it doesn't already exist. This - // function also returns NULL if the target exists but is implied (that - // is, not declared in a buildfile). + // function also returns NULL if the target exists but is dynamic (that + // is, not real or implied), unless the dynamic argument is true. // static pair<const file*, bool> find_file (tracer&, const char* what, action, const scope& base, const target&, path& prerequisite, bool cache, bool normalized, + bool dynamic, const function<map_extension_func>&, const target_type& fallback, const function<prefix_map_func>& = nullptr, const srcout_map& = {}); + + // Find or insert a target file path as a target of the specified type, + // make it a member of the specified (non-ad hoc) mtime target group and + // set its path. Return the target and an indication of whether it was + // made a member (can only be false if a filter is provided; see below). + // + // The file path must be absolute and normalized. Note that this function + // assumes that this member can only be matched via this group. The group + // type must have the target_type::flag::dyn_members flag. + // + // If specified, the group_filter function is called on the target before + // making it a group member, skipping it if this function returns false. + // Note that the filter is skipped if the target is newly inserted (the + // filter is meant to be used to skip duplicates). + // + using group_filter_func = bool (mtime_target& g, const file&); + + static pair<const file&, bool> + inject_group_member (action, const scope& base, mtime_target&, + path, + const target_type&, + const function<group_filter_func>& = nullptr); + + template <typename T> + static pair<const T&, bool> + inject_group_member (action a, const scope& bs, mtime_target& g, + path f, + const function<group_filter_func>& filter = nullptr) + { + auto p (inject_group_member (a, bs, g, move (f), T::static_type, filter)); + return pair<const T&, bool> (p.first.template as<T> (), p.second); + } + + // As above but the target type is determined using the map_extension + // function if specified, falling back to the fallback type if unable to + // (the what argument is used for diagnostics during this process). + // + static pair<const file&, bool> + inject_group_member (const char* what, + action, const scope& base, mtime_target& g, + path, + const function<map_extension_func>&, + const target_type& fallback, + const function<group_filter_func>& = nullptr); + + + // Find or insert a target file path as a target, make it a member of the + // specified ad hoc group unless it already is, and set its path. Return + // the target and an indication of whether it was added as a member. + // + // The file path must be absolute and normalized. Note that this function + // assumes that this target can only be known as a member of this group. + // + static pair<const file&, bool> + inject_adhoc_group_member (action, const scope& base, target& g, + path, + const target_type&); + + // As above but the target type is determined using the map_extension + // function if specified, falling back to the fallback type if unable to + // (the what argument is used for diagnostics during this process). + // + static pair<const file&, bool> + inject_adhoc_group_member (const char* what, + action, const scope& base, target& g, + path, + const function<map_extension_func>&, + const target_type& fallback); }; } |