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 "build_log.h"
18 #include "deps_log.h"
19 #include "graph.h"
20 #include "test.h"
21 
22 /// Fixture for tests involving Plan.
23 // Though Plan doesn't use State, it's useful to have one around
24 // to create Nodes and Edges.
27 
28  /// Because FindWork does not return Edges in any sort of predictable order,
29  // provide a means to get available Edges in order and in a format which is
30  // easy to write tests around.
31  void FindWorkSorted(deque<Edge*>* ret, int count) {
32  struct CompareEdgesByOutput {
33  static bool cmp(const Edge* a, const Edge* b) {
34  return a->outputs_[0]->path() < b->outputs_[0]->path();
35  }
36  };
37 
38  for (int i = 0; i < count; ++i) {
39  ASSERT_TRUE(plan_.more_to_do());
40  Edge* edge = plan_.FindWork();
41  ASSERT_TRUE(edge);
42  ret->push_back(edge);
43  }
44  ASSERT_FALSE(plan_.FindWork());
45  sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
46  }
47 };
48 
49 TEST_F(PlanTest, Basic) {
50  AssertParse(&state_,
51 "build out: cat mid\n"
52 "build mid: cat in\n");
53  GetNode("mid")->MarkDirty();
54  GetNode("out")->MarkDirty();
55  string err;
56  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
57  ASSERT_EQ("", err);
58  ASSERT_TRUE(plan_.more_to_do());
59 
60  Edge* edge = plan_.FindWork();
61  ASSERT_TRUE(edge);
62  ASSERT_EQ("in", edge->inputs_[0]->path());
63  ASSERT_EQ("mid", edge->outputs_[0]->path());
64 
65  ASSERT_FALSE(plan_.FindWork());
66 
67  plan_.EdgeFinished(edge);
68 
69  edge = plan_.FindWork();
70  ASSERT_TRUE(edge);
71  ASSERT_EQ("mid", edge->inputs_[0]->path());
72  ASSERT_EQ("out", edge->outputs_[0]->path());
73 
74  plan_.EdgeFinished(edge);
75 
76  ASSERT_FALSE(plan_.more_to_do());
77  edge = plan_.FindWork();
78  ASSERT_EQ(0, edge);
79 }
80 
81 // Test that two outputs from one rule can be handled as inputs to the next.
82 TEST_F(PlanTest, DoubleOutputDirect) {
83  AssertParse(&state_,
84 "build out: cat mid1 mid2\n"
85 "build mid1 mid2: cat in\n");
86  GetNode("mid1")->MarkDirty();
87  GetNode("mid2")->MarkDirty();
88  GetNode("out")->MarkDirty();
89 
90  string err;
91  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
92  ASSERT_EQ("", err);
93  ASSERT_TRUE(plan_.more_to_do());
94 
95  Edge* edge;
96  edge = plan_.FindWork();
97  ASSERT_TRUE(edge); // cat in
98  plan_.EdgeFinished(edge);
99 
100  edge = plan_.FindWork();
101  ASSERT_TRUE(edge); // cat mid1 mid2
102  plan_.EdgeFinished(edge);
103 
104  edge = plan_.FindWork();
105  ASSERT_FALSE(edge); // done
106 }
107 
108 // Test that two outputs from one rule can eventually be routed to another.
109 TEST_F(PlanTest, DoubleOutputIndirect) {
110  AssertParse(&state_,
111 "build out: cat b1 b2\n"
112 "build b1: cat a1\n"
113 "build b2: cat a2\n"
114 "build a1 a2: cat in\n");
115  GetNode("a1")->MarkDirty();
116  GetNode("a2")->MarkDirty();
117  GetNode("b1")->MarkDirty();
118  GetNode("b2")->MarkDirty();
119  GetNode("out")->MarkDirty();
120  string err;
121  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
122  ASSERT_EQ("", err);
123  ASSERT_TRUE(plan_.more_to_do());
124 
125  Edge* edge;
126  edge = plan_.FindWork();
127  ASSERT_TRUE(edge); // cat in
128  plan_.EdgeFinished(edge);
129 
130  edge = plan_.FindWork();
131  ASSERT_TRUE(edge); // cat a1
132  plan_.EdgeFinished(edge);
133 
134  edge = plan_.FindWork();
135  ASSERT_TRUE(edge); // cat a2
136  plan_.EdgeFinished(edge);
137 
138  edge = plan_.FindWork();
139  ASSERT_TRUE(edge); // cat b1 b2
140  plan_.EdgeFinished(edge);
141 
142  edge = plan_.FindWork();
143  ASSERT_FALSE(edge); // done
144 }
145 
146 // Test that two edges from one output can both execute.
147 TEST_F(PlanTest, DoubleDependent) {
148  AssertParse(&state_,
149 "build out: cat a1 a2\n"
150 "build a1: cat mid\n"
151 "build a2: cat mid\n"
152 "build mid: cat in\n");
153  GetNode("mid")->MarkDirty();
154  GetNode("a1")->MarkDirty();
155  GetNode("a2")->MarkDirty();
156  GetNode("out")->MarkDirty();
157 
158  string err;
159  EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
160  ASSERT_EQ("", err);
161  ASSERT_TRUE(plan_.more_to_do());
162 
163  Edge* edge;
164  edge = plan_.FindWork();
165  ASSERT_TRUE(edge); // cat in
166  plan_.EdgeFinished(edge);
167 
168  edge = plan_.FindWork();
169  ASSERT_TRUE(edge); // cat mid
170  plan_.EdgeFinished(edge);
171 
172  edge = plan_.FindWork();
173  ASSERT_TRUE(edge); // cat mid
174  plan_.EdgeFinished(edge);
175 
176  edge = plan_.FindWork();
177  ASSERT_TRUE(edge); // cat a1 a2
178  plan_.EdgeFinished(edge);
179 
180  edge = plan_.FindWork();
181  ASSERT_FALSE(edge); // done
182 }
183 
184 TEST_F(PlanTest, DependencyCycle) {
185  AssertParse(&state_,
186 "build out: cat mid\n"
187 "build mid: cat in\n"
188 "build in: cat pre\n"
189 "build pre: cat out\n");
190  GetNode("out")->MarkDirty();
191  GetNode("mid")->MarkDirty();
192  GetNode("in")->MarkDirty();
193  GetNode("pre")->MarkDirty();
194 
195  string err;
196  EXPECT_FALSE(plan_.AddTarget(GetNode("out"), &err));
197  ASSERT_EQ("dependency cycle: out -> mid -> in -> pre -> out", err);
198 }
199 
200 TEST_F(PlanTest, PoolWithDepthOne) {
201  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
202 "pool foobar\n"
203 " depth = 1\n"
204 "rule poolcat\n"
205 " command = cat $in > $out\n"
206 " pool = foobar\n"
207 "build out1: poolcat in\n"
208 "build out2: poolcat in\n"));
209  GetNode("out1")->MarkDirty();
210  GetNode("out2")->MarkDirty();
211  string err;
212  EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
213  ASSERT_EQ("", err);
214  EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
215  ASSERT_EQ("", err);
216  ASSERT_TRUE(plan_.more_to_do());
217 
218  Edge* edge = plan_.FindWork();
219  ASSERT_TRUE(edge);
220  ASSERT_EQ("in", edge->inputs_[0]->path());
221  ASSERT_EQ("out1", edge->outputs_[0]->path());
222 
223  // This will be false since poolcat is serialized
224  ASSERT_FALSE(plan_.FindWork());
225 
226  plan_.EdgeFinished(edge);
227 
228  edge = plan_.FindWork();
229  ASSERT_TRUE(edge);
230  ASSERT_EQ("in", edge->inputs_[0]->path());
231  ASSERT_EQ("out2", edge->outputs_[0]->path());
232 
233  ASSERT_FALSE(plan_.FindWork());
234 
235  plan_.EdgeFinished(edge);
236 
237  ASSERT_FALSE(plan_.more_to_do());
238  edge = plan_.FindWork();
239  ASSERT_EQ(0, edge);
240 }
241 
242 TEST_F(PlanTest, PoolsWithDepthTwo) {
243  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
244 "pool foobar\n"
245 " depth = 2\n"
246 "pool bazbin\n"
247 " depth = 2\n"
248 "rule foocat\n"
249 " command = cat $in > $out\n"
250 " pool = foobar\n"
251 "rule bazcat\n"
252 " command = cat $in > $out\n"
253 " pool = bazbin\n"
254 "build out1: foocat in\n"
255 "build out2: foocat in\n"
256 "build out3: foocat in\n"
257 "build outb1: bazcat in\n"
258 "build outb2: bazcat in\n"
259 "build outb3: bazcat in\n"
260 " pool =\n"
261 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
262 ));
263  // Mark all the out* nodes dirty
264  for (int i = 0; i < 3; ++i) {
265  GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
266  GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
267  }
268  GetNode("allTheThings")->MarkDirty();
269 
270  string err;
271  EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
272  ASSERT_EQ("", err);
273 
274  deque<Edge*> edges;
275  FindWorkSorted(&edges, 5);
276 
277  for (int i = 0; i < 4; ++i) {
278  Edge *edge = edges[i];
279  ASSERT_EQ("in", edge->inputs_[0]->path());
280  string base_name(i < 2 ? "out" : "outb");
281  ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
282  }
283 
284  // outb3 is exempt because it has an empty pool
285  Edge* edge = edges[4];
286  ASSERT_TRUE(edge);
287  ASSERT_EQ("in", edge->inputs_[0]->path());
288  ASSERT_EQ("outb3", edge->outputs_[0]->path());
289 
290  // finish out1
291  plan_.EdgeFinished(edges.front());
292  edges.pop_front();
293 
294  // out3 should be available
295  Edge* out3 = plan_.FindWork();
296  ASSERT_TRUE(out3);
297  ASSERT_EQ("in", out3->inputs_[0]->path());
298  ASSERT_EQ("out3", out3->outputs_[0]->path());
299 
300  ASSERT_FALSE(plan_.FindWork());
301 
302  plan_.EdgeFinished(out3);
303 
304  ASSERT_FALSE(plan_.FindWork());
305 
306  for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
307  plan_.EdgeFinished(*it);
308  }
309 
310  Edge* last = plan_.FindWork();
311  ASSERT_TRUE(last);
312  ASSERT_EQ("allTheThings", last->outputs_[0]->path());
313 
314  plan_.EdgeFinished(last);
315 
316  ASSERT_FALSE(plan_.more_to_do());
317  ASSERT_FALSE(plan_.FindWork());
318 }
319 
320 TEST_F(PlanTest, PoolWithRedundantEdges) {
321  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
322  "pool compile\n"
323  " depth = 1\n"
324  "rule gen_foo\n"
325  " command = touch foo.cpp\n"
326  "rule gen_bar\n"
327  " command = touch bar.cpp\n"
328  "rule echo\n"
329  " command = echo $out > $out\n"
330  "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
331  " pool = compile\n"
332  "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
333  " pool = compile\n"
334  "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
335  "build foo.cpp: gen_foo\n"
336  "build bar.cpp: gen_bar\n"
337  "build all: phony libfoo.a\n"));
338  GetNode("foo.cpp")->MarkDirty();
339  GetNode("foo.cpp.obj")->MarkDirty();
340  GetNode("bar.cpp")->MarkDirty();
341  GetNode("bar.cpp.obj")->MarkDirty();
342  GetNode("libfoo.a")->MarkDirty();
343  GetNode("all")->MarkDirty();
344  string err;
345  EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
346  ASSERT_EQ("", err);
347  ASSERT_TRUE(plan_.more_to_do());
348 
349  Edge* edge = NULL;
350 
351  deque<Edge*> initial_edges;
352  FindWorkSorted(&initial_edges, 2);
353 
354  edge = initial_edges[1]; // Foo first
355  ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
356  plan_.EdgeFinished(edge);
357 
358  edge = plan_.FindWork();
359  ASSERT_TRUE(edge);
360  ASSERT_FALSE(plan_.FindWork());
361  ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
362  ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
363  ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
364  plan_.EdgeFinished(edge);
365 
366  edge = initial_edges[0]; // Now for bar
367  ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
368  plan_.EdgeFinished(edge);
369 
370  edge = plan_.FindWork();
371  ASSERT_TRUE(edge);
372  ASSERT_FALSE(plan_.FindWork());
373  ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
374  ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
375  ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
376  plan_.EdgeFinished(edge);
377 
378  edge = plan_.FindWork();
379  ASSERT_TRUE(edge);
380  ASSERT_FALSE(plan_.FindWork());
381  ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
382  ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
383  ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
384  plan_.EdgeFinished(edge);
385 
386  edge = plan_.FindWork();
387  ASSERT_TRUE(edge);
388  ASSERT_FALSE(plan_.FindWork());
389  ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
390  ASSERT_EQ("all", edge->outputs_[0]->path());
391  plan_.EdgeFinished(edge);
392 
393  edge = plan_.FindWork();
394  ASSERT_FALSE(edge);
395  ASSERT_FALSE(plan_.more_to_do());
396 }
397 
398 /// Fake implementation of CommandRunner, useful for tests.
401  last_command_(NULL), fs_(fs) {}
402 
403  // CommandRunner impl
404  virtual bool CanRunMore();
405  virtual bool StartCommand(Edge* edge);
406  virtual bool WaitForCommand(Result* result);
407  virtual vector<Edge*> GetActiveEdges();
408  virtual void Abort();
409 
410  vector<string> commands_ran_;
413 };
414 
417  builder_(&state_, config_, NULL, NULL, &fs_),
418  status_(config_) {
419  }
420 
421  virtual void SetUp() {
422  StateTestWithBuiltinRules::SetUp();
423 
426 "build cat1: cat in1\n"
427 "build cat2: cat in1 in2\n"
428 "build cat12: cat cat1 cat2\n");
429 
430  fs_.Create("in1", "");
431  fs_.Create("in2", "");
432  }
433 
435  builder_.command_runner_.release();
436  }
437 
438  // Mark a path dirty.
439  void Dirty(const string& path);
440 
442  BuildConfig config;
443  config.verbosity = BuildConfig::QUIET;
444  return config;
445  }
446 
451 
453 };
454 
456  // Only run one at a time.
457  return last_command_ == NULL;
458 }
459 
461  assert(!last_command_);
462  commands_ran_.push_back(edge->EvaluateCommand());
463  if (edge->rule().name() == "cat" ||
464  edge->rule().name() == "cat_rsp" ||
465  edge->rule().name() == "cc" ||
466  edge->rule().name() == "touch" ||
467  edge->rule().name() == "touch-interrupt") {
468  for (vector<Node*>::iterator out = edge->outputs_.begin();
469  out != edge->outputs_.end(); ++out) {
470  fs_->Create((*out)->path(), "");
471  }
472  } else if (edge->rule().name() == "true" ||
473  edge->rule().name() == "fail" ||
474  edge->rule().name() == "interrupt") {
475  // Don't do anything.
476  } else {
477  printf("unknown command\n");
478  return false;
479  }
480 
481  last_command_ = edge;
482  return true;
483 }
484 
486  if (!last_command_)
487  return false;
488 
489  Edge* edge = last_command_;
490  result->edge = edge;
491 
492  if (edge->rule().name() == "interrupt" ||
493  edge->rule().name() == "touch-interrupt") {
494  result->status = ExitInterrupted;
495  return true;
496  }
497 
498  if (edge->rule().name() == "fail")
499  result->status = ExitFailure;
500  else
501  result->status = ExitSuccess;
502  last_command_ = NULL;
503  return true;
504 }
505 
507  vector<Edge*> edges;
508  if (last_command_)
509  edges.push_back(last_command_);
510  return edges;
511 }
512 
514  last_command_ = NULL;
515 }
516 
517 void BuildTest::Dirty(const string& path) {
518  Node* node = GetNode(path);
519  node->MarkDirty();
520 
521  // If it's an input file, mark that we've already stat()ed it and
522  // it's missing.
523  if (!node->in_edge())
524  node->MarkMissing();
525 }
526 
527 TEST_F(BuildTest, NoWork) {
528  string err;
529  EXPECT_TRUE(builder_.AlreadyUpToDate());
530 }
531 
532 TEST_F(BuildTest, OneStep) {
533  // Given a dirty target with one ready input,
534  // we should rebuild the target.
535  Dirty("cat1");
536  string err;
537  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
538  ASSERT_EQ("", err);
539  EXPECT_TRUE(builder_.Build(&err));
540  ASSERT_EQ("", err);
541 
542  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
543  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
544 }
545 
546 TEST_F(BuildTest, OneStep2) {
547  // Given a target with one dirty input,
548  // we should rebuild the target.
549  Dirty("cat1");
550  string err;
551  EXPECT_TRUE(builder_.AddTarget("cat1", &err));
552  ASSERT_EQ("", err);
553  EXPECT_TRUE(builder_.Build(&err));
554  EXPECT_EQ("", err);
555 
556  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
557  EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
558 }
559 
560 TEST_F(BuildTest, TwoStep) {
561  string err;
562  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
563  ASSERT_EQ("", err);
564  EXPECT_TRUE(builder_.Build(&err));
565  EXPECT_EQ("", err);
566  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
567  // Depending on how the pointers work out, we could've ran
568  // the first two commands in either order.
569  EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
570  command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
571  (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
572  command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
573 
574  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
575 
576  fs_.Tick();
577 
578  // Modifying in2 requires rebuilding one intermediate file
579  // and the final file.
580  fs_.Create("in2", "");
581  state_.Reset();
582  EXPECT_TRUE(builder_.AddTarget("cat12", &err));
583  ASSERT_EQ("", err);
584  EXPECT_TRUE(builder_.Build(&err));
585  ASSERT_EQ("", err);
586  ASSERT_EQ(5u, command_runner_.commands_ran_.size());
587  EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
588  EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
589 }
590 
591 TEST_F(BuildTest, TwoOutputs) {
592  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
593 "rule touch\n"
594 " command = touch $out\n"
595 "build out1 out2: touch in.txt\n"));
596 
597  fs_.Create("in.txt", "");
598 
599  string err;
600  EXPECT_TRUE(builder_.AddTarget("out1", &err));
601  ASSERT_EQ("", err);
602  EXPECT_TRUE(builder_.Build(&err));
603  EXPECT_EQ("", err);
604  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
605  EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
606 }
607 
608 // Test case from
609 // https://github.com/martine/ninja/issues/148
610 TEST_F(BuildTest, MultiOutIn) {
611  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
612 "rule touch\n"
613 " command = touch $out\n"
614 "build in1 otherfile: touch in\n"
615 "build out: touch in | in1\n"));
616 
617  fs_.Create("in", "");
618  fs_.Tick();
619  fs_.Create("in1", "");
620 
621  string err;
622  EXPECT_TRUE(builder_.AddTarget("out", &err));
623  ASSERT_EQ("", err);
624  EXPECT_TRUE(builder_.Build(&err));
625  EXPECT_EQ("", err);
626 }
627 
628 TEST_F(BuildTest, Chain) {
629  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
630 "build c2: cat c1\n"
631 "build c3: cat c2\n"
632 "build c4: cat c3\n"
633 "build c5: cat c4\n"));
634 
635  fs_.Create("c1", "");
636 
637  string err;
638  EXPECT_TRUE(builder_.AddTarget("c5", &err));
639  ASSERT_EQ("", err);
640  EXPECT_TRUE(builder_.Build(&err));
641  EXPECT_EQ("", err);
642  ASSERT_EQ(4u, command_runner_.commands_ran_.size());
643 
644  err.clear();
645  command_runner_.commands_ran_.clear();
646  state_.Reset();
647  EXPECT_TRUE(builder_.AddTarget("c5", &err));
648  ASSERT_EQ("", err);
649  EXPECT_TRUE(builder_.AlreadyUpToDate());
650 
651  fs_.Tick();
652 
653  fs_.Create("c3", "");
654  err.clear();
655  command_runner_.commands_ran_.clear();
656  state_.Reset();
657  EXPECT_TRUE(builder_.AddTarget("c5", &err));
658  ASSERT_EQ("", err);
659  EXPECT_FALSE(builder_.AlreadyUpToDate());
660  EXPECT_TRUE(builder_.Build(&err));
661  ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // 3->4, 4->5
662 }
663 
664 TEST_F(BuildTest, MissingInput) {
665  // Input is referenced by build file, but no rule for it.
666  string err;
667  Dirty("in1");
668  EXPECT_FALSE(builder_.AddTarget("cat1", &err));
669  EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
670  err);
671 }
672 
673 TEST_F(BuildTest, MissingTarget) {
674  // Target is not referenced by build file.
675  string err;
676  EXPECT_FALSE(builder_.AddTarget("meow", &err));
677  EXPECT_EQ("unknown target: 'meow'", err);
678 }
679 
680 TEST_F(BuildTest, MakeDirs) {
681  string err;
682 
683 #ifdef _WIN32
684  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
685  "build subdir\\dir2\\file: cat in1\n"));
686  EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
687 #else
688  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
689  "build subdir/dir2/file: cat in1\n"));
690  EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
691 #endif
692 
693  EXPECT_EQ("", err);
694  EXPECT_TRUE(builder_.Build(&err));
695  ASSERT_EQ("", err);
696  ASSERT_EQ(2u, fs_.directories_made_.size());
697  EXPECT_EQ("subdir", fs_.directories_made_[0]);
698 #ifdef _WIN32
699  EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
700 #else
701  EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
702 #endif
703 }
704 
705 TEST_F(BuildTest, DepFileMissing) {
706  string err;
707  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
708 "rule cc\n command = cc $in\n depfile = $out.d\n"
709 "build foo.o: cc foo.c\n"));
710  fs_.Create("foo.c", "");
711 
712  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
713  ASSERT_EQ("", err);
714  ASSERT_EQ(1u, fs_.files_read_.size());
715  EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
716 }
717 
718 TEST_F(BuildTest, DepFileOK) {
719  string err;
720  int orig_edges = state_.edges_.size();
721  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
722 "rule cc\n command = cc $in\n depfile = $out.d\n"
723 "build foo.o: cc foo.c\n"));
724  Edge* edge = state_.edges_.back();
725 
726  fs_.Create("foo.c", "");
727  GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
728  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
729  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
730  ASSERT_EQ("", err);
731  ASSERT_EQ(1u, fs_.files_read_.size());
732  EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
733 
734  // Expect three new edges: one generating foo.o, and two more from
735  // loading the depfile.
736  ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
737  // Expect our edge to now have three inputs: foo.c and two headers.
738  ASSERT_EQ(3u, edge->inputs_.size());
739 
740  // Expect the command line we generate to only use the original input.
741  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
742 }
743 
744 TEST_F(BuildTest, DepFileParseError) {
745  string err;
746  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
747 "rule cc\n command = cc $in\n depfile = $out.d\n"
748 "build foo.o: cc foo.c\n"));
749  fs_.Create("foo.c", "");
750  fs_.Create("foo.o.d", "randomtext\n");
751  EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
752  EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
753  err);
754 }
755 
756 TEST_F(BuildTest, OrderOnlyDeps) {
757  string err;
758  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
759 "rule cc\n command = cc $in\n depfile = $out.d\n"
760 "build foo.o: cc foo.c || otherfile\n"));
761  Edge* edge = state_.edges_.back();
762 
763  fs_.Create("foo.c", "");
764  fs_.Create("otherfile", "");
765  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
766  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
767  ASSERT_EQ("", err);
768 
769  // One explicit, two implicit, one order only.
770  ASSERT_EQ(4u, edge->inputs_.size());
771  EXPECT_EQ(2, edge->implicit_deps_);
772  EXPECT_EQ(1, edge->order_only_deps_);
773  // Verify the inputs are in the order we expect
774  // (explicit then implicit then orderonly).
775  EXPECT_EQ("foo.c", edge->inputs_[0]->path());
776  EXPECT_EQ("blah.h", edge->inputs_[1]->path());
777  EXPECT_EQ("bar.h", edge->inputs_[2]->path());
778  EXPECT_EQ("otherfile", edge->inputs_[3]->path());
779 
780  // Expect the command line we generate to only use the original input.
781  ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
782 
783  // explicit dep dirty, expect a rebuild.
784  EXPECT_TRUE(builder_.Build(&err));
785  ASSERT_EQ("", err);
786  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
787 
788  fs_.Tick();
789 
790  // Recreate the depfile, as it should have been deleted by the build.
791  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
792 
793  // implicit dep dirty, expect a rebuild.
794  fs_.Create("blah.h", "");
795  fs_.Create("bar.h", "");
796  command_runner_.commands_ran_.clear();
797  state_.Reset();
798  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
799  EXPECT_TRUE(builder_.Build(&err));
800  ASSERT_EQ("", err);
801  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
802 
803  fs_.Tick();
804 
805  // Recreate the depfile, as it should have been deleted by the build.
806  fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
807 
808  // order only dep dirty, no rebuild.
809  fs_.Create("otherfile", "");
810  command_runner_.commands_ran_.clear();
811  state_.Reset();
812  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
813  EXPECT_EQ("", err);
814  EXPECT_TRUE(builder_.AlreadyUpToDate());
815 
816  // implicit dep missing, expect rebuild.
817  fs_.RemoveFile("bar.h");
818  command_runner_.commands_ran_.clear();
819  state_.Reset();
820  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
821  EXPECT_TRUE(builder_.Build(&err));
822  ASSERT_EQ("", err);
823  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
824 }
825 
826 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
827  string err;
828  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
829 "rule cc\n command = cc $in\n"
830 "rule true\n command = true\n"
831 "build oo.h: cc oo.h.in\n"
832 "build foo.o: cc foo.c || oo.h\n"));
833 
834  fs_.Create("foo.c", "");
835  fs_.Create("oo.h.in", "");
836 
837  // foo.o and order-only dep dirty, build both.
838  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
839  EXPECT_TRUE(builder_.Build(&err));
840  ASSERT_EQ("", err);
841  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
842 
843  // all clean, no rebuild.
844  command_runner_.commands_ran_.clear();
845  state_.Reset();
846  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
847  EXPECT_EQ("", err);
848  EXPECT_TRUE(builder_.AlreadyUpToDate());
849 
850  // order-only dep missing, build it only.
851  fs_.RemoveFile("oo.h");
852  command_runner_.commands_ran_.clear();
853  state_.Reset();
854  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
855  EXPECT_TRUE(builder_.Build(&err));
856  ASSERT_EQ("", err);
857  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
858  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
859 
860  fs_.Tick();
861 
862  // order-only dep dirty, build it only.
863  fs_.Create("oo.h.in", "");
864  command_runner_.commands_ran_.clear();
865  state_.Reset();
866  EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
867  EXPECT_TRUE(builder_.Build(&err));
868  ASSERT_EQ("", err);
869  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
870  ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
871 }
872 
873 TEST_F(BuildTest, Phony) {
874  string err;
875  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
876 "build out: cat bar.cc\n"
877 "build all: phony out\n"));
878  fs_.Create("bar.cc", "");
879 
880  EXPECT_TRUE(builder_.AddTarget("all", &err));
881  ASSERT_EQ("", err);
882 
883  // Only one command to run, because phony runs no command.
884  EXPECT_FALSE(builder_.AlreadyUpToDate());
885  EXPECT_TRUE(builder_.Build(&err));
886  ASSERT_EQ("", err);
887  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
888 }
889 
890 TEST_F(BuildTest, PhonyNoWork) {
891  string err;
892  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
893 "build out: cat bar.cc\n"
894 "build all: phony out\n"));
895  fs_.Create("bar.cc", "");
896  fs_.Create("out", "");
897 
898  EXPECT_TRUE(builder_.AddTarget("all", &err));
899  ASSERT_EQ("", err);
900  EXPECT_TRUE(builder_.AlreadyUpToDate());
901 }
902 
904  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
905 "rule fail\n"
906 " command = fail\n"
907 "build out1: fail\n"));
908 
909  string err;
910  EXPECT_TRUE(builder_.AddTarget("out1", &err));
911  ASSERT_EQ("", err);
912 
913  EXPECT_FALSE(builder_.Build(&err));
914  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
915  ASSERT_EQ("subcommand failed", err);
916 }
917 
918 TEST_F(BuildTest, SwallowFailures) {
919  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
920 "rule fail\n"
921 " command = fail\n"
922 "build out1: fail\n"
923 "build out2: fail\n"
924 "build out3: fail\n"
925 "build all: phony out1 out2 out3\n"));
926 
927  // Swallow two failures, die on the third.
928  config_.failures_allowed = 3;
929 
930  string err;
931  EXPECT_TRUE(builder_.AddTarget("all", &err));
932  ASSERT_EQ("", err);
933 
934  EXPECT_FALSE(builder_.Build(&err));
935  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
936  ASSERT_EQ("subcommands failed", err);
937 }
938 
939 TEST_F(BuildTest, SwallowFailuresLimit) {
940  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
941 "rule fail\n"
942 " command = fail\n"
943 "build out1: fail\n"
944 "build out2: fail\n"
945 "build out3: fail\n"
946 "build final: cat out1 out2 out3\n"));
947 
948  // Swallow ten failures; we should stop before building final.
949  config_.failures_allowed = 11;
950 
951  string err;
952  EXPECT_TRUE(builder_.AddTarget("final", &err));
953  ASSERT_EQ("", err);
954 
955  EXPECT_FALSE(builder_.Build(&err));
956  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
957  ASSERT_EQ("cannot make progress due to previous errors", err);
958 }
959 
960 struct BuildWithLogTest : public BuildTest {
963  }
964 
966 };
967 
968 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
969  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
970 "rule cc\n"
971 " command = cc\n"
972 "build out1: cc in\n"));
973 
974  // Create input/output that would be considered up to date when
975  // not considering the command line hash.
976  fs_.Create("in", "");
977  fs_.Create("out1", "");
978  string err;
979 
980  // Because it's not in the log, it should not be up-to-date until
981  // we build again.
982  EXPECT_TRUE(builder_.AddTarget("out1", &err));
983  EXPECT_FALSE(builder_.AlreadyUpToDate());
984 
985  command_runner_.commands_ran_.clear();
986  state_.Reset();
987 
988  EXPECT_TRUE(builder_.AddTarget("out1", &err));
989  EXPECT_TRUE(builder_.Build(&err));
990  EXPECT_TRUE(builder_.AlreadyUpToDate());
991 }
992 
993 TEST_F(BuildWithLogTest, RestatTest) {
994  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
995 "rule true\n"
996 " command = true\n"
997 " restat = 1\n"
998 "rule cc\n"
999 " command = cc\n"
1000 " restat = 1\n"
1001 "build out1: cc in\n"
1002 "build out2: true out1\n"
1003 "build out3: cat out2\n"));
1004 
1005  fs_.Create("out1", "");
1006  fs_.Create("out2", "");
1007  fs_.Create("out3", "");
1008 
1009  fs_.Tick();
1010 
1011  fs_.Create("in", "");
1012 
1013  // Do a pre-build so that there's commands in the log for the outputs,
1014  // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1015  // regardless of restat.
1016  string err;
1017  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1018  ASSERT_EQ("", err);
1019  EXPECT_TRUE(builder_.Build(&err));
1020  ASSERT_EQ("", err);
1021  command_runner_.commands_ran_.clear();
1022  state_.Reset();
1023 
1024  fs_.Tick();
1025 
1026  fs_.Create("in", "");
1027  // "cc" touches out1, so we should build out2. But because "true" does not
1028  // touch out2, we should cancel the build of out3.
1029  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1030  ASSERT_EQ("", err);
1031  EXPECT_TRUE(builder_.Build(&err));
1032  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1033 
1034  // If we run again, it should be a no-op, because the build log has recorded
1035  // that we've already built out2 with an input timestamp of 2 (from out1).
1036  command_runner_.commands_ran_.clear();
1037  state_.Reset();
1038  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1039  ASSERT_EQ("", err);
1040  EXPECT_TRUE(builder_.AlreadyUpToDate());
1041 
1042  fs_.Tick();
1043 
1044  fs_.Create("in", "");
1045 
1046  // The build log entry should not, however, prevent us from rebuilding out2
1047  // if out1 changes.
1048  command_runner_.commands_ran_.clear();
1049  state_.Reset();
1050  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1051  ASSERT_EQ("", err);
1052  EXPECT_TRUE(builder_.Build(&err));
1053  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1054 }
1055 
1056 TEST_F(BuildWithLogTest, RestatMissingFile) {
1057  // If a restat rule doesn't create its output, and the output didn't
1058  // exist before the rule was run, consider that behavior equivalent
1059  // to a rule that doesn't modify its existent output file.
1060 
1061  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1062 "rule true\n"
1063 " command = true\n"
1064 " restat = 1\n"
1065 "rule cc\n"
1066 " command = cc\n"
1067 "build out1: true in\n"
1068 "build out2: cc out1\n"));
1069 
1070  fs_.Create("in", "");
1071  fs_.Create("out2", "");
1072 
1073  // Do a pre-build so that there's commands in the log for the outputs,
1074  // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1075  // regardless of restat.
1076  string err;
1077  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1078  ASSERT_EQ("", err);
1079  EXPECT_TRUE(builder_.Build(&err));
1080  ASSERT_EQ("", err);
1081  command_runner_.commands_ran_.clear();
1082  state_.Reset();
1083 
1084  fs_.Tick();
1085  fs_.Create("in", "");
1086  fs_.Create("out2", "");
1087 
1088  // Run a build, expect only the first command to run.
1089  // It doesn't touch its output (due to being the "true" command), so
1090  // we shouldn't run the dependent build.
1091  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1092  ASSERT_EQ("", err);
1093  EXPECT_TRUE(builder_.Build(&err));
1094  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1095 }
1096 
1097 // Test scenario, in which an input file is removed, but output isn't changed
1098 // https://github.com/martine/ninja/issues/295
1099 TEST_F(BuildWithLogTest, RestatMissingInput) {
1100  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1101  "rule true\n"
1102  " command = true\n"
1103  " depfile = $out.d\n"
1104  " restat = 1\n"
1105  "rule cc\n"
1106  " command = cc\n"
1107  "build out1: true in\n"
1108  "build out2: cc out1\n"));
1109 
1110  // Create all necessary files
1111  fs_.Create("in", "");
1112 
1113  // The implicit dependencies and the depfile itself
1114  // are newer than the output
1115  TimeStamp restat_mtime = fs_.Tick();
1116  fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1117  fs_.Create("will.be.deleted", "");
1118  fs_.Create("restat.file", "");
1119 
1120  // Run the build, out1 and out2 get built
1121  string err;
1122  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1123  ASSERT_EQ("", err);
1124  EXPECT_TRUE(builder_.Build(&err));
1125  ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1126 
1127  // See that an entry in the logfile is created, capturing
1128  // the right mtime
1129  BuildLog::LogEntry * log_entry = build_log_.LookupByOutput("out1");
1130  ASSERT_TRUE(NULL != log_entry);
1131  ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1132 
1133  // Now remove a file, referenced from depfile, so that target becomes
1134  // dirty, but the output does not change
1135  fs_.RemoveFile("will.be.deleted");
1136 
1137  // Trigger the build again - only out1 gets built
1138  command_runner_.commands_ran_.clear();
1139  state_.Reset();
1140  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1141  ASSERT_EQ("", err);
1142  EXPECT_TRUE(builder_.Build(&err));
1143  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1144 
1145  // Check that the logfile entry remains correctly set
1146  log_entry = build_log_.LookupByOutput("out1");
1147  ASSERT_TRUE(NULL != log_entry);
1148  ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1149 }
1150 
1153  config_.dry_run = true;
1154  }
1155 };
1156 
1157 TEST_F(BuildDryRun, AllCommandsShown) {
1158  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1159 "rule true\n"
1160 " command = true\n"
1161 " restat = 1\n"
1162 "rule cc\n"
1163 " command = cc\n"
1164 " restat = 1\n"
1165 "build out1: cc in\n"
1166 "build out2: true out1\n"
1167 "build out3: cat out2\n"));
1168 
1169  fs_.Create("out1", "");
1170  fs_.Create("out2", "");
1171  fs_.Create("out3", "");
1172 
1173  fs_.Tick();
1174 
1175  fs_.Create("in", "");
1176 
1177  // "cc" touches out1, so we should build out2. But because "true" does not
1178  // touch out2, we should cancel the build of out3.
1179  string err;
1180  EXPECT_TRUE(builder_.AddTarget("out3", &err));
1181  ASSERT_EQ("", err);
1182  EXPECT_TRUE(builder_.Build(&err));
1183  ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1184 }
1185 
1186 // Test that RSP files are created when & where appropriate and deleted after
1187 // successful execution.
1188 TEST_F(BuildTest, RspFileSuccess)
1189 {
1190  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1191  "rule cat_rsp\n"
1192  " command = cat $rspfile > $out\n"
1193  " rspfile = $rspfile\n"
1194  " rspfile_content = $long_command\n"
1195  "build out1: cat in\n"
1196  "build out2: cat_rsp in\n"
1197  " rspfile = out2.rsp\n"
1198  " long_command = Some very long command\n"));
1199 
1200  fs_.Create("out1", "");
1201  fs_.Create("out2", "");
1202  fs_.Create("out3", "");
1203 
1204  fs_.Tick();
1205 
1206  fs_.Create("in", "");
1207 
1208  string err;
1209  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1210  ASSERT_EQ("", err);
1211  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1212  ASSERT_EQ("", err);
1213 
1214  size_t files_created = fs_.files_created_.size();
1215  size_t files_removed = fs_.files_removed_.size();
1216 
1217  EXPECT_TRUE(builder_.Build(&err));
1218  ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
1219 
1220  // The RSP file was created
1221  ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1222  ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
1223 
1224  // The RSP file was removed
1225  ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
1226  ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
1227 }
1228 
1229 // Test that RSP file is created but not removed for commands, which fail
1230 TEST_F(BuildTest, RspFileFailure) {
1231  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1232  "rule fail\n"
1233  " command = fail\n"
1234  " rspfile = $rspfile\n"
1235  " rspfile_content = $long_command\n"
1236  "build out: fail in\n"
1237  " rspfile = out.rsp\n"
1238  " long_command = Another very long command\n"));
1239 
1240  fs_.Create("out", "");
1241  fs_.Tick();
1242  fs_.Create("in", "");
1243 
1244  string err;
1245  EXPECT_TRUE(builder_.AddTarget("out", &err));
1246  ASSERT_EQ("", err);
1247 
1248  size_t files_created = fs_.files_created_.size();
1249  size_t files_removed = fs_.files_removed_.size();
1250 
1251  EXPECT_FALSE(builder_.Build(&err));
1252  ASSERT_EQ("subcommand failed", err);
1253  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1254 
1255  // The RSP file was created
1256  ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1257  ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1258 
1259  // The RSP file was NOT removed
1260  ASSERT_EQ(files_removed, fs_.files_removed_.size());
1261  ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1262 
1263  // The RSP file contains what it should
1264  ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1265 }
1266 
1267 // Test that contens of the RSP file behaves like a regular part of
1268 // command line, i.e. triggers a rebuild if changed
1269 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1270  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1271  "rule cat_rsp\n"
1272  " command = cat $rspfile > $out\n"
1273  " rspfile = $rspfile\n"
1274  " rspfile_content = $long_command\n"
1275  "build out: cat_rsp in\n"
1276  " rspfile = out.rsp\n"
1277  " long_command = Original very long command\n"));
1278 
1279  fs_.Create("out", "");
1280  fs_.Tick();
1281  fs_.Create("in", "");
1282 
1283  string err;
1284  EXPECT_TRUE(builder_.AddTarget("out", &err));
1285  ASSERT_EQ("", err);
1286 
1287  // 1. Build for the 1st time (-> populate log)
1288  EXPECT_TRUE(builder_.Build(&err));
1289  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1290 
1291  // 2. Build again (no change)
1292  command_runner_.commands_ran_.clear();
1293  state_.Reset();
1294  EXPECT_TRUE(builder_.AddTarget("out", &err));
1295  EXPECT_EQ("", err);
1296  ASSERT_TRUE(builder_.AlreadyUpToDate());
1297 
1298  // 3. Alter the entry in the logfile
1299  // (to simulate a change in the command line between 2 builds)
1300  BuildLog::LogEntry * log_entry = build_log_.LookupByOutput("out");
1301  ASSERT_TRUE(NULL != log_entry);
1302  ASSERT_NO_FATAL_FAILURE(AssertHash(
1303  "cat out.rsp > out;rspfile=Original very long command",
1304  log_entry->command_hash));
1305  log_entry->command_hash++; // Change the command hash to something else.
1306  // Now expect the target to be rebuilt
1307  command_runner_.commands_ran_.clear();
1308  state_.Reset();
1309  EXPECT_TRUE(builder_.AddTarget("out", &err));
1310  EXPECT_EQ("", err);
1311  EXPECT_TRUE(builder_.Build(&err));
1312  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1313 }
1314 
1315 TEST_F(BuildTest, InterruptCleanup) {
1316  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1317 "rule interrupt\n"
1318 " command = interrupt\n"
1319 "rule touch-interrupt\n"
1320 " command = touch-interrupt\n"
1321 "build out1: interrupt in1\n"
1322 "build out2: touch-interrupt in2\n"));
1323 
1324  fs_.Create("out1", "");
1325  fs_.Create("out2", "");
1326  fs_.Tick();
1327  fs_.Create("in1", "");
1328  fs_.Create("in2", "");
1329 
1330  // An untouched output of an interrupted command should be retained.
1331  string err;
1332  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1333  EXPECT_EQ("", err);
1334  EXPECT_FALSE(builder_.Build(&err));
1335  EXPECT_EQ("interrupted by user", err);
1336  builder_.Cleanup();
1337  EXPECT_GT(fs_.Stat("out1"), 0);
1338  err = "";
1339 
1340  // A touched output of an interrupted command should be deleted.
1341  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1342  EXPECT_EQ("", err);
1343  EXPECT_FALSE(builder_.Build(&err));
1344  EXPECT_EQ("interrupted by user", err);
1345  builder_.Cleanup();
1346  EXPECT_EQ(0, fs_.Stat("out2"));
1347 }
1348 
1349 TEST_F(BuildTest, PhonyWithNoInputs) {
1350  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1351 "build nonexistent: phony\n"
1352 "build out1: cat || nonexistent\n"
1353 "build out2: cat nonexistent\n"));
1354  fs_.Create("out1", "");
1355  fs_.Create("out2", "");
1356 
1357  // out1 should be up to date even though its input is dirty, because its
1358  // order-only dependency has nothing to do.
1359  string err;
1360  EXPECT_TRUE(builder_.AddTarget("out1", &err));
1361  ASSERT_EQ("", err);
1362  EXPECT_TRUE(builder_.AlreadyUpToDate());
1363 
1364  // out2 should still be out of date though, because its input is dirty.
1365  err.clear();
1366  command_runner_.commands_ran_.clear();
1367  state_.Reset();
1368  EXPECT_TRUE(builder_.AddTarget("out2", &err));
1369  ASSERT_EQ("", err);
1370  EXPECT_TRUE(builder_.Build(&err));
1371  EXPECT_EQ("", err);
1372  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1373 }
1374 
1375 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1376  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1377 "rule cc\n"
1378 " command = cc\n"
1379 " deps = gcc\n"
1380 "build out: cc\n"));
1381  Dirty("out");
1382 
1383  string err;
1384  EXPECT_TRUE(builder_.AddTarget("out", &err));
1385  ASSERT_EQ("", err);
1386  EXPECT_FALSE(builder_.AlreadyUpToDate());
1387 
1388  EXPECT_FALSE(builder_.Build(&err));
1389  ASSERT_EQ("subcommand failed", err);
1390  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1391 }
1392 
1393 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1394  EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1395  status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
1396 }
1397 
1398 TEST_F(BuildTest, FailedDepsParse) {
1399  ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1400 "build bad_deps.o: cat in1\n"
1401 " deps = gcc\n"
1402 " depfile = in1.d\n"));
1403 
1404  string err;
1405  EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1406  ASSERT_EQ("", err);
1407 
1408  // These deps will fail to parse, as they should only have one
1409  // path to the left of the colon.
1410  fs_.Create("in1.d", "AAA BBB");
1411 
1412  EXPECT_FALSE(builder_.Build(&err));
1413  EXPECT_EQ("subcommand failed", err);
1414 }
1415 
1416 /// Tests of builds involving deps logs necessarily must span
1417 /// multiple builds. We reuse methods on BuildTest but not the
1418 /// builder_ it sets up, because we want pristine objects for
1419 /// each build.
1422 
1423  virtual void SetUp() {
1424  BuildTest::SetUp();
1425 
1426  temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
1427  }
1428 
1429  virtual void TearDown() {
1430  temp_dir_.Cleanup();
1431  }
1432 
1434 
1435  /// Shadow parent class builder_ so we don't accidentally use it.
1436  void* builder_;
1437 };
1438 
1439 /// Run a straightforwad build where the deps log is used.
1440 TEST_F(BuildWithDepsLogTest, Straightforward) {
1441  string err;
1442  // Note: in1 was created by the superclass SetUp().
1443  const char* manifest =
1444  "build out: cat in1\n"
1445  " deps = gcc\n"
1446  " depfile = in1.d\n";
1447  {
1448  State state;
1449  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1450  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1451 
1452  // Run the build once, everything should be ok.
1453  DepsLog deps_log;
1454  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1455  ASSERT_EQ("", err);
1456 
1457  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1458  builder.command_runner_.reset(&command_runner_);
1459  EXPECT_TRUE(builder.AddTarget("out", &err));
1460  ASSERT_EQ("", err);
1461  fs_.Create("in1.d", "out: in2");
1462  EXPECT_TRUE(builder.Build(&err));
1463  EXPECT_EQ("", err);
1464 
1465  // The deps file should have been removed.
1466  EXPECT_EQ(0, fs_.Stat("in1.d"));
1467  // Recreate it for the next step.
1468  fs_.Create("in1.d", "out: in2");
1469  deps_log.Close();
1470  builder.command_runner_.release();
1471  }
1472 
1473  {
1474  State state;
1475  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1476  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1477 
1478  // Touch the file only mentioned in the deps.
1479  fs_.Tick();
1480  fs_.Create("in2", "");
1481 
1482  // Run the build again.
1483  DepsLog deps_log;
1484  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1485  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1486 
1487  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1488  builder.command_runner_.reset(&command_runner_);
1489  command_runner_.commands_ran_.clear();
1490  EXPECT_TRUE(builder.AddTarget("out", &err));
1491  ASSERT_EQ("", err);
1492  EXPECT_TRUE(builder.Build(&err));
1493  EXPECT_EQ("", err);
1494 
1495  // We should have rebuilt the output due to in2 being
1496  // out of date.
1497  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1498 
1499  builder.command_runner_.release();
1500  }
1501 }
1502 
1503 /// Verify that obsolete dependency info causes a rebuild.
1504 /// 1) Run a successful build where everything has time t, record deps.
1505 /// 2) Move input/output to time t+1 -- despite files in alignment,
1506 /// should still need to rebuild due to deps at older time.
1508  string err;
1509  // Note: in1 was created by the superclass SetUp().
1510  const char* manifest =
1511  "build out: cat in1\n"
1512  " deps = gcc\n"
1513  " depfile = in1.d\n";
1514  {
1515  // Run an ordinary build that gathers dependencies.
1516  fs_.Create("in1", "");
1517  fs_.Create("in1.d", "out: ");
1518 
1519  State state;
1520  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1521  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1522 
1523  // Run the build once, everything should be ok.
1524  DepsLog deps_log;
1525  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1526  ASSERT_EQ("", err);
1527 
1528  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1529  builder.command_runner_.reset(&command_runner_);
1530  EXPECT_TRUE(builder.AddTarget("out", &err));
1531  ASSERT_EQ("", err);
1532  EXPECT_TRUE(builder.Build(&err));
1533  EXPECT_EQ("", err);
1534 
1535  deps_log.Close();
1536  builder.command_runner_.release();
1537  }
1538 
1539  // Push all files one tick forward so that only the deps are out
1540  // of date.
1541  fs_.Tick();
1542  fs_.Create("in1", "");
1543  fs_.Create("out", "");
1544 
1545  // The deps file should have been removed, so no need to timestamp it.
1546  EXPECT_EQ(0, fs_.Stat("in1.d"));
1547 
1548  {
1549  State state;
1550  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1551  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1552 
1553  DepsLog deps_log;
1554  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1555  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1556 
1557  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1558  builder.command_runner_.reset(&command_runner_);
1559  command_runner_.commands_ran_.clear();
1560  EXPECT_TRUE(builder.AddTarget("out", &err));
1561  ASSERT_EQ("", err);
1562 
1563  // Recreate the deps file here because the build expects them to exist.
1564  fs_.Create("in1.d", "out: ");
1565 
1566  EXPECT_TRUE(builder.Build(&err));
1567  EXPECT_EQ("", err);
1568 
1569  // We should have rebuilt the output due to the deps being
1570  // out of date.
1571  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1572 
1573  builder.command_runner_.release();
1574  }
1575 }
1576 
1577 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
1578  const char* manifest =
1579  "build out: cat in1\n"
1580  " deps = gcc\n"
1581  " depfile = in1.d\n";
1582 
1583  fs_.Create("out", "");
1584  fs_.Tick();
1585  fs_.Create("in1", "");
1586 
1587  State state;
1588  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1589  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1590 
1591  // The deps log is NULL in dry runs.
1592  config_.dry_run = true;
1593  Builder builder(&state, config_, NULL, NULL, &fs_);
1594  builder.command_runner_.reset(&command_runner_);
1595  command_runner_.commands_ran_.clear();
1596 
1597  string err;
1598  EXPECT_TRUE(builder.AddTarget("out", &err));
1599  ASSERT_EQ("", err);
1600  EXPECT_TRUE(builder.Build(&err));
1601  ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1602 
1603  builder.command_runner_.release();
1604 }
1605 
1606 /// Check that a restat rule generating a header cancels compilations correctly.
1607 TEST_F(BuildWithDepsLogTest, RestatDepfileDependency) {
1608  string err;
1609  // Note: in1 was created by the superclass SetUp().
1610  const char* manifest =
1611  "rule true\n"
1612  " command = true\n" // Would be "write if out-of-date" in reality.
1613  " restat = 1\n"
1614  "build header.h: true header.in\n"
1615  "build out: cat in1\n"
1616  " deps = gcc\n"
1617  " depfile = in1.d\n";
1618  {
1619  State state;
1620  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1621  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1622 
1623  // Run the build once, everything should be ok.
1624  DepsLog deps_log;
1625  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1626  ASSERT_EQ("", err);
1627 
1628  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1629  builder.command_runner_.reset(&command_runner_);
1630  EXPECT_TRUE(builder.AddTarget("out", &err));
1631  ASSERT_EQ("", err);
1632  fs_.Create("in1.d", "out: header.h");
1633  EXPECT_TRUE(builder.Build(&err));
1634  EXPECT_EQ("", err);
1635 
1636  deps_log.Close();
1637  builder.command_runner_.release();
1638  }
1639 
1640  {
1641  State state;
1642  ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1643  ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1644 
1645  // Touch the input of the restat rule.
1646  fs_.Tick();
1647  fs_.Create("header.in", "");
1648 
1649  // Run the build again.
1650  DepsLog deps_log;
1651  ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1652  ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1653 
1654  Builder builder(&state, config_, NULL, &deps_log, &fs_);
1655  builder.command_runner_.reset(&command_runner_);
1656  command_runner_.commands_ran_.clear();
1657  EXPECT_TRUE(builder.AddTarget("out", &err));
1658  ASSERT_EQ("", err);
1659  EXPECT_TRUE(builder.Build(&err));
1660  EXPECT_EQ("", err);
1661 
1662  // Rule "true" should have run again, but the build of "out" should have
1663  // been cancelled due to restat propagating through the depfile header.
1664  EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1665 
1666  builder.command_runner_.release();
1667  }
1668 }
FakeCommandRunner command_runner_
Definition: build_test.cc:448
BuildConfig config_
Definition: build_test.cc:447
An implementation of DiskInterface that uses an in-memory representation of disk state.
Definition: test.h:49
CommandRunner is an interface that wraps running the build subcommands.
Definition: build.h:103
Verbosity verbosity
Definition: build.h:133
FakeCommandRunner(VirtualFileSystem *fs)
Definition: build_test.cc:400
BuildLog build_log_
Definition: build_test.cc:965
int order_only_deps_
Definition: graph.h:175
Node * GetNode(const string &path)
Short way to get a Node by its path from state_.
Definition: test.cc:86
int implicit_deps_
Definition: graph.h:174
BuildConfig MakeConfig()
Definition: build_test.cc:441
Plan stores the state of a build plan: what we intend to build, which steps we're ready to execute...
Definition: build.h:41
bool more_to_do() const
Returns true if there's more work to be done.
Definition: build.h:54
void * builder_
Shadow parent class builder_ so we don't accidentally use it.
Definition: build_test.cc:1436
The result of waiting for a command.
Definition: build.h:109
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
Definition: graph.h:35
Edge * FindWork()
Definition: build.cc:331
Edge * in_edge() const
Definition: graph.h:80
Fixture for tests involving Plan.
Definition: build_test.cc:25
virtual vector< Edge * > GetActiveEdges()
Definition: build_test.cc:506
int TimeStamp
Definition: timestamp.h:22
void AssertParse(State *state, const char *input)
Definition: test.cc:90
void Create(const string &path, const string &contents)
"Create" a file with contents.
Definition: test.cc:101
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:137
Store a log of every command ran for every build.
Definition: build_log.h:35
string EvaluateCommand(bool incl_rsp_file=false)
Expand all variables in a command and return it as a string.
Definition: graph.cc:274
A base test fixture that includes a State object with a builtin "cat" rule.
Definition: test.h:30
void MarkDirty()
Definition: graph.h:78
Plan plan_
Definition: build_test.cc:26
vector< Node * > inputs_
Definition: graph.h:156
As build commands run they can output extra dependency information (e.g.
Definition: deps_log.h:63
void FindWorkSorted(deque< Edge * > *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Definition: build_test.cc:31
bool OpenForWrite(const string &path, string *err)
Definition: deps_log.cc:39
TEST_F(PlanTest, Basic)
Definition: build_test.cc:49
Tests of builds involving deps logs necessarily must span multiple builds.
Definition: build_test.cc:1420
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
Definition: build_test.cc:485
void MarkMissing()
Mark the Node as already-stat()ed and missing.
Definition: graph.h:61
virtual void TearDown()
Definition: build_test.cc:1429
bool Load(const string &path, State *state, string *err)
Definition: deps_log.cc:143
Fake implementation of CommandRunner, useful for tests.
Definition: build_test.cc:399
ScopedTempDir temp_dir_
Definition: build_test.cc:1433
ExitStatus status
Definition: build.h:112
virtual void SetUp()
Definition: build_test.cc:421
virtual bool CanRunMore()
Definition: build_test.cc:455
virtual void Abort()
Definition: build_test.cc:513
auto_ptr< CommandRunner > command_runner_
Definition: build.h:176
VirtualFileSystem * fs_
Definition: build_test.cc:412
void SetBuildLog(BuildLog *log)
Used for tests.
Definition: build.h:169
void Close()
Definition: deps_log.cc:137
Builder wraps the build process: starting commands, updating status.
Definition: build.h:143
Tracks the status of a build: completion fraction, printing updates.
Definition: build.h:192
void Cleanup()
Clean up the temporary directory.
Definition: test.cc:169
virtual bool StartCommand(Edge *edge)
Definition: build_test.cc:460
VirtualFileSystem fs_
Definition: build_test.cc:449
void CreateAndEnter(const string &name)
Create a temporary directory and chdir into it.
Definition: test.cc:147
Builder builder_
Definition: build_test.cc:450
Options (e.g. verbosity, parallelism) passed to a build.
Definition: build.h:124
Global state (file status, loaded rules) for a single run.
Definition: state.h:83
const string & name() const
Definition: graph.h:119
void Dirty(const string &path)
Definition: build_test.cc:517
BuildStatus status_
Definition: build_test.cc:452
bool Build(string *err)
Run the build.
Definition: build.cc:593
const Rule & rule() const
Definition: graph.h:161
virtual void SetUp()
Definition: build_test.cc:1423
vector< string > commands_ran_
Definition: build_test.cc:410
void AssertHash(const char *expected, uint64_t actual)
Definition: test.cc:97
Node * AddTarget(const string &name, string *err)
Definition: build.cc:563
bool dry_run
Definition: build.h:134
vector< Node * > outputs_
Definition: graph.h:157