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 /// Fixture for tests involving Plan.
25 // Though Plan doesn't use State, it's useful to have one around
26 // to create Nodes and Edges.
29 
30  /// Because FindWork does not return Edges in any sort of predictable order,
31  // provide a means to get available Edges in order and in a format which is
32  // easy to write tests around.
33  void FindWorkSorted(deque<Edge*>* ret, int count) {
34  struct CompareEdgesByOutput {
35  static bool cmp(const Edge* a, const Edge* b) {
36  return a->outputs_[0]->path() < b->outputs_[0]->path();
37  }
38  };
39 
40  for (int i = 0; i < count; ++i) {
42  Edge* edge = plan_.FindWork();
43  ASSERT_TRUE(edge);
44  ret->push_back(edge);
45  }
47  sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
48  }
49 
50  void TestPoolWithDepthOne(const char *test_case);
51 };
52 
53 TEST_F(PlanTest, Basic) {
55 "build out: cat mid\n"
56 "build mid: cat in\n"));
57  GetNode("mid")->MarkDirty();
58  GetNode("out")->MarkDirty();
59  string err;
60  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
61  ASSERT_EQ("", err);
62  ASSERT_TRUE(plan_.more_to_do());
63 
64  Edge* edge = plan_.FindWork();
65  ASSERT_TRUE(edge);
66  ASSERT_EQ("in", edge->inputs_[0]->path());
67  ASSERT_EQ("mid", edge->outputs_[0]->path());
68 
69  ASSERT_FALSE(plan_.FindWork());
70 
71  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
72 
73  edge = plan_.FindWork();
74  ASSERT_TRUE(edge);
75  ASSERT_EQ("mid", edge->inputs_[0]->path());
76  ASSERT_EQ("out", edge->outputs_[0]->path());
77 
78  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
79 
80  ASSERT_FALSE(plan_.more_to_do());
81  edge = plan_.FindWork();
82  ASSERT_EQ(0, edge);
83 }
84 
85 // Test that two outputs from one rule can be handled as inputs to the next.
86 TEST_F(PlanTest, DoubleOutputDirect) {
88 "build out: cat mid1 mid2\n"
89 "build mid1 mid2: cat in\n"));
90  GetNode("mid1")->MarkDirty();
91  GetNode("mid2")->MarkDirty();
92  GetNode("out")->MarkDirty();
93 
94  string err;
95  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
96  ASSERT_EQ("", err);
97  ASSERT_TRUE(plan_.more_to_do());
98 
99  Edge* edge;
100  edge = plan_.FindWork();
101  ASSERT_TRUE(edge); // cat in
102  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
103 
104  edge = plan_.FindWork();
105  ASSERT_TRUE(edge); // cat mid1 mid2
106  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
107 
108  edge = plan_.FindWork();
109  ASSERT_FALSE(edge); // done
110 }
111 
112 // Test that two outputs from one rule can eventually be routed to another.
113 TEST_F(PlanTest, DoubleOutputIndirect) {
115 "build out: cat b1 b2\n"
116 "build b1: cat a1\n"
117 "build b2: cat a2\n"
118 "build a1 a2: cat in\n"));
119  GetNode("a1")->MarkDirty();
120  GetNode("a2")->MarkDirty();
121  GetNode("b1")->MarkDirty();
122  GetNode("b2")->MarkDirty();
123  GetNode("out")->MarkDirty();
124  string err;
125  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
126  ASSERT_EQ("", err);
127  ASSERT_TRUE(plan_.more_to_do());
128 
129  Edge* edge;
130  edge = plan_.FindWork();
131  ASSERT_TRUE(edge); // cat in
132  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
133 
134  edge = plan_.FindWork();
135  ASSERT_TRUE(edge); // cat a1
136  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
137 
138  edge = plan_.FindWork();
139  ASSERT_TRUE(edge); // cat a2
140  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
141 
142  edge = plan_.FindWork();
143  ASSERT_TRUE(edge); // cat b1 b2
144  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
145 
146  edge = plan_.FindWork();
147  ASSERT_FALSE(edge); // done
148 }
149 
150 // Test that two edges from one output can both execute.
151 TEST_F(PlanTest, DoubleDependent) {
153 "build out: cat a1 a2\n"
154 "build a1: cat mid\n"
155 "build a2: cat mid\n"
156 "build mid: cat in\n"));
157  GetNode("mid")->MarkDirty();
158  GetNode("a1")->MarkDirty();
159  GetNode("a2")->MarkDirty();
160  GetNode("out")->MarkDirty();
161 
162  string err;
163  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
164  ASSERT_EQ("", err);
165  ASSERT_TRUE(plan_.more_to_do());
166 
167  Edge* edge;
168  edge = plan_.FindWork();
169  ASSERT_TRUE(edge); // cat in
170  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
171 
172  edge = plan_.FindWork();
173  ASSERT_TRUE(edge); // cat mid
174  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
175 
176  edge = plan_.FindWork();
177  ASSERT_TRUE(edge); // cat mid
178  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
179 
180  edge = plan_.FindWork();
181  ASSERT_TRUE(edge); // cat a1 a2
182  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
183 
184  edge = plan_.FindWork();
185  ASSERT_FALSE(edge); // done
186 }
187 
188 void PlanTest::TestPoolWithDepthOne(const char* test_case) {
190  GetNode("out1")->MarkDirty();
191  GetNode("out2")->MarkDirty();
192  string err;
193  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
194  ASSERT_EQ("", err);
195  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
196  ASSERT_EQ("", err);
198 
199  Edge* edge = plan_.FindWork();
200  ASSERT_TRUE(edge);
201  ASSERT_EQ("in", edge->inputs_[0]->path());
202  ASSERT_EQ("out1", edge->outputs_[0]->path());
203 
204  // This will be false since poolcat is serialized
206 
208 
209  edge = plan_.FindWork();
210  ASSERT_TRUE(edge);
211  ASSERT_EQ("in", edge->inputs_[0]->path());
212  ASSERT_EQ("out2", edge->outputs_[0]->path());
213 
215 
217 
219  edge = plan_.FindWork();
220  ASSERT_EQ(0, edge);
221 }
222 
223 TEST_F(PlanTest, PoolWithDepthOne) {
224  TestPoolWithDepthOne(
225 "pool foobar\n"
226 " depth = 1\n"
227 "rule poolcat\n"
228 " command = cat $in > $out\n"
229 " pool = foobar\n"
230 "build out1: poolcat in\n"
231 "build out2: poolcat in\n");
232 }
233 
234 TEST_F(PlanTest, ConsolePool) {
235  TestPoolWithDepthOne(
236 "rule poolcat\n"
237 " command = cat $in > $out\n"
238 " pool = console\n"
239 "build out1: poolcat in\n"
240 "build out2: poolcat in\n");
241 }
242 
243 TEST_F(PlanTest, PoolsWithDepthTwo) {
245 "pool foobar\n"
246 " depth = 2\n"
247 "pool bazbin\n"
248 " depth = 2\n"
249 "rule foocat\n"
250 " command = cat $in > $out\n"
251 " pool = foobar\n"
252 "rule bazcat\n"
253 " command = cat $in > $out\n"
254 " pool = bazbin\n"
255 "build out1: foocat in\n"
256 "build out2: foocat in\n"
257 "build out3: foocat in\n"
258 "build outb1: bazcat in\n"
259 "build outb2: bazcat in\n"
260 "build outb3: bazcat in\n"
261 " pool =\n"
262 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
263 ));
264  // Mark all the out* nodes dirty
265  for (int i = 0; i < 3; ++i) {
266  GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
267  GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
268  }
269  GetNode("allTheThings")->MarkDirty();
270 
271  string err;
272  EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
273  ASSERT_EQ("", err);
274 
275  deque<Edge*> edges;
276  FindWorkSorted(&edges, 5);
277 
278  for (int i = 0; i < 4; ++i) {
279  Edge *edge = edges[i];
280  ASSERT_EQ("in", edge->inputs_[0]->path());
281  string base_name(i < 2 ? "out" : "outb");
282  ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
283  }
284 
285  // outb3 is exempt because it has an empty pool
286  Edge* edge = edges[4];
287  ASSERT_TRUE(edge);
288  ASSERT_EQ("in", edge->inputs_[0]->path());
289  ASSERT_EQ("outb3", edge->outputs_[0]->path());
290 
291  // finish out1
292  plan_.EdgeFinished(edges.front(), Plan::kEdgeSucceeded);
293  edges.pop_front();
294 
295  // out3 should be available
296  Edge* out3 = plan_.FindWork();
297  ASSERT_TRUE(out3);
298  ASSERT_EQ("in", out3->inputs_[0]->path());
299  ASSERT_EQ("out3", out3->outputs_[0]->path());
300 
301  ASSERT_FALSE(plan_.FindWork());
302 
303  plan_.EdgeFinished(out3, Plan::kEdgeSucceeded);
304 
305  ASSERT_FALSE(plan_.FindWork());
306 
307  for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
308  plan_.EdgeFinished(*it, Plan::kEdgeSucceeded);
309  }
310 
311  Edge* last = plan_.FindWork();
312  ASSERT_TRUE(last);
313  ASSERT_EQ("allTheThings", last->outputs_[0]->path());
314 
315  plan_.EdgeFinished(last, Plan::kEdgeSucceeded);
316 
317  ASSERT_FALSE(plan_.more_to_do());
318  ASSERT_FALSE(plan_.FindWork());
319 }
320 
321 TEST_F(PlanTest, PoolWithRedundantEdges) {
323  "pool compile\n"
324  " depth = 1\n"
325  "rule gen_foo\n"
326  " command = touch foo.cpp\n"
327  "rule gen_bar\n"
328  " command = touch bar.cpp\n"
329  "rule echo\n"
330  " command = echo $out > $out\n"
331  "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
332  " pool = compile\n"
333  "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
334  " pool = compile\n"
335  "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
336  "build foo.cpp: gen_foo\n"
337  "build bar.cpp: gen_bar\n"
338  "build all: phony libfoo.a\n"));
339  GetNode("foo.cpp")->MarkDirty();
340  GetNode("foo.cpp.obj")->MarkDirty();
341  GetNode("bar.cpp")->MarkDirty();
342  GetNode("bar.cpp.obj")->MarkDirty();
343  GetNode("libfoo.a")->MarkDirty();
344  GetNode("all")->MarkDirty();
345  string err;
346  EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
347  ASSERT_EQ("", err);
348  ASSERT_TRUE(plan_.more_to_do());
349 
350  Edge* edge = NULL;
351 
352  deque<Edge*> initial_edges;
353  FindWorkSorted(&initial_edges, 2);
354 
355  edge = initial_edges[1]; // Foo first
356  ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
357  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
358 
359  edge = plan_.FindWork();
360  ASSERT_TRUE(edge);
361  ASSERT_FALSE(plan_.FindWork());
362  ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
363  ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
364  ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
365  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
366 
367  edge = initial_edges[0]; // Now for bar
368  ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
369  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
370 
371  edge = plan_.FindWork();
372  ASSERT_TRUE(edge);
373  ASSERT_FALSE(plan_.FindWork());
374  ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
375  ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
376  ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
377  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
378 
379  edge = plan_.FindWork();
380  ASSERT_TRUE(edge);
381  ASSERT_FALSE(plan_.FindWork());
382  ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
383  ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
384  ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
385  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
386 
387  edge = plan_.FindWork();
388  ASSERT_TRUE(edge);
389  ASSERT_FALSE(plan_.FindWork());
390  ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
391  ASSERT_EQ("all", edge->outputs_[0]->path());
392  plan_.EdgeFinished(edge, Plan::kEdgeSucceeded);
393 
394  edge = plan_.FindWork();
395  ASSERT_FALSE(edge);
396  ASSERT_FALSE(plan_.more_to_do());
397 }
398 
399 TEST_F(PlanTest, PoolWithFailingEdge) {
401  "pool foobar\n"
402  " depth = 1\n"
403  "rule poolcat\n"
404  " command = cat $in > $out\n"
405  " pool = foobar\n"
406  "build out1: poolcat in\n"
407  "build out2: poolcat in\n"));
408  GetNode("out1")->MarkDirty();
409  GetNode("out2")->MarkDirty();
410  string err;
411  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
412  ASSERT_EQ("", err);
413  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
414  ASSERT_EQ("", err);
415  ASSERT_TRUE(plan_.more_to_do());
416 
417  Edge* edge = plan_.FindWork();
418  ASSERT_TRUE(edge);
419  ASSERT_EQ("in", edge->inputs_[0]->path());
420  ASSERT_EQ("out1", edge->outputs_[0]->path());
421 
422  // This will be false since poolcat is serialized
423  ASSERT_FALSE(plan_.FindWork());
424 
425  plan_.EdgeFinished(edge, Plan::kEdgeFailed);
426 
427  edge = plan_.FindWork();
428  ASSERT_TRUE(edge);
429  ASSERT_EQ("in", edge->inputs_[0]->path());
430  ASSERT_EQ("out2", edge->outputs_[0]->path());
431 
432  ASSERT_FALSE(plan_.FindWork());
433 
434  plan_.EdgeFinished(edge, Plan::kEdgeFailed);
435 
436  ASSERT_TRUE(plan_.more_to_do()); // Jobs have failed
437  edge = plan_.FindWork();
438  ASSERT_EQ(0, edge);
439 }
440 
441 /// Fake implementation of CommandRunner, useful for tests.
444  last_command_(NULL), fs_(fs) {}
445 
446  // CommandRunner impl
447  virtual bool CanRunMore();
448  virtual bool StartCommand(Edge* edge);
449  virtual bool WaitForCommand(Result* result);
450  virtual vector<Edge*> GetActiveEdges();
451  virtual void Abort();
452 
453  vector<string> commands_ran_;
456 };
457 
460  builder_(&state_, config_, NULL, NULL, &fs_),
461  status_(config_) {
462  }
463 
464  virtual void SetUp() {
466 
469 "build cat1: cat in1\n"
470 "build cat2: cat in1 in2\n"
471 "build cat12: cat cat1 cat2\n");
472 
473  fs_.Create("in1", "");
474  fs_.Create("in2", "");
475  }
476 
478  builder_.command_runner_.release();
479  }
480 
481  virtual bool IsPathDead(StringPiece s) const { return false; }
482 
483  /// Rebuild target in the 'working tree' (fs_).
484  /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
485  /// Handy to check for NOOP builds, and higher-level rebuild tests.
486  void RebuildTarget(const string& target, const char* manifest,
487  const char* log_path = NULL, const char* deps_path = NULL,
488  State* state = NULL);
489 
490  // Mark a path dirty.
491  void Dirty(const string& path);
492 
494  BuildConfig config;
495  config.verbosity = BuildConfig::QUIET;
496  return config;
497  }
498 
503 
505 };
506 
507 void BuildTest::RebuildTarget(const string& target, const char* manifest,
508  const char* log_path, const char* deps_path,
509  State* state) {
510  State local_state, *pstate = &local_state;
511  if (state)
512  pstate = state;
514  AssertParse(pstate, manifest);
515 
516  string err;
517  BuildLog build_log, *pbuild_log = NULL;
518  if (log_path) {
519  ASSERT_TRUE(build_log.Load(log_path, &err));
520  ASSERT_TRUE(build_log.OpenForWrite(log_path, *this, &err));
521  ASSERT_EQ("", err);
522  pbuild_log = &build_log;
523  }
524 
525  DepsLog deps_log, *pdeps_log = NULL;
526  if (deps_path) {
527  ASSERT_TRUE(deps_log.Load(deps_path, pstate, &err));
528  ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
529  ASSERT_EQ("", err);
530  pdeps_log = &deps_log;
531  }
532 
533  Builder builder(pstate, config_, pbuild_log, pdeps_log, &fs_);
534  EXPECT_TRUE(builder.AddTarget(target, &err));
535 
537  builder.command_runner_.reset(&command_runner_);
538  if (!builder.AlreadyUpToDate()) {
539  bool build_res = builder.Build(&err);
540  EXPECT_TRUE(build_res);
541  }
542  builder.command_runner_.release();
543 }
544 
546  // Only run one at a time.
547  return last_command_ == NULL;
548 }
549 
551  assert(!last_command_);
552  commands_ran_.push_back(edge->EvaluateCommand());
553  if (edge->rule().name() == "cat" ||
554  edge->rule().name() == "cat_rsp" ||
555  edge->rule().name() == "cat_rsp_out" ||
556  edge->rule().name() == "cc" ||
557  edge->rule().name() == "touch" ||
558  edge->rule().name() == "touch-interrupt" ||
559  edge->rule().name() == "touch-fail-tick2") {
560  for (vector<Node*>::iterator out = edge->outputs_.begin();
561  out != edge->outputs_.end(); ++out) {
562  fs_->Create((*out)->path(), "");
563  }
564  } else if (edge->rule().name() == "true" ||
565  edge->rule().name() == "fail" ||
566  edge->rule().name() == "interrupt" ||
567  edge->rule().name() == "console") {
568  // Don't do anything.
569  } else {
570  printf("unknown command\n");
571  return false;
572  }
573 
574  last_command_ = edge;
575  return true;
576 }
577 
579  if (!last_command_)
580  return false;
581 
582  Edge* edge = last_command_;
583  result->edge = edge;
584 
585  if (edge->rule().name() == "interrupt" ||
586  edge->rule().name() == "touch-interrupt") {
587  result->status = ExitInterrupted;
588  return true;
589  }
590 
591  if (edge->rule().name() == "console") {
592  if (edge->use_console())
593  result->status = ExitSuccess;
594  else
595  result->status = ExitFailure;
596  last_command_ = NULL;
597  return true;
598  }
599 
600  if (edge->rule().name() == "fail" ||
601  (edge->rule().name() == "touch-fail-tick2" && fs_->now_ == 2))
602  result->status = ExitFailure;
603  else
604  result->status = ExitSuccess;
605  last_command_ = NULL;
606  return true;
607 }
608 
610  vector<Edge*> edges;
611  if (last_command_)
612  edges.push_back(last_command_);
613  return edges;
614 }
615 
617  last_command_ = NULL;
618 }
619 
620 void BuildTest::Dirty(const string& path) {
621  Node* node = GetNode(path);
622  node->MarkDirty();
623 
624  // If it's an input file, mark that we've already stat()ed it and
625  // it's missing.
626  if (!node->in_edge())
627  node->MarkMissing();
628 }
629 
630 TEST_F(BuildTest, NoWork) {
631  string err;
632  EXPECT_TRUE(builder_.AlreadyUpToDate());
633 }
634 
635 TEST_F(BuildTest, OneStep) {
636  // Given a dirty target with one ready input,
637  // we should rebuild the target.
638  Dirty("cat1");
639  string err;
640  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
641  ASSERT_EQ("", err);
642  EXPECT_TRUE(builder_.Build(&err));
643  ASSERT_EQ("", err);
644 
645  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
646  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
647 }
648 
649 TEST_F(BuildTest, OneStep2) {
650  // Given a target with one dirty input,
651  // we should rebuild the target.
652  Dirty("cat1");
653  string err;
654  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
655  ASSERT_EQ("", err);
656  EXPECT_TRUE(builder_.Build(&err));
657  EXPECT_EQ("", err);
658 
659  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
660  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
661 }
662 
663 TEST_F(BuildTest, TwoStep) {
664  string err;
665  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
666  ASSERT_EQ("", err);
667  EXPECT_TRUE(builder_.Build(&err));
668  EXPECT_EQ("", err);
669  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
670  // Depending on how the pointers work out, we could've ran
671  // the first two commands in either order.
672  EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
673  command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
674  (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
675  command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
676 
677  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
678 
679  fs_.Tick();
680 
681  // Modifying in2 requires rebuilding one intermediate file
682  // and the final file.
683  fs_.Create("in2", "");
684  state_.Reset();
685  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
686  ASSERT_EQ("", err);
687  EXPECT_TRUE(builder_.Build(&err));
688  ASSERT_EQ("", err);
689  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
690  EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
691  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
692 }
693 
694 TEST_F(BuildTest, TwoOutputs) {
696 "rule touch\n"
697 " command = touch $out\n"
698 "build out1 out2: touch in.txt\n"));
699 
700  fs_.Create("in.txt", "");
701 
702  string err;
703  EXPECT_TRUE(builder_.AddTarget("out1", &err));
704  ASSERT_EQ("", err);
705  EXPECT_TRUE(builder_.Build(&err));
706  EXPECT_EQ("", err);
707  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
708  EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
709 }
710 
711 TEST_F(BuildTest, ImplicitOutput) {
713 "rule touch\n"
714 " command = touch $out $out.imp\n"
715 "build out | out.imp: touch in.txt\n"));
716  fs_.Create("in.txt", "");
717 
718  string err;
719  EXPECT_TRUE(builder_.AddTarget("out.imp", &err));
720  ASSERT_EQ("", err);
721  EXPECT_TRUE(builder_.Build(&err));
722  EXPECT_EQ("", err);
723  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
724  EXPECT_EQ("touch out out.imp", command_runner_.commands_ran_[0]);
725 }
726 
727 // Test case from
728 // https://github.com/ninja-build/ninja/issues/148
729 TEST_F(BuildTest, MultiOutIn) {
731 "rule touch\n"
732 " command = touch $out\n"
733 "build in1 otherfile: touch in\n"
734 "build out: touch in | in1\n"));
735 
736  fs_.Create("in", "");
737  fs_.Tick();
738  fs_.Create("in1", "");
739 
740  string err;
741  EXPECT_TRUE(builder_.AddTarget("out", &err));
742  ASSERT_EQ("", err);
743  EXPECT_TRUE(builder_.Build(&err));
744  EXPECT_EQ("", err);
745 }
746 
747 TEST_F(BuildTest, Chain) {
749 "build c2: cat c1\n"
750 "build c3: cat c2\n"
751 "build c4: cat c3\n"
752 "build c5: cat c4\n"));
753 
754  fs_.Create("c1", "");
755 
756  string err;
757  EXPECT_TRUE(builder_.AddTarget("c5", &err));
758  ASSERT_EQ("", err);
759  EXPECT_TRUE(builder_.Build(&err));
760  EXPECT_EQ("", err);
761  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
762 
763  err.clear();
764  command_runner_.commands_ran_.clear();
765  state_.Reset();
766  EXPECT_TRUE(builder_.AddTarget("c5", &err));
767  ASSERT_EQ("", err);
768  EXPECT_TRUE(builder_.AlreadyUpToDate());
769 
770  fs_.Tick();
771 
772  fs_.Create("c3", "");
773  err.clear();
774  command_runner_.commands_ran_.clear();
775  state_.Reset();
776  EXPECT_TRUE(builder_.AddTarget("c5", &err));
777  ASSERT_EQ("", err);
778  EXPECT_FALSE(builder_.AlreadyUpToDate());
779  EXPECT_TRUE(builder_.Build(&err));
780  ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // 3->4, 4->5
781 }
782 
783 TEST_F(BuildTest, MissingInput) {
784  // Input is referenced by build file, but no rule for it.
785  string err;
786  Dirty("in1");
787  EXPECT_FALSE(builder_.AddTarget("cat1", &err));
788  EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
789  err);
790 }
791 
792 TEST_F(BuildTest, MissingTarget) {
793  // Target is not referenced by build file.
794  string err;
795  EXPECT_FALSE(builder_.AddTarget("meow", &err));
796  EXPECT_EQ("unknown target: 'meow'", err);
797 }
798 
799 TEST_F(BuildTest, MakeDirs) {
800  string err;
801 
802 #ifdef _WIN32
804  "build subdir\\dir2\\file: cat in1\n"));
805 #else
807  "build subdir/dir2/file: cat in1\n"));
808 #endif
809  EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
810 
811  EXPECT_EQ("", err);
812  EXPECT_TRUE(builder_.Build(&err));
813  ASSERT_EQ("", err);
814  ASSERT_EQ(2u, fs_.directories_made_.size());
815  EXPECT_EQ("subdir", fs_.directories_made_[0]);
816  EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
817 }
818 
819 TEST_F(BuildTest, DepFileMissing) {
820  string err;
822 "rule cc\n command = cc $in\n depfile = $out.d\n"
823 "build fo$ o.o: cc foo.c\n"));
824  fs_.Create("foo.c", "");
825 
826  EXPECT_TRUE(builder_.AddTarget("fo o.o", &err));
827  ASSERT_EQ("", err);
828  ASSERT_EQ(1u, fs_.files_read_.size());
829  EXPECT_EQ("fo o.o.d", fs_.files_read_[0]);
830 }
831 
832 TEST_F(BuildTest, DepFileOK) {
833  string err;
834  int orig_edges = state_.edges_.size();
836 "rule cc\n command = cc $in\n depfile = $out.d\n"
837 "build foo.o: cc foo.c\n"));
838  Edge* edge = state_.edges_.back();
839 
840  fs_.Create("foo.c", "");
841  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
842  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
843  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
844  ASSERT_EQ("", err);
845  ASSERT_EQ(1u, fs_.files_read_.size());
846  EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
847 
848  // Expect three new edges: one generating foo.o, and two more from
849  // loading the depfile.
850  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
851  // Expect our edge to now have three inputs: foo.c and two headers.
852  ASSERT_EQ(3u, edge->inputs_.size());
853 
854  // Expect the command line we generate to only use the original input.
855  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
856 }
857 
858 TEST_F(BuildTest, DepFileParseError) {
859  string err;
861 "rule cc\n command = cc $in\n depfile = $out.d\n"
862 "build foo.o: cc foo.c\n"));
863  fs_.Create("foo.c", "");
864  fs_.Create("foo.o.d", "randomtext\n");
865  EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
866  EXPECT_EQ("foo.o.d: expected ':' in depfile", err);
867 }
868 
869 TEST_F(BuildTest, EncounterReadyTwice) {
870  string err;
872 "rule touch\n"
873 " command = touch $out\n"
874 "build c: touch\n"
875 "build b: touch || c\n"
876 "build a: touch | b || c\n"));
877 
878  vector<Edge*> c_out = GetNode("c")->out_edges();
879  ASSERT_EQ(2u, c_out.size());
880  EXPECT_EQ("b", c_out[0]->outputs_[0]->path());
881  EXPECT_EQ("a", c_out[1]->outputs_[0]->path());
882 
883  fs_.Create("b", "");
884  EXPECT_TRUE(builder_.AddTarget("a", &err));
885  ASSERT_EQ("", err);
886 
887  EXPECT_TRUE(builder_.Build(&err));
888  ASSERT_EQ("", err);
889  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
890 }
891 
892 TEST_F(BuildTest, OrderOnlyDeps) {
893  string err;
895 "rule cc\n command = cc $in\n depfile = $out.d\n"
896 "build foo.o: cc foo.c || otherfile\n"));
897  Edge* edge = state_.edges_.back();
898 
899  fs_.Create("foo.c", "");
900  fs_.Create("otherfile", "");
901  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
902  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
903  ASSERT_EQ("", err);
904 
905  // One explicit, two implicit, one order only.
906  ASSERT_EQ(4u, edge->inputs_.size());
907  EXPECT_EQ(2, edge->implicit_deps_);
908  EXPECT_EQ(1, edge->order_only_deps_);
909  // Verify the inputs are in the order we expect
910  // (explicit then implicit then orderonly).
911  EXPECT_EQ("foo.c", edge->inputs_[0]->path());
912  EXPECT_EQ("blah.h", edge->inputs_[1]->path());
913  EXPECT_EQ("bar.h", edge->inputs_[2]->path());
914  EXPECT_EQ("otherfile", edge->inputs_[3]->path());
915 
916  // Expect the command line we generate to only use the original input.
917  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
918 
919  // explicit dep dirty, expect a rebuild.
920  EXPECT_TRUE(builder_.Build(&err));
921  ASSERT_EQ("", err);
922  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
923 
924  fs_.Tick();
925 
926  // Recreate the depfile, as it should have been deleted by the build.
927  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
928 
929  // implicit dep dirty, expect a rebuild.
930  fs_.Create("blah.h", "");
931  fs_.Create("bar.h", "");
932  command_runner_.commands_ran_.clear();
933  state_.Reset();
934  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
935  EXPECT_TRUE(builder_.Build(&err));
936  ASSERT_EQ("", err);
937  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
938 
939  fs_.Tick();
940 
941  // Recreate the depfile, as it should have been deleted by the build.
942  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
943 
944  // order only dep dirty, no rebuild.
945  fs_.Create("otherfile", "");
946  command_runner_.commands_ran_.clear();
947  state_.Reset();
948  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
949  EXPECT_EQ("", err);
950  EXPECT_TRUE(builder_.AlreadyUpToDate());
951 
952  // implicit dep missing, expect rebuild.
953  fs_.RemoveFile("bar.h");
954  command_runner_.commands_ran_.clear();
955  state_.Reset();
956  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
957  EXPECT_TRUE(builder_.Build(&err));
958  ASSERT_EQ("", err);
959  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
960 }
961 
962 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
963  string err;
965 "rule cc\n command = cc $in\n"
966 "rule true\n command = true\n"
967 "build oo.h: cc oo.h.in\n"
968 "build foo.o: cc foo.c || oo.h\n"));
969 
970  fs_.Create("foo.c", "");
971  fs_.Create("oo.h.in", "");
972 
973  // foo.o and order-only dep dirty, build both.
974  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
975  EXPECT_TRUE(builder_.Build(&err));
976  ASSERT_EQ("", err);
977  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
978 
979  // all clean, no rebuild.
980  command_runner_.commands_ran_.clear();
981  state_.Reset();
982  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
983  EXPECT_EQ("", err);
984  EXPECT_TRUE(builder_.AlreadyUpToDate());
985 
986  // order-only dep missing, build it only.
987  fs_.RemoveFile("oo.h");
988  command_runner_.commands_ran_.clear();
989  state_.Reset();
990  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
991  EXPECT_TRUE(builder_.Build(&err));
992  ASSERT_EQ("", err);
993  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
994  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
995 
996  fs_.Tick();
997 
998  // order-only dep dirty, build it only.
999  fs_.Create("oo.h.in", "");
1000  command_runner_.commands_ran_.clear();
1001  state_.Reset();
1002  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
1003  EXPECT_TRUE(builder_.Build(&err));
1004  ASSERT_EQ("", err);
1005  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1006  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
1007 }
1008 
1009 #ifdef _WIN32
1010 TEST_F(BuildTest, DepFileCanonicalize) {
1011  string err;
1012  int orig_edges = state_.edges_.size();
1014 "rule cc\n command = cc $in\n depfile = $out.d\n"
1015 "build gen/stuff\\things/foo.o: cc x\\y/z\\foo.c\n"));
1016  Edge* edge = state_.edges_.back();
1017 
1018  fs_.Create("x/y/z/foo.c", "");
1019  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
1020  // Note, different slashes from manifest.
1021  fs_.Create("gen/stuff\\things/foo.o.d",
1022  "gen\\stuff\\things\\foo.o: blah.h bar.h\n");
1023  EXPECT_TRUE(builder_.AddTarget("gen/stuff/things/foo.o", &err));
1024  ASSERT_EQ("", err);
1025  ASSERT_EQ(1u, fs_.files_read_.size());
1026  // The depfile path does not get Canonicalize as it seems unnecessary.
1027  EXPECT_EQ("gen/stuff\\things/foo.o.d", fs_.files_read_[0]);
1028 
1029  // Expect three new edges: one generating foo.o, and two more from
1030  // loading the depfile.
1031  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
1032  // Expect our edge to now have three inputs: foo.c and two headers.
1033  ASSERT_EQ(3u, edge->inputs_.size());
1034 
1035  // Expect the command line we generate to only use the original input, and
1036  // using the slashes from the manifest.
1037  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
1038 }
1039 #endif
1040 
1042  string err;
1044 "build out: cat bar.cc\n"
1045 "build all: phony out\n"));
1046  fs_.Create("bar.cc", "");
1047 
1048  EXPECT_TRUE(builder_.AddTarget("all", &err));
1049  ASSERT_EQ("", err);
1050 
1051  // Only one command to run, because phony runs no command.
1052  EXPECT_FALSE(builder_.AlreadyUpToDate());
1053  EXPECT_TRUE(builder_.Build(&err));
1054  ASSERT_EQ("", err);
1055  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1056 }
1057 
1058 TEST_F(BuildTest, PhonyNoWork) {
1059  string err;
1061 "build out: cat bar.cc\n"
1062 "build all: phony out\n"));
1063  fs_.Create("bar.cc", "");
1064  fs_.Create("out", "");
1065 
1066  EXPECT_TRUE(builder_.AddTarget("all", &err));
1067  ASSERT_EQ("", err);
1068  EXPECT_TRUE(builder_.AlreadyUpToDate());
1069 }
1070 
1071 // Test a self-referencing phony. Ideally this should not work, but
1072 // ninja 1.7 and below tolerated and CMake 2.8.12.x and 3.0.x both
1073 // incorrectly produce it. We tolerate it for compatibility.
1074 TEST_F(BuildTest, PhonySelfReference) {
1075  string err;
1077 "build a: phony a\n"));
1078 
1079  EXPECT_TRUE(builder_.AddTarget("a", &err));
1080  ASSERT_EQ("", err);
1081  EXPECT_TRUE(builder_.AlreadyUpToDate());
1082 }
1083 
1086 "rule fail\n"
1087 " command = fail\n"
1088 "build out1: fail\n"));
1089 
1090  string err;
1091  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1092  ASSERT_EQ("", err);
1093 
1094  EXPECT_FALSE(builder_.Build(&err));
1095  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1096  ASSERT_EQ("subcommand failed", err);
1097 }
1098 
1099 TEST_F(BuildTest, SwallowFailures) {
1101 "rule fail\n"
1102 " command = fail\n"
1103 "build out1: fail\n"
1104 "build out2: fail\n"
1105 "build out3: fail\n"
1106 "build all: phony out1 out2 out3\n"));
1107 
1108  // Swallow two failures, die on the third.
1109  config_.failures_allowed = 3;
1110 
1111  string err;
1112  EXPECT_TRUE(builder_.AddTarget("all", &err));
1113  ASSERT_EQ("", err);
1114 
1115  EXPECT_FALSE(builder_.Build(&err));
1116  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1117  ASSERT_EQ("subcommands failed", err);
1118 }
1119 
1120 TEST_F(BuildTest, SwallowFailuresLimit) {
1122 "rule fail\n"
1123 " command = fail\n"
1124 "build out1: fail\n"
1125 "build out2: fail\n"
1126 "build out3: fail\n"
1127 "build final: cat out1 out2 out3\n"));
1128 
1129  // Swallow ten failures; we should stop before building final.
1130  config_.failures_allowed = 11;
1131 
1132  string err;
1133  EXPECT_TRUE(builder_.AddTarget("final", &err));
1134  ASSERT_EQ("", err);
1135 
1136  EXPECT_FALSE(builder_.Build(&err));
1137  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1138  ASSERT_EQ("cannot make progress due to previous errors", err);
1139 }
1140 
1141 TEST_F(BuildTest, SwallowFailuresPool) {
1143 "pool failpool\n"
1144 " depth = 1\n"
1145 "rule fail\n"
1146 " command = fail\n"
1147 " pool = failpool\n"
1148 "build out1: fail\n"
1149 "build out2: fail\n"
1150 "build out3: fail\n"
1151 "build final: cat out1 out2 out3\n"));
1152 
1153  // Swallow ten failures; we should stop before building final.
1154  config_.failures_allowed = 11;
1155 
1156  string err;
1157  EXPECT_TRUE(builder_.AddTarget("final", &err));
1158  ASSERT_EQ("", err);
1159 
1160  EXPECT_FALSE(builder_.Build(&err));
1161  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1162  ASSERT_EQ("cannot make progress due to previous errors", err);
1163 }
1164 
1165 TEST_F(BuildTest, PoolEdgesReadyButNotWanted) {
1166  fs_.Create("x", "");
1167 
1168  const char* manifest =
1169  "pool some_pool\n"
1170  " depth = 4\n"
1171  "rule touch\n"
1172  " command = touch $out\n"
1173  " pool = some_pool\n"
1174  "rule cc\n"
1175  " command = touch grit\n"
1176  "\n"
1177  "build B.d.stamp: cc | x\n"
1178  "build C.stamp: touch B.d.stamp\n"
1179  "build final.stamp: touch || C.stamp\n";
1180 
1181  RebuildTarget("final.stamp", manifest);
1182 
1183  fs_.RemoveFile("B.d.stamp");
1184 
1185  State save_state;
1186  RebuildTarget("final.stamp", manifest, NULL, NULL, &save_state);
1187  EXPECT_GE(save_state.LookupPool("some_pool")->current_use(), 0);
1188 }
1189 
1190 struct BuildWithLogTest : public BuildTest {
1193  }
1194 
1196 };
1197 
1198 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1200 "rule cc\n"
1201 " command = cc\n"
1202 "build out1: cc in\n"));
1203 
1204  // Create input/output that would be considered up to date when
1205  // not considering the command line hash.
1206  fs_.Create("in", "");
1207  fs_.Create("out1", "");
1208  string err;
1209 
1210  // Because it's not in the log, it should not be up-to-date until
1211  // we build again.
1212  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1213  EXPECT_FALSE(builder_.AlreadyUpToDate());
1214 
1215  command_runner_.commands_ran_.clear();
1216  state_.Reset();
1217 
1218  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1219  EXPECT_TRUE(builder_.Build(&err));
1220  EXPECT_TRUE(builder_.AlreadyUpToDate());
1221 }
1222 
1223 TEST_F(BuildWithLogTest, RebuildAfterFailure) {
1225 "rule touch-fail-tick2\n"
1226 " command = touch-fail-tick2\n"
1227 "build out1: touch-fail-tick2 in\n"));
1228 
1229  string err;
1230 
1231  fs_.Create("in", "");
1232 
1233  // Run once successfully to get out1 in the log
1234  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1235  EXPECT_TRUE(builder_.Build(&err));
1236  EXPECT_EQ("", err);
1237  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1238 
1239  command_runner_.commands_ran_.clear();
1240  state_.Reset();
1241  builder_.Cleanup();
1242  builder_.plan_.Reset();
1243 
1244  fs_.Tick();
1245  fs_.Create("in", "");
1246 
1247  // Run again with a failure that updates the output file timestamp
1248  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1249  EXPECT_FALSE(builder_.Build(&err));
1250  EXPECT_EQ("subcommand failed", err);
1251  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1252 
1253  command_runner_.commands_ran_.clear();
1254  state_.Reset();
1255  builder_.Cleanup();
1256  builder_.plan_.Reset();
1257 
1258  fs_.Tick();
1259 
1260  // Run again, should rerun even though the output file is up to date on disk
1261  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1262  EXPECT_FALSE(builder_.AlreadyUpToDate());
1263  EXPECT_TRUE(builder_.Build(&err));
1264  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1265  EXPECT_EQ("", err);
1266 }
1267 
1268 TEST_F(BuildWithLogTest, RebuildWithNoInputs) {
1270 "rule touch\n"
1271 " command = touch\n"
1272 "build out1: touch\n"
1273 "build out2: touch in\n"));
1274 
1275  string err;
1276 
1277  fs_.Create("in", "");
1278 
1279  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1280  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1281  EXPECT_TRUE(builder_.Build(&err));
1282  EXPECT_EQ("", err);
1283  EXPECT_EQ(2u, command_runner_.commands_ran_.size());
1284 
1285  command_runner_.commands_ran_.clear();
1286  state_.Reset();
1287 
1288  fs_.Tick();
1289 
1290  fs_.Create("in", "");
1291 
1292  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1293  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1294  EXPECT_TRUE(builder_.Build(&err));
1295  EXPECT_EQ("", err);
1296  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1297 }
1298 
1299 TEST_F(BuildWithLogTest, RestatTest) {
1301 "rule true\n"
1302 " command = true\n"
1303 " restat = 1\n"
1304 "rule cc\n"
1305 " command = cc\n"
1306 " restat = 1\n"
1307 "build out1: cc in\n"
1308 "build out2: true out1\n"
1309 "build out3: cat out2\n"));
1310 
1311  fs_.Create("out1", "");
1312  fs_.Create("out2", "");
1313  fs_.Create("out3", "");
1314 
1315  fs_.Tick();
1316 
1317  fs_.Create("in", "");
1318 
1319  // Do a pre-build so that there's commands in the log for the outputs,
1320  // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1321  // regardless of restat.
1322  string err;
1323  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1324  ASSERT_EQ("", err);
1325  EXPECT_TRUE(builder_.Build(&err));
1326  ASSERT_EQ("", err);
1327  EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]",
1329  command_runner_.commands_ran_.clear();
1330  state_.Reset();
1331 
1332  fs_.Tick();
1333 
1334  fs_.Create("in", "");
1335  // "cc" touches out1, so we should build out2. But because "true" does not
1336  // touch out2, we should cancel the build of out3.
1337  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1338  ASSERT_EQ("", err);
1339  EXPECT_TRUE(builder_.Build(&err));
1340  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1341 
1342  // If we run again, it should be a no-op, because the build log has recorded
1343  // that we've already built out2 with an input timestamp of 2 (from out1).
1344  command_runner_.commands_ran_.clear();
1345  state_.Reset();
1346  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1347  ASSERT_EQ("", err);
1348  EXPECT_TRUE(builder_.AlreadyUpToDate());
1349 
1350  fs_.Tick();
1351 
1352  fs_.Create("in", "");
1353 
1354  // The build log entry should not, however, prevent us from rebuilding out2
1355  // if out1 changes.
1356  command_runner_.commands_ran_.clear();
1357  state_.Reset();
1358  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1359  ASSERT_EQ("", err);
1360  EXPECT_TRUE(builder_.Build(&err));
1361  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1362 }
1363 
1364 TEST_F(BuildWithLogTest, RestatMissingFile) {
1365  // If a restat rule doesn't create its output, and the output didn't
1366  // exist before the rule was run, consider that behavior equivalent
1367  // to a rule that doesn't modify its existent output file.
1368 
1370 "rule true\n"
1371 " command = true\n"
1372 " restat = 1\n"
1373 "rule cc\n"
1374 " command = cc\n"
1375 "build out1: true in\n"
1376 "build out2: cc out1\n"));
1377 
1378  fs_.Create("in", "");
1379  fs_.Create("out2", "");
1380 
1381  // Do a pre-build so that there's commands in the log for the outputs,
1382  // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1383  // regardless of restat.
1384  string err;
1385  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1386  ASSERT_EQ("", err);
1387  EXPECT_TRUE(builder_.Build(&err));
1388  ASSERT_EQ("", err);
1389  command_runner_.commands_ran_.clear();
1390  state_.Reset();
1391 
1392  fs_.Tick();
1393  fs_.Create("in", "");
1394  fs_.Create("out2", "");
1395 
1396  // Run a build, expect only the first command to run.
1397  // It doesn't touch its output (due to being the "true" command), so
1398  // we shouldn't run the dependent build.
1399  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1400  ASSERT_EQ("", err);
1401  EXPECT_TRUE(builder_.Build(&err));
1402  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1403 }
1404 
1405 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1407  "rule true\n"
1408  " command = true\n"
1409  " restat = 1\n"
1410  "rule touch\n"
1411  " command = touch\n"
1412  "build out1: true in\n"
1413  "build out2 out3: touch out1\n"
1414  "build out4: touch out2\n"
1415  ));
1416 
1417  // Create the necessary files
1418  fs_.Create("in", "");
1419 
1420  string err;
1421  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1422  ASSERT_EQ("", err);
1423  EXPECT_TRUE(builder_.Build(&err));
1424  ASSERT_EQ("", err);
1425  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1426 
1427  fs_.Tick();
1428  fs_.Create("in", "");
1429  fs_.RemoveFile("out3");
1430 
1431  // Since "in" is missing, out1 will be built. Since "out3" is missing,
1432  // out2 and out3 will be built even though "in" is not touched when built.
1433  // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1434  // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1435  // cleard.
1436  command_runner_.commands_ran_.clear();
1437  state_.Reset();
1438  EXPECT_TRUE(builder_.AddTarget("out4", &err));
1439  ASSERT_EQ("", err);
1440  EXPECT_TRUE(builder_.Build(&err));
1441  ASSERT_EQ("", err);
1442  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1443 }
1444 
1445 // Test scenario, in which an input file is removed, but output isn't changed
1446 // https://github.com/ninja-build/ninja/issues/295
1447 TEST_F(BuildWithLogTest, RestatMissingInput) {
1449  "rule true\n"
1450  " command = true\n"
1451  " depfile = $out.d\n"
1452  " restat = 1\n"
1453  "rule cc\n"
1454  " command = cc\n"
1455  "build out1: true in\n"
1456  "build out2: cc out1\n"));
1457 
1458  // Create all necessary files
1459  fs_.Create("in", "");
1460 
1461  // The implicit dependencies and the depfile itself
1462  // are newer than the output
1463  TimeStamp restat_mtime = fs_.Tick();
1464  fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1465  fs_.Create("will.be.deleted", "");
1466  fs_.Create("restat.file", "");
1467 
1468  // Run the build, out1 and out2 get built
1469  string err;
1470  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1471  ASSERT_EQ("", err);
1472  EXPECT_TRUE(builder_.Build(&err));
1473  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1474 
1475  // See that an entry in the logfile is created, capturing
1476  // the right mtime
1477  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1478  ASSERT_TRUE(NULL != log_entry);
1479  ASSERT_EQ(restat_mtime, log_entry->mtime);
1480 
1481  // Now remove a file, referenced from depfile, so that target becomes
1482  // dirty, but the output does not change
1483  fs_.RemoveFile("will.be.deleted");
1484 
1485  // Trigger the build again - only out1 gets built
1486  command_runner_.commands_ran_.clear();
1487  state_.Reset();
1488  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1489  ASSERT_EQ("", err);
1490  EXPECT_TRUE(builder_.Build(&err));
1491  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1492 
1493  // Check that the logfile entry remains correctly set
1494  log_entry = build_log_.LookupByOutput("out1");
1495  ASSERT_TRUE(NULL != log_entry);
1496  ASSERT_EQ(restat_mtime, log_entry->mtime);
1497 }
1498 
1501  config_.dry_run = true;
1502  }
1503 };
1504 
1505 TEST_F(BuildDryRun, AllCommandsShown) {
1507 "rule true\n"
1508 " command = true\n"
1509 " restat = 1\n"
1510 "rule cc\n"
1511 " command = cc\n"
1512 " restat = 1\n"
1513 "build out1: cc in\n"
1514 "build out2: true out1\n"
1515 "build out3: cat out2\n"));
1516 
1517  fs_.Create("out1", "");
1518  fs_.Create("out2", "");
1519  fs_.Create("out3", "");
1520 
1521  fs_.Tick();
1522 
1523  fs_.Create("in", "");
1524 
1525  // "cc" touches out1, so we should build out2. But because "true" does not
1526  // touch out2, we should cancel the build of out3.
1527  string err;
1528  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1529  ASSERT_EQ("", err);
1530  EXPECT_TRUE(builder_.Build(&err));
1531  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1532 }
1533 
1534 // Test that RSP files are created when & where appropriate and deleted after
1535 // successful execution.
1536 TEST_F(BuildTest, RspFileSuccess)
1537 {
1539  "rule cat_rsp\n"
1540  " command = cat $rspfile > $out\n"
1541  " rspfile = $rspfile\n"
1542  " rspfile_content = $long_command\n"
1543  "rule cat_rsp_out\n"
1544  " command = cat $rspfile > $out\n"
1545  " rspfile = $out.rsp\n"
1546  " rspfile_content = $long_command\n"
1547  "build out1: cat in\n"
1548  "build out2: cat_rsp in\n"
1549  " rspfile = out 2.rsp\n"
1550  " long_command = Some very long command\n"
1551  "build out$ 3: cat_rsp_out in\n"
1552  " long_command = Some very long command\n"));
1553 
1554  fs_.Create("out1", "");
1555  fs_.Create("out2", "");
1556  fs_.Create("out 3", "");
1557 
1558  fs_.Tick();
1559 
1560  fs_.Create("in", "");
1561 
1562  string err;
1563  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1564  ASSERT_EQ("", err);
1565  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1566  ASSERT_EQ("", err);
1567  EXPECT_TRUE(builder_.AddTarget("out 3", &err));
1568  ASSERT_EQ("", err);
1569 
1570  size_t files_created = fs_.files_created_.size();
1571  size_t files_removed = fs_.files_removed_.size();
1572 
1573  EXPECT_TRUE(builder_.Build(&err));
1574  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1575 
1576  // The RSP files were created
1577  ASSERT_EQ(files_created + 2, fs_.files_created_.size());
1578  ASSERT_EQ(1u, fs_.files_created_.count("out 2.rsp"));
1579  ASSERT_EQ(1u, fs_.files_created_.count("out 3.rsp"));
1580 
1581  // The RSP files were removed
1582  ASSERT_EQ(files_removed + 2, fs_.files_removed_.size());
1583  ASSERT_EQ(1u, fs_.files_removed_.count("out 2.rsp"));
1584  ASSERT_EQ(1u, fs_.files_removed_.count("out 3.rsp"));
1585 }
1586 
1587 // Test that RSP file is created but not removed for commands, which fail
1588 TEST_F(BuildTest, RspFileFailure) {
1590  "rule fail\n"
1591  " command = fail\n"
1592  " rspfile = $rspfile\n"
1593  " rspfile_content = $long_command\n"
1594  "build out: fail in\n"
1595  " rspfile = out.rsp\n"
1596  " long_command = Another very long command\n"));
1597 
1598  fs_.Create("out", "");
1599  fs_.Tick();
1600  fs_.Create("in", "");
1601 
1602  string err;
1603  EXPECT_TRUE(builder_.AddTarget("out", &err));
1604  ASSERT_EQ("", err);
1605 
1606  size_t files_created = fs_.files_created_.size();
1607  size_t files_removed = fs_.files_removed_.size();
1608 
1609  EXPECT_FALSE(builder_.Build(&err));
1610  ASSERT_EQ("subcommand failed", err);
1611  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1612 
1613  // The RSP file was created
1614  ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1615  ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1616 
1617  // The RSP file was NOT removed
1618  ASSERT_EQ(files_removed, fs_.files_removed_.size());
1619  ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1620 
1621  // The RSP file contains what it should
1622  ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1623 }
1624 
1625 // Test that contents of the RSP file behaves like a regular part of
1626 // command line, i.e. triggers a rebuild if changed
1627 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1629  "rule cat_rsp\n"
1630  " command = cat $rspfile > $out\n"
1631  " rspfile = $rspfile\n"
1632  " rspfile_content = $long_command\n"
1633  "build out: cat_rsp in\n"
1634  " rspfile = out.rsp\n"
1635  " long_command = Original very long command\n"));
1636 
1637  fs_.Create("out", "");
1638  fs_.Tick();
1639  fs_.Create("in", "");
1640 
1641  string err;
1642  EXPECT_TRUE(builder_.AddTarget("out", &err));
1643  ASSERT_EQ("", err);
1644 
1645  // 1. Build for the 1st time (-> populate log)
1646  EXPECT_TRUE(builder_.Build(&err));
1647  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1648 
1649  // 2. Build again (no change)
1650  command_runner_.commands_ran_.clear();
1651  state_.Reset();
1652  EXPECT_TRUE(builder_.AddTarget("out", &err));
1653  EXPECT_EQ("", err);
1654  ASSERT_TRUE(builder_.AlreadyUpToDate());
1655 
1656  // 3. Alter the entry in the logfile
1657  // (to simulate a change in the command line between 2 builds)
1658  BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1659  ASSERT_TRUE(NULL != log_entry);
1661  "cat out.rsp > out;rspfile=Original very long command",
1662  log_entry->command_hash));
1663  log_entry->command_hash++; // Change the command hash to something else.
1664  // Now expect the target to be rebuilt
1665  command_runner_.commands_ran_.clear();
1666  state_.Reset();
1667  EXPECT_TRUE(builder_.AddTarget("out", &err));
1668  EXPECT_EQ("", err);
1669  EXPECT_TRUE(builder_.Build(&err));
1670  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1671 }
1672 
1673 TEST_F(BuildTest, InterruptCleanup) {
1675 "rule interrupt\n"
1676 " command = interrupt\n"
1677 "rule touch-interrupt\n"
1678 " command = touch-interrupt\n"
1679 "build out1: interrupt in1\n"
1680 "build out2: touch-interrupt in2\n"));
1681 
1682  fs_.Create("out1", "");
1683  fs_.Create("out2", "");
1684  fs_.Tick();
1685  fs_.Create("in1", "");
1686  fs_.Create("in2", "");
1687 
1688  // An untouched output of an interrupted command should be retained.
1689  string err;
1690  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1691  EXPECT_EQ("", err);
1692  EXPECT_FALSE(builder_.Build(&err));
1693  EXPECT_EQ("interrupted by user", err);
1694  builder_.Cleanup();
1695  EXPECT_GT(fs_.Stat("out1", &err), 0);
1696  err = "";
1697 
1698  // A touched output of an interrupted command should be deleted.
1699  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1700  EXPECT_EQ("", err);
1701  EXPECT_FALSE(builder_.Build(&err));
1702  EXPECT_EQ("interrupted by user", err);
1703  builder_.Cleanup();
1704  EXPECT_EQ(0, fs_.Stat("out2", &err));
1705 }
1706 
1707 TEST_F(BuildTest, StatFailureAbortsBuild) {
1708  const string kTooLongToStat(400, 'i');
1710 ("build " + kTooLongToStat + ": cat in\n").c_str()));
1711  fs_.Create("in", "");
1712 
1713  // This simulates a stat failure:
1714  fs_.files_[kTooLongToStat].mtime = -1;
1715  fs_.files_[kTooLongToStat].stat_error = "stat failed";
1716 
1717  string err;
1718  EXPECT_FALSE(builder_.AddTarget(kTooLongToStat, &err));
1719  EXPECT_EQ("stat failed", err);
1720 }
1721 
1722 TEST_F(BuildTest, PhonyWithNoInputs) {
1724 "build nonexistent: phony\n"
1725 "build out1: cat || nonexistent\n"
1726 "build out2: cat nonexistent\n"));
1727  fs_.Create("out1", "");
1728  fs_.Create("out2", "");
1729 
1730  // out1 should be up to date even though its input is dirty, because its
1731  // order-only dependency has nothing to do.
1732  string err;
1733  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1734  ASSERT_EQ("", err);
1735  EXPECT_TRUE(builder_.AlreadyUpToDate());
1736 
1737  // out2 should still be out of date though, because its input is dirty.
1738  err.clear();
1739  command_runner_.commands_ran_.clear();
1740  state_.Reset();
1741  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1742  ASSERT_EQ("", err);
1743  EXPECT_TRUE(builder_.Build(&err));
1744  EXPECT_EQ("", err);
1745  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1746 }
1747 
1748 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1750 "rule cc\n"
1751 " command = cc\n"
1752 " deps = gcc\n"
1753 "build out: cc\n"));
1754  Dirty("out");
1755 
1756  string err;
1757  EXPECT_TRUE(builder_.AddTarget("out", &err));
1758  ASSERT_EQ("", err);
1759  EXPECT_FALSE(builder_.AlreadyUpToDate());
1760 
1761  EXPECT_FALSE(builder_.Build(&err));
1762  ASSERT_EQ("subcommand failed", err);
1763  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1764 }
1765 
1766 TEST_F(BuildTest, StatusFormatElapsed) {
1767  status_.BuildStarted();
1768  // Before any task is done, the elapsed time must be zero.
1769  EXPECT_EQ("[%/e0.000]",
1770  status_.FormatProgressStatus("[%%/e%e]",
1772 }
1773 
1774 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1775  EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1776  status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]",
1778 }
1779 
1780 TEST_F(BuildTest, FailedDepsParse) {
1782 "build bad_deps.o: cat in1\n"
1783 " deps = gcc\n"
1784 " depfile = in1.d\n"));
1785 
1786  string err;
1787  EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1788  ASSERT_EQ("", err);
1789 
1790  // These deps will fail to parse, as they should only have one
1791  // path to the left of the colon.
1792  fs_.Create("in1.d", "AAA BBB");
1793 
1794  EXPECT_FALSE(builder_.Build(&err));
1795  EXPECT_EQ("subcommand failed", err);
1796 }
1797 
1798 /// Tests of builds involving deps logs necessarily must span
1799 /// multiple builds. We reuse methods on BuildTest but not the
1800 /// builder_ it sets up, because we want pristine objects for
1801 /// each build.
1804 
1805  virtual void SetUp() {
1806  BuildTest::SetUp();
1807 
1808  temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
1809  }
1810 
1811  virtual void TearDown() {
1812  temp_dir_.Cleanup();
1813  }
1814 
1816 
1817  /// Shadow parent class builder_ so we don't accidentally use it.
1818  void* builder_;
1819 };
1820 
1821 /// Run a straightforwad build where the deps log is used.
1822 TEST_F(BuildWithDepsLogTest, Straightforward) {
1823  string err;
1824  // Note: in1 was created by the superclass SetUp().
1825  const char* manifest =
1826  "build out: cat in1\n"
1827  " deps = gcc\n"
1828  " depfile = in1.d\n";
1829  {
1830  State state;
1831  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1832  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1833 
1834  // Run the build once, everything should be ok.
1835  DepsLog deps_log;
1836  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1837  ASSERT_EQ("", err);
1838 
1839  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1840  builder.command_runner_.reset(&command_runner_);
1841  EXPECT_TRUE(builder.AddTarget("out", &err));
1842  ASSERT_EQ("", err);
1843  fs_.Create("in1.d", "out: in2");
1844  EXPECT_TRUE(builder.Build(&err));
1845  EXPECT_EQ("", err);
1846 
1847  // The deps file should have been removed.
1848  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
1849  // Recreate it for the next step.
1850  fs_.Create("in1.d", "out: in2");
1851  deps_log.Close();
1852  builder.command_runner_.release();
1853  }
1854 
1855  {
1856  State state;
1857  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1858  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1859 
1860  // Touch the file only mentioned in the deps.
1861  fs_.Tick();
1862  fs_.Create("in2", "");
1863 
1864  // Run the build again.
1865  DepsLog deps_log;
1866  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1867  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1868 
1869  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1870  builder.command_runner_.reset(&command_runner_);
1871  command_runner_.commands_ran_.clear();
1872  EXPECT_TRUE(builder.AddTarget("out", &err));
1873  ASSERT_EQ("", err);
1874  EXPECT_TRUE(builder.Build(&err));
1875  EXPECT_EQ("", err);
1876 
1877  // We should have rebuilt the output due to in2 being
1878  // out of date.
1879  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1880 
1881  builder.command_runner_.release();
1882  }
1883 }
1884 
1885 /// Verify that obsolete dependency info causes a rebuild.
1886 /// 1) Run a successful build where everything has time t, record deps.
1887 /// 2) Move input/output to time t+1 -- despite files in alignment,
1888 /// should still need to rebuild due to deps at older time.
1890  string err;
1891  // Note: in1 was created by the superclass SetUp().
1892  const char* manifest =
1893  "build out: cat in1\n"
1894  " deps = gcc\n"
1895  " depfile = in1.d\n";
1896  {
1897  // Run an ordinary build that gathers dependencies.
1898  fs_.Create("in1", "");
1899  fs_.Create("in1.d", "out: ");
1900 
1901  State state;
1902  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1903  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1904 
1905  // Run the build once, everything should be ok.
1906  DepsLog deps_log;
1907  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1908  ASSERT_EQ("", err);
1909 
1910  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1911  builder.command_runner_.reset(&command_runner_);
1912  EXPECT_TRUE(builder.AddTarget("out", &err));
1913  ASSERT_EQ("", err);
1914  EXPECT_TRUE(builder.Build(&err));
1915  EXPECT_EQ("", err);
1916 
1917  deps_log.Close();
1918  builder.command_runner_.release();
1919  }
1920 
1921  // Push all files one tick forward so that only the deps are out
1922  // of date.
1923  fs_.Tick();
1924  fs_.Create("in1", "");
1925  fs_.Create("out", "");
1926 
1927  // The deps file should have been removed, so no need to timestamp it.
1928  EXPECT_EQ(0, fs_.Stat("in1.d", &err));
1929 
1930  {
1931  State state;
1932  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1933  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1934 
1935  DepsLog deps_log;
1936  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1937  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1938 
1939  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1940  builder.command_runner_.reset(&command_runner_);
1941  command_runner_.commands_ran_.clear();
1942  EXPECT_TRUE(builder.AddTarget("out", &err));
1943  ASSERT_EQ("", err);
1944 
1945  // Recreate the deps file here because the build expects them to exist.
1946  fs_.Create("in1.d", "out: ");
1947 
1948  EXPECT_TRUE(builder.Build(&err));
1949  EXPECT_EQ("", err);
1950 
1951  // We should have rebuilt the output due to the deps being
1952  // out of date.
1953  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1954 
1955  builder.command_runner_.release();
1956  }
1957 }
1958 
1959 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
1960  const char* manifest =
1961  "build out: cat in1\n"
1962  " deps = gcc\n"
1963  " depfile = in1.d\n";
1964 
1965  fs_.Create("out", "");
1966  fs_.Tick();
1967  fs_.Create("in1", "");
1968 
1969  State state;
1970  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1971  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1972 
1973  // The deps log is NULL in dry runs.
1974  config_.dry_run = true;
1975  Builder builder(&state, config_, NULL, NULL, &fs_);
1976  builder.command_runner_.reset(&command_runner_);
1977  command_runner_.commands_ran_.clear();
1978 
1979  string err;
1980  EXPECT_TRUE(builder.AddTarget("out", &err));
1981  ASSERT_EQ("", err);
1982  EXPECT_TRUE(builder.Build(&err));
1983  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1984 
1985  builder.command_runner_.release();
1986 }
1987 
1988 /// Check that a restat rule generating a header cancels compilations correctly.
1989 TEST_F(BuildTest, RestatDepfileDependency) {
1991 "rule true\n"
1992 " command = true\n" // Would be "write if out-of-date" in reality.
1993 " restat = 1\n"
1994 "build header.h: true header.in\n"
1995 "build out: cat in1\n"
1996 " depfile = in1.d\n"));
1997 
1998  fs_.Create("header.h", "");
1999  fs_.Create("in1.d", "out: header.h");
2000  fs_.Tick();
2001  fs_.Create("header.in", "");
2002 
2003  string err;
2004  EXPECT_TRUE(builder_.AddTarget("out", &err));
2005  ASSERT_EQ("", err);
2006  EXPECT_TRUE(builder_.Build(&err));
2007  EXPECT_EQ("", err);
2008 }
2009 
2010 /// Check that a restat rule generating a header cancels compilations correctly,
2011 /// depslog case.
2012 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
2013  string err;
2014  // Note: in1 was created by the superclass SetUp().
2015  const char* manifest =
2016  "rule true\n"
2017  " command = true\n" // Would be "write if out-of-date" in reality.
2018  " restat = 1\n"
2019  "build header.h: true header.in\n"
2020  "build out: cat in1\n"
2021  " deps = gcc\n"
2022  " depfile = in1.d\n";
2023  {
2024  State state;
2025  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2026  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2027 
2028  // Run the build once, everything should be ok.
2029  DepsLog deps_log;
2030  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2031  ASSERT_EQ("", err);
2032 
2033  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2034  builder.command_runner_.reset(&command_runner_);
2035  EXPECT_TRUE(builder.AddTarget("out", &err));
2036  ASSERT_EQ("", err);
2037  fs_.Create("in1.d", "out: header.h");
2038  EXPECT_TRUE(builder.Build(&err));
2039  EXPECT_EQ("", err);
2040 
2041  deps_log.Close();
2042  builder.command_runner_.release();
2043  }
2044 
2045  {
2046  State state;
2047  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2048  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2049 
2050  // Touch the input of the restat rule.
2051  fs_.Tick();
2052  fs_.Create("header.in", "");
2053 
2054  // Run the build again.
2055  DepsLog deps_log;
2056  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2057  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2058 
2059  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2060  builder.command_runner_.reset(&command_runner_);
2061  command_runner_.commands_ran_.clear();
2062  EXPECT_TRUE(builder.AddTarget("out", &err));
2063  ASSERT_EQ("", err);
2064  EXPECT_TRUE(builder.Build(&err));
2065  EXPECT_EQ("", err);
2066 
2067  // Rule "true" should have run again, but the build of "out" should have
2068  // been cancelled due to restat propagating through the depfile header.
2069  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2070 
2071  builder.command_runner_.release();
2072  }
2073 }
2074 
2075 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
2076  string err;
2077  const char* manifest =
2078  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2079  "build fo$ o.o: cc foo.c\n";
2080 
2081  fs_.Create("foo.c", "");
2082 
2083  {
2084  State state;
2085  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2086 
2087  // Run the build once, everything should be ok.
2088  DepsLog deps_log;
2089  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2090  ASSERT_EQ("", err);
2091 
2092  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2093  builder.command_runner_.reset(&command_runner_);
2094  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2095  ASSERT_EQ("", err);
2096  fs_.Create("fo o.o.d", "fo\\ o.o: blah.h bar.h\n");
2097  EXPECT_TRUE(builder.Build(&err));
2098  EXPECT_EQ("", err);
2099 
2100  deps_log.Close();
2101  builder.command_runner_.release();
2102  }
2103 
2104  {
2105  State state;
2106  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2107 
2108  DepsLog deps_log;
2109  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2110  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2111  ASSERT_EQ("", err);
2112 
2113  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2114  builder.command_runner_.reset(&command_runner_);
2115 
2116  Edge* edge = state.edges_.back();
2117 
2118  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2119  EXPECT_TRUE(builder.AddTarget("fo o.o", &err));
2120  ASSERT_EQ("", err);
2121 
2122  // Expect three new edges: one generating fo o.o, and two more from
2123  // loading the depfile.
2124  ASSERT_EQ(3u, state.edges_.size());
2125  // Expect our edge to now have three inputs: foo.c and two headers.
2126  ASSERT_EQ(3u, edge->inputs_.size());
2127 
2128  // Expect the command line we generate to only use the original input.
2129  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
2130 
2131  deps_log.Close();
2132  builder.command_runner_.release();
2133  }
2134 }
2135 
2136 #ifdef _WIN32
2137 TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
2138  string err;
2139  const char* manifest =
2140  "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
2141  "build a/b\\c\\d/e/fo$ o.o: cc x\\y/z\\foo.c\n";
2142 
2143  fs_.Create("x/y/z/foo.c", "");
2144 
2145  {
2146  State state;
2147  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2148 
2149  // Run the build once, everything should be ok.
2150  DepsLog deps_log;
2151  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2152  ASSERT_EQ("", err);
2153 
2154  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2155  builder.command_runner_.reset(&command_runner_);
2156  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2157  ASSERT_EQ("", err);
2158  // Note, different slashes from manifest.
2159  fs_.Create("a/b\\c\\d/e/fo o.o.d",
2160  "a\\b\\c\\d\\e\\fo\\ o.o: blah.h bar.h\n");
2161  EXPECT_TRUE(builder.Build(&err));
2162  EXPECT_EQ("", err);
2163 
2164  deps_log.Close();
2165  builder.command_runner_.release();
2166  }
2167 
2168  {
2169  State state;
2170  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
2171 
2172  DepsLog deps_log;
2173  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
2174  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
2175  ASSERT_EQ("", err);
2176 
2177  Builder builder(&state, config_, NULL, &deps_log, &fs_);
2178  builder.command_runner_.reset(&command_runner_);
2179 
2180  Edge* edge = state.edges_.back();
2181 
2182  state.GetNode("bar.h", 0)->MarkDirty(); // Mark bar.h as missing.
2183  EXPECT_TRUE(builder.AddTarget("a/b/c/d/e/fo o.o", &err));
2184  ASSERT_EQ("", err);
2185 
2186  // Expect three new edges: one generating fo o.o, and two more from
2187  // loading the depfile.
2188  ASSERT_EQ(3u, state.edges_.size());
2189  // Expect our edge to now have three inputs: foo.c and two headers.
2190  ASSERT_EQ(3u, edge->inputs_.size());
2191 
2192  // Expect the command line we generate to only use the original input.
2193  // Note, slashes from manifest, not .d.
2194  ASSERT_EQ("cc x\\y/z\\foo.c", edge->EvaluateCommand());
2195 
2196  deps_log.Close();
2197  builder.command_runner_.release();
2198  }
2199 }
2200 #endif
2201 
2202 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
2203 /// Follows from: https://github.com/ninja-build/ninja/issues/603
2204 TEST_F(BuildTest, RestatMissingDepfile) {
2205 const char* manifest =
2206 "rule true\n"
2207 " command = true\n" // Would be "write if out-of-date" in reality.
2208 " restat = 1\n"
2209 "build header.h: true header.in\n"
2210 "build out: cat header.h\n"
2211 " depfile = out.d\n";
2212 
2213  fs_.Create("header.h", "");
2214  fs_.Tick();
2215  fs_.Create("out", "");
2216  fs_.Create("header.in", "");
2217 
2218  // Normally, only 'header.h' would be rebuilt, as
2219  // its rule doesn't touch the output and has 'restat=1' set.
2220  // But we are also missing the depfile for 'out',
2221  // which should force its command to run anyway!
2222  RebuildTarget("out", manifest);
2223  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2224 }
2225 
2226 /// Check that a restat rule doesn't clear an edge if the deps are missing.
2227 /// https://github.com/ninja-build/ninja/issues/603
2228 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
2229  string err;
2230  const char* manifest =
2231 "rule true\n"
2232 " command = true\n" // Would be "write if out-of-date" in reality.
2233 " restat = 1\n"
2234 "build header.h: true header.in\n"
2235 "build out: cat header.h\n"
2236 " deps = gcc\n"
2237 " depfile = out.d\n";
2238 
2239  // Build once to populate ninja deps logs from out.d
2240  fs_.Create("header.in", "");
2241  fs_.Create("out.d", "out: header.h");
2242  fs_.Create("header.h", "");
2243 
2244  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2245  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2246 
2247  // Sanity: this rebuild should be NOOP
2248  RebuildTarget("out", manifest, "build_log", "ninja_deps");
2249  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2250 
2251  // Touch 'header.in', blank dependencies log (create a different one).
2252  // Building header.h triggers 'restat' outputs cleanup.
2253  // Validate that out is rebuilt netherless, as deps are missing.
2254  fs_.Tick();
2255  fs_.Create("header.in", "");
2256 
2257  // (switch to a new blank deps_log "ninja_deps2")
2258  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2259  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2260 
2261  // Sanity: this build should be NOOP
2262  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2263  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2264 
2265  // Check that invalidating deps by target timestamp also works here
2266  // Repeat the test but touch target instead of blanking the log.
2267  fs_.Tick();
2268  fs_.Create("header.in", "");
2269  fs_.Create("out", "");
2270  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2271  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
2272 
2273  // And this build should be NOOP again
2274  RebuildTarget("out", manifest, "build_log", "ninja_deps2");
2275  ASSERT_EQ(0u, command_runner_.commands_ran_.size());
2276 }
2277 
2278 TEST_F(BuildTest, WrongOutputInDepfileCausesRebuild) {
2279  string err;
2280  const char* manifest =
2281 "rule cc\n"
2282 " command = cc $in\n"
2283 " depfile = $out.d\n"
2284 "build foo.o: cc foo.c\n";
2285 
2286  fs_.Create("foo.c", "");
2287  fs_.Create("foo.o", "");
2288  fs_.Create("header.h", "");
2289  fs_.Create("foo.o.d", "bar.o.d: header.h\n");
2290 
2291  RebuildTarget("foo.o", manifest, "build_log", "ninja_deps");
2292  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2293 }
2294 
2295 TEST_F(BuildTest, Console) {
2297 "rule console\n"
2298 " command = console\n"
2299 " pool = console\n"
2300 "build cons: console in.txt\n"));
2301 
2302  fs_.Create("in.txt", "");
2303 
2304  string err;
2305  EXPECT_TRUE(builder_.AddTarget("cons", &err));
2306  ASSERT_EQ("", err);
2307  EXPECT_TRUE(builder_.Build(&err));
2308  EXPECT_EQ("", err);
2309  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2310 }
FakeCommandRunner command_runner_
Definition: build_test.cc:500
BuildConfig config_
Definition: build_test.cc:499
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:118
Verbosity verbosity
Definition: build.h:148
FakeCommandRunner(VirtualFileSystem *fs)
Definition: build_test.cc:443
BuildLog build_log_
Definition: build_test.cc:1195
int order_only_deps_
Definition: graph.h:184
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
Definition: test.cc:98
vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:125
Node * GetNode(const string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:93
int implicit_deps_
Definition: graph.h:183
BuildConfig MakeConfig()
Definition: build_test.cc:493
void TestPoolWithDepthOne(const char *test_case)
Definition: build_test.cc:188
#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:42
Edge * in_edge() const
Definition: graph.h:90
Node * GetNode(StringPiece path, uint64_t slash_bits)
Definition: state.cc:103
void * builder_
Shadow parent class builder_ so we don&#39;t accidentally use it.
Definition: build_test.cc:1818
Pool * LookupPool(const string &pool_name)
Definition: state.cc:87
The result of waiting for a command.
Definition: build.h:124
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:27
#define EXPECT_TRUE(a)
Definition: test.h:76
bool AddTarget(Node *node, string *err)
Add a target to our plan (including all its dependencies).
Definition: build.cc:299
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:348
#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:481
Fixture for tests involving Plan.
Definition: build_test.cc:27
int now_
A simple fake timestamp for file operations.
Definition: test.h:168
virtual vector< Edge * > GetActiveEdges()
Definition: build_test.cc:609
void Create(const string &path, const string &contents)
"Create" a file with contents.
Definition: test.cc:143
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:131
Store a log of every command ran for every build.
Definition: build_log.h:42
string EvaluateCommand(bool incl_rsp_file=false)
Expand all variables in a command and return it as a string.
Definition: graph.cc:362
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:113
void MarkDirty()
Definition: graph.h:88
Plan plan_
Definition: build_test.cc:28
void AddCatRule(State *state)
Add a "cat" rule to state.
Definition: test.cc:87
vector< Node * > inputs_
Definition: graph.h:163
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:68
int current_use() const
Definition: state.h:48
bool OpenForWrite(const string &path, const BuildLogUser &user, string *err)
Definition: build_log.cc:127
bool OpenForWrite(const string &path, string *err)
Definition: deps_log.cc:46
TEST_F(PlanTest, Basic)
Definition: build_test.cc:53
Tests of builds involving deps logs necessarily must span multiple builds.
Definition: build_test.cc:1802
#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:578
#define ASSERT_FALSE(a)
Definition: test.h:95
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:63
virtual void TearDown()
Definition: build_test.cc:1811
bool Load(const string &path, State *state, string *err)
Definition: deps_log.cc:170
Fake implementation of CommandRunner, useful for tests.
Definition: build_test.cc:442
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:507
ScopedTempDir temp_dir_
Definition: build_test.cc:1815
ExitStatus status
Definition: build.h:127
virtual void SetUp()
Definition: build_test.cc:464
int64_t TimeStamp
Definition: timestamp.h:31
virtual bool CanRunMore()
Definition: build_test.cc:545
virtual void Abort()
Definition: build_test.cc:616
auto_ptr< CommandRunner > command_runner_
Definition: build.h:196
VirtualFileSystem * fs_
Definition: build_test.cc:455
#define ASSERT_EQ(a, b)
Definition: test.h:81
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:188
void Close()
Definition: deps_log.cc:164
void FindWorkSorted(deque< Edge *> *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Definition: build_test.cc:33
Builder wraps the build process: starting commands, updating status.
Definition: build.h:159
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:216
void Cleanup()
Clean up the temporary directory.
Definition: test.cc:218
virtual bool StartCommand(Edge *edge)
Definition: build_test.cc:550
#define EXPECT_GT(a, b)
Definition: test.h:68
#define ASSERT_NO_FATAL_FAILURE(a)
Definition: test.h:97
const string & name() const
Definition: eval_env.h:58
const Rule & rule() const
Definition: graph.h:170
VirtualFileSystem fs_
Definition: build_test.cc:501
void CreateAndEnter(const string &name)
Create a temporary directory and chdir into it.
Definition: test.cc:196
Builder builder_
Definition: build_test.cc:502
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:139
Global state (file status) for a single run.
Definition: state.h:85
void Dirty(const string &path)
Definition: build_test.cc:620
BuildStatus status_
Definition: build_test.cc:504
#define ASSERT_TRUE(a)
Definition: test.h:93
bool Load(const string &path, string *err)
Load the on-disk log.
Definition: build_log.cc:244
bool Build(string *err)
Run the build.
Definition: build.cc:629
bool use_console() const
Definition: graph.cc:416
bool more_to_do() const
Returns true if there&#39;s more work to be done.
Definition: build.h:55
void EdgeFinished(Edge *edge, EdgeResult result)
Mark an edge as done building (whether it succeeded or failed).
Definition: build.cc:379
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
Definition: build.cc:625
virtual void SetUp()
Definition: build_test.cc:1805
vector< string > commands_ran_
Definition: build_test.cc:453
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:107
Node * AddTarget(const string &name, string *err)
Definition: build.cc:599
bool dry_run
Definition: build.h:149
Can answer questions about the manifest for the BuildLog.
Definition: build_log.h:29
vector< Node * > outputs_
Definition: graph.h:164