Ninja
build_test.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "build.h"
16 
17 #include <assert.h>
18 
19 #include "build_log.h"
20 #include "deps_log.h"
21 #include "graph.h"
22 #include "test.h"
23 
24 using namespace std;
25 
27  static bool cmp(const Edge* a, const Edge* b) {
28  return a->outputs_[0]->path() < b->outputs_[0]->path();
29  }
30 };
31 
32 /// Fixture for tests involving Plan.
33 // Though Plan doesn't use State, it's useful to have one around
34 // to create Nodes and Edges.
37 
38  /// Because FindWork does not return Edges in any sort of predictable order,
39  // provide a means to get available Edges in order and in a format which is
40  // easy to write tests around.
41  void FindWorkSorted(deque<Edge*>* ret, int count) {
42  for (int i = 0; i < count; ++i) {
43  ASSERT_TRUE(plan_.more_to_do());
44  Edge* edge = plan_.FindWork();
45  ASSERT_TRUE(edge);
46  ret->push_back(edge);
47  }
48  ASSERT_FALSE(plan_.FindWork());
49  sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
50  }
51 
52  void TestPoolWithDepthOne(const char *test_case);
53 };
54 
55 TEST_F(PlanTest, Basic) {
57 "build out: cat mid\n"
58 "build mid: cat in\n"));
59  GetNode("mid")->MarkDirty();
60  GetNode("out")->MarkDirty();
61  string err;
62  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
63  ASSERT_EQ("", err);
64  ASSERT_TRUE(plan_.more_to_do());
65 
66  Edge* edge = plan_.FindWork();
67  ASSERT_TRUE(edge);
68  ASSERT_EQ("in", edge->inputs_[0]->path());
69  ASSERT_EQ("mid", edge->outputs_[0]->path());
70 
71  ASSERT_FALSE(plan_.FindWork());
72 
73  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
74  ASSERT_EQ("", err);
75 
76  edge = plan_.FindWork();
77  ASSERT_TRUE(edge);
78  ASSERT_EQ("mid", edge->inputs_[0]->path());
79  ASSERT_EQ("out", edge->outputs_[0]->path());
80 
81  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
82  ASSERT_EQ("", err);
83 
84  ASSERT_FALSE(plan_.more_to_do());
85  edge = plan_.FindWork();
86  ASSERT_EQ(0, edge);
87 }
88 
89 // Test that two outputs from one rule can be handled as inputs to the next.
90 TEST_F(PlanTest, DoubleOutputDirect) {
92 "build out: cat mid1 mid2\n"
93 "build mid1 mid2: cat in\n"));
94  GetNode("mid1")->MarkDirty();
95  GetNode("mid2")->MarkDirty();
96  GetNode("out")->MarkDirty();
97 
98  string err;
99  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
100  ASSERT_EQ("", err);
101  ASSERT_TRUE(plan_.more_to_do());
102 
103  Edge* edge;
104  edge = plan_.FindWork();
105  ASSERT_TRUE(edge); // cat in
106  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
107  ASSERT_EQ("", err);
108 
109  edge = plan_.FindWork();
110  ASSERT_TRUE(edge); // cat mid1 mid2
111  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
112  ASSERT_EQ("", err);
113 
114  edge = plan_.FindWork();
115  ASSERT_FALSE(edge); // done
116 }
117 
118 // Test that two outputs from one rule can eventually be routed to another.
119 TEST_F(PlanTest, DoubleOutputIndirect) {
121 "build out: cat b1 b2\n"
122 "build b1: cat a1\n"
123 "build b2: cat a2\n"
124 "build a1 a2: cat in\n"));
125  GetNode("a1")->MarkDirty();
126  GetNode("a2")->MarkDirty();
127  GetNode("b1")->MarkDirty();
128  GetNode("b2")->MarkDirty();
129  GetNode("out")->MarkDirty();
130  string err;
131  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
132  ASSERT_EQ("", err);
133  ASSERT_TRUE(plan_.more_to_do());
134 
135  Edge* edge;
136  edge = plan_.FindWork();
137  ASSERT_TRUE(edge); // cat in
138  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
139  ASSERT_EQ("", err);
140 
141  edge = plan_.FindWork();
142  ASSERT_TRUE(edge); // cat a1
143  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
144  ASSERT_EQ("", err);
145 
146  edge = plan_.FindWork();
147  ASSERT_TRUE(edge); // cat a2
148  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
149  ASSERT_EQ("", err);
150 
151  edge = plan_.FindWork();
152  ASSERT_TRUE(edge); // cat b1 b2
153  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
154  ASSERT_EQ("", err);
155 
156  edge = plan_.FindWork();
157  ASSERT_FALSE(edge); // done
158 }
159 
160 // Test that two edges from one output can both execute.
161 TEST_F(PlanTest, DoubleDependent) {
163 "build out: cat a1 a2\n"
164 "build a1: cat mid\n"
165 "build a2: cat mid\n"
166 "build mid: cat in\n"));
167  GetNode("mid")->MarkDirty();
168  GetNode("a1")->MarkDirty();
169  GetNode("a2")->MarkDirty();
170  GetNode("out")->MarkDirty();
171 
172  string err;
173  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
174  ASSERT_EQ("", err);
175  ASSERT_TRUE(plan_.more_to_do());
176 
177  Edge* edge;
178  edge = plan_.FindWork();
179  ASSERT_TRUE(edge); // cat in
180  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
181  ASSERT_EQ("", err);
182 
183  edge = plan_.FindWork();
184  ASSERT_TRUE(edge); // cat mid
185  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
186  ASSERT_EQ("", err);
187 
188  edge = plan_.FindWork();
189  ASSERT_TRUE(edge); // cat mid
190  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
191  ASSERT_EQ("", err);
192 
193  edge = plan_.FindWork();
194  ASSERT_TRUE(edge); // cat a1 a2
195  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
196  ASSERT_EQ("", err);
197 
198  edge = plan_.FindWork();
199  ASSERT_FALSE(edge); // done
200 }
201 
202 void PlanTest::TestPoolWithDepthOne(const char* test_case) {
203  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_, test_case));
204  GetNode("out1")->MarkDirty();
205  GetNode("out2")->MarkDirty();
206  string err;
207  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
208  ASSERT_EQ("", err);
209  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
210  ASSERT_EQ("", err);
211  ASSERT_TRUE(plan_.more_to_do());
212 
213  Edge* edge = plan_.FindWork();
214  ASSERT_TRUE(edge);
215  ASSERT_EQ("in", edge->inputs_[0]->path());
216  ASSERT_EQ("out1", edge->outputs_[0]->path());
217 
218  // This will be false since poolcat is serialized
219  ASSERT_FALSE(plan_.FindWork());
220 
221  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
222  ASSERT_EQ("", err);
223 
224  edge = plan_.FindWork();
225  ASSERT_TRUE(edge);
226  ASSERT_EQ("in", edge->inputs_[0]->path());
227  ASSERT_EQ("out2", edge->outputs_[0]->path());
228 
229  ASSERT_FALSE(plan_.FindWork());
230 
231  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
232  ASSERT_EQ("", err);
233 
234  ASSERT_FALSE(plan_.more_to_do());
235  edge = plan_.FindWork();
236  ASSERT_EQ(0, edge);
237 }
238 
239 TEST_F(PlanTest, PoolWithDepthOne) {
240  TestPoolWithDepthOne(
241 "pool foobar\n"
242 " depth = 1\n"
243 "rule poolcat\n"
244 " command = cat $in > $out\n"
245 " pool = foobar\n"
246 "build out1: poolcat in\n"
247 "build out2: poolcat in\n");
248 }
249 
250 TEST_F(PlanTest, ConsolePool) {
251  TestPoolWithDepthOne(
252 "rule poolcat\n"
253 " command = cat $in > $out\n"
254 " pool = console\n"
255 "build out1: poolcat in\n"
256 "build out2: poolcat in\n");
257 }
258 
259 TEST_F(PlanTest, PoolsWithDepthTwo) {
261 "pool foobar\n"
262 " depth = 2\n"
263 "pool bazbin\n"
264 " depth = 2\n"
265 "rule foocat\n"
266 " command = cat $in > $out\n"
267 " pool = foobar\n"
268 "rule bazcat\n"
269 " command = cat $in > $out\n"
270 " pool = bazbin\n"
271 "build out1: foocat in\n"
272 "build out2: foocat in\n"
273 "build out3: foocat in\n"
274 "build outb1: bazcat in\n"
275 "build outb2: bazcat in\n"
276 "build outb3: bazcat in\n"
277 " pool =\n"
278 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
279 ));
280  // Mark all the out* nodes dirty
281  for (int i = 0; i < 3; ++i) {
282  GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
283  GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
284  }
285  GetNode("allTheThings")->MarkDirty();
286 
287  string err;
288  EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
289  ASSERT_EQ("", err);
290 
291  deque<Edge*> edges;
292  FindWorkSorted(&edges, 5);
293 
294  for (int i = 0; i < 4; ++i) {
295  Edge *edge = edges[i];
296  ASSERT_EQ("in", edge->inputs_[0]->path());
297  string base_name(i < 2 ? "out" : "outb");
298  ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
299  }
300 
301  // outb3 is exempt because it has an empty pool
302  Edge* edge = edges[4];
303  ASSERT_TRUE(edge);
304  ASSERT_EQ("in", edge->inputs_[0]->path());
305  ASSERT_EQ("outb3", edge->outputs_[0]->path());
306 
307  // finish out1
308  plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded, &err);
309  ASSERT_EQ("", err);
310  edges.pop_front();
311 
312  // out3 should be available
313  Edge* out3 = plan_.FindWork();
314  ASSERT_TRUE(out3);
315  ASSERT_EQ("in", out3->inputs_[0]->path());
316  ASSERT_EQ("out3", out3->outputs_[0]->path());
317 
318  ASSERT_FALSE(plan_.FindWork());
319 
320  plan_.EdgeFinished(out3, Plan::kEdgeSucceeded, &err);
321  ASSERT_EQ("", err);
322 
323  ASSERT_FALSE(plan_.FindWork());
324 
325  for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
326  plan_.EdgeFinished(*it, Plan::kEdgeSucceeded, &err);
327  ASSERT_EQ("", err);
328  }
329 
330  Edge* last = plan_.FindWork();
331  ASSERT_TRUE(last);
332  ASSERT_EQ("allTheThings", last->outputs_[0]->path());
333 
334  plan_.EdgeFinished(last, Plan::kEdgeSucceeded, &err);
335  ASSERT_EQ("", err);
336 
337  ASSERT_FALSE(plan_.more_to_do());
338  ASSERT_FALSE(plan_.FindWork());
339 }
340 
341 TEST_F(PlanTest, PoolWithRedundantEdges) {
343  "pool compile\n"
344  " depth = 1\n"
345  "rule gen_foo\n"
346  " command = touch foo.cpp\n"
347  "rule gen_bar\n"
348  " command = touch bar.cpp\n"
349  "rule echo\n"
350  " command = echo $out > $out\n"
351  "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
352  " pool = compile\n"
353  "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
354  " pool = compile\n"
355  "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
356  "build foo.cpp: gen_foo\n"
357  "build bar.cpp: gen_bar\n"
358  "build all: phony libfoo.a\n"));
359  GetNode("foo.cpp")->MarkDirty();
360  GetNode("foo.cpp.obj")->MarkDirty();
361  GetNode("bar.cpp")->MarkDirty();
362  GetNode("bar.cpp.obj")->MarkDirty();
363  GetNode("libfoo.a")->MarkDirty();
364  GetNode("all")->MarkDirty();
365  string err;
366  EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
367  ASSERT_EQ("", err);
368  ASSERT_TRUE(plan_.more_to_do());
369 
370  Edge* edge = NULL;
371 
372  deque<Edge*> initial_edges;
373  FindWorkSorted(&initial_edges, 2);
374 
375  edge = initial_edges[1]; // Foo first
376  ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
377  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
378  ASSERT_EQ("", err);
379 
380  edge = plan_.FindWork();
381  ASSERT_TRUE(edge);
382  ASSERT_FALSE(plan_.FindWork());
383  ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
384  ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
385  ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
386  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
387  ASSERT_EQ("", err);
388 
389  edge = initial_edges[0]; // Now for bar
390  ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
391  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
392  ASSERT_EQ("", err);
393 
394  edge = plan_.FindWork();
395  ASSERT_TRUE(edge);
396  ASSERT_FALSE(plan_.FindWork());
397  ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
398  ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
399  ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
400  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
401  ASSERT_EQ("", err);
402 
403  edge = plan_.FindWork();
404  ASSERT_TRUE(edge);
405  ASSERT_FALSE(plan_.FindWork());
406  ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
407  ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
408  ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
409  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
410  ASSERT_EQ("", err);
411 
412  edge = plan_.FindWork();
413  ASSERT_TRUE(edge);
414  ASSERT_FALSE(plan_.FindWork());
415  ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
416  ASSERT_EQ("all", edge->outputs_[0]->path());
417  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded, &err);
418  ASSERT_EQ("", err);
419 
420  edge = plan_.FindWork();
421  ASSERT_FALSE(edge);
422  ASSERT_FALSE(plan_.more_to_do());
423 }
424 
425 TEST_F(PlanTest, PoolWithFailingEdge) {
427  "pool foobar\n"
428  " depth = 1\n"
429  "rule poolcat\n"
430  " command = cat $in > $out\n"
431  " pool = foobar\n"
432  "build out1: poolcat in\n"
433  "build out2: poolcat in\n"));
434  GetNode("out1")->MarkDirty();
435  GetNode("out2")->MarkDirty();
436  string err;
437  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
438  ASSERT_EQ("", err);
439  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
440  ASSERT_EQ("", err);
441  ASSERT_TRUE(plan_.more_to_do());
442 
443  Edge* edge = plan_.FindWork();
444  ASSERT_TRUE(edge);
445  ASSERT_EQ("in", edge->inputs_[0]->path());
446  ASSERT_EQ("out1", edge->outputs_[0]->path());
447 
448  // This will be false since poolcat is serialized
449  ASSERT_FALSE(plan_.FindWork());
450 
451  plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
452  ASSERT_EQ("", err);
453 
454  edge = plan_.FindWork();
455  ASSERT_TRUE(edge);
456  ASSERT_EQ("in", edge->inputs_[0]->path());
457  ASSERT_EQ("out2", edge->outputs_[0]->path());
458 
459  ASSERT_FALSE(plan_.FindWork());
460 
461  plan_.EdgeFinished(edge, Plan::kEdgeFailed, &err);
462  ASSERT_EQ("", err);
463 
464  ASSERT_TRUE(plan_.more_to_do()); // Jobs have failed
465  edge = plan_.FindWork();
466  ASSERT_EQ(0, edge);
467 }
468 
469 /// Fake implementation of CommandRunner, useful for tests.
472  max_active_edges_(1), fs_(fs) {}
473 
474  // CommandRunner impl
475  virtual bool CanRunMore() const;
476  virtual bool StartCommand(Edge* edge);
477  virtual bool WaitForCommand(Result* result);
478  virtual vector<Edge*> GetActiveEdges();
479  virtual void Abort();
480 
481  vector<string> commands_ran_;
482  vector<Edge*> active_edges_;
485 };
486 
488  BuildTest() : config_(MakeConfig()), command_runner_(&fs_),
489  builder_(&state_, config_, NULL, NULL, &fs_),
490  status_(config_) {
491  }
492 
493  BuildTest(DepsLog* log) : config_(MakeConfig()), command_runner_(&fs_),
494  builder_(&state_, config_, NULL, log, &fs_),
495  status_(config_) {
496  }
497 
498  virtual void SetUp() {
500 
501  builder_.command_runner_.reset(&command_runner_);
502  AssertParse(&state_,
503 "build cat1: cat in1\n"
504 "build cat2: cat in1 in2\n"
505 "build cat12: cat cat1 cat2\n");
506 
507  fs_.Create("in1", "");
508  fs_.Create("in2", "");
509  }
510 
512  builder_.command_runner_.release();
513  }
514 
515  virtual bool IsPathDead(StringPiece s) const { return false; }
516 
517  /// Rebuild target in the 'working tree' (fs_).
518  /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
519  /// Handy to check for NOOP builds, and higher-level rebuild tests.
520  void RebuildTarget(const string& target, const char* manifest,
521  const char* log_path = NULL, const char* deps_path = NULL,
522  State* state = NULL);
523 
524  // Mark a path dirty.
525  void Dirty(const string& path);
526 
528  BuildConfig config;
529  config.verbosity = BuildConfig::QUIET;
530  return config;
531  }
532 
537 
539 };
540 
541 void BuildTest::RebuildTarget(const string& target, const char* manifest,
542  const char* log_path, const char* deps_path,
543  State* state) {
544  State local_state, *pstate = &local_state;
545  if (state)
546  pstate = state;
547  ASSERT_NO_FATAL_FAILURE(AddCatRule(pstate));
548  AssertParse(pstate, manifest);
549 
550  string err;
551  BuildLog build_log, *pbuild_log = NULL;
552  if (log_path) {
553  ASSERT_TRUE(build_log.Load(log_path, &err));
554  ASSERT_TRUE(build_log.OpenForWrite(log_path, *this, &err));
555  ASSERT_EQ("", err);
556  pbuild_log = &build_log;
557  }
558 
559  DepsLog deps_log, *pdeps_log = NULL;
560  if (deps_path) {
561  ASSERT_TRUE(deps_log.Load(deps_path, pstate, &err));
562  ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
563  ASSERT_EQ("", err);
564  pdeps_log = &deps_log;
565  }
566 
567  Builder builder(pstate, config_, pbuild_log, pdeps_log, &fs_);
568  EXPECT_TRUE(builder.AddTarget(target, &err));
569 
570  command_runner_.commands_ran_.clear();
571  builder.command_runner_.reset(&command_runner_);
572  if (!builder.AlreadyUpToDate()) {
573  bool build_res = builder.Build(&err);
574  EXPECT_TRUE(build_res);
575  }
576  builder.command_runner_.release();
577 }
578 
580  return active_edges_.size() < max_active_edges_;
581 }
582 
584  assert(active_edges_.size() < max_active_edges_);
585  assert(find(active_edges_.begin(), active_edges_.end(), edge)
586  == active_edges_.end());
587  commands_ran_.push_back(edge->EvaluateCommand());
588  if (edge->rule().name() == "cat" ||
589  edge->rule().name() == "cat_rsp" ||
590  edge->rule().name() == "cat_rsp_out" ||
591  edge->rule().name() == "cc" ||
592  edge->rule().name() == "cp_multi_msvc" ||
593  edge->rule().name() == "cp_multi_gcc" ||
594  edge->rule().name() == "touch" ||
595  edge->rule().name() == "touch-interrupt" ||
596  edge->rule().name() == "touch-fail-tick2") {
597  for (vector<Node*>::iterator out = edge->outputs_.begin();
598  out != edge->outputs_.end(); ++out) {
599  fs_->Create((*out)->path(), "");
600  }
601  } else if (edge->rule().name() == "true" ||
602  edge->rule().name() == "fail" ||
603  edge->rule().name() == "interrupt" ||
604  edge->rule().name() == "console") {
605  // Don't do anything.
606  } else if (edge->rule().name() == "cp") {
607  assert(!edge->inputs_.empty());
608  assert(edge->outputs_.size() == 1);
609  string content;
610  string err;
611  if (fs_->ReadFile(edge->inputs_[0]->path(), &content, &err) ==
613  fs_->WriteFile(edge->outputs_[0]->path(), content);
614  } else {
615  printf("unknown command\n");
616  return false;
617  }
618 
619  active_edges_.push_back(edge);
620 
621  // Allow tests to control the order by the name of the first output.
622  sort(active_edges_.begin(), active_edges_.end(),
624 
625  return true;
626 }
627 
629  if (active_edges_.empty())
630  return false;
631 
632  // All active edges were already completed immediately when started,
633  // so we can pick any edge here. Pick the last edge. Tests can
634  // control the order of edges by the name of the first output.
635  vector<Edge*>::iterator edge_iter = active_edges_.end() - 1;
636 
637  Edge* edge = *edge_iter;
638  result->edge = edge;
639 
640  if (edge->rule().name() == "interrupt" ||
641  edge->rule().name() == "touch-interrupt") {
642  result->status = ExitInterrupted;
643  return true;
644  }
645 
646  if (edge->rule().name() == "console") {
647  if (edge->use_console())
648  result->status = ExitSuccess;
649  else
650  result->status = ExitFailure;
651  active_edges_.erase(edge_iter);
652  return true;
653  }
654 
655  if (edge->rule().name() == "cp_multi_msvc") {
656  const std::string prefix = edge->GetBinding("msvc_deps_prefix");
657  for (std::vector<Node*>::iterator in = edge->inputs_.begin();
658  in != edge->inputs_.end(); ++in) {
659  result->output += prefix + (*in)->path() + '\n';
660  }
661  }
662 
663  if (edge->rule().name() == "fail" ||
664  (edge->rule().name() == "touch-fail-tick2" && fs_->now_ == 2))
665  result->status = ExitFailure;
666  else
667  result->status = ExitSuccess;
668 
669  // Provide a way for test cases to verify when an edge finishes that
670  // some other edge is still active. This is useful for test cases
671  // covering behavior involving multiple active edges.
672  const string& verify_active_edge = edge->GetBinding("verify_active_edge");
673  if (!verify_active_edge.empty()) {
674  bool verify_active_edge_found = false;
675  for (vector<Edge*>::iterator i = active_edges_.begin();
676  i != active_edges_.end(); ++i) {
677  if (!(*i)->outputs_.empty() &&
678  (*i)->outputs_[0]->path() == verify_active_edge) {
679  verify_active_edge_found = true;
680  }
681  }
682  EXPECT_TRUE(verify_active_edge_found);
683  }
684 
685  active_edges_.erase(edge_iter);
686  return true;
687 }
688 
690  return active_edges_;
691 }
692 
694  active_edges_.clear();
695 }
696 
697 void BuildTest::Dirty(const string& path) {
698  Node* node = GetNode(path);
699  node->MarkDirty();
700 
701  // If it's an input file, mark that we've already stat()ed it and
702  // it's missing.
703  if (!node->in_edge())
704  node->MarkMissing();
705 }
706 
707 TEST_F(BuildTest, NoWork) {
708  string err;
709  EXPECT_TRUE(builder_.AlreadyUpToDate());
710 }
711 
712 TEST_F(BuildTest, OneStep) {
713  // Given a dirty target with one ready input,
714  // we should rebuild the target.
715  Dirty("cat1");
716  string err;
717  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
718  ASSERT_EQ("", err);
719  EXPECT_TRUE(builder_.Build(&err));
720  ASSERT_EQ("", err);
721 
722  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
723  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
724 }
725 
726 TEST_F(BuildTest, OneStep2) {
727  // Given a target with one dirty input,
728  // we should rebuild the target.
729  Dirty("cat1");
730  string err;
731  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
732  ASSERT_EQ("", err);
733  EXPECT_TRUE(builder_.Build(&err));
734  EXPECT_EQ("", err);
735 
736  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
737  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
738 }
739 
740 TEST_F(BuildTest, TwoStep) {
741  string err;
742  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
743  ASSERT_EQ("", err);
744  EXPECT_TRUE(builder_.Build(&err));
745  EXPECT_EQ("", err);
746  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
747  // Depending on how the pointers work out, we could've ran
748  // the first two commands in either order.
749  EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
750  command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
751  (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
752  command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
753 
754  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
755 
756  fs_.Tick();
757 
758  // Modifying in2 requires rebuilding one intermediate file
759  // and the final file.
760  fs_.Create("in2", "");
761  state_.Reset();
762  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
763  ASSERT_EQ("", err);
764  EXPECT_TRUE(builder_.Build(&err));
765  ASSERT_EQ("", err);
766  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
767  EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
768  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
769 }
770 
771 TEST_F(BuildTest, TwoOutputs) {
773 "rule touch\n"
774 " command = touch $out\n"
775 "build out1 out2: touch in.txt\n"));
776 
777  fs_.Create("in.txt", "");
778 
779  string err;
780  EXPECT_TRUE(builder_.AddTarget("out1", &err));
781  ASSERT_EQ("", err);
782  EXPECT_TRUE(builder_.Build(&err));
783  EXPECT_EQ("", err);
784  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
785  EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
786 }
787 
788 TEST_F(BuildTest, ImplicitOutput) {
790 "rule touch\n"
791 " command = touch $out $out.imp\n"
792 "build out | out.imp: touch in.txt\n"));
793  fs_.Create("in.txt", "");
794 
795  string err;
796  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
797  ASSERT_EQ("", err);
798  EXPECT_TRUE(builder_.Build(&err));
799  EXPECT_EQ("", err);
800  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
801  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[0]);
802 }
803 
804 // Test case from
805 // https://github.com/ninja-build/ninja/issues/148
806 TEST_F(BuildTest, MultiOutIn) {
808 "rule touch\n"
809 " command = touch $out\n"
810 "build in1 otherfile: touch in\n"
811 "build out: touch in | in1\n"));
812 
813  fs_.Create("in", "");
814  fs_.Tick();
815  fs_.Create("in1", "");
816 
817  string err;
818  EXPECT_TRUE(builder_.AddTarget("out", &err));
819  ASSERT_EQ("", err);
820  EXPECT_TRUE(builder_.Build(&err));
821  EXPECT_EQ("", err);
822 }
823 
824 TEST_F(BuildTest, Chain) {
826 "build c2: cat c1\n"
827 "build c3: cat c2\n"
828 "build c4: cat c3\n"
829 "build c5: cat c4\n"));
830 
831  fs_.Create("c1", "");
832 
833  string err;
834  EXPECT_TRUE(builder_.AddTarget("c5", &err));
835  ASSERT_EQ("", err);
836  EXPECT_TRUE(builder_.Build(&err));
837  EXPECT_EQ("", err);
838  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
839 
840  err.clear();
841  command_runner_.commands_ran_.clear();
842  state_.Reset();
843  EXPECT_TRUE(builder_.AddTarget("c5", &err));
844  ASSERT_EQ("", err);
845  EXPECT_TRUE(builder_.AlreadyUpToDate());
846 
847  fs_.Tick();
848 
849  fs_.Create("c3", "");
850  err.clear();
851  command_runner_.commands_ran_.clear();
852  state_.Reset();
853  EXPECT_TRUE(builder_.AddTarget("c5", &err));
854  ASSERT_EQ("", err);
855  EXPECT_FALSE(builder_.AlreadyUpToDate());
856  EXPECT_TRUE(builder_.Build(&err));
857  ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // 3->4, 4->5
858 }
859 
860 TEST_F(BuildTest, MissingInput) {
861  // Input is referenced by build file, but no rule for it.
862  string err;
863  Dirty("in1");
864  EXPECT_FALSE(builder_.AddTarget("cat1", &err));
865  EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
866  err);
867 }
868 
869 TEST_F(BuildTest, MissingTarget) {
870  // Target is not referenced by build file.
871  string err;
872  EXPECT_FALSE(builder_.AddTarget("meow", &err));
873  EXPECT_EQ("unknown target: 'meow'", err);
874 }
875 
876 TEST_F(BuildTest, MakeDirs) {
877  string err;
878 
879 #ifdef _WIN32
881  "build subdir\\dir2\\file: cat in1\n"));
882 #else
884  "build subdir/dir2/file: cat in1\n"));
885 #endif
886  EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
887 
888  EXPECT_EQ("", err);
889  EXPECT_TRUE(builder_.Build(&err));
890  ASSERT_EQ("", err);
891  ASSERT_EQ(2u, fs_.directories_made_.size());
892  EXPECT_EQ("subdir", fs_.directories_made_[0]);
893  EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
894 }
895 
896 TEST_F(BuildTest, DepFileMissing) {
897  string err;
899 "rule cc\n command = cc $in\n depfile = $out.d\n"
900 "build fo$ o.o: cc foo.c\n"));
901  fs_.Create("foo.c", "");
902 
903  EXPECT_TRUE(builder_.AddTarget("fo o.o", &err));
904  ASSERT_EQ("", err);
905  ASSERT_EQ(1u, fs_.files_read_.size());
906  EXPECT_EQ("fo o.o.d", fs_.files_read_[0]);
907 }
908 
909 TEST_F(BuildTest, DepFileOK) {
910  string err;
911  int orig_edges = state_.edges_.size();
913 "rule cc\n command = cc $in\n depfile = $out.d\n"
914 "build foo.o: cc foo.c\n"));
915  Edge* edge = state_.edges_.back();
916 
917  fs_.Create("foo.c", "");
918  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
919  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
920  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
921  ASSERT_EQ("", err);
922  ASSERT_EQ(1u, fs_.files_read_.size());
923  EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
924 
925  // Expect three new edges: one generating foo.o, and two more from
926  // loading the depfile.
927  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
928  // Expect our edge to now have three inputs: foo.c and two headers.
929  ASSERT_EQ(3u, edge->inputs_.size());
930 
931  // Expect the command line we generate to only use the original input.
932  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
933 }
934 
935 TEST_F(BuildTest, DepFileParseError) {
936  string err;
938 "rule cc\n command = cc $in\n depfile = $out.d\n"
939 "build foo.o: cc foo.c\n"));
940  fs_.Create("foo.c", "");
941  fs_.Create("foo.o.d", "randomtext\n");
942  EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
943  EXPECT_EQ("foo.o.d: expected ':' in depfile", err);
944 }
945 
946 TEST_F(BuildTest, EncounterReadyTwice) {
947  string err;
949 "rule touch\n"
950 " command = touch $out\n"
951 "build c: touch\n"
952 "build b: touch || c\n"
953 "build a: touch | b || c\n"));
954 
955  vector<Edge*> c_out = GetNode("c")->out_edges();
956  ASSERT_EQ(2u, c_out.size());
957  EXPECT_EQ("b", c_out[0]->outputs_[0]->path());
958  EXPECT_EQ("a", c_out[1]->outputs_[0]->path());
959 
960  fs_.Create("b", "");
961  EXPECT_TRUE(builder_.AddTarget("a", &err));
962  ASSERT_EQ("", err);
963 
964  EXPECT_TRUE(builder_.Build(&err));
965  ASSERT_EQ("", err);
966  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
967 }
968 
969 TEST_F(BuildTest, OrderOnlyDeps) {
970  string err;
972 "rule cc\n command = cc $in\n depfile = $out.d\n"
973 "build foo.o: cc foo.c || otherfile\n"));
974  Edge* edge = state_.edges_.back();
975 
976  fs_.Create("foo.c", "");
977  fs_.Create("otherfile", "");
978  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
979  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
980  ASSERT_EQ("", err);
981 
982  // One explicit, two implicit, one order only.
983  ASSERT_EQ(4u, edge->inputs_.size());
984  EXPECT_EQ(2, edge->implicit_deps_);
985  EXPECT_EQ(1, edge->order_only_deps_);
986  // Verify the inputs are in the order we expect
987  // (explicit then implicit then orderonly).
988  EXPECT_EQ("foo.c", edge->inputs_[0]->path());
989  EXPECT_EQ("blah.h", edge->inputs_[1]->path());
990  EXPECT_EQ("bar.h", edge->inputs_[2]->path());
991  EXPECT_EQ("otherfile", edge->inputs_[3]->path());
992 
993  // Expect the command line we generate to only use the original input.
994  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
995 
996  // explicit dep dirty, expect a rebuild.
997  EXPECT_TRUE(builder_.Build(&err));
998  ASSERT_EQ("", err);
999  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1000 
1001  fs_.Tick();
1002 
1003  // Recreate the depfile, as it should have been deleted by the build.
1004  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1005 
1006  // implicit dep dirty, expect a rebuild.
1007  fs_.Create("blah.h", "");
1008  fs_.Create("bar.h", "");
1009  command_runner_.commands_ran_.clear();
1010  state_.Reset();
1011  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1012  EXPECT_TRUE(builder_.Build(&err));
1013  ASSERT_EQ("", err);
1014  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1015 
1016  fs_.Tick();
1017 
1018  // Recreate the depfile, as it should have been deleted by the build.
1019  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1020 
1021  // order only dep dirty, no rebuild.
1022  fs_.Create("otherfile", "");
1023  command_runner_.commands_ran_.clear();
1024  state_.Reset();
1025  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1026  EXPECT_EQ("", err);
1027  EXPECT_TRUE(builder_.AlreadyUpToDate());
1028 
1029  // implicit dep missing, expect rebuild.
1030  fs_.RemoveFile("bar.h");
1031  command_runner_.commands_ran_.clear();
1032  state_.Reset();
1033  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1034  EXPECT_TRUE(builder_.Build(&err));
1035  ASSERT_EQ("", err);
1036  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1037 }
1038 
1039 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
1040  string err;
1042 "rule cc\n command = cc $in\n"
1043 "rule true\n command = true\n"
1044 "build oo.h: cc oo.h.in\n"
1045 "build foo.o: cc foo.c || oo.h\n"));
1046 
1047  fs_.Create("foo.c", "");
1048  fs_.Create("oo.h.in", "");
1049 
1050  // foo.o and order-only dep dirty, build both.
1051  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1052  EXPECT_TRUE(builder_.Build(&err));
1053  ASSERT_EQ("", err);
1054  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1055 
1056  // all clean, no rebuild.
1057  command_runner_.commands_ran_.clear();
1058  state_.Reset();
1059  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1060  EXPECT_EQ("", err);
1061  EXPECT_TRUE(builder_.AlreadyUpToDate());
1062 
1063  // order-only dep missing, build it only.
1064  fs_.RemoveFile("oo.h");
1065  command_runner_.commands_ran_.clear();
1066  state_.Reset();
1067  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1068  EXPECT_TRUE(builder_.Build(&err));
1069  ASSERT_EQ("", err);
1070  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1071  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1072 
1073  fs_.Tick();
1074 
1075  // order-only dep dirty, build it only.
1076  fs_.Create("oo.h.in", "");
1077  command_runner_.commands_ran_.clear();
1078  state_.Reset();
1079  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1080  EXPECT_TRUE(builder_.Build(&err));
1081  ASSERT_EQ("", err);
1082  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1083  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1084 }
1085 
1086 #ifdef _WIN32
1087 TEST_F(BuildTest, DepFileCanonicalize) {
1088  string err;
1089  int orig_edges = state_.edges_.size();
1091 "rule cc\n command = cc $in\n depfile = $out.d\n"
1092 "build gen/stuff\\things/foo.o: cc x\\y/z\\foo.c\n"));
1093  Edge* edge = state_.edges_.back();
1094 
1095  fs_.Create("x/y/z/foo.c", "");
1096  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
1097  // Note, different slashes from manifest.
1098  fs_.Create("gen/stuff\\things/foo.o.d",
1099  "gen\\stuff\\things\\foo.o: blah.h bar.h\n");
1100  EXPECT_TRUE(builder_.AddTarget("gen/stuff/things/foo.o", &err));
1101  ASSERT_EQ("", err);
1102  ASSERT_EQ(1u, fs_.files_read_.size());
1103  // The depfile path does not get Canonicalize as it seems unnecessary.
1104  EXPECT_EQ("gen/stuff\\things/foo.o.d", fs_.files_read_[0]);
1105 
1106  // Expect three new edges: one generating foo.o, and two more from
1107  // loading the depfile.
1108  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
1109  // Expect our edge to now have three inputs: foo.c and two headers.
1110  ASSERT_EQ(3u, edge->inputs_.size());
1111 
1112  // Expect the command line we generate to only use the original input, and
1113  // using the slashes from the manifest.
1114  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
1115 }
1116 #endif
1117 
1119  string err;
1121 "build out: cat bar.cc\n"
1122 "build all: phony out\n"));
1123  fs_.Create("bar.cc", "");
1124 
1125  EXPECT_TRUE(builder_.AddTarget("all", &err));
1126  ASSERT_EQ("", err);
1127 
1128  // Only one command to run, because phony runs no command.
1129  EXPECT_FALSE(builder_.AlreadyUpToDate());
1130  EXPECT_TRUE(builder_.Build(&err));
1131  ASSERT_EQ("", err);
1132  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1133 }
1134 
1135 TEST_F(BuildTest, PhonyNoWork) {
1136  string err;
1138 "build out: cat bar.cc\n"
1139 "build all: phony out\n"));
1140  fs_.Create("bar.cc", "");
1141  fs_.Create("out", "");
1142 
1143  EXPECT_TRUE(builder_.AddTarget("all", &err));
1144  ASSERT_EQ("", err);
1145  EXPECT_TRUE(builder_.AlreadyUpToDate());
1146 }
1147 
1148 // Test a self-referencing phony. Ideally this should not work, but
1149 // ninja 1.7 and below tolerated and CMake 2.8.12.x and 3.0.x both
1150 // incorrectly produce it. We tolerate it for compatibility.
1151 TEST_F(BuildTest, PhonySelfReference) {
1152  string err;
1154 "build a: phony a\n"));
1155 
1156  EXPECT_TRUE(builder_.AddTarget("a", &err));
1157  ASSERT_EQ("", err);
1158  EXPECT_TRUE(builder_.AlreadyUpToDate());
1159 }
1160 
1163 "rule fail\n"
1164 " command = fail\n"
1165 "build out1: fail\n"));
1166 
1167  string err;
1168  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1169  ASSERT_EQ("", err);
1170 
1171  EXPECT_FALSE(builder_.Build(&err));
1172  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1173  ASSERT_EQ("subcommand failed", err);
1174 }
1175 
1176 TEST_F(BuildTest, SwallowFailures) {
1178 "rule fail\n"
1179 " command = fail\n"
1180 "build out1: fail\n"
1181 "build out2: fail\n"
1182 "build out3: fail\n"
1183 "build all: phony out1 out2 out3\n"));
1184 
1185  // Swallow two failures, die on the third.
1186  config_.failures_allowed = 3;
1187 
1188  string err;
1189  EXPECT_TRUE(builder_.AddTarget("all", &err));
1190  ASSERT_EQ("", err);
1191 
1192  EXPECT_FALSE(builder_.Build(&err));
1193  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1194  ASSERT_EQ("subcommands failed", err);
1195 }
1196 
1197 TEST_F(BuildTest, SwallowFailuresLimit) {
1199 "rule fail\n"
1200 " command = fail\n"
1201 "build out1: fail\n"
1202 "build out2: fail\n"
1203 "build out3: fail\n"
1204 "build final: cat out1 out2 out3\n"));
1205 
1206  // Swallow ten failures; we should stop before building final.
1207  config_.failures_allowed = 11;
1208 
1209  string err;
1210  EXPECT_TRUE(builder_.AddTarget("final", &err));
1211  ASSERT_EQ("", err);
1212 
1213  EXPECT_FALSE(builder_.Build(&err));
1214  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1215  ASSERT_EQ("cannot make progress due to previous errors", err);
1216 }
1217 
1218 TEST_F(BuildTest, SwallowFailuresPool) {
1220 "pool failpool\n"
1221 " depth = 1\n"
1222 "rule fail\n"
1223 " command = fail\n"
1224 " pool = failpool\n"
1225 "build out1: fail\n"
1226 "build out2: fail\n"
1227 "build out3: fail\n"
1228 "build final: cat out1 out2 out3\n"));
1229 
1230  // Swallow ten failures; we should stop before building final.
1231  config_.failures_allowed = 11;
1232 
1233  string err;
1234  EXPECT_TRUE(builder_.AddTarget("final", &err));
1235  ASSERT_EQ("", err);
1236 
1237  EXPECT_FALSE(builder_.Build(&err));
1238  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1239  ASSERT_EQ("cannot make progress due to previous errors", err);
1240 }
1241 
1242 TEST_F(BuildTest, PoolEdgesReadyButNotWanted) {
1243  fs_.Create("x", "");
1244 
1245  const char* manifest =
1246  "pool some_pool\n"
1247  " depth = 4\n"
1248  "rule touch\n"
1249  " command = touch $out\n"
1250  " pool = some_pool\n"
1251  "rule cc\n"
1252  " command = touch grit\n"
1253  "\n"
1254  "build B.d.stamp: cc | x\n"
1255  "build C.stamp: touch B.d.stamp\n"
1256  "build final.stamp: touch || C.stamp\n";
1257 
1258  RebuildTarget("final.stamp", manifest);
1259 
1260  fs_.RemoveFile("B.d.stamp");
1261 
1262  State save_state;
1263  RebuildTarget("final.stamp", manifest, NULL, NULL, &save_state);
1264  EXPECT_GE(save_state.LookupPool("some_pool")->current_use(), 0);
1265 }
1266 
1267 struct BuildWithLogTest : public BuildTest {
1269  builder_.SetBuildLog(&build_log_);
1270  }
1271 
1273 };
1274 
1275 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1277 "rule cc\n"
1278 " command = cc\n"
1279 "build out1: cc in\n"));
1280 
1281  // Create input/output that would be considered up to date when
1282  // not considering the command line hash.
1283  fs_.Create("in", "");
1284  fs_.Create("out1", "");
1285  string err;
1286 
1287  // Because it's not in the log, it should not be up-to-date until
1288  // we build again.
1289  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1290  EXPECT_FALSE(builder_.AlreadyUpToDate());
1291 
1292  command_runner_.commands_ran_.clear();
1293  state_.Reset();
1294 
1295  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1296  EXPECT_TRUE(builder_.Build(&err));
1297  EXPECT_TRUE(builder_.AlreadyUpToDate());
1298 }
1299 
1300 TEST_F(BuildWithLogTest, RebuildAfterFailure) {
1302 "rule touch-fail-tick2\n"
1303 " command = touch-fail-tick2\n"
1304 "build out1: touch-fail-tick2 in\n"));
1305 
1306  string err;
1307 
1308  fs_.Create("in", "");
1309 
1310  // Run once successfully to get out1 in the log
1311  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1312  EXPECT_TRUE(builder_.Build(&err));
1313  EXPECT_EQ("", err);
1314  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1315 
1316  command_runner_.commands_ran_.clear();
1317  state_.Reset();
1318  builder_.Cleanup();
1319  builder_.plan_.Reset();
1320 
1321  fs_.Tick();
1322  fs_.Create("in", "");
1323 
1324  // Run again with a failure that updates the output file timestamp
1325  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1326  EXPECT_FALSE(builder_.Build(&err));
1327  EXPECT_EQ("subcommand failed", err);
1328  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1329 
1330  command_runner_.commands_ran_.clear();
1331  state_.Reset();
1332  builder_.Cleanup();
1333  builder_.plan_.Reset();
1334 
1335  fs_.Tick();
1336 
1337  // Run again, should rerun even though the output file is up to date on disk
1338  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1339  EXPECT_FALSE(builder_.AlreadyUpToDate());
1340  EXPECT_TRUE(builder_.Build(&err));
1341  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1342  EXPECT_EQ("", err);
1343 }
1344 
1345 TEST_F(BuildWithLogTest, RebuildWithNoInputs) {
1347 "rule touch\n"
1348 " command = touch\n"
1349 "build out1: touch\n"
1350 "build out2: touch in\n"));
1351 
1352  string err;
1353 
1354  fs_.Create("in", "");
1355 
1356  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1357  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1358  EXPECT_TRUE(builder_.Build(&err));
1359  EXPECT_EQ("", err);
1360  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
1361 
1362  command_runner_.commands_ran_.clear();
1363  state_.Reset();
1364 
1365  fs_.Tick();
1366 
1367  fs_.Create("in", "");
1368 
1369  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1370  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1371  EXPECT_TRUE(builder_.Build(&err));
1372  EXPECT_EQ("", err);
1373  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1374 }
1375 
1376 TEST_F(BuildWithLogTest, RestatTest) {
1378 "rule true\n"
1379 " command = true\n"
1380 " restat = 1\n"
1381 "rule cc\n"
1382 " command = cc\n"
1383 " restat = 1\n"
1384 "build out1: cc in\n"
1385 "build out2: true out1\n"
1386 "build out3: cat out2\n"));
1387 
1388  fs_.Create("out1", "");
1389  fs_.Create("out2", "");
1390  fs_.Create("out3", "");
1391 
1392  fs_.Tick();
1393 
1394  fs_.Create("in", "");
1395 
1396  // Do a pre-build so that there's commands in the log for the outputs,
1397  // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1398  // regardless of restat.
1399  string err;
1400  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1401  ASSERT_EQ("", err);
1402  EXPECT_TRUE(builder_.Build(&err));
1403  ASSERT_EQ("", err);
1404  EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]",
1406  command_runner_.commands_ran_.clear();
1407  state_.Reset();
1408 
1409  fs_.Tick();
1410 
1411  fs_.Create("in", "");
1412  // "cc" touches out1, so we should build out2. But because "true" does not
1413  // touch out2, we should cancel the build of out3.
1414  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1415  ASSERT_EQ("", err);
1416  EXPECT_TRUE(builder_.Build(&err));
1417  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1418 
1419  // If we run again, it should be a no-op, because the build log has recorded
1420  // that we've already built out2 with an input timestamp of 2 (from out1).
1421  command_runner_.commands_ran_.clear();
1422  state_.Reset();
1423  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1424  ASSERT_EQ("", err);
1425  EXPECT_TRUE(builder_.AlreadyUpToDate());
1426 
1427  fs_.Tick();
1428 
1429  fs_.Create("in", "");
1430 
1431  // The build log entry should not, however, prevent us from rebuilding out2
1432  // if out1 changes.
1433  command_runner_.commands_ran_.clear();
1434  state_.Reset();
1435  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1436  ASSERT_EQ("", err);
1437  EXPECT_TRUE(builder_.Build(&err));
1438  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1439 }
1440 
1441 TEST_F(BuildWithLogTest, RestatMissingFile) {
1442  // If a restat rule doesn't create its output, and the output didn't
1443  // exist before the rule was run, consider that behavior equivalent
1444  // to a rule that doesn't modify its existent output file.
1445 
1447 "rule true\n"
1448 " command = true\n"
1449 " restat = 1\n"
1450 "rule cc\n"
1451 " command = cc\n"
1452 "build out1: true in\n"
1453 "build out2: cc out1\n"));
1454 
1455  fs_.Create("in", "");
1456  fs_.Create("out2", "");
1457 
1458  // Do a pre-build so that there's commands in the log for the outputs,
1459  // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1460  // regardless of restat.
1461  string err;
1462  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1463  ASSERT_EQ("", err);
1464  EXPECT_TRUE(builder_.Build(&err));
1465  ASSERT_EQ("", err);
1466  command_runner_.commands_ran_.clear();
1467  state_.Reset();
1468 
1469  fs_.Tick();
1470  fs_.Create("in", "");
1471  fs_.Create("out2", "");
1472 
1473  // Run a build, expect only the first command to run.
1474  // It doesn't touch its output (due to being the "true" command), so
1475  // we shouldn't run the dependent build.
1476  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1477  ASSERT_EQ("", err);
1478  EXPECT_TRUE(builder_.Build(&err));
1479  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1480 }
1481 
1482 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1484  "rule true\n"
1485  " command = true\n"
1486  " restat = 1\n"
1487  "rule touch\n"
1488  " command = touch\n"
1489  "build out1: true in\n"
1490  "build out2 out3: touch out1\n"
1491  "build out4: touch out2\n"
1492  ));
1493 
1494  // Create the necessary files
1495  fs_.Create("in", "");
1496 
1497  string err;
1498  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1499  ASSERT_EQ("", err);
1500  EXPECT_TRUE(builder_.Build(&err));
1501  ASSERT_EQ("", err);
1502  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1503 
1504  fs_.Tick();
1505  fs_.Create("in", "");
1506  fs_.RemoveFile("out3");
1507 
1508  // Since "in" is missing, out1 will be built. Since "out3" is missing,
1509  // out2 and out3 will be built even though "in" is not touched when built.
1510  // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1511  // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1512  // cleard.
1513  command_runner_.commands_ran_.clear();
1514  state_.Reset();
1515  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1516  ASSERT_EQ("", err);
1517  EXPECT_TRUE(builder_.Build(&err));
1518  ASSERT_EQ("", err);
1519  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1520 }
1521 
1522 // Test scenario, in which an input file is removed, but output isn't changed
1523 // https://github.com/ninja-build/ninja/issues/295
1524 TEST_F(BuildWithLogTest, RestatMissingInput) {
1526  "rule true\n"
1527  " command = true\n"
1528  " depfile = $out.d\n"
1529  " restat = 1\n"
1530  "rule cc\n"
1531  " command = cc\n"
1532  "build out1: true in\n"
1533  "build out2: cc out1\n"));
1534 
1535  // Create all necessary files
1536  fs_.Create("in", "");
1537 
1538  // The implicit dependencies and the depfile itself
1539  // are newer than the output
1540  TimeStamp restat_mtime = fs_.Tick();
1541  fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1542  fs_.Create("will.be.deleted", "");
1543  fs_.Create("restat.file", "");
1544 
1545  // Run the build, out1 and out2 get built
1546  string err;
1547  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1548  ASSERT_EQ("", err);
1549  EXPECT_TRUE(builder_.Build(&err));
1550  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1551 
1552  // See that an entry in the logfile is created, capturing
1553  // the right mtime
1554  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1555  ASSERT_TRUE(NULL != log_entry);
1556  ASSERT_EQ(restat_mtime, log_entry->mtime);
1557 
1558  // Now remove a file, referenced from depfile, so that target becomes
1559  // dirty, but the output does not change
1560  fs_.RemoveFile("will.be.deleted");
1561 
1562  // Trigger the build again - only out1 gets built
1563  command_runner_.commands_ran_.clear();
1564  state_.Reset();
1565  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1566  ASSERT_EQ("", err);
1567  EXPECT_TRUE(builder_.Build(&err));
1568  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1569 
1570  // Check that the logfile entry remains correctly set
1571  log_entry = build_log_.LookupByOutput("out1");
1572  ASSERT_TRUE(NULL != log_entry);
1573  ASSERT_EQ(restat_mtime, log_entry->mtime);
1574 }
1575 
1578  config_.dry_run = true;
1579  }
1580 };
1581 
1582 TEST_F(BuildDryRun, AllCommandsShown) {
1584 "rule true\n"
1585 " command = true\n"
1586 " restat = 1\n"
1587 "rule cc\n"
1588 " command = cc\n"
1589 " restat = 1\n"
1590 "build out1: cc in\n"
1591 "build out2: true out1\n"
1592 "build out3: cat out2\n"));
1593 
1594  fs_.Create("out1", "");
1595  fs_.Create("out2", "");
1596  fs_.Create("out3", "");
1597 
1598  fs_.Tick();
1599 
1600  fs_.Create("in", "");
1601 
1602  // "cc" touches out1, so we should build out2. But because "true" does not
1603  // touch out2, we should cancel the build of out3.
1604  string err;
1605  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1606  ASSERT_EQ("", err);
1607  EXPECT_TRUE(builder_.Build(&err));
1608  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1609 }
1610 
1611 // Test that RSP files are created when & where appropriate and deleted after
1612 // successful execution.
1613 TEST_F(BuildTest, RspFileSuccess)
1614 {
1616  "rule cat_rsp\n"
1617  " command = cat $rspfile > $out\n"
1618  " rspfile = $rspfile\n"
1619  " rspfile_content = $long_command\n"
1620  "rule cat_rsp_out\n"
1621  " command = cat $rspfile > $out\n"
1622  " rspfile = $out.rsp\n"
1623  " rspfile_content = $long_command\n"
1624  "build out1: cat in\n"
1625  "build out2: cat_rsp in\n"
1626  " rspfile = out 2.rsp\n"
1627  " long_command = Some very long command\n"
1628  "build out$ 3: cat_rsp_out in\n"
1629  " long_command = Some very long command\n"));
1630 
1631  fs_.Create("out1", "");
1632  fs_.Create("out2", "");
1633  fs_.Create("out 3", "");
1634 
1635  fs_.Tick();
1636 
1637  fs_.Create("in", "");
1638 
1639  string err;
1640  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1641  ASSERT_EQ("", err);
1642  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1643  ASSERT_EQ("", err);
1644  EXPECT_TRUE(builder_.AddTarget("out 3", &err));
1645  ASSERT_EQ("", err);
1646 
1647  size_t files_created = fs_.files_created_.size();
1648  size_t files_removed = fs_.files_removed_.size();
1649 
1650  EXPECT_TRUE(builder_.Build(&err));
1651  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1652 
1653  // The RSP files were created
1654  ASSERT_EQ(files_created + 2, fs_.files_created_.size());
1655  ASSERT_EQ(1u, fs_.files_created_.count("out 2.rsp"));
1656  ASSERT_EQ(1u, fs_.files_created_.count("out 3.rsp"));
1657 
1658  // The RSP files were removed
1659  ASSERT_EQ(files_removed + 2, fs_.files_removed_.size());
1660  ASSERT_EQ(1u, fs_.files_removed_.count("out 2.rsp"));
1661  ASSERT_EQ(1u, fs_.files_removed_.count("out 3.rsp"));
1662 }
1663 
1664 // Test that RSP file is created but not removed for commands, which fail
1665 TEST_F(BuildTest, RspFileFailure) {
1667  "rule fail\n"
1668  " command = fail\n"
1669  " rspfile = $rspfile\n"
1670  " rspfile_content = $long_command\n"
1671  "build out: fail in\n"
1672  " rspfile = out.rsp\n"
1673  " long_command = Another very long command\n"));
1674 
1675  fs_.Create("out", "");
1676  fs_.Tick();
1677  fs_.Create("in", "");
1678 
1679  string err;
1680  EXPECT_TRUE(builder_.AddTarget("out", &err));
1681  ASSERT_EQ("", err);
1682 
1683  size_t files_created = fs_.files_created_.size();
1684  size_t files_removed = fs_.files_removed_.size();
1685 
1686  EXPECT_FALSE(builder_.Build(&err));
1687  ASSERT_EQ("subcommand failed", err);
1688  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1689 
1690  // The RSP file was created
1691  ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1692  ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1693 
1694  // The RSP file was NOT removed
1695  ASSERT_EQ(files_removed, fs_.files_removed_.size());
1696  ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1697 
1698  // The RSP file contains what it should
1699  ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1700 }
1701 
1702 // Test that contents of the RSP file behaves like a regular part of
1703 // command line, i.e. triggers a rebuild if changed
1704 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1706  "rule cat_rsp\n"
1707  " command = cat $rspfile > $out\n"
1708  " rspfile = $rspfile\n"
1709  " rspfile_content = $long_command\n"
1710  "build out: cat_rsp in\n"
1711  " rspfile = out.rsp\n"
1712  " long_command = Original very long command\n"));
1713 
1714  fs_.Create("out", "");
1715  fs_.Tick();
1716  fs_.Create("in", "");
1717 
1718  string err;
1719  EXPECT_TRUE(builder_.AddTarget("out", &err));
1720  ASSERT_EQ("", err);
1721 
1722  // 1. Build for the 1st time (-> populate log)
1723  EXPECT_TRUE(builder_.Build(&err));
1724  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1725 
1726  // 2. Build again (no change)
1727  command_runner_.commands_ran_.clear();
1728  state_.Reset();
1729  EXPECT_TRUE(builder_.AddTarget("out", &err));
1730  EXPECT_EQ("", err);
1731  ASSERT_TRUE(builder_.AlreadyUpToDate());
1732 
1733  // 3. Alter the entry in the logfile
1734  // (to simulate a change in the command line between 2 builds)
1735  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1736  ASSERT_TRUE(NULL != log_entry);
1738  "cat out.rsp > out;rspfile=Original very long command",
1739  log_entry->command_hash));
1740  log_entry->command_hash++; // Change the command hash to something else.
1741  // Now expect the target to be rebuilt
1742  command_runner_.commands_ran_.clear();
1743  state_.Reset();
1744  EXPECT_TRUE(builder_.AddTarget("out", &err));
1745  EXPECT_EQ("", err);
1746  EXPECT_TRUE(builder_.Build(&err));
1747  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1748 }
1749 
1750 TEST_F(BuildTest, InterruptCleanup) {
1752 "rule interrupt\n"
1753 " command = interrupt\n"
1754 "rule touch-interrupt\n"
1755 " command = touch-interrupt\n"
1756 "build out1: interrupt in1\n"
1757 "build out2: touch-interrupt in2\n"));
1758 
1759  fs_.Create("out1", "");
1760  fs_.Create("out2", "");
1761  fs_.Tick();
1762  fs_.Create("in1", "");
1763  fs_.Create("in2", "");
1764 
1765  // An untouched output of an interrupted command should be retained.
1766  string err;
1767  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1768  EXPECT_EQ("", err);
1769  EXPECT_FALSE(builder_.Build(&err));
1770  EXPECT_EQ("interrupted by user", err);
1771  builder_.Cleanup();
1772  EXPECT_GT(fs_.Stat("out1", &err), 0);
1773  err = "";
1774 
1775  // A touched output of an interrupted command should be deleted.
1776  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1777  EXPECT_EQ("", err);
1778  EXPECT_FALSE(builder_.Build(&err));
1779  EXPECT_EQ("interrupted by user", err);
1780  builder_.Cleanup();
1781  EXPECT_EQ(0, fs_.Stat("out2", &err));
1782 }
1783 
1784 TEST_F(BuildTest, StatFailureAbortsBuild) {
1785  const string kTooLongToStat(400, 'i');
1787 ("build " + kTooLongToStat + ": cat in\n").c_str()));
1788  fs_.Create("in", "");
1789 
1790  // This simulates a stat failure:
1791  fs_.files_[kTooLongToStat].mtime = -1;
1792  fs_.files_[kTooLongToStat].stat_error = "stat failed";
1793 
1794  string err;
1795  EXPECT_FALSE(builder_.AddTarget(kTooLongToStat, &err));
1796  EXPECT_EQ("stat failed", err);
1797 }
1798 
1799 TEST_F(BuildTest, PhonyWithNoInputs) {
1801 "build nonexistent: phony\n"
1802 "build out1: cat || nonexistent\n"
1803 "build out2: cat nonexistent\n"));
1804  fs_.Create("out1", "");
1805  fs_.Create("out2", "");
1806 
1807  // out1 should be up to date even though its input is dirty, because its
1808  // order-only dependency has nothing to do.
1809  string err;
1810  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1811  ASSERT_EQ("", err);
1812  EXPECT_TRUE(builder_.AlreadyUpToDate());
1813 
1814  // out2 should still be out of date though, because its input is dirty.
1815  err.clear();
1816  command_runner_.commands_ran_.clear();
1817  state_.Reset();
1818  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1819  ASSERT_EQ("", err);
1820  EXPECT_TRUE(builder_.Build(&err));
1821  EXPECT_EQ("", err);
1822  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1823 }
1824 
1825 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1827 "rule cc\n"
1828 " command = cc\n"
1829 " deps = gcc\n"
1830 "build out: cc\n"));
1831  Dirty("out");
1832 
1833  string err;
1834  EXPECT_TRUE(builder_.AddTarget("out", &err));
1835  ASSERT_EQ("", err);
1836  EXPECT_FALSE(builder_.AlreadyUpToDate());
1837 
1838  EXPECT_FALSE(builder_.Build(&err));
1839  ASSERT_EQ("subcommand failed", err);
1840  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1841 }
1842 
1843 TEST_F(BuildTest, StatusFormatElapsed) {
1844  status_.BuildStarted();
1845  // Before any task is done, the elapsed time must be zero.
1846  EXPECT_EQ("[%/e0.000]",
1847  status_.FormatProgressStatus("[%%/e%e]",
1849 }
1850 
1851 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1852  EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1853  status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]",
1855 }
1856 
1857 TEST_F(BuildTest, FailedDepsParse) {
1859 "build bad_deps.o: cat in1\n"
1860 " deps = gcc\n"
1861 " depfile = in1.d\n"));
1862 
1863  string err;
1864  EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1865  ASSERT_EQ("", err);
1866 
1867  // These deps will fail to parse, as they should only have one
1868  // path to the left of the colon.
1869  fs_.Create("in1.d", "AAA BBB");
1870 
1871  EXPECT_FALSE(builder_.Build(&err));
1872  EXPECT_EQ("subcommand failed", err);
1873 }
1874 
1877  }
1878 
1880  log_.Close();
1881  }
1882 
1883  virtual void SetUp() {
1884  BuildTest::SetUp();
1885 
1886  temp_dir_.CreateAndEnter("BuildWithQueryDepsLogTest");
1887 
1888  std::string err;
1889  ASSERT_TRUE(log_.OpenForWrite("ninja_deps", &err));
1890  ASSERT_EQ("", err);
1891  }
1892 
1894 
1896 };
1897 
1898 /// Test a MSVC-style deps log with multiple outputs.
1899 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileMSVC) {
1901 "rule cp_multi_msvc\n"
1902 " command = echo 'using $in' && for file in $out; do cp $in $$file; done\n"
1903 " deps = msvc\n"
1904 " msvc_deps_prefix = using \n"
1905 "build out1 out2: cp_multi_msvc in1\n"));
1906 
1907  std::string err;
1908  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1909  ASSERT_EQ("", err);
1910  EXPECT_TRUE(builder_.Build(&err));
1911  EXPECT_EQ("", err);
1912  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1913  EXPECT_EQ("echo 'using in1' && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1914 
1915  Node* out1_node = state_.LookupNode("out1");
1916  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1917  EXPECT_EQ(1, out1_deps->node_count);
1918  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1919 
1920  Node* out2_node = state_.LookupNode("out2");
1921  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1922  EXPECT_EQ(1, out2_deps->node_count);
1923  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1924 }
1925 
1926 /// Test a GCC-style deps log with multiple outputs.
1927 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOneLine) {
1929 "rule cp_multi_gcc\n"
1930 " command = echo '$out: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
1931 " deps = gcc\n"
1932 " depfile = in.d\n"
1933 "build out1 out2: cp_multi_gcc in1 in2\n"));
1934 
1935  std::string err;
1936  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1937  ASSERT_EQ("", err);
1938  fs_.Create("in.d", "out1 out2: in1 in2");
1939  EXPECT_TRUE(builder_.Build(&err));
1940  EXPECT_EQ("", err);
1941  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1942  EXPECT_EQ("echo 'out1 out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1943 
1944  Node* out1_node = state_.LookupNode("out1");
1945  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1946  EXPECT_EQ(2, out1_deps->node_count);
1947  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1948  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
1949 
1950  Node* out2_node = state_.LookupNode("out2");
1951  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1952  EXPECT_EQ(2, out2_deps->node_count);
1953  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1954  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
1955 }
1956 
1957 /// Test a GCC-style deps log with multiple outputs using a line per input.
1958 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineInput) {
1960 "rule cp_multi_gcc\n"
1961 " command = echo '$out: in1\\n$out: in2' > in.d && for file in $out; do cp in1 $$file; done\n"
1962 " deps = gcc\n"
1963 " depfile = in.d\n"
1964 "build out1 out2: cp_multi_gcc in1 in2\n"));
1965 
1966  std::string err;
1967  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1968  ASSERT_EQ("", err);
1969  fs_.Create("in.d", "out1 out2: in1\nout1 out2: in2");
1970  EXPECT_TRUE(builder_.Build(&err));
1971  EXPECT_EQ("", err);
1972  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1973  EXPECT_EQ("echo 'out1 out2: in1\\nout1 out2: in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
1974 
1975  Node* out1_node = state_.LookupNode("out1");
1976  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
1977  EXPECT_EQ(2, out1_deps->node_count);
1978  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
1979  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
1980 
1981  Node* out2_node = state_.LookupNode("out2");
1982  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
1983  EXPECT_EQ(2, out2_deps->node_count);
1984  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
1985  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
1986 }
1987 
1988 /// Test a GCC-style deps log with multiple outputs using a line per output.
1989 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCMultiLineOutput) {
1991 "rule cp_multi_gcc\n"
1992 " command = echo 'out1: $in\\nout2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
1993 " deps = gcc\n"
1994 " depfile = in.d\n"
1995 "build out1 out2: cp_multi_gcc in1 in2\n"));
1996 
1997  std::string err;
1998  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1999  ASSERT_EQ("", err);
2000  fs_.Create("in.d", "out1: in1 in2\nout2: in1 in2");
2001  EXPECT_TRUE(builder_.Build(&err));
2002  EXPECT_EQ("", err);
2003  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2004  EXPECT_EQ("echo 'out1: in1 in2\\nout2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2005 
2006  Node* out1_node = state_.LookupNode("out1");
2007  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2008  EXPECT_EQ(2, out1_deps->node_count);
2009  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2010  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2011 
2012  Node* out2_node = state_.LookupNode("out2");
2013  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2014  EXPECT_EQ(2, out2_deps->node_count);
2015  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2016  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2017 }
2018 
2019 /// Test a GCC-style deps log with multiple outputs mentioning only the main output.
2020 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlyMainOutput) {
2022 "rule cp_multi_gcc\n"
2023 " command = echo 'out1: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2024 " deps = gcc\n"
2025 " depfile = in.d\n"
2026 "build out1 out2: cp_multi_gcc in1 in2\n"));
2027 
2028  std::string err;
2029  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2030  ASSERT_EQ("", err);
2031  fs_.Create("in.d", "out1: in1 in2");
2032  EXPECT_TRUE(builder_.Build(&err));
2033  EXPECT_EQ("", err);
2034  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2035  EXPECT_EQ("echo 'out1: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2036 
2037  Node* out1_node = state_.LookupNode("out1");
2038  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2039  EXPECT_EQ(2, out1_deps->node_count);
2040  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2041  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2042 
2043  Node* out2_node = state_.LookupNode("out2");
2044  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2045  EXPECT_EQ(2, out2_deps->node_count);
2046  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2047  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2048 }
2049 
2050 /// Test a GCC-style deps log with multiple outputs mentioning only the secondary output.
2051 TEST_F(BuildWithQueryDepsLogTest, TwoOutputsDepFileGCCOnlySecondaryOutput) {
2052  // Note: This ends up short-circuiting the node creation due to the primary
2053  // output not being present, but it should still work.
2055 "rule cp_multi_gcc\n"
2056 " command = echo 'out2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2057 " deps = gcc\n"
2058 " depfile = in.d\n"
2059 "build out1 out2: cp_multi_gcc in1 in2\n"));
2060 
2061  std::string err;
2062  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2063  ASSERT_EQ("", err);
2064  fs_.Create("in.d", "out2: in1 in2");
2065  EXPECT_TRUE(builder_.Build(&err));
2066  EXPECT_EQ("", err);
2067  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2068  EXPECT_EQ("echo 'out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2069 
2070  Node* out1_node = state_.LookupNode("out1");
2071  DepsLog::Deps* out1_deps = log_.GetDeps(out1_node);
2072  EXPECT_EQ(2, out1_deps->node_count);
2073  EXPECT_EQ("in1", out1_deps->nodes[0]->path());
2074  EXPECT_EQ("in2", out1_deps->nodes[1]->path());
2075 
2076  Node* out2_node = state_.LookupNode("out2");
2077  DepsLog::Deps* out2_deps = log_.GetDeps(out2_node);
2078  EXPECT_EQ(2, out2_deps->node_count);
2079  EXPECT_EQ("in1", out2_deps->nodes[0]->path());
2080  EXPECT_EQ("in2", out2_deps->nodes[1]->path());
2081 }
2082 
2083 /// Tests of builds involving deps logs necessarily must span
2084 /// multiple builds. We reuse methods on BuildTest but not the
2085 /// builder_ it sets up, because we want pristine objects for
2086 /// each build.
2089 
2090  virtual void SetUp() {
2091  BuildTest::SetUp();
2092 
2093  temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
2094  }
2095 
2096  virtual void TearDown() {
2097  temp_dir_.Cleanup();
2098  }
2099 
2101 
2102  /// Shadow parent class builder_ so we don't accidentally use it.
2103  void* builder_;
2104 };
2105 
2106 /// Run a straightforwad build where the deps log is used.
2107 TEST_F(BuildWithDepsLogTest, Straightforward) {
2108  string err;
2109  // Note: in1 was created by the superclass SetUp().
2110  const char* manifest =
2111  "build out: cat in1\n"
2112  " deps = gcc\n"
2113  " depfile = in1.d\n";
2114  {
2115  State state;
2116  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2117  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2118 
2119  // Run the build once, everything should be ok.
2120  DepsLog deps_log;
2121  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2122  ASSERT_EQ("", err);
2123 
2124  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2125  builder.command_runner_.reset(&command_runner_);
2126  EXPECT_TRUE(builder.AddTarget("out", &err));
2127  ASSERT_EQ("", err);
2128  fs_.Create("in1.d", "out: in2");
2129  EXPECT_TRUE(builder.Build(&err));
2130  EXPECT_EQ("", err);
2131 
2132  // The deps file should have been removed.
2133  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2134  // Recreate it for the next step.
2135  fs_.Create("in1.d", "out: in2");
2136  deps_log.Close();
2137  builder.command_runner_.release();
2138  }
2139 
2140  {
2141  State state;
2142  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2143  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2144 
2145  // Touch the file only mentioned in the deps.
2146  fs_.Tick();
2147  fs_.Create("in2", "");
2148 
2149  // Run the build again.
2150  DepsLog deps_log;
2151  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2152  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2153 
2154  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2155  builder.command_runner_.reset(&command_runner_);
2156  command_runner_.commands_ran_.clear();
2157  EXPECT_TRUE(builder.AddTarget("out", &err));
2158  ASSERT_EQ("", err);
2159  EXPECT_TRUE(builder.Build(&err));
2160  EXPECT_EQ("", err);
2161 
2162  // We should have rebuilt the output due to in2 being
2163  // out of date.
2164  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2165 
2166  builder.command_runner_.release();
2167  }
2168 }
2169 
2170 /// Verify that obsolete dependency info causes a rebuild.
2171 /// 1) Run a successful build where everything has time t, record deps.
2172 /// 2) Move input/output to time t+1 -- despite files in alignment,
2173 /// should still need to rebuild due to deps at older time.
2175  string err;
2176  // Note: in1 was created by the superclass SetUp().
2177  const char* manifest =
2178  "build out: cat in1\n"
2179  " deps = gcc\n"
2180  " depfile = in1.d\n";
2181  {
2182  // Run an ordinary build that gathers dependencies.
2183  fs_.Create("in1", "");
2184  fs_.Create("in1.d", "out: ");
2185 
2186  State state;
2187  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2188  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2189 
2190  // Run the build once, everything should be ok.
2191  DepsLog deps_log;
2192  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2193  ASSERT_EQ("", err);
2194 
2195  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2196  builder.command_runner_.reset(&command_runner_);
2197  EXPECT_TRUE(builder.AddTarget("out", &err));
2198  ASSERT_EQ("", err);
2199  EXPECT_TRUE(builder.Build(&err));
2200  EXPECT_EQ("", err);
2201 
2202  deps_log.Close();
2203  builder.command_runner_.release();
2204  }
2205 
2206  // Push all files one tick forward so that only the deps are out
2207  // of date.
2208  fs_.Tick();
2209  fs_.Create("in1", "");
2210  fs_.Create("out", "");
2211 
2212  // The deps file should have been removed, so no need to timestamp it.
2213  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
2214 
2215  {
2216  State state;
2217  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2218  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2219 
2220  DepsLog deps_log;
2221  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2222  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2223 
2224  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2225  builder.command_runner_.reset(&command_runner_);
2226  command_runner_.commands_ran_.clear();
2227  EXPECT_TRUE(builder.AddTarget("out", &err));
2228  ASSERT_EQ("", err);
2229 
2230  // Recreate the deps file here because the build expects them to exist.
2231  fs_.Create("in1.d", "out: ");
2232 
2233  EXPECT_TRUE(builder.Build(&err));
2234  EXPECT_EQ("", err);
2235 
2236  // We should have rebuilt the output due to the deps being
2237  // out of date.
2238  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2239 
2240  builder.command_runner_.release();
2241  }
2242 }
2243 
2244 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
2245  const char* manifest =
2246  "build out: cat in1\n"
2247  " deps = gcc\n"
2248  " depfile = in1.d\n";
2249 
2250  fs_.Create("out", "");
2251  fs_.Tick();
2252  fs_.Create("in1", "");
2253 
2254  State state;
2255  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2256  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2257 
2258  // The deps log is NULL in dry runs.
2259  config_.dry_run = true;
2260  Builder builder(&state, config_, NULL, NULL, &fs_);
2261  builder.command_runner_.reset(&command_runner_);
2262  command_runner_.commands_ran_.clear();
2263 
2264  string err;
2265  EXPECT_TRUE(builder.AddTarget("out", &err));
2266  ASSERT_EQ("", err);
2267  EXPECT_TRUE(builder.Build(&err));
2268  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2269 
2270  builder.command_runner_.release();
2271 }
2272 
2273 /// Check that a restat rule generating a header cancels compilations correctly.
2274 TEST_F(BuildTest, RestatDepfileDependency) {
2276 "rule true\n"
2277 " command = true\n" // Would be "write if out-of-date" in reality.
2278 " restat = 1\n"
2279 "build header.h: true header.in\n"
2280 "build out: cat in1\n"
2281 " depfile = in1.d\n"));
2282 
2283  fs_.Create("header.h", "");
2284  fs_.Create("in1.d", "out: header.h");
2285  fs_.Tick();
2286  fs_.Create("header.in", "");
2287 
2288  string err;
2289  EXPECT_TRUE(builder_.AddTarget("out", &err));
2290  ASSERT_EQ("", err);
2291  EXPECT_TRUE(builder_.Build(&err));
2292  EXPECT_EQ("", err);
2293 }
2294 
2295 /// Check that a restat rule generating a header cancels compilations correctly,
2296 /// depslog case.
2297 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
2298  string err;
2299  // Note: in1 was created by the superclass SetUp().
2300  const char* manifest =
2301  "rule true\n"
2302  " command = true\n" // Would be "write if out-of-date" in reality.
2303  " restat = 1\n"
2304  "build header.h: true header.in\n"
2305  "build out: cat in1\n"
2306  " deps = gcc\n"
2307  " depfile = in1.d\n";
2308  {
2309  State state;
2310  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2311  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2312 
2313  // Run the build once, everything should be ok.
2314  DepsLog deps_log;
2315  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2316  ASSERT_EQ("", err);
2317 
2318  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2319  builder.command_runner_.reset(&command_runner_);
2320  EXPECT_TRUE(builder.AddTarget("out", &err));
2321  ASSERT_EQ("", err);
2322  fs_.Create("in1.d", "out: header.h");
2323  EXPECT_TRUE(builder.Build(&err));
2324  EXPECT_EQ("", err);
2325 
2326  deps_log.Close();
2327  builder.command_runner_.release();
2328  }
2329 
2330  {
2331  State state;
2332  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2333  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2334 
2335  // Touch the input of the restat rule.
2336  fs_.Tick();
2337  fs_.Create("header.in", "");
2338 
2339  // Run the build again.
2340  DepsLog deps_log;
2341  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2342  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2343 
2344  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2345  builder.command_runner_.reset(&command_runner_);
2346  command_runner_.commands_ran_.clear();
2347  EXPECT_TRUE(builder.AddTarget("out", &err));
2348  ASSERT_EQ("", err);
2349  EXPECT_TRUE(builder.Build(&err));
2350  EXPECT_EQ("", err);
2351 
2352  // Rule "true" should have run again, but the build of "out" should have
2353  // been cancelled due to restat propagating through the depfile header.
2354  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2355 
2356  builder.command_runner_.release();
2357  }
2358 }
2359 
2360 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
2361  string err;
2362  const char* manifest =
2363  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2364  "build fo$ o.o: cc foo.c\n";
2365 
2366  fs_.Create("foo.c", "");
2367 
2368  {
2369  State state;
2370  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2371 
2372  // Run the build once, everything should be ok.
2373  DepsLog deps_log;
2374  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2375  ASSERT_EQ("", err);
2376 
2377  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2378  builder.command_runner_.reset(&command_runner_);
2379  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2380  ASSERT_EQ("", err);
2381  fs_.Create("fo o.o.d", "fo\\ o.o: blah.h bar.h\n");
2382  EXPECT_TRUE(builder.Build(&err));
2383  EXPECT_EQ("", err);
2384 
2385  deps_log.Close();
2386  builder.command_runner_.release();
2387  }
2388 
2389  {
2390  State state;
2391  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2392 
2393  DepsLog deps_log;
2394  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2395  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2396  ASSERT_EQ("", err);
2397 
2398  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2399  builder.command_runner_.reset(&command_runner_);
2400 
2401  Edge* edge = state.edges_.back();
2402 
2403  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2404  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2405  ASSERT_EQ("", err);
2406 
2407  // Expect three new edges: one generating fo o.o, and two more from
2408  // loading the depfile.
2409  ASSERT_EQ(3u, state.edges_.size());
2410  // Expect our edge to now have three inputs: foo.c and two headers.
2411  ASSERT_EQ(3u, edge->inputs_.size());
2412 
2413  // Expect the command line we generate to only use the original input.
2414  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
2415 
2416  deps_log.Close();
2417  builder.command_runner_.release();
2418  }
2419 }
2420 
2421 #ifdef _WIN32
2422 TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
2423  string err;
2424  const char* manifest =
2425  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2426  "build a/b\\c\\d/e/fo$ o.o: cc x\\y/z\\foo.c\n";
2427 
2428  fs_.Create("x/y/z/foo.c", "");
2429 
2430  {
2431  State state;
2432  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2433 
2434  // Run the build once, everything should be ok.
2435  DepsLog deps_log;
2436  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2437  ASSERT_EQ("", err);
2438 
2439  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2440  builder.command_runner_.reset(&command_runner_);
2441  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2442  ASSERT_EQ("", err);
2443  // Note, different slashes from manifest.
2444  fs_.Create("a/b\\c\\d/e/fo o.o.d",
2445  "a\\b\\c\\d\\e\\fo\\ o.o: blah.h bar.h\n");
2446  EXPECT_TRUE(builder.Build(&err));
2447  EXPECT_EQ("", err);
2448 
2449  deps_log.Close();
2450  builder.command_runner_.release();
2451  }
2452 
2453  {
2454  State state;
2455  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2456 
2457  DepsLog deps_log;
2458  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2459  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2460  ASSERT_EQ("", err);
2461 
2462  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2463  builder.command_runner_.reset(&command_runner_);
2464 
2465  Edge* edge = state.edges_.back();
2466 
2467  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2468  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2469  ASSERT_EQ("", err);
2470 
2471  // Expect three new edges: one generating fo o.o, and two more from
2472  // loading the depfile.
2473  ASSERT_EQ(3u, state.edges_.size());
2474  // Expect our edge to now have three inputs: foo.c and two headers.
2475  ASSERT_EQ(3u, edge->inputs_.size());
2476 
2477  // Expect the command line we generate to only use the original input.
2478  // Note, slashes from manifest, not .d.
2479  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
2480 
2481  deps_log.Close();
2482  builder.command_runner_.release();
2483  }
2484 }
2485 #endif
2486 
2487 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
2488 /// Follows from: https://github.com/ninja-build/ninja/issues/603
2489 TEST_F(BuildTest, RestatMissingDepfile) {
2490 const char* manifest =
2491 "rule true\n"
2492 " command = true\n" // Would be "write if out-of-date" in reality.
2493 " restat = 1\n"
2494 "build header.h: true header.in\n"
2495 "build out: cat header.h\n"
2496 " depfile = out.d\n";
2497 
2498  fs_.Create("header.h", "");
2499  fs_.Tick();
2500  fs_.Create("out", "");
2501  fs_.Create("header.in", "");
2502 
2503  // Normally, only 'header.h' would be rebuilt, as
2504  // its rule doesn't touch the output and has 'restat=1' set.
2505  // But we are also missing the depfile for 'out',
2506  // which should force its command to run anyway!
2507  RebuildTarget("out", manifest);
2508  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2509 }
2510 
2511 /// Check that a restat rule doesn't clear an edge if the deps are missing.
2512 /// https://github.com/ninja-build/ninja/issues/603
2513 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
2514  string err;
2515  const char* manifest =
2516 "rule true\n"
2517 " command = true\n" // Would be "write if out-of-date" in reality.
2518 " restat = 1\n"
2519 "build header.h: true header.in\n"
2520 "build out: cat header.h\n"
2521 " deps = gcc\n"
2522 " depfile = out.d\n";
2523 
2524  // Build once to populate ninja deps logs from out.d
2525  fs_.Create("header.in", "");
2526  fs_.Create("out.d", "out: header.h");
2527  fs_.Create("header.h", "");
2528 
2529  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2530  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2531 
2532  // Sanity: this rebuild should be NOOP
2533  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2534  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2535 
2536  // Touch 'header.in', blank dependencies log (create a different one).
2537  // Building header.h triggers 'restat' outputs cleanup.
2538  // Validate that out is rebuilt netherless, as deps are missing.
2539  fs_.Tick();
2540  fs_.Create("header.in", "");
2541 
2542  // (switch to a new blank deps_log "ninja_deps2")
2543  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2544  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2545 
2546  // Sanity: this build should be NOOP
2547  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2548  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2549 
2550  // Check that invalidating deps by target timestamp also works here
2551  // Repeat the test but touch target instead of blanking the log.
2552  fs_.Tick();
2553  fs_.Create("header.in", "");
2554  fs_.Create("out", "");
2555  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2556  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2557 
2558  // And this build should be NOOP again
2559  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2560  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2561 }
2562 
2563 TEST_F(BuildTest, WrongOutputInDepfileCausesRebuild) {
2564  string err;
2565  const char* manifest =
2566 "rule cc\n"
2567 " command = cc $in\n"
2568 " depfile = $out.d\n"
2569 "build foo.o: cc foo.c\n";
2570 
2571  fs_.Create("foo.c", "");
2572  fs_.Create("foo.o", "");
2573  fs_.Create("header.h", "");
2574  fs_.Create("foo.o.d", "bar.o.d: header.h\n");
2575 
2576  RebuildTarget("foo.o", manifest, "build_log", "ninja_deps");
2577  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2578 }
2579 
2580 TEST_F(BuildTest, Console) {
2582 "rule console\n"
2583 " command = console\n"
2584 " pool = console\n"
2585 "build cons: console in.txt\n"));
2586 
2587  fs_.Create("in.txt", "");
2588 
2589  string err;
2590  EXPECT_TRUE(builder_.AddTarget("cons", &err));
2591  ASSERT_EQ("", err);
2592  EXPECT_TRUE(builder_.Build(&err));
2593  EXPECT_EQ("", err);
2594  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2595 }
2596 
2597 TEST_F(BuildTest, DyndepMissingAndNoRule) {
2598  // Verify that we can diagnose when a dyndep file is missing and
2599  // has no rule to build it.
2601 "rule touch\n"
2602 " command = touch $out\n"
2603 "build out: touch || dd\n"
2604 " dyndep = dd\n"
2605 ));
2606 
2607  string err;
2608  EXPECT_FALSE(builder_.AddTarget("out", &err));
2609  EXPECT_EQ("loading 'dd': No such file or directory", err);
2610 }
2611 
2612 TEST_F(BuildTest, DyndepReadyImplicitConnection) {
2613  // Verify that a dyndep file can be loaded immediately to discover
2614  // that one edge has an implicit output that is also an implicit
2615  // input of another edge.
2617 "rule touch\n"
2618 " command = touch $out $out.imp\n"
2619 "build tmp: touch || dd\n"
2620 " dyndep = dd\n"
2621 "build out: touch || dd\n"
2622 " dyndep = dd\n"
2623 ));
2624  fs_.Create("dd",
2625 "ninja_dyndep_version = 1\n"
2626 "build out | out.imp: dyndep | tmp.imp\n"
2627 "build tmp | tmp.imp: dyndep\n"
2628 );
2629 
2630  string err;
2631  EXPECT_TRUE(builder_.AddTarget("out", &err));
2632  ASSERT_EQ("", err);
2633  EXPECT_TRUE(builder_.Build(&err));
2634  EXPECT_EQ("", err);
2635  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2636  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[0]);
2637  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
2638 }
2639 
2640 TEST_F(BuildTest, DyndepReadySyntaxError) {
2641  // Verify that a dyndep file can be loaded immediately to discover
2642  // and reject a syntax error in it.
2644 "rule touch\n"
2645 " command = touch $out\n"
2646 "build out: touch || dd\n"
2647 " dyndep = dd\n"
2648 ));
2649  fs_.Create("dd",
2650 "build out: dyndep\n"
2651 );
2652 
2653  string err;
2654  EXPECT_FALSE(builder_.AddTarget("out", &err));
2655  EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
2656 }
2657 
2658 TEST_F(BuildTest, DyndepReadyCircular) {
2659  // Verify that a dyndep file can be loaded immediately to discover
2660  // and reject a circular dependency.
2662 "rule r\n"
2663 " command = unused\n"
2664 "build out: r in || dd\n"
2665 " dyndep = dd\n"
2666 "build in: r circ\n"
2667  ));
2668  fs_.Create("dd",
2669 "ninja_dyndep_version = 1\n"
2670 "build out | circ: dyndep\n"
2671  );
2672  fs_.Create("out", "");
2673 
2674  string err;
2675  EXPECT_FALSE(builder_.AddTarget("out", &err));
2676  EXPECT_EQ("dependency cycle: circ -> in -> circ", err);
2677 }
2678 
2679 TEST_F(BuildTest, DyndepBuild) {
2680  // Verify that a dyndep file can be built and loaded to discover nothing.
2682 "rule touch\n"
2683 " command = touch $out\n"
2684 "rule cp\n"
2685 " command = cp $in $out\n"
2686 "build dd: cp dd-in\n"
2687 "build out: touch || dd\n"
2688 " dyndep = dd\n"
2689 ));
2690  fs_.Create("dd-in",
2691 "ninja_dyndep_version = 1\n"
2692 "build out: dyndep\n"
2693 );
2694 
2695  string err;
2696  EXPECT_TRUE(builder_.AddTarget("out", &err));
2697  EXPECT_EQ("", err);
2698 
2699  size_t files_created = fs_.files_created_.size();
2700  EXPECT_TRUE(builder_.Build(&err));
2701  EXPECT_EQ("", err);
2702 
2703  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2704  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2705  EXPECT_EQ("touch out", command_runner_.commands_ran_[1]);
2706  ASSERT_EQ(2u, fs_.files_read_.size());
2707  EXPECT_EQ("dd-in", fs_.files_read_[0]);
2708  EXPECT_EQ("dd", fs_.files_read_[1]);
2709  ASSERT_EQ(2u + files_created, fs_.files_created_.size());
2710  EXPECT_EQ(1u, fs_.files_created_.count("dd"));
2711  EXPECT_EQ(1u, fs_.files_created_.count("out"));
2712 }
2713 
2714 TEST_F(BuildTest, DyndepBuildSyntaxError) {
2715  // Verify that a dyndep file can be built and loaded to discover
2716  // and reject a syntax error in it.
2718 "rule touch\n"
2719 " command = touch $out\n"
2720 "rule cp\n"
2721 " command = cp $in $out\n"
2722 "build dd: cp dd-in\n"
2723 "build out: touch || dd\n"
2724 " dyndep = dd\n"
2725 ));
2726  fs_.Create("dd-in",
2727 "build out: dyndep\n"
2728 );
2729 
2730  string err;
2731  EXPECT_TRUE(builder_.AddTarget("out", &err));
2732  EXPECT_EQ("", err);
2733 
2734  EXPECT_FALSE(builder_.Build(&err));
2735  EXPECT_EQ("dd:1: expected 'ninja_dyndep_version = ...'\n", err);
2736 }
2737 
2738 TEST_F(BuildTest, DyndepBuildUnrelatedOutput) {
2739  // Verify that a dyndep file can have dependents that do not specify
2740  // it as their dyndep binding.
2742 "rule touch\n"
2743 " command = touch $out\n"
2744 "rule cp\n"
2745 " command = cp $in $out\n"
2746 "build dd: cp dd-in\n"
2747 "build unrelated: touch || dd\n"
2748 "build out: touch unrelated || dd\n"
2749 " dyndep = dd\n"
2750  ));
2751  fs_.Create("dd-in",
2752 "ninja_dyndep_version = 1\n"
2753 "build out: dyndep\n"
2754 );
2755  fs_.Tick();
2756  fs_.Create("out", "");
2757 
2758  string err;
2759  EXPECT_TRUE(builder_.AddTarget("out", &err));
2760  EXPECT_EQ("", err);
2761 
2762  EXPECT_TRUE(builder_.Build(&err));
2763  EXPECT_EQ("", err);
2764  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2765  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2766  EXPECT_EQ("touch unrelated", command_runner_.commands_ran_[1]);
2767  EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
2768 }
2769 
2770 TEST_F(BuildTest, DyndepBuildDiscoverNewOutput) {
2771  // Verify that a dyndep file can be built and loaded to discover
2772  // a new output of an edge.
2774 "rule touch\n"
2775 " command = touch $out $out.imp\n"
2776 "rule cp\n"
2777 " command = cp $in $out\n"
2778 "build dd: cp dd-in\n"
2779 "build out: touch in || dd\n"
2780 " dyndep = dd\n"
2781  ));
2782  fs_.Create("in", "");
2783  fs_.Create("dd-in",
2784 "ninja_dyndep_version = 1\n"
2785 "build out | out.imp: dyndep\n"
2786 );
2787  fs_.Tick();
2788  fs_.Create("out", "");
2789 
2790  string err;
2791  EXPECT_TRUE(builder_.AddTarget("out", &err));
2792  EXPECT_EQ("", err);
2793 
2794  EXPECT_TRUE(builder_.Build(&err));
2795  EXPECT_EQ("", err);
2796  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2797  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2798  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[1]);
2799 }
2800 
2801 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules1) {
2802  // Verify that a dyndep file can be built and loaded to discover
2803  // a new output of an edge that is already the output of another edge.
2805 "rule touch\n"
2806 " command = touch $out $out.imp\n"
2807 "rule cp\n"
2808 " command = cp $in $out\n"
2809 "build dd: cp dd-in\n"
2810 "build out1 | out-twice.imp: touch in\n"
2811 "build out2: touch in || dd\n"
2812 " dyndep = dd\n"
2813  ));
2814  fs_.Create("in", "");
2815  fs_.Create("dd-in",
2816 "ninja_dyndep_version = 1\n"
2817 "build out2 | out-twice.imp: dyndep\n"
2818 );
2819  fs_.Tick();
2820  fs_.Create("out1", "");
2821  fs_.Create("out2", "");
2822 
2823  string err;
2824  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2825  EXPECT_TRUE(builder_.AddTarget("out2", &err));
2826  EXPECT_EQ("", err);
2827 
2828  EXPECT_FALSE(builder_.Build(&err));
2829  EXPECT_EQ("multiple rules generate out-twice.imp", err);
2830 }
2831 
2832 TEST_F(BuildTest, DyndepBuildDiscoverNewOutputWithMultipleRules2) {
2833  // Verify that a dyndep file can be built and loaded to discover
2834  // a new output of an edge that is already the output of another
2835  // edge also discovered by dyndep.
2837 "rule touch\n"
2838 " command = touch $out $out.imp\n"
2839 "rule cp\n"
2840 " command = cp $in $out\n"
2841 "build dd1: cp dd1-in\n"
2842 "build out1: touch || dd1\n"
2843 " dyndep = dd1\n"
2844 "build dd2: cp dd2-in || dd1\n" // make order predictable for test
2845 "build out2: touch || dd2\n"
2846 " dyndep = dd2\n"
2847 ));
2848  fs_.Create("out1", "");
2849  fs_.Create("out2", "");
2850  fs_.Create("dd1-in",
2851 "ninja_dyndep_version = 1\n"
2852 "build out1 | out-twice.imp: dyndep\n"
2853 );
2854  fs_.Create("dd2-in", "");
2855  fs_.Create("dd2",
2856 "ninja_dyndep_version = 1\n"
2857 "build out2 | out-twice.imp: dyndep\n"
2858 );
2859  fs_.Tick();
2860  fs_.Create("out1", "");
2861  fs_.Create("out2", "");
2862 
2863  string err;
2864  EXPECT_TRUE(builder_.AddTarget("out1", &err));
2865  EXPECT_TRUE(builder_.AddTarget("out2", &err));
2866  EXPECT_EQ("", err);
2867 
2868  EXPECT_FALSE(builder_.Build(&err));
2869  EXPECT_EQ("multiple rules generate out-twice.imp", err);
2870 }
2871 
2872 TEST_F(BuildTest, DyndepBuildDiscoverNewInput) {
2873  // Verify that a dyndep file can be built and loaded to discover
2874  // a new input to an edge.
2876 "rule touch\n"
2877 " command = touch $out\n"
2878 "rule cp\n"
2879 " command = cp $in $out\n"
2880 "build dd: cp dd-in\n"
2881 "build in: touch\n"
2882 "build out: touch || dd\n"
2883 " dyndep = dd\n"
2884  ));
2885  fs_.Create("dd-in",
2886 "ninja_dyndep_version = 1\n"
2887 "build out: dyndep | in\n"
2888 );
2889  fs_.Tick();
2890  fs_.Create("out", "");
2891 
2892  string err;
2893  EXPECT_TRUE(builder_.AddTarget("out", &err));
2894  EXPECT_EQ("", err);
2895 
2896  EXPECT_TRUE(builder_.Build(&err));
2897  EXPECT_EQ("", err);
2898  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2899  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2900  EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
2901  EXPECT_EQ("touch out", command_runner_.commands_ran_[2]);
2902 }
2903 
2904 TEST_F(BuildTest, DyndepBuildDiscoverImplicitConnection) {
2905  // Verify that a dyndep file can be built and loaded to discover
2906  // that one edge has an implicit output that is also an implicit
2907  // input of another edge.
2909 "rule touch\n"
2910 " command = touch $out $out.imp\n"
2911 "rule cp\n"
2912 " command = cp $in $out\n"
2913 "build dd: cp dd-in\n"
2914 "build tmp: touch || dd\n"
2915 " dyndep = dd\n"
2916 "build out: touch || dd\n"
2917 " dyndep = dd\n"
2918 ));
2919  fs_.Create("dd-in",
2920 "ninja_dyndep_version = 1\n"
2921 "build out | out.imp: dyndep | tmp.imp\n"
2922 "build tmp | tmp.imp: dyndep\n"
2923 );
2924 
2925  string err;
2926  EXPECT_TRUE(builder_.AddTarget("out", &err));
2927  ASSERT_EQ("", err);
2928  EXPECT_TRUE(builder_.Build(&err));
2929  EXPECT_EQ("", err);
2930  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2931  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2932  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2933  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2934 }
2935 
2936 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdge) {
2937  // Verify that a dyndep file can be built and loaded to discover
2938  // that an edge is actually wanted due to a missing implicit output.
2940 "rule touch\n"
2941 " command = touch $out $out.imp\n"
2942 "rule cp\n"
2943 " command = cp $in $out\n"
2944 "build dd: cp dd-in\n"
2945 "build tmp: touch || dd\n"
2946 " dyndep = dd\n"
2947 "build out: touch tmp || dd\n"
2948 " dyndep = dd\n"
2949 ));
2950  fs_.Create("tmp", "");
2951  fs_.Create("out", "");
2952  fs_.Create("dd-in",
2953 "ninja_dyndep_version = 1\n"
2954 "build out: dyndep\n"
2955 "build tmp | tmp.imp: dyndep\n"
2956 );
2957 
2958  string err;
2959  EXPECT_TRUE(builder_.AddTarget("out", &err));
2960  ASSERT_EQ("", err);
2961  EXPECT_TRUE(builder_.Build(&err));
2962  EXPECT_EQ("", err);
2963  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2964  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2965  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2966  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2967 }
2968 
2969 TEST_F(BuildTest, DyndepBuildDiscoverNowWantEdgeAndDependent) {
2970  // Verify that a dyndep file can be built and loaded to discover
2971  // that an edge and a dependent are actually wanted.
2973 "rule touch\n"
2974 " command = touch $out $out.imp\n"
2975 "rule cp\n"
2976 " command = cp $in $out\n"
2977 "build dd: cp dd-in\n"
2978 "build tmp: touch || dd\n"
2979 " dyndep = dd\n"
2980 "build out: touch tmp\n"
2981 ));
2982  fs_.Create("tmp", "");
2983  fs_.Create("out", "");
2984  fs_.Create("dd-in",
2985 "ninja_dyndep_version = 1\n"
2986 "build tmp | tmp.imp: dyndep\n"
2987 );
2988 
2989  string err;
2990  EXPECT_TRUE(builder_.AddTarget("out", &err));
2991  ASSERT_EQ("", err);
2992  EXPECT_TRUE(builder_.Build(&err));
2993  EXPECT_EQ("", err);
2994  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2995  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
2996  EXPECT_EQ("touch tmp tmp.imp", command_runner_.commands_ran_[1]);
2997  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[2]);
2998 }
2999 
3000 TEST_F(BuildTest, DyndepBuildDiscoverCircular) {
3001  // Verify that a dyndep file can be built and loaded to discover
3002  // and reject a circular dependency.
3004 "rule r\n"
3005 " command = unused\n"
3006 "rule cp\n"
3007 " command = cp $in $out\n"
3008 "build dd: cp dd-in\n"
3009 "build out: r in || dd\n"
3010 " depfile = out.d\n"
3011 " dyndep = dd\n"
3012 "build in: r || dd\n"
3013 " dyndep = dd\n"
3014  ));
3015  fs_.Create("out.d", "out: inimp\n");
3016  fs_.Create("dd-in",
3017 "ninja_dyndep_version = 1\n"
3018 "build out | circ: dyndep\n"
3019 "build in: dyndep | circ\n"
3020  );
3021  fs_.Create("out", "");
3022 
3023  string err;
3024  EXPECT_TRUE(builder_.AddTarget("out", &err));
3025  EXPECT_EQ("", err);
3026 
3027  EXPECT_FALSE(builder_.Build(&err));
3028  // Depending on how the pointers in Plan::ready_ work out, we could have
3029  // discovered the cycle from either starting point.
3030  EXPECT_TRUE(err == "dependency cycle: circ -> in -> circ" ||
3031  err == "dependency cycle: in -> circ -> in");
3032 }
3033 
3034 TEST_F(BuildWithLogTest, DyndepBuildDiscoverRestat) {
3035  // Verify that a dyndep file can be built and loaded to discover
3036  // that an edge has a restat binding.
3038 "rule true\n"
3039 " command = true\n"
3040 "rule cp\n"
3041 " command = cp $in $out\n"
3042 "build dd: cp dd-in\n"
3043 "build out1: true in || dd\n"
3044 " dyndep = dd\n"
3045 "build out2: cat out1\n"));
3046 
3047  fs_.Create("out1", "");
3048  fs_.Create("out2", "");
3049  fs_.Create("dd-in",
3050 "ninja_dyndep_version = 1\n"
3051 "build out1: dyndep\n"
3052 " restat = 1\n"
3053 );
3054  fs_.Tick();
3055  fs_.Create("in", "");
3056 
3057  // Do a pre-build so that there's commands in the log for the outputs,
3058  // otherwise, the lack of an entry in the build log will cause "out2" to
3059  // rebuild regardless of restat.
3060  string err;
3061  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3062  ASSERT_EQ("", err);
3063  EXPECT_TRUE(builder_.Build(&err));
3064  ASSERT_EQ("", err);
3065  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3066  EXPECT_EQ("cp dd-in dd", command_runner_.commands_ran_[0]);
3067  EXPECT_EQ("true", command_runner_.commands_ran_[1]);
3068  EXPECT_EQ("cat out1 > out2", command_runner_.commands_ran_[2]);
3069 
3070  command_runner_.commands_ran_.clear();
3071  state_.Reset();
3072  fs_.Tick();
3073  fs_.Create("in", "");
3074 
3075  // We touched "in", so we should build "out1". But because "true" does not
3076  // touch "out1", we should cancel the build of "out2".
3077  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3078  ASSERT_EQ("", err);
3079  EXPECT_TRUE(builder_.Build(&err));
3080  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3081  EXPECT_EQ("true", command_runner_.commands_ran_[0]);
3082 }
3083 
3084 TEST_F(BuildTest, DyndepBuildDiscoverScheduledEdge) {
3085  // Verify that a dyndep file can be built and loaded to discover a
3086  // new input that itself is an output from an edge that has already
3087  // been scheduled but not finished. We should not re-schedule it.
3089 "rule touch\n"
3090 " command = touch $out $out.imp\n"
3091 "rule cp\n"
3092 " command = cp $in $out\n"
3093 "build out1 | out1.imp: touch\n"
3094 "build zdd: cp zdd-in\n"
3095 " verify_active_edge = out1\n" // verify out1 is active when zdd is finished
3096 "build out2: cp out1 || zdd\n"
3097 " dyndep = zdd\n"
3098 ));
3099  fs_.Create("zdd-in",
3100 "ninja_dyndep_version = 1\n"
3101 "build out2: dyndep | out1.imp\n"
3102 );
3103 
3104  // Enable concurrent builds so that we can load the dyndep file
3105  // while another edge is still active.
3106  command_runner_.max_active_edges_ = 2;
3107 
3108  // During the build "out1" and "zdd" should be built concurrently.
3109  // The fake command runner will finish these in reverse order
3110  // of the names of the first outputs, so "zdd" will finish first
3111  // and we will load the dyndep file while the edge for "out1" is
3112  // still active. This will add a new dependency on "out1.imp",
3113  // also produced by the active edge. The builder should not
3114  // re-schedule the already-active edge.
3115 
3116  string err;
3117  EXPECT_TRUE(builder_.AddTarget("out1", &err));
3118  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3119  ASSERT_EQ("", err);
3120  EXPECT_TRUE(builder_.Build(&err));
3121  EXPECT_EQ("", err);
3122  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3123  // Depending on how the pointers in Plan::ready_ work out, the first
3124  // two commands may have run in either order.
3125  EXPECT_TRUE((command_runner_.commands_ran_[0] == "touch out1 out1.imp" &&
3126  command_runner_.commands_ran_[1] == "cp zdd-in zdd") ||
3127  (command_runner_.commands_ran_[1] == "touch out1 out1.imp" &&
3128  command_runner_.commands_ran_[0] == "cp zdd-in zdd"));
3129  EXPECT_EQ("cp out1 out2", command_runner_.commands_ran_[2]);
3130 }
3131 
3132 TEST_F(BuildTest, DyndepTwoLevelDirect) {
3133  // Verify that a clean dyndep file can depend on a dirty dyndep file
3134  // and be loaded properly after the dirty one is built and loaded.
3136 "rule touch\n"
3137 " command = touch $out $out.imp\n"
3138 "rule cp\n"
3139 " command = cp $in $out\n"
3140 "build dd1: cp dd1-in\n"
3141 "build out1 | out1.imp: touch || dd1\n"
3142 " dyndep = dd1\n"
3143 "build dd2: cp dd2-in || dd1\n" // direct order-only dep on dd1
3144 "build out2: touch || dd2\n"
3145 " dyndep = dd2\n"
3146 ));
3147  fs_.Create("out1.imp", "");
3148  fs_.Create("out2", "");
3149  fs_.Create("out2.imp", "");
3150  fs_.Create("dd1-in",
3151 "ninja_dyndep_version = 1\n"
3152 "build out1: dyndep\n"
3153 );
3154  fs_.Create("dd2-in", "");
3155  fs_.Create("dd2",
3156 "ninja_dyndep_version = 1\n"
3157 "build out2 | out2.imp: dyndep | out1.imp\n"
3158 );
3159 
3160  // During the build dd1 should be built and loaded. The RecomputeDirty
3161  // called as a result of loading dd1 should not cause dd2 to be loaded
3162  // because the builder will never get a chance to update the build plan
3163  // to account for dd2. Instead dd2 should only be later loaded once the
3164  // builder recognizes that it is now ready (as its order-only dependency
3165  // on dd1 has been satisfied). This test case verifies that each dyndep
3166  // file is loaded to update the build graph independently.
3167 
3168  string err;
3169  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3170  ASSERT_EQ("", err);
3171  EXPECT_TRUE(builder_.Build(&err));
3172  EXPECT_EQ("", err);
3173  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3174  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3175  EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3176  EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3177 }
3178 
3179 TEST_F(BuildTest, DyndepTwoLevelIndirect) {
3180  // Verify that dyndep files can add to an edge new implicit inputs that
3181  // correspond to implicit outputs added to other edges by other dyndep
3182  // files on which they (order-only) depend.
3184 "rule touch\n"
3185 " command = touch $out $out.imp\n"
3186 "rule cp\n"
3187 " command = cp $in $out\n"
3188 "build dd1: cp dd1-in\n"
3189 "build out1: touch || dd1\n"
3190 " dyndep = dd1\n"
3191 "build dd2: cp dd2-in || out1\n" // indirect order-only dep on dd1
3192 "build out2: touch || dd2\n"
3193 " dyndep = dd2\n"
3194 ));
3195  fs_.Create("out1.imp", "");
3196  fs_.Create("out2", "");
3197  fs_.Create("out2.imp", "");
3198  fs_.Create("dd1-in",
3199 "ninja_dyndep_version = 1\n"
3200 "build out1 | out1.imp: dyndep\n"
3201 );
3202  fs_.Create("dd2-in", "");
3203  fs_.Create("dd2",
3204 "ninja_dyndep_version = 1\n"
3205 "build out2 | out2.imp: dyndep | out1.imp\n"
3206 );
3207 
3208  // During the build dd1 should be built and loaded. Then dd2 should
3209  // be built and loaded. Loading dd2 should cause the builder to
3210  // recognize that out2 needs to be built even though it was originally
3211  // clean without dyndep info.
3212 
3213  string err;
3214  EXPECT_TRUE(builder_.AddTarget("out2", &err));
3215  ASSERT_EQ("", err);
3216  EXPECT_TRUE(builder_.Build(&err));
3217  EXPECT_EQ("", err);
3218  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3219  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3220  EXPECT_EQ("touch out1 out1.imp", command_runner_.commands_ran_[1]);
3221  EXPECT_EQ("touch out2 out2.imp", command_runner_.commands_ran_[2]);
3222 }
3223 
3224 TEST_F(BuildTest, DyndepTwoLevelDiscoveredReady) {
3225  // Verify that a dyndep file can discover a new input whose
3226  // edge also has a dyndep file that is ready to load immediately.
3228 "rule touch\n"
3229 " command = touch $out\n"
3230 "rule cp\n"
3231 " command = cp $in $out\n"
3232 "build dd0: cp dd0-in\n"
3233 "build dd1: cp dd1-in\n"
3234 "build in: touch\n"
3235 "build tmp: touch || dd0\n"
3236 " dyndep = dd0\n"
3237 "build out: touch || dd1\n"
3238 " dyndep = dd1\n"
3239  ));
3240  fs_.Create("dd1-in",
3241 "ninja_dyndep_version = 1\n"
3242 "build out: dyndep | tmp\n"
3243 );
3244  fs_.Create("dd0-in", "");
3245  fs_.Create("dd0",
3246 "ninja_dyndep_version = 1\n"
3247 "build tmp: dyndep | in\n"
3248 );
3249  fs_.Tick();
3250  fs_.Create("out", "");
3251 
3252  string err;
3253  EXPECT_TRUE(builder_.AddTarget("out", &err));
3254  EXPECT_EQ("", err);
3255 
3256  EXPECT_TRUE(builder_.Build(&err));
3257  EXPECT_EQ("", err);
3258  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
3259  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3260  EXPECT_EQ("touch in", command_runner_.commands_ran_[1]);
3261  EXPECT_EQ("touch tmp", command_runner_.commands_ran_[2]);
3262  EXPECT_EQ("touch out", command_runner_.commands_ran_[3]);
3263 }
3264 
3265 TEST_F(BuildTest, DyndepTwoLevelDiscoveredDirty) {
3266  // Verify that a dyndep file can discover a new input whose
3267  // edge also has a dyndep file that needs to be built.
3269 "rule touch\n"
3270 " command = touch $out\n"
3271 "rule cp\n"
3272 " command = cp $in $out\n"
3273 "build dd0: cp dd0-in\n"
3274 "build dd1: cp dd1-in\n"
3275 "build in: touch\n"
3276 "build tmp: touch || dd0\n"
3277 " dyndep = dd0\n"
3278 "build out: touch || dd1\n"
3279 " dyndep = dd1\n"
3280  ));
3281  fs_.Create("dd1-in",
3282 "ninja_dyndep_version = 1\n"
3283 "build out: dyndep | tmp\n"
3284 );
3285  fs_.Create("dd0-in",
3286 "ninja_dyndep_version = 1\n"
3287 "build tmp: dyndep | in\n"
3288 );
3289  fs_.Tick();
3290  fs_.Create("out", "");
3291 
3292  string err;
3293  EXPECT_TRUE(builder_.AddTarget("out", &err));
3294  EXPECT_EQ("", err);
3295 
3296  EXPECT_TRUE(builder_.Build(&err));
3297  EXPECT_EQ("", err);
3298  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
3299  EXPECT_EQ("cp dd1-in dd1", command_runner_.commands_ran_[0]);
3300  EXPECT_EQ("cp dd0-in dd0", command_runner_.commands_ran_[1]);
3301  EXPECT_EQ("touch in", command_runner_.commands_ran_[2]);
3302  EXPECT_EQ("touch tmp", command_runner_.commands_ran_[3]);
3303  EXPECT_EQ("touch out", command_runner_.commands_ran_[4]);
3304 }
bool OpenForWrite(const std::string &path, const BuildLogUser &user, std::string *err)
Prepares writing to the log file without actually opening it - that will happen when/if it&#39;s needed...
Definition: build_log.cc:131
FakeCommandRunner command_runner_
Definition: build_test.cc:534
bool Build(std::string *err)
Run the build.
Definition: build.cc:804
BuildConfig config_
Definition: build_test.cc:533
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:134
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:139
std::auto_ptr< CommandRunner > command_runner_
Definition: build.h:220
Verbosity verbosity
Definition: build.h:169
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
Definition: build_log.cc:261
FakeCommandRunner(VirtualFileSystem *fs)
Definition: build_test.cc:471
BuildLog build_log_
Definition: build_test.cc:1272
int order_only_deps_
Definition: graph.h:197
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:100
int implicit_deps_
Definition: graph.h:196
BuildConfig MakeConfig()
Definition: build_test.cc:527
void TestPoolWithDepthOne(const char *test_case)
Definition: build_test.cc:202
#define EXPECT_GE(a, b)
Definition: test.h:72
Plan stores the state of a build plan: what we intend to build, which steps we&#39;re ready to execute...
Definition: build.h:43
Edge * in_edge() const
Definition: graph.h:94
Node * GetNode(StringPiece path, uint64_t slash_bits)
Definition: state.cc:104
void * builder_
Shadow parent class builder_ so we don&#39;t accidentally use it.
Definition: build_test.cc:2103
The result of waiting for a command.
Definition: build.h:145
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:25
const std::string & name() const
Definition: eval_env.h:62
#define EXPECT_TRUE(a)
Definition: test.h:76
virtual void SetUp()
Definition: test.h:36
Information about a node in the dependency graph: the file, whether it&#39;s dirty, mtime, etc.
Definition: graph.h:37
Edge * FindWork()
Definition: build.cc:381
vector< Edge * > active_edges_
Definition: build_test.cc:482
#define EXPECT_FALSE(a)
Definition: test.h:78
virtual bool IsPathDead(StringPiece s) const
Return if a given output is no longer part of the build manifest.
Definition: build_test.cc:515
std::string output
Definition: build.h:149
Fixture for tests involving Plan.
Definition: build_test.cc:35
Node ** nodes
Definition: deps_log.h:85
std::vector< Node * > outputs_
Definition: graph.h:175
virtual vector< Edge * > GetActiveEdges()
Definition: build_test.cc:689
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:139
Store a log of every command ran for every build.
Definition: build_log.h:43
LoadStatus Load(const std::string &path, State *state, std::string *err)
Definition: deps_log.cc:152
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:113
const std::string & path() const
Definition: graph.h:76
size_t max_active_edges_
Definition: build_test.cc:483
void MarkDirty()
Definition: graph.h:89
Plan plan_
Definition: build_test.cc:36
BuildTest(DepsLog *log)
Definition: build_test.cc:493
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
int current_use() const
Definition: state.h:47
TEST_F(PlanTest, Basic)
Definition: build_test.cc:55
Tests of builds involving deps logs necessarily must span multiple builds.
Definition: build_test.cc:2087
#define EXPECT_EQ(a, b)
Definition: test.h:64
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
Definition: build_test.cc:628
#define ASSERT_FALSE(a)
Definition: test.h:95
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:64
int node_count
Definition: deps_log.h:84
virtual void TearDown()
Definition: build_test.cc:2096
Node * AddTarget(const std::string &name, std::string *err)
Fake implementation of CommandRunner, useful for tests.
Definition: build_test.cc:470
void RebuildTarget(const string &target, const char *manifest, const char *log_path=NULL, const char *deps_path=NULL, State *state=NULL)
Rebuild target in the &#39;working tree&#39; (fs_).
Definition: build_test.cc:541
ScopedTempDir temp_dir_
Definition: build_test.cc:2100
ExitStatus status
Definition: build.h:148
virtual void SetUp()
Definition: build_test.cc:498
int64_t TimeStamp
Definition: timestamp.h:31
virtual void Abort()
Definition: build_test.cc:693
Pool * LookupPool(const std::string &pool_name)
Definition: state.cc:88
VirtualFileSystem * fs_
Definition: build_test.cc:484
bool OpenForWrite(const std::string &path, std::string *err)
Definition: deps_log.cc:48
std::vector< Node * > inputs_
Definition: graph.h:174
#define ASSERT_EQ(a, b)
Definition: test.h:81
void Close()
Definition: deps_log.cc:145
void FindWorkSorted(deque< Edge *> *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Definition: build_test.cc:41
static bool cmp(const Edge *a, const Edge *b)
Definition: build_test.cc:27
Builder wraps the build process: starting commands, updating status.
Definition: build.h:180
virtual bool CanRunMore() const
Definition: build_test.cc:579
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
Definition: graph.cc:411
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:240
virtual bool StartCommand(Edge *edge)
Definition: build_test.cc:583
#define EXPECT_GT(a, b)
Definition: test.h:68
#define ASSERT_NO_FATAL_FAILURE(a)
Definition: test.h:97
const Rule & rule() const
Definition: graph.h:183
VirtualFileSystem fs_
Definition: build_test.cc:535
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
Definition: graph.cc:401
Builder builder_
Definition: build_test.cc:536
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:160
Global state (file status) for a single run.
Definition: state.h:84
std::vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:124
void Dirty(const string &path)
Definition: build_test.cc:697
BuildStatus status_
Definition: build_test.cc:538
#define ASSERT_TRUE(a)
Definition: test.h:93
bool use_console() const
Definition: graph.cc:460
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:56
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:800
virtual void SetUp()
Definition: build_test.cc:2090
vector< string > commands_ran_
Definition: build_test.cc:481
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:109
Can answer questions about the manifest for the BuildLog.
Definition: build_log.h:30