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