build: dynamic dependencies using dependency callbacks
parent
6845f5a8d8
commit
3673438e8c
|
@ -75,6 +75,9 @@ struct make_rule {
|
||||||
using body_func = std::function<
|
using body_func = std::function<
|
||||||
void(string_range, iterator_range<string_range *>)
|
void(string_range, iterator_range<string_range *>)
|
||||||
>;
|
>;
|
||||||
|
using depend_func = std::function<
|
||||||
|
void(decltype(appender<std::vector<std::string>>()) &)
|
||||||
|
>;
|
||||||
|
|
||||||
make_rule() = delete;
|
make_rule() = delete;
|
||||||
make_rule(string_range target):
|
make_rule(string_range target):
|
||||||
|
@ -130,15 +133,20 @@ struct make_rule {
|
||||||
return p_cond(target);
|
return p_cond(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator_range<std::string const *> depends() const noexcept {
|
void depends(std::function<void(string_range)> body) const {
|
||||||
return iterator_range<std::string const *>(
|
auto app = appender<std::vector<std::string>>();
|
||||||
p_deps.data(), p_deps.data() + p_deps.size()
|
for (auto &f: p_deps) {
|
||||||
);
|
app.clear();
|
||||||
|
f(app);
|
||||||
|
for (auto &s: app.get()) {
|
||||||
|
body(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ...A>
|
template<typename ...A>
|
||||||
make_rule &depend(A const &...args) {
|
make_rule &depend(A &&...args) {
|
||||||
(add_depend(args), ...);
|
(add_depend(std::forward<A>(args)), ...);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,19 +165,23 @@ private:
|
||||||
>;
|
>;
|
||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
void add_depend(R const &v) {
|
void add_depend(R &&v) {
|
||||||
if constexpr (std::is_constructible_v<std::string, R const &>) {
|
if constexpr (std::is_constructible_v<std::string, R const &>) {
|
||||||
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<depend_func, R &&>) {
|
||||||
|
p_deps.push_back(std::forward<R>(v));
|
||||||
} else {
|
} else {
|
||||||
R mr{v};
|
R mr{v};
|
||||||
for (auto const &sv: mr) {
|
for (auto const &sv: mr) {
|
||||||
p_deps.emplace_back(sv);
|
add_depend(sv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
make_pattern p_target;
|
make_pattern p_target;
|
||||||
std::vector<std::string> p_deps{};
|
std::vector<depend_func> p_deps{};
|
||||||
body_func p_body{};
|
body_func p_body{};
|
||||||
std::function<bool(string_range)> p_cond{};
|
std::function<bool(string_range)> p_cond{};
|
||||||
bool p_action = false;
|
bool p_action = false;
|
||||||
|
|
|
@ -185,10 +185,9 @@ void make::find_rules(string_range target, std::vector<rule_inst> &rlist) {
|
||||||
rlist.emplace_back();
|
rlist.emplace_back();
|
||||||
rule_inst &sr = rlist.back();
|
rule_inst &sr = rlist.back();
|
||||||
sr.rule = &rule;
|
sr.rule = &rule;
|
||||||
sr.deps.reserve(rule.depends().size());
|
rule.depends([&sr, &tgt](string_range d) {
|
||||||
for (auto &d: rule.depends()) {
|
|
||||||
sr.deps.push_back(tgt.replace(d));
|
sr.deps.push_back(tgt.replace(d));
|
||||||
}
|
});
|
||||||
if (!rule.has_body()) {
|
if (!rule.has_body()) {
|
||||||
if (fnl != target.size()) {
|
if (fnl != target.size()) {
|
||||||
throw make_error{"pattern rule '%s' needs a body", target};
|
throw make_error{"pattern rule '%s' needs a body", target};
|
||||||
|
|
Loading…
Reference in New Issue