23 #if defined(__SVR4) && defined(__sun)
24 #include <sys/termios.h>
41 virtual ~DryRunCommandRunner() {}
44 virtual bool CanRunMore();
45 virtual bool StartCommand(
Edge* edge);
46 virtual bool WaitForCommand(Result* result);
49 queue<Edge*> finished_;
52 bool DryRunCommandRunner::CanRunMore() {
56 bool DryRunCommandRunner::StartCommand(
Edge* edge) {
61 bool DryRunCommandRunner::WaitForCommand(Result* result) {
62 if (finished_.empty())
66 result->edge = finished_.front();
76 started_edges_(0), finished_edges_(0), total_edges_(0),
77 progress_status_format_(NULL),
78 overall_rate_(), current_rate_(config.parallelism) {
103 const string& output,
110 *start_time = i->second;
124 if (!output.empty()) {
141 final_output = output;
151 const char* progress_status_format)
const {
155 for (
const char* s = progress_status_format; *s !=
'\0'; ++s) {
210 snprintf(buf,
sizeof(buf),
"%3i%%", percent);
216 snprintf(buf,
sizeof(buf),
"%.3f", elapsed);
222 Fatal(
"unknown placeholder '%%%c' in $NINJA_STATUS", *s);
239 string to_print = edge->
GetBinding(
"description");
240 if (to_print.empty() || force_full_command)
266 referenced =
", needed by '" + stack->back()->path() +
"',";
267 *err =
"'" + node->
path() +
"'" + referenced +
" missing "
268 "and no known rule to make it";
281 pair<map<Edge*, bool>::iterator,
bool> want_ins =
282 want_.insert(make_pair(edge,
false));
283 bool& want = want_ins.first->second;
287 if (node->
dirty() && !want) {
296 if (!want_ins.second)
299 stack->push_back(node);
300 for (vector<Node*>::iterator i = edge->
inputs_.begin();
301 i != edge->
inputs_.end(); ++i) {
305 assert(stack->back() == node);
312 vector<Node*>::reverse_iterator ri =
313 find(stack->rbegin(), stack->rend(), node);
314 if (ri == stack->rend())
319 stack->push_back(node);
321 vector<Node*>::iterator start = find(stack->begin(), stack->end(), node);
322 *err =
"dependency cycle: ";
323 for (vector<Node*>::iterator i = start; i != stack->end(); ++i) {
326 err->append((*i)->path());
334 set<Edge*>::iterator i =
ready_.begin();
363 map<Edge*, bool>::iterator i =
want_.find(edge);
364 assert(i !=
want_.end());
374 for (vector<Node*>::iterator i = edge->
outputs_.begin();
382 for (vector<Edge*>::const_iterator i = node->
out_edges().begin();
384 map<Edge*, bool>::iterator want_i =
want_.find(*i);
385 if (want_i ==
want_.end())
389 if ((*i)->AllInputsReady()) {
390 if (want_i->second) {
404 for (vector<Edge*>::const_iterator ei = node->
out_edges().begin();
407 map<Edge*, bool>::iterator want_i =
want_.find(*ei);
408 if (want_i ==
want_.end() || !want_i->second)
413 vector<Node*>::iterator
414 begin = (*ei)->inputs_.begin(),
415 end = (*ei)->inputs_.end() - (*ei)->order_only_deps_;
416 if (find_if(begin, end, mem_fun(&
Node::dirty)) == end) {
418 Node* most_recent_input = NULL;
419 for (vector<Node*>::iterator ni = begin; ni != end; ++ni) {
420 if (!most_recent_input || (*ni)->
mtime() > most_recent_input->
mtime())
421 most_recent_input = *ni;
423 string command = (*ei)->EvaluateCommand(
true);
426 bool all_outputs_clean =
true;
427 for (vector<Node*>::iterator ni = (*ei)->outputs_.begin();
428 ni != (*ei)->outputs_.end(); ++ni) {
435 all_outputs_clean =
false;
442 if (all_outputs_clean) {
443 want_i->second =
false;
445 if (!(*ei)->is_phony())
453 printf(
"pending: %d\n", (
int)
want_.size());
454 for (map<Edge*, bool>::iterator i =
want_.begin(); i !=
want_.end(); ++i) {
459 printf(
"ready: %d\n", (
int)
ready_.size());
469 virtual void Abort();
480 edges.push_back(i->second);
516 result->
edge = i->second;
526 : state_(state), config_(config), disk_interface_(disk_interface),
527 scan_(state, build_log, deps_log, disk_interface) {
540 for (vector<Edge*>::iterator i = active_edges.begin();
541 i != active_edges.end(); ++i) {
542 string depfile = (*i)->GetBinding(
"depfile");
543 for (vector<Node*>::iterator ni = (*i)->outputs_.begin();
544 ni != (*i)->outputs_.end(); ++ni) {
552 if (!depfile.empty() ||
557 if (!depfile.empty())
566 *err =
"unknown target: '" + name +
"'";
579 if (in_edge->outputs_ready())
597 int pending_commands = 0;
634 if (pending_commands) {
639 *err =
"interrupted by user";
647 if (failures_allowed)
657 if (failures_allowed == 0) {
659 *err =
"subcommands failed";
661 *err =
"subcommand failed";
663 *err =
"cannot make progress due to previous errors";
665 *err =
"stuck [this is a bug]";
683 for (vector<Node*>::iterator i = edge->
outputs_.begin();
692 if (!rspfile.empty()) {
693 string content = edge->
GetBinding(
"rspfile_content");
717 vector<Node*> deps_nodes;
719 if (!deps_type.empty()) {
721 if (!
ExtractDeps(result, deps_type, &deps_nodes, &extract_err) &&
723 if (!result->
output.empty())
724 result->
output.append(
"\n");
725 result->
output.append(extract_err);
730 int start_time, end_time;
732 &start_time, &end_time);
741 bool node_cleaned =
false;
743 for (vector<Node*>::iterator i = edge->
outputs_.begin();
746 if ((*i)->mtime() == new_mtime) {
758 for (vector<Node*>::iterator i = edge->
inputs_.begin();
761 if (input_mtime > restat_mtime)
762 restat_mtime = input_mtime;
766 if (restat_mtime != 0 && !depfile.empty()) {
768 if (depfile_mtime > restat_mtime)
769 restat_mtime = depfile_mtime;
782 if (!rspfile.empty())
791 assert(edge->
outputs_.size() == 1 &&
"should have been rejected by parser");
800 const string& deps_type,
801 vector<Node*>* deps_nodes,
804 if (deps_type ==
"msvc") {
807 for (set<string>::iterator i = parser.
includes_.begin();
813 if (deps_type ==
"gcc") {
815 if (depfile.empty()) {
816 *err = string(
"edge with deps=gcc but no depfile makes no sense");
827 if (!deps.
Parse(&content, err))
831 deps_nodes->reserve(deps.
ins_.size());
832 for (vector<StringPiece>::iterator i = deps.
ins_.begin();
833 i != deps.
ins_.end(); ++i) {
840 *err = string(
"deleting depfile: ") + strerror(errno) + string(
"\n");
844 Fatal(
"unknown deps type '%s'", deps_type.c_str());