From 36e62584b33b5c168b8b42564d7f45b2150eef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 9 Feb 2022 10:13:15 +0200 Subject: Add dyndep_rule::inject_group_member() --- libbuild2/dyndep.cxx | 45 +++++++++++++++++++++++++++++++++++++++++++++ libbuild2/dyndep.hxx | 25 ++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/libbuild2/dyndep.cxx b/libbuild2/dyndep.cxx index 73fc8eb..f1fc5ec 100644 --- a/libbuild2/dyndep.cxx +++ b/libbuild2/dyndep.cxx @@ -799,4 +799,49 @@ namespace build2 false /* insert */, map_ext, fallback, pfx_map, so_map); } + + const file& dyndep_rule:: + inject_group_member (action a, const scope& bs, mtime_target& g, + path p, const target_type& tt) + { + path n (p.leaf ()); + string e (n.extension ()); + + // Assume nobody else can insert these members (seems reasonable seeing + // that their names are dynamically discovered). + // + auto l (search_new_locked ( + bs.ctx, + tt, + p.directory (), + dir_path (), // Always in out. + move (n.make_base ()).string (), + &e, + &bs)); + + const file& t (l.first.as ()); // Note: non-const only if have lock. + + if (l.second) + { + l.first.group = &g; + l.second.unlock (); + t.path (move (p)); // Only do this once. + } + else + // Must have been already done (e.g., on previous operation in a + // batch). + // + assert (t.group == &g); + + // This shouldn't fail since we are the only ones that should be matching + // this target. + // + target_lock tl (lock (a, t)); + assert (tl); + + match_inc_dependents (a, g); + match_recipe (tl, group_recipe); + + return t; + } } diff --git a/libbuild2/dyndep.hxx b/libbuild2/dyndep.hxx index b285704..257ef7b 100644 --- a/libbuild2/dyndep.hxx +++ b/libbuild2/dyndep.hxx @@ -14,7 +14,8 @@ #include // 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 { @@ -214,6 +215,28 @@ namespace build2 const target_type& fallback, const function& = 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. + // + // The file path must be absolute and normalized. Note that this function + // assumes that this member can only be matched via this group. + // + // Note: we can split this function into {enter,match}_group_member() + // if necessary. + // + static const file& + inject_group_member (action, const scope& base, mtime_target&, + path, const target_type&); + + template + static const T& + inject_group_member (action a, const scope& bs, mtime_target& g, path p) + { + return inject_group_member ( + a, bs, g, move (p), T::static_type).template as (); + } }; } -- cgit v1.1