1 // Copyright 2011 Google Inc. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "build_log.h"
22 /// Fixture for tests involving Plan.
23 // Though Plan doesn't use State, it's useful to have one around
24 // to create Nodes and Edges.
25 struct PlanTest : public StateTestWithBuiltinRules {
28 /// Because FindWork does not return Edges in any sort of predictable order,
29 // provide a means to get available Edges in order and in a format which is
30 // easy to write tests around.
31 void FindWorkSorted(deque<Edge*>* ret, int count) {
32 struct CompareEdgesByOutput {
33 static bool cmp(const Edge* a, const Edge* b) {
34 return a->outputs_[0]->path() < b->outputs_[0]->path();
38 for (int i = 0; i < count; ++i) {
39 ASSERT_TRUE(plan_.more_to_do());
40 Edge* edge = plan_.FindWork();
44 ASSERT_FALSE(plan_.FindWork());
45 sort(ret->begin(), ret->end(), CompareEdgesByOutput::cmp);
49 TEST_F(PlanTest, Basic) {
51 "build out: cat mid\n"
52 "build mid: cat in\n");
53 GetNode("mid")->MarkDirty();
54 GetNode("out")->MarkDirty();
56 EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
58 ASSERT_TRUE(plan_.more_to_do());
60 Edge* edge = plan_.FindWork();
62 ASSERT_EQ("in", edge->inputs_[0]->path());
63 ASSERT_EQ("mid", edge->outputs_[0]->path());
65 ASSERT_FALSE(plan_.FindWork());
67 plan_.EdgeFinished(edge);
69 edge = plan_.FindWork();
71 ASSERT_EQ("mid", edge->inputs_[0]->path());
72 ASSERT_EQ("out", edge->outputs_[0]->path());
74 plan_.EdgeFinished(edge);
76 ASSERT_FALSE(plan_.more_to_do());
77 edge = plan_.FindWork();
81 // Test that two outputs from one rule can be handled as inputs to the next.
82 TEST_F(PlanTest, DoubleOutputDirect) {
84 "build out: cat mid1 mid2\n"
85 "build mid1 mid2: cat in\n");
86 GetNode("mid1")->MarkDirty();
87 GetNode("mid2")->MarkDirty();
88 GetNode("out")->MarkDirty();
91 EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
93 ASSERT_TRUE(plan_.more_to_do());
96 edge = plan_.FindWork();
97 ASSERT_TRUE(edge); // cat in
98 plan_.EdgeFinished(edge);
100 edge = plan_.FindWork();
101 ASSERT_TRUE(edge); // cat mid1 mid2
102 plan_.EdgeFinished(edge);
104 edge = plan_.FindWork();
105 ASSERT_FALSE(edge); // done
108 // Test that two outputs from one rule can eventually be routed to another.
109 TEST_F(PlanTest, DoubleOutputIndirect) {
111 "build out: cat b1 b2\n"
114 "build a1 a2: cat in\n");
115 GetNode("a1")->MarkDirty();
116 GetNode("a2")->MarkDirty();
117 GetNode("b1")->MarkDirty();
118 GetNode("b2")->MarkDirty();
119 GetNode("out")->MarkDirty();
121 EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
123 ASSERT_TRUE(plan_.more_to_do());
126 edge = plan_.FindWork();
127 ASSERT_TRUE(edge); // cat in
128 plan_.EdgeFinished(edge);
130 edge = plan_.FindWork();
131 ASSERT_TRUE(edge); // cat a1
132 plan_.EdgeFinished(edge);
134 edge = plan_.FindWork();
135 ASSERT_TRUE(edge); // cat a2
136 plan_.EdgeFinished(edge);
138 edge = plan_.FindWork();
139 ASSERT_TRUE(edge); // cat b1 b2
140 plan_.EdgeFinished(edge);
142 edge = plan_.FindWork();
143 ASSERT_FALSE(edge); // done
146 // Test that two edges from one output can both execute.
147 TEST_F(PlanTest, DoubleDependent) {
149 "build out: cat a1 a2\n"
150 "build a1: cat mid\n"
151 "build a2: cat mid\n"
152 "build mid: cat in\n");
153 GetNode("mid")->MarkDirty();
154 GetNode("a1")->MarkDirty();
155 GetNode("a2")->MarkDirty();
156 GetNode("out")->MarkDirty();
159 EXPECT_TRUE(plan_.AddTarget(GetNode("out"), &err));
161 ASSERT_TRUE(plan_.more_to_do());
164 edge = plan_.FindWork();
165 ASSERT_TRUE(edge); // cat in
166 plan_.EdgeFinished(edge);
168 edge = plan_.FindWork();
169 ASSERT_TRUE(edge); // cat mid
170 plan_.EdgeFinished(edge);
172 edge = plan_.FindWork();
173 ASSERT_TRUE(edge); // cat mid
174 plan_.EdgeFinished(edge);
176 edge = plan_.FindWork();
177 ASSERT_TRUE(edge); // cat a1 a2
178 plan_.EdgeFinished(edge);
180 edge = plan_.FindWork();
181 ASSERT_FALSE(edge); // done
184 TEST_F(PlanTest, DependencyCycle) {
186 "build out: cat mid\n"
187 "build mid: cat in\n"
188 "build in: cat pre\n"
189 "build pre: cat out\n");
190 GetNode("out")->MarkDirty();
191 GetNode("mid")->MarkDirty();
192 GetNode("in")->MarkDirty();
193 GetNode("pre")->MarkDirty();
196 EXPECT_FALSE(plan_.AddTarget(GetNode("out"), &err));
197 ASSERT_EQ("dependency cycle: out -> mid -> in -> pre -> out", err);
200 TEST_F(PlanTest, PoolWithDepthOne) {
201 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
205 " command = cat $in > $out\n"
207 "build out1: poolcat in\n"
208 "build out2: poolcat in\n"));
209 GetNode("out1")->MarkDirty();
210 GetNode("out2")->MarkDirty();
212 EXPECT_TRUE(plan_.AddTarget(GetNode("out1"), &err));
214 EXPECT_TRUE(plan_.AddTarget(GetNode("out2"), &err));
216 ASSERT_TRUE(plan_.more_to_do());
218 Edge* edge = plan_.FindWork();
220 ASSERT_EQ("in", edge->inputs_[0]->path());
221 ASSERT_EQ("out1", edge->outputs_[0]->path());
223 // This will be false since poolcat is serialized
224 ASSERT_FALSE(plan_.FindWork());
226 plan_.EdgeFinished(edge);
228 edge = plan_.FindWork();
230 ASSERT_EQ("in", edge->inputs_[0]->path());
231 ASSERT_EQ("out2", edge->outputs_[0]->path());
233 ASSERT_FALSE(plan_.FindWork());
235 plan_.EdgeFinished(edge);
237 ASSERT_FALSE(plan_.more_to_do());
238 edge = plan_.FindWork();
242 TEST_F(PlanTest, PoolsWithDepthTwo) {
243 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
249 " command = cat $in > $out\n"
252 " command = cat $in > $out\n"
254 "build out1: foocat in\n"
255 "build out2: foocat in\n"
256 "build out3: foocat in\n"
257 "build outb1: bazcat in\n"
258 "build outb2: bazcat in\n"
259 "build outb3: bazcat in\n"
261 "build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
263 // Mark all the out* nodes dirty
264 for (int i = 0; i < 3; ++i) {
265 GetNode("out" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
266 GetNode("outb" + string(1, '1' + static_cast<char>(i)))->MarkDirty();
268 GetNode("allTheThings")->MarkDirty();
271 EXPECT_TRUE(plan_.AddTarget(GetNode("allTheThings"), &err));
275 FindWorkSorted(&edges, 5);
277 for (int i = 0; i < 4; ++i) {
278 Edge *edge = edges[i];
279 ASSERT_EQ("in", edge->inputs_[0]->path());
280 string base_name(i < 2 ? "out" : "outb");
281 ASSERT_EQ(base_name + string(1, '1' + (i % 2)), edge->outputs_[0]->path());
284 // outb3 is exempt because it has an empty pool
285 Edge* edge = edges[4];
287 ASSERT_EQ("in", edge->inputs_[0]->path());
288 ASSERT_EQ("outb3", edge->outputs_[0]->path());
291 plan_.EdgeFinished(edges.front());
294 // out3 should be available
295 Edge* out3 = plan_.FindWork();
297 ASSERT_EQ("in", out3->inputs_[0]->path());
298 ASSERT_EQ("out3", out3->outputs_[0]->path());
300 ASSERT_FALSE(plan_.FindWork());
302 plan_.EdgeFinished(out3);
304 ASSERT_FALSE(plan_.FindWork());
306 for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
307 plan_.EdgeFinished(*it);
310 Edge* last = plan_.FindWork();
312 ASSERT_EQ("allTheThings", last->outputs_[0]->path());
314 plan_.EdgeFinished(last);
316 ASSERT_FALSE(plan_.more_to_do());
317 ASSERT_FALSE(plan_.FindWork());
320 TEST_F(PlanTest, PoolWithRedundantEdges) {
321 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
325 " command = touch foo.cpp\n"
327 " command = touch bar.cpp\n"
329 " command = echo $out > $out\n"
330 "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
332 "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
334 "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
335 "build foo.cpp: gen_foo\n"
336 "build bar.cpp: gen_bar\n"
337 "build all: phony libfoo.a\n"));
338 GetNode("foo.cpp")->MarkDirty();
339 GetNode("foo.cpp.obj")->MarkDirty();
340 GetNode("bar.cpp")->MarkDirty();
341 GetNode("bar.cpp.obj")->MarkDirty();
342 GetNode("libfoo.a")->MarkDirty();
343 GetNode("all")->MarkDirty();
345 EXPECT_TRUE(plan_.AddTarget(GetNode("all"), &err));
347 ASSERT_TRUE(plan_.more_to_do());
351 deque<Edge*> initial_edges;
352 FindWorkSorted(&initial_edges, 2);
354 edge = initial_edges[1]; // Foo first
355 ASSERT_EQ("foo.cpp", edge->outputs_[0]->path());
356 plan_.EdgeFinished(edge);
358 edge = plan_.FindWork();
360 ASSERT_FALSE(plan_.FindWork());
361 ASSERT_EQ("foo.cpp", edge->inputs_[0]->path());
362 ASSERT_EQ("foo.cpp", edge->inputs_[1]->path());
363 ASSERT_EQ("foo.cpp.obj", edge->outputs_[0]->path());
364 plan_.EdgeFinished(edge);
366 edge = initial_edges[0]; // Now for bar
367 ASSERT_EQ("bar.cpp", edge->outputs_[0]->path());
368 plan_.EdgeFinished(edge);
370 edge = plan_.FindWork();
372 ASSERT_FALSE(plan_.FindWork());
373 ASSERT_EQ("bar.cpp", edge->inputs_[0]->path());
374 ASSERT_EQ("bar.cpp", edge->inputs_[1]->path());
375 ASSERT_EQ("bar.cpp.obj", edge->outputs_[0]->path());
376 plan_.EdgeFinished(edge);
378 edge = plan_.FindWork();
380 ASSERT_FALSE(plan_.FindWork());
381 ASSERT_EQ("foo.cpp.obj", edge->inputs_[0]->path());
382 ASSERT_EQ("bar.cpp.obj", edge->inputs_[1]->path());
383 ASSERT_EQ("libfoo.a", edge->outputs_[0]->path());
384 plan_.EdgeFinished(edge);
386 edge = plan_.FindWork();
388 ASSERT_FALSE(plan_.FindWork());
389 ASSERT_EQ("libfoo.a", edge->inputs_[0]->path());
390 ASSERT_EQ("all", edge->outputs_[0]->path());
391 plan_.EdgeFinished(edge);
393 edge = plan_.FindWork();
395 ASSERT_FALSE(plan_.more_to_do());
398 /// Fake implementation of CommandRunner, useful for tests.
399 struct FakeCommandRunner : public CommandRunner {
400 explicit FakeCommandRunner(VirtualFileSystem* fs) :
401 last_command_(NULL), fs_(fs) {}
403 // CommandRunner impl
404 virtual bool CanRunMore();
405 virtual bool StartCommand(Edge* edge);
406 virtual bool WaitForCommand(Result* result);
407 virtual vector<Edge*> GetActiveEdges();
408 virtual void Abort();
410 vector<string> commands_ran_;
412 VirtualFileSystem* fs_;
415 struct BuildTest : public StateTestWithBuiltinRules {
416 BuildTest() : config_(MakeConfig()), command_runner_(&fs_),
417 builder_(&state_, config_, NULL, NULL, &fs_),
421 virtual void SetUp() {
422 StateTestWithBuiltinRules::SetUp();
424 builder_.command_runner_.reset(&command_runner_);
426 "build cat1: cat in1\n"
427 "build cat2: cat in1 in2\n"
428 "build cat12: cat cat1 cat2\n");
430 fs_.Create("in1", "");
431 fs_.Create("in2", "");
435 builder_.command_runner_.release();
438 /// Rebuild target in the 'working tree' (fs_).
439 /// State of command_runner_ and logs contents (if specified) ARE MODIFIED.
440 /// Handy to check for NOOP builds, and higher-level rebuild tests.
441 void RebuildTarget(const string& target, const char* manifest,
442 const char* log_path = NULL,
443 const char* deps_path = NULL);
445 // Mark a path dirty.
446 void Dirty(const string& path);
448 BuildConfig MakeConfig() {
450 config.verbosity = BuildConfig::QUIET;
455 FakeCommandRunner command_runner_;
456 VirtualFileSystem fs_;
462 void BuildTest::RebuildTarget(const string& target, const char* manifest,
463 const char* log_path, const char* deps_path) {
465 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
466 AssertParse(&state, manifest);
469 BuildLog build_log, *pbuild_log = NULL;
471 ASSERT_TRUE(build_log.Load(log_path, &err));
472 ASSERT_TRUE(build_log.OpenForWrite(log_path, &err));
474 pbuild_log = &build_log;
477 DepsLog deps_log, *pdeps_log = NULL;
479 ASSERT_TRUE(deps_log.Load(deps_path, &state, &err));
480 ASSERT_TRUE(deps_log.OpenForWrite(deps_path, &err));
482 pdeps_log = &deps_log;
485 Builder builder(&state, config_, pbuild_log, pdeps_log, &fs_);
486 EXPECT_TRUE(builder.AddTarget(target, &err));
488 command_runner_.commands_ran_.clear();
489 builder.command_runner_.reset(&command_runner_);
490 bool build_res = true;
491 if (!builder.AlreadyUpToDate()) {
492 build_res = builder.Build(&err);
494 builder.command_runner_.release();
495 EXPECT_TRUE(build_res) << "builder.Build(&err)";
498 bool FakeCommandRunner::CanRunMore() {
499 // Only run one at a time.
500 return last_command_ == NULL;
503 bool FakeCommandRunner::StartCommand(Edge* edge) {
504 assert(!last_command_);
505 commands_ran_.push_back(edge->EvaluateCommand());
506 if (edge->rule().name() == "cat" ||
507 edge->rule().name() == "cat_rsp" ||
508 edge->rule().name() == "cc" ||
509 edge->rule().name() == "touch" ||
510 edge->rule().name() == "touch-interrupt") {
511 for (vector<Node*>::iterator out = edge->outputs_.begin();
512 out != edge->outputs_.end(); ++out) {
513 fs_->Create((*out)->path(), "");
515 } else if (edge->rule().name() == "true" ||
516 edge->rule().name() == "fail" ||
517 edge->rule().name() == "interrupt") {
518 // Don't do anything.
520 printf("unknown command\n");
524 last_command_ = edge;
528 bool FakeCommandRunner::WaitForCommand(Result* result) {
532 Edge* edge = last_command_;
535 if (edge->rule().name() == "interrupt" ||
536 edge->rule().name() == "touch-interrupt") {
537 result->status = ExitInterrupted;
541 if (edge->rule().name() == "fail")
542 result->status = ExitFailure;
544 result->status = ExitSuccess;
545 last_command_ = NULL;
549 vector<Edge*> FakeCommandRunner::GetActiveEdges() {
552 edges.push_back(last_command_);
556 void FakeCommandRunner::Abort() {
557 last_command_ = NULL;
560 void BuildTest::Dirty(const string& path) {
561 Node* node = GetNode(path);
564 // If it's an input file, mark that we've already stat()ed it and
566 if (!node->in_edge())
570 TEST_F(BuildTest, NoWork) {
572 EXPECT_TRUE(builder_.AlreadyUpToDate());
575 TEST_F(BuildTest, OneStep) {
576 // Given a dirty target with one ready input,
577 // we should rebuild the target.
580 EXPECT_TRUE(builder_.AddTarget("cat1", &err));
582 EXPECT_TRUE(builder_.Build(&err));
585 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
586 EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
589 TEST_F(BuildTest, OneStep2) {
590 // Given a target with one dirty input,
591 // we should rebuild the target.
594 EXPECT_TRUE(builder_.AddTarget("cat1", &err));
596 EXPECT_TRUE(builder_.Build(&err));
599 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
600 EXPECT_EQ("cat in1 > cat1", command_runner_.commands_ran_[0]);
603 TEST_F(BuildTest, TwoStep) {
605 EXPECT_TRUE(builder_.AddTarget("cat12", &err));
607 EXPECT_TRUE(builder_.Build(&err));
609 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
610 // Depending on how the pointers work out, we could've ran
611 // the first two commands in either order.
612 EXPECT_TRUE((command_runner_.commands_ran_[0] == "cat in1 > cat1" &&
613 command_runner_.commands_ran_[1] == "cat in1 in2 > cat2") ||
614 (command_runner_.commands_ran_[1] == "cat in1 > cat1" &&
615 command_runner_.commands_ran_[0] == "cat in1 in2 > cat2"));
617 EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
621 // Modifying in2 requires rebuilding one intermediate file
622 // and the final file.
623 fs_.Create("in2", "");
625 EXPECT_TRUE(builder_.AddTarget("cat12", &err));
627 EXPECT_TRUE(builder_.Build(&err));
629 ASSERT_EQ(5u, command_runner_.commands_ran_.size());
630 EXPECT_EQ("cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
631 EXPECT_EQ("cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
634 TEST_F(BuildTest, TwoOutputs) {
635 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
637 " command = touch $out\n"
638 "build out1 out2: touch in.txt\n"));
640 fs_.Create("in.txt", "");
643 EXPECT_TRUE(builder_.AddTarget("out1", &err));
645 EXPECT_TRUE(builder_.Build(&err));
647 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
648 EXPECT_EQ("touch out1 out2", command_runner_.commands_ran_[0]);
652 // https://github.com/martine/ninja/issues/148
653 TEST_F(BuildTest, MultiOutIn) {
654 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
656 " command = touch $out\n"
657 "build in1 otherfile: touch in\n"
658 "build out: touch in | in1\n"));
660 fs_.Create("in", "");
662 fs_.Create("in1", "");
665 EXPECT_TRUE(builder_.AddTarget("out", &err));
667 EXPECT_TRUE(builder_.Build(&err));
671 TEST_F(BuildTest, Chain) {
672 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
676 "build c5: cat c4\n"));
678 fs_.Create("c1", "");
681 EXPECT_TRUE(builder_.AddTarget("c5", &err));
683 EXPECT_TRUE(builder_.Build(&err));
685 ASSERT_EQ(4u, command_runner_.commands_ran_.size());
688 command_runner_.commands_ran_.clear();
690 EXPECT_TRUE(builder_.AddTarget("c5", &err));
692 EXPECT_TRUE(builder_.AlreadyUpToDate());
696 fs_.Create("c3", "");
698 command_runner_.commands_ran_.clear();
700 EXPECT_TRUE(builder_.AddTarget("c5", &err));
702 EXPECT_FALSE(builder_.AlreadyUpToDate());
703 EXPECT_TRUE(builder_.Build(&err));
704 ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // 3->4, 4->5
707 TEST_F(BuildTest, MissingInput) {
708 // Input is referenced by build file, but no rule for it.
711 EXPECT_FALSE(builder_.AddTarget("cat1", &err));
712 EXPECT_EQ("'in1', needed by 'cat1', missing and no known rule to make it",
716 TEST_F(BuildTest, MissingTarget) {
717 // Target is not referenced by build file.
719 EXPECT_FALSE(builder_.AddTarget("meow", &err));
720 EXPECT_EQ("unknown target: 'meow'", err);
723 TEST_F(BuildTest, MakeDirs) {
727 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
728 "build subdir\\dir2\\file: cat in1\n"));
729 EXPECT_TRUE(builder_.AddTarget("subdir\\dir2\\file", &err));
731 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
732 "build subdir/dir2/file: cat in1\n"));
733 EXPECT_TRUE(builder_.AddTarget("subdir/dir2/file", &err));
737 EXPECT_TRUE(builder_.Build(&err));
739 ASSERT_EQ(2u, fs_.directories_made_.size());
740 EXPECT_EQ("subdir", fs_.directories_made_[0]);
742 EXPECT_EQ("subdir\\dir2", fs_.directories_made_[1]);
744 EXPECT_EQ("subdir/dir2", fs_.directories_made_[1]);
748 TEST_F(BuildTest, DepFileMissing) {
750 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
751 "rule cc\n command = cc $in\n depfile = $out.d\n"
752 "build foo.o: cc foo.c\n"));
753 fs_.Create("foo.c", "");
755 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
757 ASSERT_EQ(1u, fs_.files_read_.size());
758 EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
761 TEST_F(BuildTest, DepFileOK) {
763 int orig_edges = state_.edges_.size();
764 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
765 "rule cc\n command = cc $in\n depfile = $out.d\n"
766 "build foo.o: cc foo.c\n"));
767 Edge* edge = state_.edges_.back();
769 fs_.Create("foo.c", "");
770 GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
771 fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
772 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
774 ASSERT_EQ(1u, fs_.files_read_.size());
775 EXPECT_EQ("foo.o.d", fs_.files_read_[0]);
777 // Expect three new edges: one generating foo.o, and two more from
778 // loading the depfile.
779 ASSERT_EQ(orig_edges + 3, (int)state_.edges_.size());
780 // Expect our edge to now have three inputs: foo.c and two headers.
781 ASSERT_EQ(3u, edge->inputs_.size());
783 // Expect the command line we generate to only use the original input.
784 ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
787 TEST_F(BuildTest, DepFileParseError) {
789 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
790 "rule cc\n command = cc $in\n depfile = $out.d\n"
791 "build foo.o: cc foo.c\n"));
792 fs_.Create("foo.c", "");
793 fs_.Create("foo.o.d", "randomtext\n");
794 EXPECT_FALSE(builder_.AddTarget("foo.o", &err));
795 EXPECT_EQ("expected depfile 'foo.o.d' to mention 'foo.o', got 'randomtext'",
799 TEST_F(BuildTest, OrderOnlyDeps) {
801 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
802 "rule cc\n command = cc $in\n depfile = $out.d\n"
803 "build foo.o: cc foo.c || otherfile\n"));
804 Edge* edge = state_.edges_.back();
806 fs_.Create("foo.c", "");
807 fs_.Create("otherfile", "");
808 fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
809 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
812 // One explicit, two implicit, one order only.
813 ASSERT_EQ(4u, edge->inputs_.size());
814 EXPECT_EQ(2, edge->implicit_deps_);
815 EXPECT_EQ(1, edge->order_only_deps_);
816 // Verify the inputs are in the order we expect
817 // (explicit then implicit then orderonly).
818 EXPECT_EQ("foo.c", edge->inputs_[0]->path());
819 EXPECT_EQ("blah.h", edge->inputs_[1]->path());
820 EXPECT_EQ("bar.h", edge->inputs_[2]->path());
821 EXPECT_EQ("otherfile", edge->inputs_[3]->path());
823 // Expect the command line we generate to only use the original input.
824 ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
826 // explicit dep dirty, expect a rebuild.
827 EXPECT_TRUE(builder_.Build(&err));
829 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
833 // Recreate the depfile, as it should have been deleted by the build.
834 fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
836 // implicit dep dirty, expect a rebuild.
837 fs_.Create("blah.h", "");
838 fs_.Create("bar.h", "");
839 command_runner_.commands_ran_.clear();
841 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
842 EXPECT_TRUE(builder_.Build(&err));
844 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
848 // Recreate the depfile, as it should have been deleted by the build.
849 fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
851 // order only dep dirty, no rebuild.
852 fs_.Create("otherfile", "");
853 command_runner_.commands_ran_.clear();
855 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
857 EXPECT_TRUE(builder_.AlreadyUpToDate());
859 // implicit dep missing, expect rebuild.
860 fs_.RemoveFile("bar.h");
861 command_runner_.commands_ran_.clear();
863 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
864 EXPECT_TRUE(builder_.Build(&err));
866 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
869 TEST_F(BuildTest, RebuildOrderOnlyDeps) {
871 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
872 "rule cc\n command = cc $in\n"
873 "rule true\n command = true\n"
874 "build oo.h: cc oo.h.in\n"
875 "build foo.o: cc foo.c || oo.h\n"));
877 fs_.Create("foo.c", "");
878 fs_.Create("oo.h.in", "");
880 // foo.o and order-only dep dirty, build both.
881 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
882 EXPECT_TRUE(builder_.Build(&err));
884 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
886 // all clean, no rebuild.
887 command_runner_.commands_ran_.clear();
889 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
891 EXPECT_TRUE(builder_.AlreadyUpToDate());
893 // order-only dep missing, build it only.
894 fs_.RemoveFile("oo.h");
895 command_runner_.commands_ran_.clear();
897 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
898 EXPECT_TRUE(builder_.Build(&err));
900 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
901 ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
905 // order-only dep dirty, build it only.
906 fs_.Create("oo.h.in", "");
907 command_runner_.commands_ran_.clear();
909 EXPECT_TRUE(builder_.AddTarget("foo.o", &err));
910 EXPECT_TRUE(builder_.Build(&err));
912 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
913 ASSERT_EQ("cc oo.h.in", command_runner_.commands_ran_[0]);
916 TEST_F(BuildTest, Phony) {
918 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
919 "build out: cat bar.cc\n"
920 "build all: phony out\n"));
921 fs_.Create("bar.cc", "");
923 EXPECT_TRUE(builder_.AddTarget("all", &err));
926 // Only one command to run, because phony runs no command.
927 EXPECT_FALSE(builder_.AlreadyUpToDate());
928 EXPECT_TRUE(builder_.Build(&err));
930 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
933 TEST_F(BuildTest, PhonyNoWork) {
935 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
936 "build out: cat bar.cc\n"
937 "build all: phony out\n"));
938 fs_.Create("bar.cc", "");
939 fs_.Create("out", "");
941 EXPECT_TRUE(builder_.AddTarget("all", &err));
943 EXPECT_TRUE(builder_.AlreadyUpToDate());
946 TEST_F(BuildTest, Fail) {
947 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
950 "build out1: fail\n"));
953 EXPECT_TRUE(builder_.AddTarget("out1", &err));
956 EXPECT_FALSE(builder_.Build(&err));
957 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
958 ASSERT_EQ("subcommand failed", err);
961 TEST_F(BuildTest, SwallowFailures) {
962 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
968 "build all: phony out1 out2 out3\n"));
970 // Swallow two failures, die on the third.
971 config_.failures_allowed = 3;
974 EXPECT_TRUE(builder_.AddTarget("all", &err));
977 EXPECT_FALSE(builder_.Build(&err));
978 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
979 ASSERT_EQ("subcommands failed", err);
982 TEST_F(BuildTest, SwallowFailuresLimit) {
983 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
989 "build final: cat out1 out2 out3\n"));
991 // Swallow ten failures; we should stop before building final.
992 config_.failures_allowed = 11;
995 EXPECT_TRUE(builder_.AddTarget("final", &err));
998 EXPECT_FALSE(builder_.Build(&err));
999 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1000 ASSERT_EQ("cannot make progress due to previous errors", err);
1003 struct BuildWithLogTest : public BuildTest {
1004 BuildWithLogTest() {
1005 builder_.SetBuildLog(&build_log_);
1008 BuildLog build_log_;
1011 TEST_F(BuildWithLogTest, NotInLogButOnDisk) {
1012 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1015 "build out1: cc in\n"));
1017 // Create input/output that would be considered up to date when
1018 // not considering the command line hash.
1019 fs_.Create("in", "");
1020 fs_.Create("out1", "");
1023 // Because it's not in the log, it should not be up-to-date until
1025 EXPECT_TRUE(builder_.AddTarget("out1", &err));
1026 EXPECT_FALSE(builder_.AlreadyUpToDate());
1028 command_runner_.commands_ran_.clear();
1031 EXPECT_TRUE(builder_.AddTarget("out1", &err));
1032 EXPECT_TRUE(builder_.Build(&err));
1033 EXPECT_TRUE(builder_.AlreadyUpToDate());
1036 TEST_F(BuildWithLogTest, RestatTest) {
1037 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1044 "build out1: cc in\n"
1045 "build out2: true out1\n"
1046 "build out3: cat out2\n"));
1048 fs_.Create("out1", "");
1049 fs_.Create("out2", "");
1050 fs_.Create("out3", "");
1054 fs_.Create("in", "");
1056 // Do a pre-build so that there's commands in the log for the outputs,
1057 // otherwise, the lack of an entry in the build log will cause out3 to rebuild
1058 // regardless of restat.
1060 EXPECT_TRUE(builder_.AddTarget("out3", &err));
1062 EXPECT_TRUE(builder_.Build(&err));
1064 EXPECT_EQ("[3/3]", builder_.status_->FormatProgressStatus("[%s/%t]"));
1065 command_runner_.commands_ran_.clear();
1070 fs_.Create("in", "");
1071 // "cc" touches out1, so we should build out2. But because "true" does not
1072 // touch out2, we should cancel the build of out3.
1073 EXPECT_TRUE(builder_.AddTarget("out3", &err));
1075 EXPECT_TRUE(builder_.Build(&err));
1076 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1078 // If we run again, it should be a no-op, because the build log has recorded
1079 // that we've already built out2 with an input timestamp of 2 (from out1).
1080 command_runner_.commands_ran_.clear();
1082 EXPECT_TRUE(builder_.AddTarget("out3", &err));
1084 EXPECT_TRUE(builder_.AlreadyUpToDate());
1088 fs_.Create("in", "");
1090 // The build log entry should not, however, prevent us from rebuilding out2
1092 command_runner_.commands_ran_.clear();
1094 EXPECT_TRUE(builder_.AddTarget("out3", &err));
1096 EXPECT_TRUE(builder_.Build(&err));
1097 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1100 TEST_F(BuildWithLogTest, RestatMissingFile) {
1101 // If a restat rule doesn't create its output, and the output didn't
1102 // exist before the rule was run, consider that behavior equivalent
1103 // to a rule that doesn't modify its existent output file.
1105 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1111 "build out1: true in\n"
1112 "build out2: cc out1\n"));
1114 fs_.Create("in", "");
1115 fs_.Create("out2", "");
1117 // Do a pre-build so that there's commands in the log for the outputs,
1118 // otherwise, the lack of an entry in the build log will cause out2 to rebuild
1119 // regardless of restat.
1121 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1123 EXPECT_TRUE(builder_.Build(&err));
1125 command_runner_.commands_ran_.clear();
1129 fs_.Create("in", "");
1130 fs_.Create("out2", "");
1132 // Run a build, expect only the first command to run.
1133 // It doesn't touch its output (due to being the "true" command), so
1134 // we shouldn't run the dependent build.
1135 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1137 EXPECT_TRUE(builder_.Build(&err));
1138 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1141 TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
1142 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1147 " command = touch\n"
1148 "build out1: true in\n"
1149 "build out2 out3: touch out1\n"
1150 "build out4: touch out2\n"
1153 // Create the necessary files
1154 fs_.Create("in", "");
1157 EXPECT_TRUE(builder_.AddTarget("out4", &err));
1159 EXPECT_TRUE(builder_.Build(&err));
1161 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1164 fs_.Create("in", "");
1165 fs_.RemoveFile("out3");
1167 // Since "in" is missing, out1 will be built. Since "out3" is missing,
1168 // out2 and out3 will be built even though "in" is not touched when built.
1169 // Then, since out2 is rebuilt, out4 should be rebuilt -- the restat on the
1170 // "true" rule should not lead to the "touch" edge writing out2 and out3 being
1172 command_runner_.commands_ran_.clear();
1174 EXPECT_TRUE(builder_.AddTarget("out4", &err));
1176 EXPECT_TRUE(builder_.Build(&err));
1178 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1181 // Test scenario, in which an input file is removed, but output isn't changed
1182 // https://github.com/martine/ninja/issues/295
1183 TEST_F(BuildWithLogTest, RestatMissingInput) {
1184 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1187 " depfile = $out.d\n"
1191 "build out1: true in\n"
1192 "build out2: cc out1\n"));
1194 // Create all necessary files
1195 fs_.Create("in", "");
1197 // The implicit dependencies and the depfile itself
1198 // are newer than the output
1199 TimeStamp restat_mtime = fs_.Tick();
1200 fs_.Create("out1.d", "out1: will.be.deleted restat.file\n");
1201 fs_.Create("will.be.deleted", "");
1202 fs_.Create("restat.file", "");
1204 // Run the build, out1 and out2 get built
1206 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1208 EXPECT_TRUE(builder_.Build(&err));
1209 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1211 // See that an entry in the logfile is created, capturing
1213 BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out1");
1214 ASSERT_TRUE(NULL != log_entry);
1215 ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1217 // Now remove a file, referenced from depfile, so that target becomes
1218 // dirty, but the output does not change
1219 fs_.RemoveFile("will.be.deleted");
1221 // Trigger the build again - only out1 gets built
1222 command_runner_.commands_ran_.clear();
1224 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1226 EXPECT_TRUE(builder_.Build(&err));
1227 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1229 // Check that the logfile entry remains correctly set
1230 log_entry = build_log_.LookupByOutput("out1");
1231 ASSERT_TRUE(NULL != log_entry);
1232 ASSERT_EQ(restat_mtime, log_entry->restat_mtime);
1235 struct BuildDryRun : public BuildWithLogTest {
1237 config_.dry_run = true;
1241 TEST_F(BuildDryRun, AllCommandsShown) {
1242 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1249 "build out1: cc in\n"
1250 "build out2: true out1\n"
1251 "build out3: cat out2\n"));
1253 fs_.Create("out1", "");
1254 fs_.Create("out2", "");
1255 fs_.Create("out3", "");
1259 fs_.Create("in", "");
1261 // "cc" touches out1, so we should build out2. But because "true" does not
1262 // touch out2, we should cancel the build of out3.
1264 EXPECT_TRUE(builder_.AddTarget("out3", &err));
1266 EXPECT_TRUE(builder_.Build(&err));
1267 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1270 // Test that RSP files are created when & where appropriate and deleted after
1271 // successful execution.
1272 TEST_F(BuildTest, RspFileSuccess)
1274 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1276 " command = cat $rspfile > $out\n"
1277 " rspfile = $rspfile\n"
1278 " rspfile_content = $long_command\n"
1279 "build out1: cat in\n"
1280 "build out2: cat_rsp in\n"
1281 " rspfile = out2.rsp\n"
1282 " long_command = Some very long command\n"));
1284 fs_.Create("out1", "");
1285 fs_.Create("out2", "");
1286 fs_.Create("out3", "");
1290 fs_.Create("in", "");
1293 EXPECT_TRUE(builder_.AddTarget("out1", &err));
1295 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1298 size_t files_created = fs_.files_created_.size();
1299 size_t files_removed = fs_.files_removed_.size();
1301 EXPECT_TRUE(builder_.Build(&err));
1302 ASSERT_EQ(2u, command_runner_.commands_ran_.size()); // cat + cat_rsp
1304 // The RSP file was created
1305 ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1306 ASSERT_EQ(1u, fs_.files_created_.count("out2.rsp"));
1308 // The RSP file was removed
1309 ASSERT_EQ(files_removed + 1, fs_.files_removed_.size());
1310 ASSERT_EQ(1u, fs_.files_removed_.count("out2.rsp"));
1313 // Test that RSP file is created but not removed for commands, which fail
1314 TEST_F(BuildTest, RspFileFailure) {
1315 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1318 " rspfile = $rspfile\n"
1319 " rspfile_content = $long_command\n"
1320 "build out: fail in\n"
1321 " rspfile = out.rsp\n"
1322 " long_command = Another very long command\n"));
1324 fs_.Create("out", "");
1326 fs_.Create("in", "");
1329 EXPECT_TRUE(builder_.AddTarget("out", &err));
1332 size_t files_created = fs_.files_created_.size();
1333 size_t files_removed = fs_.files_removed_.size();
1335 EXPECT_FALSE(builder_.Build(&err));
1336 ASSERT_EQ("subcommand failed", err);
1337 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1339 // The RSP file was created
1340 ASSERT_EQ(files_created + 1, fs_.files_created_.size());
1341 ASSERT_EQ(1u, fs_.files_created_.count("out.rsp"));
1343 // The RSP file was NOT removed
1344 ASSERT_EQ(files_removed, fs_.files_removed_.size());
1345 ASSERT_EQ(0u, fs_.files_removed_.count("out.rsp"));
1347 // The RSP file contains what it should
1348 ASSERT_EQ("Another very long command", fs_.files_["out.rsp"].contents);
1351 // Test that contens of the RSP file behaves like a regular part of
1352 // command line, i.e. triggers a rebuild if changed
1353 TEST_F(BuildWithLogTest, RspFileCmdLineChange) {
1354 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1356 " command = cat $rspfile > $out\n"
1357 " rspfile = $rspfile\n"
1358 " rspfile_content = $long_command\n"
1359 "build out: cat_rsp in\n"
1360 " rspfile = out.rsp\n"
1361 " long_command = Original very long command\n"));
1363 fs_.Create("out", "");
1365 fs_.Create("in", "");
1368 EXPECT_TRUE(builder_.AddTarget("out", &err));
1371 // 1. Build for the 1st time (-> populate log)
1372 EXPECT_TRUE(builder_.Build(&err));
1373 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1375 // 2. Build again (no change)
1376 command_runner_.commands_ran_.clear();
1378 EXPECT_TRUE(builder_.AddTarget("out", &err));
1380 ASSERT_TRUE(builder_.AlreadyUpToDate());
1382 // 3. Alter the entry in the logfile
1383 // (to simulate a change in the command line between 2 builds)
1384 BuildLog::LogEntry* log_entry = build_log_.LookupByOutput("out");
1385 ASSERT_TRUE(NULL != log_entry);
1386 ASSERT_NO_FATAL_FAILURE(AssertHash(
1387 "cat out.rsp > out;rspfile=Original very long command",
1388 log_entry->command_hash));
1389 log_entry->command_hash++; // Change the command hash to something else.
1390 // Now expect the target to be rebuilt
1391 command_runner_.commands_ran_.clear();
1393 EXPECT_TRUE(builder_.AddTarget("out", &err));
1395 EXPECT_TRUE(builder_.Build(&err));
1396 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1399 TEST_F(BuildTest, InterruptCleanup) {
1400 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1402 " command = interrupt\n"
1403 "rule touch-interrupt\n"
1404 " command = touch-interrupt\n"
1405 "build out1: interrupt in1\n"
1406 "build out2: touch-interrupt in2\n"));
1408 fs_.Create("out1", "");
1409 fs_.Create("out2", "");
1411 fs_.Create("in1", "");
1412 fs_.Create("in2", "");
1414 // An untouched output of an interrupted command should be retained.
1416 EXPECT_TRUE(builder_.AddTarget("out1", &err));
1418 EXPECT_FALSE(builder_.Build(&err));
1419 EXPECT_EQ("interrupted by user", err);
1421 EXPECT_GT(fs_.Stat("out1"), 0);
1424 // A touched output of an interrupted command should be deleted.
1425 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1427 EXPECT_FALSE(builder_.Build(&err));
1428 EXPECT_EQ("interrupted by user", err);
1430 EXPECT_EQ(0, fs_.Stat("out2"));
1433 TEST_F(BuildTest, PhonyWithNoInputs) {
1434 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1435 "build nonexistent: phony\n"
1436 "build out1: cat || nonexistent\n"
1437 "build out2: cat nonexistent\n"));
1438 fs_.Create("out1", "");
1439 fs_.Create("out2", "");
1441 // out1 should be up to date even though its input is dirty, because its
1442 // order-only dependency has nothing to do.
1444 EXPECT_TRUE(builder_.AddTarget("out1", &err));
1446 EXPECT_TRUE(builder_.AlreadyUpToDate());
1448 // out2 should still be out of date though, because its input is dirty.
1450 command_runner_.commands_ran_.clear();
1452 EXPECT_TRUE(builder_.AddTarget("out2", &err));
1454 EXPECT_TRUE(builder_.Build(&err));
1456 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1459 TEST_F(BuildTest, DepsGccWithEmptyDepfileErrorsOut) {
1460 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1464 "build out: cc\n"));
1468 EXPECT_TRUE(builder_.AddTarget("out", &err));
1470 EXPECT_FALSE(builder_.AlreadyUpToDate());
1472 EXPECT_FALSE(builder_.Build(&err));
1473 ASSERT_EQ("subcommand failed", err);
1474 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1477 TEST_F(BuildTest, StatusFormatReplacePlaceholder) {
1478 EXPECT_EQ("[%/s0/t0/r0/u0/f0]",
1479 status_.FormatProgressStatus("[%%/s%s/t%t/r%r/u%u/f%f]"));
1482 TEST_F(BuildTest, FailedDepsParse) {
1483 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1484 "build bad_deps.o: cat in1\n"
1486 " depfile = in1.d\n"));
1489 EXPECT_TRUE(builder_.AddTarget("bad_deps.o", &err));
1492 // These deps will fail to parse, as they should only have one
1493 // path to the left of the colon.
1494 fs_.Create("in1.d", "AAA BBB");
1496 EXPECT_FALSE(builder_.Build(&err));
1497 EXPECT_EQ("subcommand failed", err);
1500 /// Tests of builds involving deps logs necessarily must span
1501 /// multiple builds. We reuse methods on BuildTest but not the
1502 /// builder_ it sets up, because we want pristine objects for
1504 struct BuildWithDepsLogTest : public BuildTest {
1505 BuildWithDepsLogTest() {}
1507 virtual void SetUp() {
1510 temp_dir_.CreateAndEnter("BuildWithDepsLogTest");
1513 virtual void TearDown() {
1514 temp_dir_.Cleanup();
1517 ScopedTempDir temp_dir_;
1519 /// Shadow parent class builder_ so we don't accidentally use it.
1523 /// Run a straightforwad build where the deps log is used.
1524 TEST_F(BuildWithDepsLogTest, Straightforward) {
1526 // Note: in1 was created by the superclass SetUp().
1527 const char* manifest =
1528 "build out: cat in1\n"
1530 " depfile = in1.d\n";
1533 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1534 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1536 // Run the build once, everything should be ok.
1538 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1541 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1542 builder.command_runner_.reset(&command_runner_);
1543 EXPECT_TRUE(builder.AddTarget("out", &err));
1545 fs_.Create("in1.d", "out: in2");
1546 EXPECT_TRUE(builder.Build(&err));
1549 // The deps file should have been removed.
1550 EXPECT_EQ(0, fs_.Stat("in1.d"));
1551 // Recreate it for the next step.
1552 fs_.Create("in1.d", "out: in2");
1554 builder.command_runner_.release();
1559 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1560 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1562 // Touch the file only mentioned in the deps.
1564 fs_.Create("in2", "");
1566 // Run the build again.
1568 ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1569 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1571 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1572 builder.command_runner_.reset(&command_runner_);
1573 command_runner_.commands_ran_.clear();
1574 EXPECT_TRUE(builder.AddTarget("out", &err));
1576 EXPECT_TRUE(builder.Build(&err));
1579 // We should have rebuilt the output due to in2 being
1581 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1583 builder.command_runner_.release();
1587 /// Verify that obsolete dependency info causes a rebuild.
1588 /// 1) Run a successful build where everything has time t, record deps.
1589 /// 2) Move input/output to time t+1 -- despite files in alignment,
1590 /// should still need to rebuild due to deps at older time.
1591 TEST_F(BuildWithDepsLogTest, ObsoleteDeps) {
1593 // Note: in1 was created by the superclass SetUp().
1594 const char* manifest =
1595 "build out: cat in1\n"
1597 " depfile = in1.d\n";
1599 // Run an ordinary build that gathers dependencies.
1600 fs_.Create("in1", "");
1601 fs_.Create("in1.d", "out: ");
1604 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1605 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1607 // Run the build once, everything should be ok.
1609 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1612 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1613 builder.command_runner_.reset(&command_runner_);
1614 EXPECT_TRUE(builder.AddTarget("out", &err));
1616 EXPECT_TRUE(builder.Build(&err));
1620 builder.command_runner_.release();
1623 // Push all files one tick forward so that only the deps are out
1626 fs_.Create("in1", "");
1627 fs_.Create("out", "");
1629 // The deps file should have been removed, so no need to timestamp it.
1630 EXPECT_EQ(0, fs_.Stat("in1.d"));
1634 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1635 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1638 ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1639 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1641 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1642 builder.command_runner_.reset(&command_runner_);
1643 command_runner_.commands_ran_.clear();
1644 EXPECT_TRUE(builder.AddTarget("out", &err));
1647 // Recreate the deps file here because the build expects them to exist.
1648 fs_.Create("in1.d", "out: ");
1650 EXPECT_TRUE(builder.Build(&err));
1653 // We should have rebuilt the output due to the deps being
1655 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1657 builder.command_runner_.release();
1661 TEST_F(BuildWithDepsLogTest, DepsIgnoredInDryRun) {
1662 const char* manifest =
1663 "build out: cat in1\n"
1665 " depfile = in1.d\n";
1667 fs_.Create("out", "");
1669 fs_.Create("in1", "");
1672 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1673 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1675 // The deps log is NULL in dry runs.
1676 config_.dry_run = true;
1677 Builder builder(&state, config_, NULL, NULL, &fs_);
1678 builder.command_runner_.reset(&command_runner_);
1679 command_runner_.commands_ran_.clear();
1682 EXPECT_TRUE(builder.AddTarget("out", &err));
1684 EXPECT_TRUE(builder.Build(&err));
1685 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1687 builder.command_runner_.release();
1690 /// Check that a restat rule generating a header cancels compilations correctly.
1691 TEST_F(BuildTest, RestatDepfileDependency) {
1692 ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
1694 " command = true\n" // Would be "write if out-of-date" in reality.
1696 "build header.h: true header.in\n"
1697 "build out: cat in1\n"
1698 " depfile = in1.d\n"));
1700 fs_.Create("header.h", "");
1701 fs_.Create("in1.d", "out: header.h");
1703 fs_.Create("header.in", "");
1706 EXPECT_TRUE(builder_.AddTarget("out", &err));
1708 EXPECT_TRUE(builder_.Build(&err));
1712 /// Check that a restat rule generating a header cancels compilations correctly,
1714 TEST_F(BuildWithDepsLogTest, RestatDepfileDependencyDepsLog) {
1716 // Note: in1 was created by the superclass SetUp().
1717 const char* manifest =
1719 " command = true\n" // Would be "write if out-of-date" in reality.
1721 "build header.h: true header.in\n"
1722 "build out: cat in1\n"
1724 " depfile = in1.d\n";
1727 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1728 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1730 // Run the build once, everything should be ok.
1732 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1735 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1736 builder.command_runner_.reset(&command_runner_);
1737 EXPECT_TRUE(builder.AddTarget("out", &err));
1739 fs_.Create("in1.d", "out: header.h");
1740 EXPECT_TRUE(builder.Build(&err));
1744 builder.command_runner_.release();
1749 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
1750 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1752 // Touch the input of the restat rule.
1754 fs_.Create("header.in", "");
1756 // Run the build again.
1758 ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1759 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1761 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1762 builder.command_runner_.reset(&command_runner_);
1763 command_runner_.commands_ran_.clear();
1764 EXPECT_TRUE(builder.AddTarget("out", &err));
1766 EXPECT_TRUE(builder.Build(&err));
1769 // Rule "true" should have run again, but the build of "out" should have
1770 // been cancelled due to restat propagating through the depfile header.
1771 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1773 builder.command_runner_.release();
1777 TEST_F(BuildWithDepsLogTest, DepFileOKDepsLog) {
1779 const char* manifest =
1780 "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
1781 "build foo.o: cc foo.c\n";
1783 fs_.Create("foo.c", "");
1787 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1789 // Run the build once, everything should be ok.
1791 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1794 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1795 builder.command_runner_.reset(&command_runner_);
1796 EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1798 fs_.Create("foo.o.d", "foo.o: blah.h bar.h\n");
1799 EXPECT_TRUE(builder.Build(&err));
1803 builder.command_runner_.release();
1808 ASSERT_NO_FATAL_FAILURE(AssertParse(&state, manifest));
1811 ASSERT_TRUE(deps_log.Load("ninja_deps", &state, &err));
1812 ASSERT_TRUE(deps_log.OpenForWrite("ninja_deps", &err));
1815 Builder builder(&state, config_, NULL, &deps_log, &fs_);
1816 builder.command_runner_.reset(&command_runner_);
1818 Edge* edge = state.edges_.back();
1820 state.GetNode("bar.h")->MarkDirty(); // Mark bar.h as missing.
1821 EXPECT_TRUE(builder.AddTarget("foo.o", &err));
1824 // Expect three new edges: one generating foo.o, and two more from
1825 // loading the depfile.
1826 ASSERT_EQ(3u, state.edges_.size());
1827 // Expect our edge to now have three inputs: foo.c and two headers.
1828 ASSERT_EQ(3u, edge->inputs_.size());
1830 // Expect the command line we generate to only use the original input.
1831 ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
1834 builder.command_runner_.release();
1838 /// Check that a restat rule doesn't clear an edge if the depfile is missing.
1839 /// Follows from: https://github.com/martine/ninja/issues/603
1840 TEST_F(BuildTest, RestatMissingDepfile) {
1841 const char* manifest =
1843 " command = true\n" // Would be "write if out-of-date" in reality.
1845 "build header.h: true header.in\n"
1846 "build out: cat header.h\n"
1847 " depfile = out.d\n";
1849 fs_.Create("header.h", "");
1851 fs_.Create("out", "");
1852 fs_.Create("header.in", "");
1854 // Normally, only 'header.h' would be rebuilt, as
1855 // its rule doesn't touch the output and has 'restat=1' set.
1856 // But we are also missing the depfile for 'out',
1857 // which should force its command to run anyway!
1858 RebuildTarget("out", manifest);
1859 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1862 /// Check that a restat rule doesn't clear an edge if the deps are missing.
1863 /// https://github.com/martine/ninja/issues/603
1864 TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
1866 const char* manifest =
1868 " command = true\n" // Would be "write if out-of-date" in reality.
1870 "build header.h: true header.in\n"
1871 "build out: cat header.h\n"
1873 " depfile = out.d\n";
1875 // Build once to populate ninja deps logs from out.d
1876 fs_.Create("header.in", "");
1877 fs_.Create("out.d", "out: header.h");
1878 fs_.Create("header.h", "");
1880 RebuildTarget("out", manifest, "build_log", "ninja_deps");
1881 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1883 // Sanity: this rebuild should be NOOP
1884 RebuildTarget("out", manifest, "build_log", "ninja_deps");
1885 ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1887 // Touch 'header.in', blank dependencies log (create a different one).
1888 // Building header.h triggers 'restat' outputs cleanup.
1889 // Validate that out is rebuilt netherless, as deps are missing.
1891 fs_.Create("header.in", "");
1893 // (switch to a new blank deps_log "ninja_deps2")
1894 RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1895 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1897 // Sanity: this build should be NOOP
1898 RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1899 ASSERT_EQ(0u, command_runner_.commands_ran_.size());
1901 // Check that invalidating deps by target timestamp also works here
1902 // Repeat the test but touch target instead of blanking the log.
1904 fs_.Create("header.in", "");
1905 fs_.Create("out", "");
1906 RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1907 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1909 // And this build should be NOOP again
1910 RebuildTarget("out", manifest, "build_log", "ninja_deps2");
1911 ASSERT_EQ(0u, command_runner_.commands_ran_.size());