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