diff options
author | Colin Cross <ccross@android.com> | 2016-11-14 23:59:41 (GMT) |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2020-12-18 20:38:29 (GMT) |
commit | 589f5b2497929a50a1c74786478cc6fea7a2e1c6 (patch) | |
tree | 0b4e837578a50a597e7fec47734abb82a917d54e /src/build.cc | |
parent | 045890cee352be512beea96da0d142f219472fbb (diff) | |
download | Ninja-589f5b2497929a50a1c74786478cc6fea7a2e1c6.zip Ninja-589f5b2497929a50a1c74786478cc6fea7a2e1c6.tar.gz Ninja-589f5b2497929a50a1c74786478cc6fea7a2e1c6.tar.bz2 |
Turn BuildStatus into an interface
Make BuildStatus an abstract interface, and move the current
implementation to StatusPrinter, to make way for a serialized
Status output.
Diffstat (limited to 'src/build.cc')
-rw-r--r-- | src/build.cc | 231 |
1 files changed, 4 insertions, 227 deletions
diff --git a/src/build.cc b/src/build.cc index 3b1a3f4..3d1e76b 100644 --- a/src/build.cc +++ b/src/build.cc @@ -20,11 +20,6 @@ #include <stdlib.h> #include <functional> -#ifdef _WIN32 -#include <fcntl.h> -#include <io.h> -#endif - #if defined(__SVR4) && defined(__sun) #include <sys/termios.h> #endif @@ -38,6 +33,7 @@ #include "graph.h" #include "metrics.h" #include "state.h" +#include "status.h" #include "subprocess.h" #include "util.h" @@ -79,225 +75,6 @@ bool DryRunCommandRunner::WaitForCommand(Result* result) { } // namespace -BuildStatus::BuildStatus(const BuildConfig& config) - : config_(config), - started_edges_(0), finished_edges_(0), total_edges_(0), running_edges_(0), - time_millis_(0), progress_status_format_(NULL), - current_rate_(config.parallelism) { - // Don't do anything fancy in verbose mode. - if (config_.verbosity != BuildConfig::NORMAL) - printer_.set_smart_terminal(false); - - progress_status_format_ = getenv("NINJA_STATUS"); - if (!progress_status_format_) - progress_status_format_ = "[%f/%t] "; -} - -void BuildStatus::PlanHasTotalEdges(int total) { - total_edges_ = total; -} - -void BuildStatus::BuildEdgeStarted(const Edge* edge, - int64_t start_time_millis) { - ++started_edges_; - time_millis_ = start_time_millis; - - if (edge->use_console() || printer_.is_smart_terminal()) - PrintStatus(edge, start_time_millis); - - if (edge->use_console()) - printer_.SetConsoleLocked(true); -} - -void BuildStatus::BuildEdgeFinished(Edge* edge, int64_t end_time_millis, - bool success, - const string& output) { - time_millis_ = end_time_millis; - ++finished_edges_; - - if (edge->use_console()) - printer_.SetConsoleLocked(false); - - if (config_.verbosity == BuildConfig::QUIET) - return; - - if (!edge->use_console()) - PrintStatus(edge, end_time_millis); - - // Update running_edges_ after PrintStatus so that the number of running - // edges doesn't oscillate between config.parallelism_ and - // config.parallelism_ - 1. - --running_edges_; - - // Print the command that is spewing before printing its output. - if (!success) { - string outputs; - for (vector<Node*>::const_iterator o = edge->outputs_.begin(); - o != edge->outputs_.end(); ++o) - outputs += (*o)->path() + " "; - - if (printer_.supports_color()) { - printer_.PrintOnNewLine("\x1B[31m" "FAILED: " "\x1B[0m" + outputs + "\n"); - } else { - printer_.PrintOnNewLine("FAILED: " + outputs + "\n"); - } - printer_.PrintOnNewLine(edge->EvaluateCommand() + "\n"); - } - - if (!output.empty()) { - // ninja sets stdout and stderr of subprocesses to a pipe, to be able to - // check if the output is empty. Some compilers, e.g. clang, check - // isatty(stderr) to decide if they should print colored output. - // To make it possible to use colored output with ninja, subprocesses should - // be run with a flag that forces them to always print color escape codes. - // To make sure these escape codes don't show up in a file if ninja's output - // is piped to a file, ninja strips ansi escape codes again if it's not - // writing to a |smart_terminal_|. - // (Launching subprocesses in pseudo ttys doesn't work because there are - // only a few hundred available on some systems, and ninja can launch - // thousands of parallel compile commands.) - string final_output; - if (!printer_.supports_color()) - final_output = StripAnsiEscapeCodes(output); - else - final_output = output; - -#ifdef _WIN32 - // Fix extra CR being added on Windows, writing out CR CR LF (#773) - _setmode(_fileno(stdout), _O_BINARY); // Begin Windows extra CR fix -#endif - - printer_.PrintOnNewLine(final_output); - -#ifdef _WIN32 - _setmode(_fileno(stdout), _O_TEXT); // End Windows extra CR fix -#endif - } -} - -void BuildStatus::BuildLoadDyndeps() { - // The DependencyScan calls EXPLAIN() to print lines explaining why - // it considers a portion of the graph to be out of date. Normally - // this is done before the build starts, but our caller is about to - // load a dyndep file during the build. Doing so may generate more - // explanation lines (via fprintf directly to stderr), but in an - // interactive console the cursor is currently at the end of a status - // line. Start a new line so that the first explanation does not - // append to the status line. After the explanations are done a - // new build status line will appear. - if (g_explaining) - printer_.PrintOnNewLine(""); -} - -void BuildStatus::BuildStarted() { - started_edges_ = 0; - finished_edges_ = 0; - running_edges_ = 0; -} - -void BuildStatus::BuildFinished() { - printer_.SetConsoleLocked(false); - printer_.PrintOnNewLine(""); -} - -string BuildStatus::FormatProgressStatus( - const char* progress_status_format, int64_t time) const { - string out; - char buf[32]; - for (const char* s = progress_status_format; *s != '\0'; ++s) { - if (*s == '%') { - ++s; - switch (*s) { - case '%': - out.push_back('%'); - break; - - // Started edges. - case 's': - snprintf(buf, sizeof(buf), "%d", started_edges_); - out += buf; - break; - - // Total edges. - case 't': - snprintf(buf, sizeof(buf), "%d", total_edges_); - out += buf; - break; - - // Running edges. - case 'r': { - snprintf(buf, sizeof(buf), "%d", running_edges_); - out += buf; - break; - } - - // Unstarted edges. - case 'u': - snprintf(buf, sizeof(buf), "%d", total_edges_ - started_edges_); - out += buf; - break; - - // Finished edges. - case 'f': - snprintf(buf, sizeof(buf), "%d", finished_edges_); - out += buf; - break; - - // Overall finished edges per second. - case 'o': - SnprintfRate(finished_edges_ / (time_millis_ / 1e3), buf, "%.1f"); - out += buf; - break; - - // Current rate, average over the last '-j' jobs. - case 'c': - current_rate_.UpdateRate(finished_edges_, time_millis_); - SnprintfRate(current_rate_.rate(), buf, "%.1f"); - out += buf; - break; - - // Percentage - case 'p': { - int percent = (100 * finished_edges_) / total_edges_; - snprintf(buf, sizeof(buf), "%3i%%", percent); - out += buf; - break; - } - - case 'e': { - snprintf(buf, sizeof(buf), "%.3f", time_millis_ / 1e3); - out += buf; - break; - } - - default: - Fatal("unknown placeholder '%%%c' in $NINJA_STATUS", *s); - return ""; - } - } else { - out.push_back(*s); - } - } - - return out; -} - -void BuildStatus::PrintStatus(const Edge* edge, int64_t time) { - if (config_.verbosity == BuildConfig::QUIET) - return; - - bool force_full_command = config_.verbosity == BuildConfig::VERBOSE; - - string to_print = edge->GetBinding("description"); - if (to_print.empty() || force_full_command) - to_print = edge->GetBinding("command"); - - to_print = FormatProgressStatus(progress_status_format_, time) + to_print; - - printer_.Print(to_print, - force_full_command ? LinePrinter::FULL : LinePrinter::ELIDE); -} - Plan::Plan(Builder* builder) : builder_(builder) , command_edges_(0) @@ -722,12 +499,12 @@ bool RealCommandRunner::WaitForCommand(Result* result) { Builder::Builder(State* state, const BuildConfig& config, BuildLog* build_log, DepsLog* deps_log, - DiskInterface* disk_interface, int64_t start_time_millis) - : state_(state), config_(config), plan_(this), + DiskInterface* disk_interface, Status *status, + int64_t start_time_millis) + : state_(state), config_(config), plan_(this), status_(status), start_time_millis_(start_time_millis), disk_interface_(disk_interface), scan_(state, build_log, deps_log, disk_interface, &config_.depfile_parser_options) { - status_ = new BuildStatus(config); } Builder::~Builder() { |