diff options
Diffstat (limited to 'libbuild2/build/script/script.cxx')
-rw-r--r-- | libbuild2/build/script/script.cxx | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/libbuild2/build/script/script.cxx b/libbuild2/build/script/script.cxx index 14dd9e1..0d96cc3 100644 --- a/libbuild2/build/script/script.cxx +++ b/libbuild2/build/script/script.cxx @@ -3,10 +3,12 @@ #include <libbuild2/build/script/script.hxx> -#include <libbutl/filesystem.mxx> +#include <libbutl/filesystem.hxx> #include <libbuild2/target.hxx> +#include <libbuild2/adhoc-rule-buildscript.hxx> // include_unmatch* + #include <libbuild2/script/timeout.hxx> #include <libbuild2/build/script/parser.hxx> @@ -28,54 +30,92 @@ namespace build2 environment:: environment (action a, const target_type& t, + const scope_type& s, bool temp, const optional<timestamp>& dl) : build2::script::environment ( t.ctx, - cast<target_triplet> (t.ctx.global_scope["build.host"]), + *t.ctx.build_host, dir_name_view (&work, &wd_name), temp_dir.path, false /* temp_dir_keep */, redirect (redirect_type::none), redirect (redirect_type::merge, 2), redirect (redirect_type::pass)), target (t), - vars (context, false /* global */), + scope (s), + vars (context, false /* shared */), // Note: managed. + var_ts (var_pool.insert (">")), + var_ps (var_pool.insert ("<")), script_deadline (to_deadline (dl, false /* success */)) { - // Set special variables. - // + set_special_variables (a); + + if (temp) + set_temp_dir_variable (); + } + + void environment:: + set_special_variables (action a) + { { // $> // + // What should it contain for an explicit group? While it may seem + // that just the members should be enough (and analogous to the ad + // hoc case), this won't let us get the group name for diagnostics. + // So the group name followed by all the members seems like the + // logical choice. + // names ns; - for (const target_type* m (&t); m != nullptr; m = m->adhoc_member) - m->as_name (ns); - assign (var_pool.insert (">")) = move (ns); + if (const group* g = target.is_a<group> ()) + { + g->as_name (ns); + for (const target_type* m: g->members) + m->as_name (ns); + } + else + { + for (const target_type* m (&target); + m != nullptr; + m = m->adhoc_member) + m->as_name (ns); + } + + assign (var_ts) = move (ns); } { // $< // - // Note that at this stage (after execute_prerequisites()) ad hoc - // prerequisites are no longer in prerequisite_targets which means - // they won't end up in $< either. While at first thought ad hoc - // prerequisites in ad hoc recipes don't seem to make much sense, - // they could be handy to exclude certain preresquisites from $< - // while still treating them as such. + // Note that ad hoc prerequisites don't end up in $<. While at first + // thought ad hoc prerequisites in ad hoc recipes don't seem to make + // much sense, they could be handy to exclude certain prerequisites + // from $< while still treating them as such, especially in rule. + // + // While initially we treated update=unmatch prerequisites as + // implicitly ad hoc, this turned out to be not quite correct, so + // now we add them unless they are explicitly marked ad hoc. // names ns; - for (const target_type* pt: t.prerequisite_targets[a]) + for (const prerequisite_target& p: target.prerequisite_targets[a]) { - if (pt != nullptr) + // See adhoc_buildscript_rule::execute_update_prerequisites(). + // + if (const target_type* pt = + p.target != nullptr ? (p.adhoc () ? nullptr : p.target) : + (p.include & adhoc_buildscript_rule::include_unmatch) != 0 && + (p.include & prerequisite_target::include_adhoc) == 0 && + (p.include & adhoc_buildscript_rule::include_unmatch_adhoc) == 0 + ? reinterpret_cast<target_type*> (p.data) + : nullptr) + { pt->as_name (ns); + } } - assign (var_pool.insert ("<")) = move (ns); + assign (var_ps) = move (ns); } - - if (temp) - set_temp_dir_variable (); } void environment:: @@ -146,7 +186,7 @@ namespace build2 } void environment:: - set_variable (string&& nm, + set_variable (string nm, names&& val, const string& attrs, const location& ll) @@ -225,7 +265,7 @@ namespace build2 // in parallel). Plus, if there is no such variable, then we cannot // possibly find any value. // - const variable* pvar (context.var_pool.find (n)); + const variable* pvar (scope.var_pool ().find (n)); if (pvar == nullptr) return lookup_type (); |