aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/dyndep.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/dyndep.hxx')
-rw-r--r--libbuild2/dyndep.hxx100
1 files changed, 79 insertions, 21 deletions
diff --git a/libbuild2/dyndep.hxx b/libbuild2/dyndep.hxx
index 6632eb6..a0949c4 100644
--- a/libbuild2/dyndep.hxx
+++ b/libbuild2/dyndep.hxx
@@ -36,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.
@@ -57,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.
@@ -91,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,
@@ -207,39 +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,
- // set its path, and match it with group_recipe.
+ // 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.
+ // assumes that this member can only be matched via this group. The group
+ // type must have the target_type::flag::dyn_members flag.
//
- // Note: we can split this function into {enter,match}_group_member()
- // if necessary.
+ // 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).
//
- static const file&
+ 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&);
+ path,
+ const target_type&,
+ const function<group_filter_func>& = nullptr);
template <typename T>
- static const T&
- inject_group_member (action a, const scope& bs, mtime_target& g, path p)
+ 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)
{
- return inject_group_member (
- a, bs, g, move (p), T::static_type).template as<T> ();
+ 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);
};
}