diff options
-rw-r--r-- | libbuild2/algorithm.cxx | 59 | ||||
-rw-r--r-- | libbuild2/algorithm.hxx | 28 | ||||
-rw-r--r-- | libbuild2/algorithm.ixx | 15 |
3 files changed, 82 insertions, 20 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index 564105c..843808d 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -1217,9 +1217,8 @@ namespace build2 match_prerequisite_range (a, t, group_prerequisite_members (a, t), msm, s); } - template <typename T> void - match_members (action a, target& t, T const* ts, size_t n) + match_members (action a, target& t, const target* const* ts, size_t n) { // Pretty much identical to match_prerequisite_range() except we don't // search. @@ -1251,15 +1250,45 @@ namespace build2 } } - // Instantiate only for what we need. - // - template LIBBUILD2_SYMEXPORT void - match_members<const target*> (action, target&, - const target* const*, size_t); + void + match_members (action a, + target& t, + prerequisite_targets& ts, + size_t s, + pair<uintptr_t, uintptr_t> imv) + { + size_t n (ts.size ()); + + wait_guard wg (t.ctx, t.ctx.count_busy (), t[a].task_count, true); - template LIBBUILD2_SYMEXPORT void - match_members<prerequisite_target> (action, target&, - prerequisite_target const*, size_t); + for (size_t i (s); i != n; ++i) + { + const prerequisite_target& pt (ts[i]); + const target* m (pt.target); + + if (m == nullptr || + marked (m) || + (imv.first != 0 && (pt.include & imv.first) != imv.second)) + continue; + + match_async (a, *m, t.ctx.count_busy (), t[a].task_count); + } + + wg.wait (); + + for (size_t i (s); i != n; ++i) + { + const prerequisite_target& pt (ts[i]); + const target* m (pt.target); + + if (m == nullptr || + marked (m) || + (imv.first != 0 && (pt.include & imv.first) != imv.second)) + continue; + + match_complete (a, *m); + } + } const fsdir* inject_fsdir (action a, target& t, bool parent) @@ -2313,6 +2342,16 @@ namespace build2 if (n == 0) return false; + // Provide additional information on what's going on. + // + auto df = make_diag_frame ( + [&t](const diag_record& dr) + { + if (verb != 0) + dr << info << "while updating during match prerequisites of " + << "target " << t; + }); + context& ctx (t.ctx); phase_switch ps (ctx, run_phase::execute); diff --git a/libbuild2/algorithm.hxx b/libbuild2/algorithm.hxx index 75976bf..db3e93d 100644 --- a/libbuild2/algorithm.hxx +++ b/libbuild2/algorithm.hxx @@ -145,6 +145,15 @@ namespace build2 const string* ext = nullptr, const scope* = nullptr); + template <typename T> + const T* + search_existing (context&, + const dir_path& dir, + const dir_path& out, + const string& name, + const string* ext = nullptr, + const scope* = nullptr); + // Search for a target identified by the name. The semantics is "as if" we // first created a prerequisite based on this name in exactly the same way // as the parser would and then searched based on this prerequisite. If the @@ -471,11 +480,8 @@ namespace build2 // dependencies. Similar in semantics to match_prerequisites(). Any marked // target pointers are skipped. // - // T can only be const target* or prerequisite_target. - // - template <typename T> - void - match_members (action, target&, T const*, size_t); + LIBBUILD2_SYMEXPORT void + match_members (action, target&, const target* const*, size_t); template <size_t N> inline void @@ -484,14 +490,16 @@ namespace build2 match_members (a, t, ts, N); } - inline void + // As above plus if the include mask (first) and value (second) are + // specified, then only match prerequisites that satisfy the + // ((prerequisite_target::include & mask) == value) condition. + // + LIBBUILD2_SYMEXPORT void match_members (action a, target& t, prerequisite_targets& ts, - size_t start = 0) - { - match_members (a, t, ts.data () + start, ts.size () - start); - } + size_t start = 0, + pair<uintptr_t, uintptr_t> include = {0, 0}); // Unless already known, match, and, if necessary, execute the group in // order to resolve its members list. Note that even after that the member's diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx index 10ed754..ea4241e 100644 --- a/libbuild2/algorithm.ixx +++ b/libbuild2/algorithm.ixx @@ -187,6 +187,21 @@ namespace build2 t, T::static_type, dir, out, name, ext, scope).template as<T> (); } + template <typename T> + inline const T* + search_existing (context& ctx, + const dir_path& dir, + const dir_path& out, + const string& name, + const string* ext, + const scope* scope) + { + const target* r ( + search_existing ( + ctx, T::static_type, dir, out, name, ext, scope)); + return r != nullptr ? &r->template as<T> () : nullptr; + } + LIBBUILD2_SYMEXPORT target_lock lock_impl (action, const target&, optional<scheduler::work_queue>); |