Loading executor.cpp +28 −27 Changes for executor.cpp: 28 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -607,54 +607,55 @@ int Executor::execute_rule(const std::string& target, const Rule* rule, auto order_only = expand_order_only(target, rule, stem); std::string full_recipe; bool is_silent = silent_; bool ignore_error = false; bool force_exec = false; // Like GNU make, every recipe line is its own shell command with its own // @/-/+ prefixes, and the first failing one (without '-') stops the // recipe. Running them as one script let a failing sub-make be followed // by CMake's "Built target" echo, whose status hid the error. struct Command { std::string text; bool silent, ignore, force; }; std::vector<Command> commands; for (size_t r_idx = 0; r_idx < rule->recipes.size(); ++r_idx) { std::string expanded = parser_.expand_with_automatic( rule->recipes[r_idx], *mfp, target, first_prereq, prereqs, newer, stem, &order_only); // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros). // Wir müssen zeilenweise (split by \n) durchgehen und bei *jeder* Zeile // die Präfixe (@, -, +) am Zeilenanfang entfernen! std::string line_accum; // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros); // jede Zeile ist ein eigenes Kommando mit eigenen Präfixen (@, -, +). std::stringstream ss(expanded); std::string single_line; bool first_subline = (r_idx == 0); while (std::getline(ss, single_line)) { Command c{"", silent_, false, false}; // Führende Leerzeichen/Tabs für das Parsen des Präfix überspringen size_t start = 0; while (start < single_line.size()) { if (single_line[start] == '@') { if (first_subline) is_silent = true; start++; } else if (single_line[start] == '-') { ignore_error = true; start++; } else if (single_line[start] == '+') { force_exec = true; start++; } if (single_line[start] == '@') { c.silent = true; start++; } else if (single_line[start] == '-') { c.ignore = true; start++; } else if (single_line[start] == '+') { c.force = true; start++; } else if (single_line[start] == ' ' || single_line[start] == '\t') { start++; } else break; } std::string cleaned_line = single_line.substr(start); if (!full_recipe.empty() || !line_accum.empty()) { full_recipe += "\n"; } full_recipe += cleaned_line; first_subline = false; c.text = single_line.substr(start); if (c.text.find_first_not_of(" \t") == std::string::npos) continue; commands.push_back(std::move(c)); } } if (full_recipe.empty()) return 0; if (!is_silent) { std::cout << full_recipe << std::endl; } if (commands.empty()) return 0; if (question_) return 1; if (!dry_run_ || force_exec) { int rc = run_command(full_recipe, recipe_env); if (rc != 0 && !ignore_error) { for (const auto& c : commands) { if (!c.silent || (dry_run_ && !c.force)) { std::cout << c.text << std::endl; } if (dry_run_ && !c.force) continue; int rc = run_command(c.text, recipe_env); if (rc != 0) { if (c.ignore) { std::cerr << "makeplus: [" << target << "] Error " << rc << " (ignored)" << std::endl; continue; } std::cerr << "makeplus: *** [" << target << "] Error " << rc << std::endl; return rc; } Loading Loading
executor.cpp +28 −27 Changes for executor.cpp: 28 added lines, 27 removed lines. Original line number Diff line number Diff line Loading @@ -607,54 +607,55 @@ int Executor::execute_rule(const std::string& target, const Rule* rule, auto order_only = expand_order_only(target, rule, stem); std::string full_recipe; bool is_silent = silent_; bool ignore_error = false; bool force_exec = false; // Like GNU make, every recipe line is its own shell command with its own // @/-/+ prefixes, and the first failing one (without '-') stops the // recipe. Running them as one script let a failing sub-make be followed // by CMake's "Built target" echo, whose status hid the error. struct Command { std::string text; bool silent, ignore, force; }; std::vector<Command> commands; for (size_t r_idx = 0; r_idx < rule->recipes.size(); ++r_idx) { std::string expanded = parser_.expand_with_automatic( rule->recipes[r_idx], *mfp, target, first_prereq, prereqs, newer, stem, &order_only); // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros). // Wir müssen zeilenweise (split by \n) durchgehen und bei *jeder* Zeile // die Präfixe (@, -, +) am Zeilenanfang entfernen! std::string line_accum; // Ein Rezept kann intern selbst Zeilenumbrüche enthalten (z. B. durch Makros); // jede Zeile ist ein eigenes Kommando mit eigenen Präfixen (@, -, +). std::stringstream ss(expanded); std::string single_line; bool first_subline = (r_idx == 0); while (std::getline(ss, single_line)) { Command c{"", silent_, false, false}; // Führende Leerzeichen/Tabs für das Parsen des Präfix überspringen size_t start = 0; while (start < single_line.size()) { if (single_line[start] == '@') { if (first_subline) is_silent = true; start++; } else if (single_line[start] == '-') { ignore_error = true; start++; } else if (single_line[start] == '+') { force_exec = true; start++; } if (single_line[start] == '@') { c.silent = true; start++; } else if (single_line[start] == '-') { c.ignore = true; start++; } else if (single_line[start] == '+') { c.force = true; start++; } else if (single_line[start] == ' ' || single_line[start] == '\t') { start++; } else break; } std::string cleaned_line = single_line.substr(start); if (!full_recipe.empty() || !line_accum.empty()) { full_recipe += "\n"; } full_recipe += cleaned_line; first_subline = false; c.text = single_line.substr(start); if (c.text.find_first_not_of(" \t") == std::string::npos) continue; commands.push_back(std::move(c)); } } if (full_recipe.empty()) return 0; if (!is_silent) { std::cout << full_recipe << std::endl; } if (commands.empty()) return 0; if (question_) return 1; if (!dry_run_ || force_exec) { int rc = run_command(full_recipe, recipe_env); if (rc != 0 && !ignore_error) { for (const auto& c : commands) { if (!c.silent || (dry_run_ && !c.force)) { std::cout << c.text << std::endl; } if (dry_run_ && !c.force) continue; int rc = run_command(c.text, recipe_env); if (rc != 0) { if (c.ignore) { std::cerr << "makeplus: [" << target << "] Error " << rc << " (ignored)" << std::endl; continue; } std::cerr << "makeplus: *** [" << target << "] Error " << rc << std::endl; return rc; } Loading