Loading executor.cpp +16 −2 Changes for executor.cpp: 16 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -296,8 +296,22 @@ int Executor::execute_rule(const std::string& target, const Rule* rule, if (entry.first != target && !pattern_key_matches(entry.first, target)) continue; if (entry.second.empty()) continue; if (!have_overrides) { local_copy = mf_; have_overrides = true; } for (const auto& kv : entry.second) local_copy.variables[kv.first] = {kv.second, VarFlavor::Recursive, false}; for (const auto& kv : entry.second) { std::string value = kv.value; if (kv.append) { // GNU make: a target-specific 'VAR += x' appends to the value // VAR has in the surrounding scope. Resolve that base value now. auto git = mf_.variables.find(kv.name); std::string base; if (git != mf_.variables.end()) { base = (git->second.flavor == VarFlavor::Recursive) ? parser_.expand(git->second.value, mf_) : git->second.value; } value = base.empty() ? kv.value : base + " " + kv.value; } local_copy.variables[kv.name] = {value, VarFlavor::Recursive, false}; } } if (have_overrides) mfp = &local_copy; // Export marked variables into the environment so recipes and any Loading parser.cpp +10 −5 Changes for parser.cpp: 10 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -849,15 +849,20 @@ bool Parser::try_parse_rule(const std::string& line, Makefile& mf, Rule*& curren auto& vec = mf.target_vars[t]; bool found = false; for (auto& pr : vec) { if (pr.first == tv_name) { pr.second = (tv_op == "+=") ? (pr.second.empty() ? val : pr.second + " " + val) : val; if (pr.name == tv_name) { if (tv_op == "+=") { pr.value = pr.value.empty() ? val : pr.value + " " + val; } else { pr.value = val; pr.append = false; } found = true; break; } } if (!found) vec.push_back({tv_name, val}); // A first-time '+=' must append to whatever value the variable // has in the surrounding (global) scope when the recipe runs. if (!found) vec.push_back({tv_name, val, tv_op == "+="}); } current_rule = nullptr; return true; Loading parser.h +9 −2 Changes for parser.h: 9 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -37,9 +37,16 @@ struct Makefile { std::set<std::string> phony_targets; std::string default_target; std::string base_dir; // Target-specific variable assignments: target name -> list of (name, value). // Target-specific variable assignments: target name -> list of bindings. // Applied (recursive flavor) while the target's recipes are expanded. std::map<std::string, std::vector<std::pair<std::string, std::string>>> target_vars; // `append` records that the binding used '+=', so at apply time it appends // to the value the variable would otherwise have (GNU make semantics). struct TargetVar { std::string name; std::string value; bool append = false; }; std::map<std::string, std::vector<TargetVar>> target_vars; // Variables marked for export into the recipe / sub-make environment. std::set<std::string> exported; bool export_all = false; Loading Loading
executor.cpp +16 −2 Changes for executor.cpp: 16 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -296,8 +296,22 @@ int Executor::execute_rule(const std::string& target, const Rule* rule, if (entry.first != target && !pattern_key_matches(entry.first, target)) continue; if (entry.second.empty()) continue; if (!have_overrides) { local_copy = mf_; have_overrides = true; } for (const auto& kv : entry.second) local_copy.variables[kv.first] = {kv.second, VarFlavor::Recursive, false}; for (const auto& kv : entry.second) { std::string value = kv.value; if (kv.append) { // GNU make: a target-specific 'VAR += x' appends to the value // VAR has in the surrounding scope. Resolve that base value now. auto git = mf_.variables.find(kv.name); std::string base; if (git != mf_.variables.end()) { base = (git->second.flavor == VarFlavor::Recursive) ? parser_.expand(git->second.value, mf_) : git->second.value; } value = base.empty() ? kv.value : base + " " + kv.value; } local_copy.variables[kv.name] = {value, VarFlavor::Recursive, false}; } } if (have_overrides) mfp = &local_copy; // Export marked variables into the environment so recipes and any Loading
parser.cpp +10 −5 Changes for parser.cpp: 10 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -849,15 +849,20 @@ bool Parser::try_parse_rule(const std::string& line, Makefile& mf, Rule*& curren auto& vec = mf.target_vars[t]; bool found = false; for (auto& pr : vec) { if (pr.first == tv_name) { pr.second = (tv_op == "+=") ? (pr.second.empty() ? val : pr.second + " " + val) : val; if (pr.name == tv_name) { if (tv_op == "+=") { pr.value = pr.value.empty() ? val : pr.value + " " + val; } else { pr.value = val; pr.append = false; } found = true; break; } } if (!found) vec.push_back({tv_name, val}); // A first-time '+=' must append to whatever value the variable // has in the surrounding (global) scope when the recipe runs. if (!found) vec.push_back({tv_name, val, tv_op == "+="}); } current_rule = nullptr; return true; Loading
parser.h +9 −2 Changes for parser.h: 9 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -37,9 +37,16 @@ struct Makefile { std::set<std::string> phony_targets; std::string default_target; std::string base_dir; // Target-specific variable assignments: target name -> list of (name, value). // Target-specific variable assignments: target name -> list of bindings. // Applied (recursive flavor) while the target's recipes are expanded. std::map<std::string, std::vector<std::pair<std::string, std::string>>> target_vars; // `append` records that the binding used '+=', so at apply time it appends // to the value the variable would otherwise have (GNU make semantics). struct TargetVar { std::string name; std::string value; bool append = false; }; std::map<std::string, std::vector<TargetVar>> target_vars; // Variables marked for export into the recipe / sub-make environment. std::set<std::string> exported; bool export_all = false; Loading