From 3673438e8cd29e4f895592ed0ce4be1887cef036 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 2 May 2018 20:32:47 +0200 Subject: [PATCH] build: dynamic dependencies using dependency callbacks --- ostd/build/make.hh | 32 ++++++++++++++++++++++---------- src/build_make.cc | 5 ++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ostd/build/make.hh b/ostd/build/make.hh index ea5f567..bf6fc8e 100644 --- a/ostd/build/make.hh +++ b/ostd/build/make.hh @@ -75,6 +75,9 @@ struct make_rule { using body_func = std::function< void(string_range, iterator_range) >; + using depend_func = std::function< + void(decltype(appender>()) &) + >; make_rule() = delete; make_rule(string_range target): @@ -130,15 +133,20 @@ struct make_rule { return p_cond(target); } - iterator_range depends() const noexcept { - return iterator_range( - p_deps.data(), p_deps.data() + p_deps.size() - ); + void depends(std::function body) const { + auto app = appender>(); + for (auto &f: p_deps) { + app.clear(); + f(app); + for (auto &s: app.get()) { + body(s); + } + } } template - make_rule &depend(A const &...args) { - (add_depend(args), ...); + make_rule &depend(A &&...args) { + (add_depend(std::forward(args)), ...); return *this; } @@ -157,19 +165,23 @@ private: >; template - void add_depend(R const &v) { + void add_depend(R &&v) { if constexpr (std::is_constructible_v) { - p_deps.emplace_back(v); + p_deps.push_back([s = std::string{v}](auto &app) { + app.put(std::move(s)); + }); + } else if constexpr(std::is_constructible_v) { + p_deps.push_back(std::forward(v)); } else { R mr{v}; for (auto const &sv: mr) { - p_deps.emplace_back(sv); + add_depend(sv); } } } make_pattern p_target; - std::vector p_deps{}; + std::vector p_deps{}; body_func p_body{}; std::function p_cond{}; bool p_action = false; diff --git a/src/build_make.cc b/src/build_make.cc index 4f652b8..c9c2aed 100644 --- a/src/build_make.cc +++ b/src/build_make.cc @@ -185,10 +185,9 @@ void make::find_rules(string_range target, std::vector &rlist) { rlist.emplace_back(); rule_inst &sr = rlist.back(); sr.rule = &rule; - sr.deps.reserve(rule.depends().size()); - for (auto &d: rule.depends()) { + rule.depends([&sr, &tgt](string_range d) { sr.deps.push_back(tgt.replace(d)); - } + }); if (!rule.has_body()) { if (fnl != target.size()) { throw make_error{"pattern rule '%s' needs a body", target};