46 for (
int i = 0; i < count; ++i) {
47 ASSERT_TRUE(
plan_.more_to_do());
52 ASSERT_FALSE(
plan_.FindWork());
61 ASSERT_TRUE(
plan_.more_to_do());
70"build mid: cat in\n"));
71 GetNode(
"mid")->MarkDirty();
72 GetNode(
"out")->MarkDirty();
73 PrepareForTarget(
"out");
75 Edge* edge = plan_.FindWork();
77 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
78 ASSERT_EQ(
"mid", edge->
outputs_[0]->path());
80 ASSERT_FALSE(plan_.FindWork());
86 edge = plan_.FindWork();
88 ASSERT_EQ(
"mid", edge->
inputs_[0]->path());
89 ASSERT_EQ(
"out", edge->
outputs_[0]->path());
94 ASSERT_FALSE(plan_.more_to_do());
95 edge = plan_.FindWork();
102"build out: cat mid1 mid2\n"
103"build mid1 mid2: cat in\n"));
104 GetNode(
"mid1")->MarkDirty();
105 GetNode(
"mid2")->MarkDirty();
106 GetNode(
"out")->MarkDirty();
107 PrepareForTarget(
"out");
110 edge = plan_.FindWork();
116 edge = plan_.FindWork();
121 edge = plan_.FindWork();
128"build out: cat b1 b2\n"
131"build a1 a2: cat in\n"));
132 GetNode(
"a1")->MarkDirty();
133 GetNode(
"a2")->MarkDirty();
134 GetNode(
"b1")->MarkDirty();
135 GetNode(
"b2")->MarkDirty();
136 GetNode(
"out")->MarkDirty();
137 PrepareForTarget(
"out");
140 edge = plan_.FindWork();
146 edge = plan_.FindWork();
151 edge = plan_.FindWork();
156 edge = plan_.FindWork();
161 edge = plan_.FindWork();
168"build out: cat a1 a2\n"
171"build mid: cat in\n"));
172 GetNode(
"mid")->MarkDirty();
173 GetNode(
"a1")->MarkDirty();
174 GetNode(
"a2")->MarkDirty();
175 GetNode(
"out")->MarkDirty();
176 PrepareForTarget(
"out");
179 edge = plan_.FindWork();
185 edge = plan_.FindWork();
190 edge = plan_.FindWork();
195 edge = plan_.FindWork();
200 edge = plan_.FindWork();
213 plan_.PrepareQueue();
214 ASSERT_TRUE(
plan_.more_to_do());
218 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
219 ASSERT_EQ(
"out1", edge->
outputs_[0]->path());
222 ASSERT_FALSE(
plan_.FindWork());
227 edge =
plan_.FindWork();
229 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
230 ASSERT_EQ(
"out2", edge->
outputs_[0]->path());
232 ASSERT_FALSE(
plan_.FindWork());
237 ASSERT_FALSE(
plan_.more_to_do());
238 edge =
plan_.FindWork();
243 TestPoolWithDepthOne(
247" command = cat $in > $out\n"
249"build out1: poolcat in\n"
250"build out2: poolcat in\n");
254 TestPoolWithDepthOne(
256" command = cat $in > $out\n"
258"build out1: poolcat in\n"
259"build out2: poolcat in\n");
269" command = cat $in > $out\n"
272" command = cat $in > $out\n"
274"build out1: foocat in\n"
275"build out2: foocat in\n"
276"build out3: foocat in\n"
277"build outb1: bazcat in\n"
278"build outb2: bazcat in\n"
279"build outb3: bazcat in\n"
281"build allTheThings: cat out1 out2 out3 outb1 outb2 outb3\n"
284 for (
int i = 0; i < 3; ++i) {
285 GetNode(
"out" +
string(1,
'1' +
static_cast<char>(i)))->MarkDirty();
286 GetNode(
"outb" +
string(1,
'1' +
static_cast<char>(i)))->MarkDirty();
288 GetNode(
"allTheThings")->MarkDirty();
289 PrepareForTarget(
"allTheThings");
292 FindWorkSorted(&edges, 5);
294 for (
int i = 0; i < 4; ++i) {
295 Edge *edge = edges[i];
296 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
297 string base_name(i < 2 ?
"out" :
"outb");
298 ASSERT_EQ(base_name +
string(1,
'1' + (i % 2)), edge->
outputs_[0]->path());
302 Edge* edge = edges[4];
304 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
305 ASSERT_EQ(
"outb3", edge->
outputs_[0]->path());
314 Edge* out3 = plan_.FindWork();
316 ASSERT_EQ(
"in", out3->
inputs_[0]->path());
317 ASSERT_EQ(
"out3", out3->
outputs_[0]->path());
319 ASSERT_FALSE(plan_.FindWork());
324 ASSERT_FALSE(plan_.FindWork());
326 for (deque<Edge*>::iterator it = edges.begin(); it != edges.end(); ++it) {
331 Edge* last = plan_.FindWork();
333 ASSERT_EQ(
"allTheThings", last->
outputs_[0]->path());
338 ASSERT_FALSE(plan_.more_to_do());
339 ASSERT_FALSE(plan_.FindWork());
347 " command = touch foo.cpp\n"
349 " command = touch bar.cpp\n"
351 " command = echo $out > $out\n"
352 "build foo.cpp.obj: echo foo.cpp || foo.cpp\n"
354 "build bar.cpp.obj: echo bar.cpp || bar.cpp\n"
356 "build libfoo.a: echo foo.cpp.obj bar.cpp.obj\n"
357 "build foo.cpp: gen_foo\n"
358 "build bar.cpp: gen_bar\n"
359 "build all: phony libfoo.a\n"));
360 GetNode(
"foo.cpp")->MarkDirty();
361 GetNode(
"foo.cpp.obj")->MarkDirty();
362 GetNode(
"bar.cpp")->MarkDirty();
363 GetNode(
"bar.cpp.obj")->MarkDirty();
364 GetNode(
"libfoo.a")->MarkDirty();
365 GetNode(
"all")->MarkDirty();
366 PrepareForTarget(
"all");
370 deque<Edge*> initial_edges;
371 FindWorkSorted(&initial_edges, 2);
373 edge = initial_edges[1];
374 ASSERT_EQ(
"foo.cpp", edge->
outputs_[0]->path());
379 edge = plan_.FindWork();
381 ASSERT_FALSE(plan_.FindWork());
382 ASSERT_EQ(
"foo.cpp", edge->
inputs_[0]->path());
383 ASSERT_EQ(
"foo.cpp", edge->
inputs_[1]->path());
384 ASSERT_EQ(
"foo.cpp.obj", edge->
outputs_[0]->path());
388 edge = initial_edges[0];
389 ASSERT_EQ(
"bar.cpp", edge->
outputs_[0]->path());
393 edge = plan_.FindWork();
395 ASSERT_FALSE(plan_.FindWork());
396 ASSERT_EQ(
"bar.cpp", edge->
inputs_[0]->path());
397 ASSERT_EQ(
"bar.cpp", edge->
inputs_[1]->path());
398 ASSERT_EQ(
"bar.cpp.obj", edge->
outputs_[0]->path());
402 edge = plan_.FindWork();
404 ASSERT_FALSE(plan_.FindWork());
405 ASSERT_EQ(
"foo.cpp.obj", edge->
inputs_[0]->path());
406 ASSERT_EQ(
"bar.cpp.obj", edge->
inputs_[1]->path());
407 ASSERT_EQ(
"libfoo.a", edge->
outputs_[0]->path());
411 edge = plan_.FindWork();
413 ASSERT_FALSE(plan_.FindWork());
414 ASSERT_EQ(
"libfoo.a", edge->
inputs_[0]->path());
415 ASSERT_EQ(
"all", edge->
outputs_[0]->path());
419 edge = plan_.FindWork();
421 ASSERT_FALSE(plan_.more_to_do());
429 " command = cat $in > $out\n"
431 "build out1: poolcat in\n"
432 "build out2: poolcat in\n"));
433 GetNode(
"out1")->MarkDirty();
434 GetNode(
"out2")->MarkDirty();
436 EXPECT_TRUE(plan_.AddTarget(GetNode(
"out1"), &err));
438 EXPECT_TRUE(plan_.AddTarget(GetNode(
"out2"), &err));
440 plan_.PrepareQueue();
441 ASSERT_TRUE(plan_.more_to_do());
443 Edge* edge = plan_.FindWork();
445 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
446 ASSERT_EQ(
"out1", edge->
outputs_[0]->path());
449 ASSERT_FALSE(plan_.FindWork());
454 edge = plan_.FindWork();
456 ASSERT_EQ(
"in", edge->
inputs_[0]->path());
457 ASSERT_EQ(
"out2", edge->
outputs_[0]->path());
459 ASSERT_FALSE(plan_.FindWork());
464 ASSERT_TRUE(plan_.more_to_do());
465 edge = plan_.FindWork();
482 " command = unused\n"
483 "build out: r a0 b0 c0\n"
489 GetNode(
"a1")->MarkDirty();
490 GetNode(
"a0")->MarkDirty();
491 GetNode(
"b0")->MarkDirty();
492 GetNode(
"c0")->MarkDirty();
493 GetNode(
"out")->MarkDirty();
495 PrepareForTarget(
"out", &log);
497 EXPECT_EQ(GetNode(
"out")->in_edge()->critical_path_weight(), 1);
498 EXPECT_EQ(GetNode(
"a0")->in_edge()->critical_path_weight(), 2);
499 EXPECT_EQ(GetNode(
"b0")->in_edge()->critical_path_weight(), 2);
500 EXPECT_EQ(GetNode(
"c0")->in_edge()->critical_path_weight(), 2);
501 EXPECT_EQ(GetNode(
"a1")->in_edge()->critical_path_weight(), 3);
503 const int n_edges = 5;
504 const char *expected_order[n_edges] = {
505 "a1",
"a0",
"b0",
"c0",
"out"};
506 for (
int i = 0; i < n_edges; ++i) {
507 Edge* edge = plan_.FindWork();
508 ASSERT_TRUE(edge !=
nullptr);
509 EXPECT_EQ(expected_order[i], edge->
outputs_[0]->path());
516 EXPECT_FALSE(plan_.FindWork());
529 virtual void Abort();
547 StateTestWithBuiltinRules::SetUp();
551"build cat1: cat in1\n"
552"build cat2: cat in1 in2\n"
553"build cat12: cat cat1 cat2\n");
555 fs_.Create(
"in1",
"");
556 fs_.Create(
"in2",
"");
568 void RebuildTarget(
const string& target,
const char* manifest,
569 const char* log_path = NULL,
const char* deps_path = NULL,
570 State* state = NULL);
573 void Dirty(
const string& path);
589 const char* log_path,
const char* deps_path,
591 State local_state, *pstate = &local_state;
598 BuildLog build_log, *pbuild_log = NULL;
600 ASSERT_TRUE(build_log.
Load(log_path, &err));
601 ASSERT_TRUE(build_log.
OpenForWrite(log_path, *
this, &err));
603 pbuild_log = &build_log;
606 DepsLog deps_log, *pdeps_log = NULL;
608 ASSERT_TRUE(deps_log.
Load(deps_path, pstate, &err));
611 pdeps_log = &deps_log;
615 EXPECT_TRUE(builder.
AddTarget(target, &err));
640 edge->
rule().
name() ==
"cat_rsp_out" ||
642 edge->
rule().
name() ==
"cp_multi_msvc" ||
643 edge->
rule().
name() ==
"cp_multi_gcc" ||
645 edge->
rule().
name() ==
"touch-interrupt" ||
646 edge->
rule().
name() ==
"touch-fail-tick2") {
647 for (vector<Node*>::iterator out = edge->
outputs_.begin();
648 out != edge->
outputs_.end(); ++out) {
649 fs_->Create((*out)->path(),
"");
651 }
else if (edge->
rule().
name() ==
"true" ||
653 edge->
rule().
name() ==
"interrupt" ||
656 }
else if (edge->
rule().
name() ==
"cp") {
657 assert(!edge->
inputs_.empty());
661 if (
fs_->ReadFile(edge->
inputs_[0]->path(), &content, &err) ==
663 fs_->WriteFile(edge->
outputs_[0]->path(), content,
false);
664 }
else if (edge->
rule().
name() ==
"touch-implicit-dep-out") {
665 string dep = edge->
GetBinding(
"test_dependency");
667 fs_->Create(dep,
"");
669 for (vector<Node*>::iterator out = edge->
outputs_.begin();
670 out != edge->
outputs_.end(); ++out) {
671 fs_->Create((*out)->path(),
"");
673 }
else if (edge->
rule().
name() ==
"touch-out-implicit-dep") {
674 string dep = edge->
GetBinding(
"test_dependency");
675 for (vector<Node*>::iterator out = edge->
outputs_.begin();
676 out != edge->
outputs_.end(); ++out) {
677 fs_->Create((*out)->path(),
"");
680 fs_->Create(dep,
"");
681 }
else if (edge->
rule().
name() ==
"generate-depfile") {
682 string dep = edge->
GetBinding(
"test_dependency");
687 fs_->Create(dep,
"");
690 for (vector<Node*>::iterator out = edge->
outputs_.begin();
691 out != edge->
outputs_.end(); ++out) {
692 contents += (*out)->path() +
": " + dep +
"\n";
693 fs_->Create((*out)->path(),
"");
695 fs_->Create(depfile, contents);
696 }
else if (edge->
rule().
name() ==
"long-cc") {
697 string dep = edge->
GetBinding(
"test_dependency");
700 for (vector<Node*>::iterator out = edge->
outputs_.begin();
701 out != edge->
outputs_.end(); ++out) {
705 fs_->Create((*out)->path(),
"");
706 contents += (*out)->path() +
": " + dep +
"\n";
708 if (!dep.empty() && !depfile.empty())
709 fs_->Create(depfile, contents);
711 printf(
"unknown command\n");
733 Edge* edge = *edge_iter;
736 if (edge->
rule().
name() ==
"interrupt" ||
737 edge->
rule().
name() ==
"touch-interrupt") {
742 if (edge->
rule().
name() ==
"console") {
751 if (edge->
rule().
name() ==
"cp_multi_msvc") {
752 const std::string prefix = edge->
GetBinding(
"msvc_deps_prefix");
753 for (std::vector<Node*>::iterator in = edge->
inputs_.begin();
754 in != edge->
inputs_.end(); ++in) {
755 result->
output += prefix + (*in)->path() +
'\n';
759 if (edge->
rule().
name() ==
"fail" ||
760 (edge->
rule().
name() ==
"touch-fail-tick2" &&
fs_->now_ == 2))
769 if (edge->
rule().
name() ==
"long-cc") {
770 string dep = edge->
GetBinding(
"test_dependency");
772 fs_->files_[dep].mtime = 3;
774 fs_->files_[dep].mtime = 9;
780 const string& verify_active_edge = edge->
GetBinding(
"verify_active_edge");
781 if (!verify_active_edge.empty()) {
782 bool verify_active_edge_found =
false;
785 if (!(*i)->outputs_.empty() &&
786 (*i)->outputs_[0]->path() == verify_active_edge) {
787 verify_active_edge_found =
true;
790 EXPECT_TRUE(verify_active_edge_found);
817 EXPECT_TRUE(builder_.AlreadyUpToDate());
825 EXPECT_TRUE(builder_.AddTarget(
"cat1", &err));
830 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
831 EXPECT_EQ(
"cat in1 > cat1", command_runner_.commands_ran_[0]);
839 EXPECT_TRUE(builder_.AddTarget(
"cat1", &err));
844 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
845 EXPECT_EQ(
"cat in1 > cat1", command_runner_.commands_ran_[0]);
850 EXPECT_TRUE(builder_.AddTarget(
"cat12", &err));
854 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
857 EXPECT_TRUE((command_runner_.commands_ran_[0] ==
"cat in1 > cat1" &&
858 command_runner_.commands_ran_[1] ==
"cat in1 in2 > cat2") ||
859 (command_runner_.commands_ran_[1] ==
"cat in1 > cat1" &&
860 command_runner_.commands_ran_[0] ==
"cat in1 in2 > cat2"));
862 EXPECT_EQ(
"cat cat1 cat2 > cat12", command_runner_.commands_ran_[2]);
868 fs_.Create(
"in2",
"");
870 EXPECT_TRUE(builder_.AddTarget(
"cat12", &err));
874 ASSERT_EQ(5u, command_runner_.commands_ran_.size());
875 EXPECT_EQ(
"cat in1 in2 > cat2", command_runner_.commands_ran_[3]);
876 EXPECT_EQ(
"cat cat1 cat2 > cat12", command_runner_.commands_ran_[4]);
882" command = touch $out\n"
883"build out1 out2: touch in.txt\n"));
885 fs_.Create(
"in.txt",
"");
888 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
892 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
893 EXPECT_EQ(
"touch out1 out2", command_runner_.commands_ran_[0]);
899" command = touch $out $out.imp\n"
900"build out | out.imp: touch in.txt\n"));
901 fs_.Create(
"in.txt",
"");
904 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
908 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
909 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[0]);
917" command = touch $out\n"
918"build in1 otherfile: touch in\n"
919"build out: touch in | in1\n"));
921 fs_.Create(
"in",
"");
923 fs_.Create(
"in1",
"");
926 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
937"build c5: cat c4\n"));
939 fs_.Create(
"c1",
"");
942 EXPECT_TRUE(builder_.AddTarget(
"c5", &err));
946 ASSERT_EQ(4u, command_runner_.commands_ran_.size());
949 command_runner_.commands_ran_.clear();
951 EXPECT_TRUE(builder_.AddTarget(
"c5", &err));
953 EXPECT_TRUE(builder_.AlreadyUpToDate());
957 fs_.Create(
"c3",
"");
959 command_runner_.commands_ran_.clear();
961 EXPECT_TRUE(builder_.AddTarget(
"c5", &err));
963 EXPECT_FALSE(builder_.AlreadyUpToDate());
965 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
972 EXPECT_FALSE(builder_.AddTarget(
"cat1", &err));
973 EXPECT_EQ(
"'in1', needed by 'cat1', missing and no known rule to make it",
980 EXPECT_FALSE(builder_.AddTarget(
"meow", &err));
981 EXPECT_EQ(
"unknown target: 'meow'", err);
988 EXPECT_FALSE(builder_.AddTarget(
"in1", &err));
989 EXPECT_EQ(
"'in1' missing and no known rule to make it", err);
997 "build subdir\\dir2\\file: cat in1\n"));
1000 "build subdir/dir2/file: cat in1\n"));
1002 EXPECT_TRUE(builder_.AddTarget(
"subdir/dir2/file", &err));
1007 ASSERT_EQ(2u, fs_.directories_made_.size());
1008 EXPECT_EQ(
"subdir", fs_.directories_made_[0]);
1009 EXPECT_EQ(
"subdir/dir2", fs_.directories_made_[1]);
1015"rule cc\n command = cc $in\n depfile = $out.d\n"
1016"build fo$ o.o: cc foo.c\n"));
1017 fs_.Create(
"foo.c",
"");
1019 EXPECT_TRUE(builder_.AddTarget(
"fo o.o", &err));
1021 ASSERT_EQ(1u, fs_.files_read_.size());
1022 EXPECT_EQ(
"fo o.o.d", fs_.files_read_[0]);
1027 int orig_edges =
static_cast<int>(state_.edges_.size());
1029"rule cc\n command = cc $in\n depfile = $out.d\n"
1030"build foo.o: cc foo.c\n"));
1031 Edge* edge = state_.edges_.back();
1033 fs_.Create(
"foo.c",
"");
1034 GetNode(
"bar.h")->MarkDirty();
1035 fs_.Create(
"foo.o.d",
"foo.o: blah.h bar.h\n");
1036 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1038 ASSERT_EQ(1u, fs_.files_read_.size());
1039 EXPECT_EQ(
"foo.o.d", fs_.files_read_[0]);
1043 ASSERT_EQ(orig_edges + 1, (
int)state_.edges_.size());
1047 ASSERT_FALSE(state_.LookupNode(
"foo.o")->generated_by_dep_loader());
1048 ASSERT_FALSE(state_.LookupNode(
"foo.c")->generated_by_dep_loader());
1049 ASSERT_TRUE(state_.LookupNode(
"blah.h"));
1050 ASSERT_TRUE(state_.LookupNode(
"blah.h")->generated_by_dep_loader());
1051 ASSERT_TRUE(state_.LookupNode(
"bar.h"));
1052 ASSERT_TRUE(state_.LookupNode(
"bar.h")->generated_by_dep_loader());
1055 ASSERT_EQ(3u, edge->
inputs_.size());
1064"rule cc\n command = cc $in\n depfile = $out.d\n"
1065"build foo.o: cc foo.c\n"));
1066 fs_.Create(
"foo.c",
"");
1067 fs_.Create(
"foo.o.d",
"randomtext\n");
1068 EXPECT_FALSE(builder_.AddTarget(
"foo.o", &err));
1069 EXPECT_EQ(
"foo.o.d: expected ':' in depfile", err);
1076" command = touch $out\n"
1078"build b: touch || c\n"
1079"build a: touch | b || c\n"));
1081 vector<Edge*> c_out = GetNode(
"c")->out_edges();
1082 ASSERT_EQ(2u, c_out.size());
1083 EXPECT_EQ(
"b", c_out[0]->outputs_[0]->path());
1084 EXPECT_EQ(
"a", c_out[1]->outputs_[0]->path());
1086 fs_.Create(
"b",
"");
1087 EXPECT_TRUE(builder_.AddTarget(
"a", &err));
1092 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1098"rule cc\n command = cc $in\n depfile = $out.d\n"
1099"build foo.o: cc foo.c || otherfile\n"));
1100 Edge* edge = state_.edges_.back();
1102 fs_.Create(
"foo.c",
"");
1103 fs_.Create(
"otherfile",
"");
1104 fs_.Create(
"foo.o.d",
"foo.o: blah.h bar.h\n");
1105 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1109 ASSERT_EQ(4u, edge->
inputs_.size());
1114 EXPECT_EQ(
"foo.c", edge->
inputs_[0]->path());
1115 EXPECT_EQ(
"blah.h", edge->
inputs_[1]->path());
1116 EXPECT_EQ(
"bar.h", edge->
inputs_[2]->path());
1117 EXPECT_EQ(
"otherfile", edge->
inputs_[3]->path());
1125 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1130 fs_.Create(
"foo.o.d",
"foo.o: blah.h bar.h\n");
1133 fs_.Create(
"blah.h",
"");
1134 fs_.Create(
"bar.h",
"");
1135 command_runner_.commands_ran_.clear();
1137 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1140 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1145 fs_.Create(
"foo.o.d",
"foo.o: blah.h bar.h\n");
1148 fs_.Create(
"otherfile",
"");
1149 command_runner_.commands_ran_.clear();
1151 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1153 EXPECT_TRUE(builder_.AlreadyUpToDate());
1156 fs_.RemoveFile(
"bar.h");
1157 command_runner_.commands_ran_.clear();
1159 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1162 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1168"rule cc\n command = cc $in\n"
1169"rule true\n command = true\n"
1170"build oo.h: cc oo.h.in\n"
1171"build foo.o: cc foo.c || oo.h\n"));
1173 fs_.Create(
"foo.c",
"");
1174 fs_.Create(
"oo.h.in",
"");
1177 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1180 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1183 command_runner_.commands_ran_.clear();
1185 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1187 EXPECT_TRUE(builder_.AlreadyUpToDate());
1190 fs_.RemoveFile(
"oo.h");
1191 command_runner_.commands_ran_.clear();
1193 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1196 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1197 ASSERT_EQ(
"cc oo.h.in", command_runner_.commands_ran_[0]);
1202 fs_.Create(
"oo.h.in",
"");
1203 command_runner_.commands_ran_.clear();
1205 EXPECT_TRUE(builder_.AddTarget(
"foo.o", &err));
1208 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1209 ASSERT_EQ(
"cc oo.h.in", command_runner_.commands_ran_[0]);
1215 int orig_edges = state_.edges_.size();
1217"rule cc\n command = cc $in\n depfile = $out.d\n"
1218"build gen/stuff\\things/foo.o: cc x\\y/z\\foo.c\n"));
1220 fs_.Create(
"x/y/z/foo.c",
"");
1221 GetNode(
"bar.h")->MarkDirty();
1223 fs_.Create(
"gen/stuff\\things/foo.o.d",
1224 "gen\\stuff\\things\\foo.o: blah.h bar.h\n");
1225 EXPECT_TRUE(builder_.AddTarget(
"gen/stuff/things/foo.o", &err));
1227 ASSERT_EQ(1u, fs_.files_read_.size());
1229 EXPECT_EQ(
"gen/stuff\\things/foo.o.d", fs_.files_read_[0]);
1232 ASSERT_EQ(orig_edges + 1, (
int)state_.edges_.size());
1234 Edge* edge = state_.edges_.back();
1235 ASSERT_EQ(3u, edge->
inputs_.size());
1246"build out: cat bar.cc\n"
1247"build all: phony out\n"));
1248 fs_.Create(
"bar.cc",
"");
1250 EXPECT_TRUE(builder_.AddTarget(
"all", &err));
1254 EXPECT_FALSE(builder_.AlreadyUpToDate());
1257 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1263"build out: cat bar.cc\n"
1264"build all: phony out\n"));
1265 fs_.Create(
"bar.cc",
"");
1266 fs_.Create(
"out",
"");
1268 EXPECT_TRUE(builder_.AddTarget(
"all", &err));
1270 EXPECT_TRUE(builder_.AlreadyUpToDate());
1279"build a: phony a\n"));
1281 EXPECT_TRUE(builder_.AddTarget(
"a", &err));
1283 EXPECT_TRUE(builder_.AlreadyUpToDate());
1315" command = touch $out\n"
1316"build notreal: phony blank\n"
1317"build phony1: phony notreal\n"
1318"build phony2: phony\n"
1319"build phony3: phony blank\n"
1320"build phony4: phony notreal\n"
1321"build phony5: phony\n"
1322"build phony6: phony blank\n"
1324"build test1: touch phony1\n"
1325"build test2: touch phony2\n"
1326"build test3: touch phony3\n"
1327"build test4: touch phony4\n"
1328"build test5: touch phony5\n"
1329"build test6: touch phony6\n"
1337 EXPECT_TRUE(builder_.
AddTarget(
"test1", &err));
1339 EXPECT_TRUE(builder_.
AddTarget(
"test2", &err));
1341 EXPECT_TRUE(builder_.
AddTarget(
"test3", &err));
1343 EXPECT_TRUE(builder_.
AddTarget(
"test4", &err));
1345 EXPECT_TRUE(builder_.
AddTarget(
"test5", &err));
1347 EXPECT_TRUE(builder_.
AddTarget(
"test6", &err));
1353 ci +=
static_cast<char>(
'0' + i);
1356 if (i != 2 && i != 5) {
1365 EXPECT_TRUE(builder_.
AddTarget(
"test" + ci, &err));
1377 EXPECT_TRUE(builder_.
AddTarget(
"test" + ci, &err));
1386 EXPECT_EQ(
string(
"touch test") + ci, command_runner_.
commands_ran_[0]);
1391 EXPECT_FALSE(phonyNode->
exists());
1392 EXPECT_FALSE(phonyNode->
dirty());
1394 EXPECT_GT(phonyNode->
mtime(), startTime);
1395 EXPECT_EQ(phonyNode->
mtime(), inputTime);
1396 ASSERT_TRUE(testNode->
Stat(&fs_, &err));
1397 EXPECT_TRUE(testNode->
exists());
1398 EXPECT_GT(testNode->
mtime(), startTime);
1406 EXPECT_TRUE(builder_.
AddTarget(
"test" + ci, &err));
1412 EXPECT_EQ(
"touch test" + ci, command_runner_.
commands_ran_[0]);
1416 EXPECT_TRUE(builder_.
AddTarget(
"test" + ci, &err));
1422 EXPECT_EQ(
"touch test" + ci, command_runner_.
commands_ran_[0]);
1437"build out1: fail\n"));
1440 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1444 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1445 ASSERT_EQ(
"subcommand failed", err);
1455"build all: phony out1 out2 out3\n"));
1458 config_.failures_allowed = 3;
1461 EXPECT_TRUE(builder_.AddTarget(
"all", &err));
1465 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1466 ASSERT_EQ(
"subcommands failed", err);
1476"build final: cat out1 out2 out3\n"));
1479 config_.failures_allowed = 11;
1482 EXPECT_TRUE(builder_.AddTarget(
"final", &err));
1486 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1487 ASSERT_EQ(
"cannot make progress due to previous errors", err);
1500"build final: cat out1 out2 out3\n"));
1503 config_.failures_allowed = 11;
1506 EXPECT_TRUE(builder_.AddTarget(
"final", &err));
1510 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1511 ASSERT_EQ(
"cannot make progress due to previous errors", err);
1515 fs_.Create(
"x",
"");
1517 const char* manifest =
1521 " command = touch $out\n"
1522 " pool = some_pool\n"
1524 " command = touch grit\n"
1526 "build B.d.stamp: cc | x\n"
1527 "build C.stamp: touch B.d.stamp\n"
1528 "build final.stamp: touch || C.stamp\n";
1530 RebuildTarget(
"final.stamp", manifest);
1532 fs_.RemoveFile(
"B.d.stamp");
1535 RebuildTarget(
"final.stamp", manifest, NULL, NULL, &save_state);
1550" command = touch $out\n"
1552"build out.imp: touch | in\n"));
1553 fs_.Create(
"out.imp",
"");
1555 fs_.Create(
"in",
"");
1559 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
1560 EXPECT_FALSE(builder_.AlreadyUpToDate());
1562 EXPECT_TRUE(GetNode(
"out.imp")->dirty());
1567"rule touch-implicit-dep-out\n"
1568" command = sleep 1 ; touch $test_dependency ; sleep 1 ; touch $out\n"
1570"build out.imp: touch-implicit-dep-out | inimp inimp2\n"
1571" test_dependency = inimp\n"));
1572 fs_.Create(
"inimp",
"");
1573 fs_.Create(
"out.imp",
"");
1575 fs_.Create(
"inimp2",
"");
1580 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
1581 EXPECT_FALSE(builder_.AlreadyUpToDate());
1584 EXPECT_TRUE(builder_.AlreadyUpToDate());
1586 command_runner_.commands_ran_.clear();
1589 builder_.plan_.Reset();
1591 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
1592 EXPECT_TRUE(builder_.AlreadyUpToDate());
1593 EXPECT_FALSE(GetNode(
"out.imp")->dirty());
1595 command_runner_.commands_ran_.clear();
1598 builder_.plan_.Reset();
1601 fs_.Create(
"inimp",
"");
1603 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
1604 EXPECT_FALSE(builder_.AlreadyUpToDate());
1607 EXPECT_TRUE(builder_.AlreadyUpToDate());
1609 command_runner_.commands_ran_.clear();
1612 builder_.plan_.Reset();
1614 EXPECT_TRUE(builder_.AddTarget(
"out.imp", &err));
1615 EXPECT_TRUE(builder_.AlreadyUpToDate());
1616 EXPECT_FALSE(GetNode(
"out.imp")->dirty());
1623"build out1: cc in\n"));
1627 fs_.Create(
"in",
"");
1628 fs_.Create(
"out1",
"");
1633 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1634 EXPECT_FALSE(builder_.AlreadyUpToDate());
1636 command_runner_.commands_ran_.clear();
1639 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1641 EXPECT_TRUE(builder_.AlreadyUpToDate());
1646"rule touch-fail-tick2\n"
1647" command = touch-fail-tick2\n"
1648"build out1: touch-fail-tick2 in\n"));
1652 fs_.Create(
"in",
"");
1655 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1658 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1660 command_runner_.commands_ran_.clear();
1663 builder_.plan_.Reset();
1666 fs_.Create(
"in",
"");
1669 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1671 EXPECT_EQ(
"subcommand failed", err);
1672 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1674 command_runner_.commands_ran_.clear();
1677 builder_.plan_.Reset();
1682 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1683 EXPECT_FALSE(builder_.AlreadyUpToDate());
1685 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1693"build out1: touch\n"
1694"build out2: touch in\n"));
1698 fs_.Create(
"in",
"");
1700 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1701 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1704 EXPECT_EQ(2u, command_runner_.commands_ran_.size());
1706 command_runner_.commands_ran_.clear();
1711 fs_.Create(
"in",
"");
1713 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1714 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1717 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
1728"build out1: cc in\n"
1729"build out2: true out1\n"
1730"build out3: cat out2\n"));
1732 fs_.Create(
"out1",
"");
1733 fs_.Create(
"out2",
"");
1734 fs_.Create(
"out3",
"");
1738 fs_.Create(
"in",
"");
1744 EXPECT_TRUE(builder_.AddTarget(
"out3", &err));
1748 EXPECT_EQ(
size_t(3), command_runner_.commands_ran_.size());
1749 EXPECT_EQ(3, builder_.plan_.command_edge_count());
1750 command_runner_.commands_ran_.clear();
1755 fs_.Create(
"in",
"");
1758 EXPECT_TRUE(builder_.AddTarget(
"out3", &err));
1761 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1765 command_runner_.commands_ran_.clear();
1767 EXPECT_TRUE(builder_.AddTarget(
"out3", &err));
1769 EXPECT_TRUE(builder_.AlreadyUpToDate());
1773 fs_.Create(
"in",
"");
1777 command_runner_.commands_ran_.clear();
1779 EXPECT_TRUE(builder_.AddTarget(
"out3", &err));
1782 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1796"build out1: true in\n"
1797"build out2: cc out1\n"));
1799 fs_.Create(
"in",
"");
1800 fs_.Create(
"out2",
"");
1806 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1810 command_runner_.commands_ran_.clear();
1814 fs_.Create(
"in",
"");
1815 fs_.Create(
"out2",
"");
1820 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1823 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1832 " command = touch\n"
1833 "build out1: true in\n"
1834 "build out2 out3: touch out1\n"
1835 "build out4: touch out2\n"
1839 fs_.Create(
"in",
"");
1842 EXPECT_TRUE(builder_.AddTarget(
"out4", &err));
1846 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1849 fs_.Create(
"in",
"");
1850 fs_.RemoveFile(
"out3");
1857 command_runner_.commands_ran_.clear();
1859 EXPECT_TRUE(builder_.AddTarget(
"out4", &err));
1863 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
1872 " depfile = $out.d\n"
1876 "build out1: true in\n"
1877 "build out2: cc out1\n"));
1880 fs_.Create(
"in",
"");
1885 fs_.Create(
"out1.d",
"out1: will.be.deleted restat.file\n");
1886 fs_.Create(
"will.be.deleted",
"");
1887 fs_.Create(
"restat.file",
"");
1891 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1894 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
1899 ASSERT_TRUE(NULL != log_entry);
1900 ASSERT_EQ(restat_mtime, log_entry->
mtime);
1904 fs_.RemoveFile(
"will.be.deleted");
1907 command_runner_.commands_ran_.clear();
1909 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
1912 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
1915 log_entry = build_log_.LookupByOutput(
"out1");
1916 ASSERT_TRUE(NULL != log_entry);
1917 ASSERT_EQ(restat_mtime, log_entry->
mtime);
1922"rule generate-depfile\n"
1923" command = sleep 1 ; touch $touch_dependency; touch $out ; echo \"$out: $test_dependency\" > $depfile\n"
1924"build out1: generate-depfile || cat1\n"
1925" test_dependency = in2\n"
1926" touch_dependency = 1\n"
1928" depfile = out.d\n"));
1935 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1939 EXPECT_EQ(
size_t(2), command_runner_.commands_ran_.size());
1940 EXPECT_EQ(2, builder_.plan_.command_edge_count());
1942 ASSERT_TRUE(NULL != log_entry);
1943 ASSERT_EQ(2u, log_entry->
mtime);
1945 command_runner_.commands_ran_.clear();
1948 builder_.plan_.Reset();
1951 fs_.Create(
"in1",
"");
1957 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
1959 EXPECT_TRUE(!state_.GetNode(
"out1", 0)->dirty());
1962 EXPECT_EQ(
size_t(1), command_runner_.commands_ran_.size());
1963 EXPECT_EQ(1, builder_.plan_.command_edge_count());
1968"rule generate-depfile\n"
1969" command = touch $out ; echo \"$out: $test_dependency\" > $depfile\n"
1970"build out: generate-depfile\n"
1971" test_dependency = inimp\n"
1972" depfile = out.d\n"));
1973 fs_.Create(
"inimp",
"");
1978 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
1979 EXPECT_FALSE(builder_.AlreadyUpToDate());
1982 EXPECT_TRUE(builder_.AlreadyUpToDate());
1984 command_runner_.commands_ran_.clear();
1987 builder_.plan_.Reset();
1989 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
1990 EXPECT_TRUE(builder_.AlreadyUpToDate());
2007"build out1: cc in\n"
2008"build out2: true out1\n"
2009"build out3: cat out2\n"));
2011 fs_.Create(
"out1",
"");
2012 fs_.Create(
"out2",
"");
2013 fs_.Create(
"out3",
"");
2017 fs_.Create(
"in",
"");
2022 EXPECT_TRUE(builder_.AddTarget(
"out3", &err));
2025 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2031" command = touch $out\n"
2033" command = cp $in $out\n"
2034"build dd: cp dd-in\n"
2035"build out: touch || dd\n"
2037"build out-copy: cp out\n"
2040"ninja_dyndep_version = 1\n"
2041"build out: dyndep\n"
2045 EXPECT_TRUE(builder_.AddTarget(
"out-copy", &err));
2048 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2057 " command = cat $rspfile > $out\n"
2058 " rspfile = $rspfile\n"
2059 " rspfile_content = $long_command\n"
2060 "rule cat_rsp_out\n"
2061 " command = cat $rspfile > $out\n"
2062 " rspfile = $out.rsp\n"
2063 " rspfile_content = $long_command\n"
2064 "build out1: cat in\n"
2065 "build out2: cat_rsp in\n"
2066 " rspfile = out 2.rsp\n"
2067 " long_command = Some very long command\n"
2068 "build out$ 3: cat_rsp_out in\n"
2069 " long_command = Some very long command\n"));
2071 fs_.Create(
"out1",
"");
2072 fs_.Create(
"out2",
"");
2073 fs_.Create(
"out 3",
"");
2077 fs_.Create(
"in",
"");
2080 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2082 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
2084 EXPECT_TRUE(builder_.AddTarget(
"out 3", &err));
2087 size_t files_created = fs_.files_created_.size();
2088 size_t files_removed = fs_.files_removed_.size();
2091 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
2094 ASSERT_EQ(files_created + 3, fs_.files_created_.size());
2095 ASSERT_EQ(1u, fs_.files_created_.count(
"out 2.rsp"));
2096 ASSERT_EQ(1u, fs_.files_created_.count(
"out 3.rsp"));
2097 ASSERT_EQ(1u, fs_.files_created_.count(
".ninja_lock"));
2100 ASSERT_EQ(files_removed + 2, fs_.files_removed_.size());
2101 ASSERT_EQ(1u, fs_.files_removed_.count(
"out 2.rsp"));
2102 ASSERT_EQ(1u, fs_.files_removed_.count(
"out 3.rsp"));
2110 " rspfile = $rspfile\n"
2111 " rspfile_content = $long_command\n"
2112 "build out: fail in\n"
2113 " rspfile = out.rsp\n"
2114 " long_command = Another very long command\n"));
2116 fs_.Create(
"out",
"");
2118 fs_.Create(
"in",
"");
2121 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2124 size_t files_created = fs_.files_created_.size();
2125 size_t files_removed = fs_.files_removed_.size();
2128 ASSERT_EQ(
"subcommand failed", err);
2129 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2132 ASSERT_EQ(files_created + 2, fs_.files_created_.size());
2133 ASSERT_EQ(1u, fs_.files_created_.count(
"out.rsp"));
2134 ASSERT_EQ(1u, fs_.files_created_.count(
".ninja_lock"));
2137 ASSERT_EQ(files_removed, fs_.files_removed_.size());
2138 ASSERT_EQ(0u, fs_.files_removed_.count(
"out.rsp"));
2141 ASSERT_EQ(
"Another very long command", fs_.files_[
"out.rsp"].contents);
2149 " command = cat $rspfile > $out\n"
2150 " rspfile = $rspfile\n"
2151 " rspfile_content = $long_command\n"
2152 "build out: cat_rsp in\n"
2153 " rspfile = out.rsp\n"
2154 " long_command = Original very long command\n"));
2156 fs_.Create(
"out",
"");
2158 fs_.Create(
"in",
"");
2161 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2166 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2169 command_runner_.commands_ran_.clear();
2171 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2173 ASSERT_TRUE(builder_.AlreadyUpToDate());
2178 ASSERT_TRUE(NULL != log_entry);
2180 "cat out.rsp > out;rspfile=Original very long command",
2184 command_runner_.commands_ran_.clear();
2186 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2189 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2195" command = interrupt\n"
2196"rule touch-interrupt\n"
2197" command = touch-interrupt\n"
2198"build out1: interrupt in1\n"
2199"build out2: touch-interrupt in2\n"));
2201 fs_.Create(
"out1",
"");
2202 fs_.Create(
"out2",
"");
2204 fs_.Create(
"in1",
"");
2205 fs_.Create(
"in2",
"");
2209 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2212 EXPECT_EQ(
"interrupted by user", err);
2214 EXPECT_GT(fs_.Stat(
"out1", &err), 0);
2218 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
2221 EXPECT_EQ(
"interrupted by user", err);
2223 EXPECT_EQ(0, fs_.Stat(
"out2", &err));
2227 const string kTooLongToStat(400,
'i');
2229(
"build " + kTooLongToStat +
": cat in\n").c_str()));
2230 fs_.Create(
"in",
"");
2233 fs_.files_[kTooLongToStat].mtime = -1;
2234 fs_.files_[kTooLongToStat].stat_error =
"stat failed";
2237 EXPECT_FALSE(builder_.AddTarget(kTooLongToStat, &err));
2238 EXPECT_EQ(
"stat failed", err);
2243"build nonexistent: phony\n"
2244"build out1: cat || nonexistent\n"
2245"build out2: cat nonexistent\n"));
2246 fs_.Create(
"out1",
"");
2247 fs_.Create(
"out2",
"");
2252 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2254 EXPECT_TRUE(builder_.AlreadyUpToDate());
2258 command_runner_.commands_ran_.clear();
2260 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
2264 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2276 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2278 EXPECT_FALSE(builder_.AlreadyUpToDate());
2281 ASSERT_EQ(
"subcommand failed", err);
2282 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2286 status_.BuildStarted();
2288 EXPECT_EQ(
"[%/e0.000]", status_.FormatProgressStatus(
"[%%/e%e]", 0));
2292 status_.BuildStarted();
2294 EXPECT_EQ(
"[%/e00:00]", status_.FormatProgressStatus(
"[%%/e%w]", 0));
2298 status_.BuildStarted();
2300 EXPECT_EQ(
"[%/E?]", status_.FormatProgressStatus(
"[%%/E%E]", 0));
2304 status_.BuildStarted();
2306 EXPECT_EQ(
"[%/p 0%]", status_.FormatProgressStatus(
"[%%/p%p]", 0));
2310 EXPECT_EQ(
"[%/s0/t0/r0/u0/f0]",
2311 status_.FormatProgressStatus(
"[%%/s%s/t%t/r%r/u%u/f%f]", 0));
2316"build bad_deps.o: cat in1\n"
2318" depfile = in1.d\n"));
2321 EXPECT_TRUE(builder_.AddTarget(
"bad_deps.o", &err));
2326 fs_.Create(
"in1.d",
"AAA BBB");
2329 EXPECT_EQ(
"subcommand failed", err);
2343 temp_dir_.CreateAndEnter(
"BuildWithQueryDepsLogTest");
2359"rule cp_multi_msvc\n"
2360" command = echo 'using $in' && for file in $out; do cp $in $$file; done\n"
2362" msvc_deps_prefix = using \n"
2363"build out1 out2: cp_multi_msvc in1\n"));
2366 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2370 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2371 EXPECT_EQ(
"echo 'using in1' && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2373 Node* out1_node = state_.LookupNode(
"out1");
2376 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2378 Node* out2_node = state_.LookupNode(
"out2");
2381 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2387"rule cp_multi_gcc\n"
2388" command = echo '$out: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2391"build out1 out2: cp_multi_gcc in1 in2\n"));
2394 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2396 fs_.Create(
"in.d",
"out1 out2: in1 in2");
2399 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2400 EXPECT_EQ(
"echo 'out1 out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2402 Node* out1_node = state_.LookupNode(
"out1");
2405 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2406 EXPECT_EQ(
"in2", out1_deps->
nodes[1]->
path());
2408 Node* out2_node = state_.LookupNode(
"out2");
2411 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2412 EXPECT_EQ(
"in2", out2_deps->
nodes[1]->
path());
2418"rule cp_multi_gcc\n"
2419" command = echo '$out: in1\\n$out: in2' > in.d && for file in $out; do cp in1 $$file; done\n"
2422"build out1 out2: cp_multi_gcc in1 in2\n"));
2425 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2427 fs_.Create(
"in.d",
"out1 out2: in1\nout1 out2: in2");
2430 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2431 EXPECT_EQ(
"echo 'out1 out2: in1\\nout1 out2: in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2433 Node* out1_node = state_.LookupNode(
"out1");
2436 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2437 EXPECT_EQ(
"in2", out1_deps->
nodes[1]->
path());
2439 Node* out2_node = state_.LookupNode(
"out2");
2442 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2443 EXPECT_EQ(
"in2", out2_deps->
nodes[1]->
path());
2449"rule cp_multi_gcc\n"
2450" command = echo 'out1: $in\\nout2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2453"build out1 out2: cp_multi_gcc in1 in2\n"));
2456 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2458 fs_.Create(
"in.d",
"out1: in1 in2\nout2: in1 in2");
2461 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2462 EXPECT_EQ(
"echo 'out1: in1 in2\\nout2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2464 Node* out1_node = state_.LookupNode(
"out1");
2467 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2468 EXPECT_EQ(
"in2", out1_deps->
nodes[1]->
path());
2470 Node* out2_node = state_.LookupNode(
"out2");
2473 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2474 EXPECT_EQ(
"in2", out2_deps->
nodes[1]->
path());
2480"rule cp_multi_gcc\n"
2481" command = echo 'out1: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2484"build out1 out2: cp_multi_gcc in1 in2\n"));
2487 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2489 fs_.Create(
"in.d",
"out1: in1 in2");
2492 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2493 EXPECT_EQ(
"echo 'out1: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2495 Node* out1_node = state_.LookupNode(
"out1");
2498 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2499 EXPECT_EQ(
"in2", out1_deps->
nodes[1]->
path());
2501 Node* out2_node = state_.LookupNode(
"out2");
2504 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2505 EXPECT_EQ(
"in2", out2_deps->
nodes[1]->
path());
2513"rule cp_multi_gcc\n"
2514" command = echo 'out2: $in' > in.d && for file in $out; do cp in1 $$file; done\n"
2517"build out1 out2: cp_multi_gcc in1 in2\n"));
2520 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
2522 fs_.Create(
"in.d",
"out2: in1 in2");
2525 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2526 EXPECT_EQ(
"echo 'out2: in1 in2' > in.d && for file in out1 out2; do cp in1 $file; done", command_runner_.commands_ran_[0]);
2528 Node* out1_node = state_.LookupNode(
"out1");
2531 EXPECT_EQ(
"in1", out1_deps->
nodes[0]->
path());
2532 EXPECT_EQ(
"in2", out1_deps->
nodes[1]->
path());
2534 Node* out2_node = state_.LookupNode(
"out2");
2537 EXPECT_EQ(
"in1", out2_deps->
nodes[0]->
path());
2538 EXPECT_EQ(
"in2", out2_deps->
nodes[1]->
path());
2552 temp_dir_.CreateAndEnter(
"BuildWithDepsLogTest");
2571 const char* manifest =
2572 "build out: cat in1\n"
2574 " depfile = in1.d\n";
2578 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2579 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2583 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2586 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2588 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2590 fs_.Create(
"in1.d",
"out: in2");
2595 EXPECT_EQ(0, fs_.Stat(
"in1.d", &err));
2597 fs_.Create(
"in1.d",
"out: in2");
2604 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2605 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2609 fs_.Create(
"in2",
"");
2613 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
2614 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2616 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2618 command_runner_.commands_ran_.clear();
2619 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2626 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2639 const char* manifest =
2640 "build out: cat in1\n"
2642 " depfile = in1.d\n";
2645 fs_.Create(
"in1",
"");
2646 fs_.Create(
"in1.d",
"out: ");
2649 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2650 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2654 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2657 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2659 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2671 fs_.Create(
"in1",
"");
2672 fs_.Create(
"out",
"");
2675 EXPECT_EQ(0, fs_.Stat(
"in1.d", &err));
2679 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2680 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2683 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
2684 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2686 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2688 command_runner_.commands_ran_.clear();
2689 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2693 fs_.Create(
"in1.d",
"out: ");
2700 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
2707 const char* manifest =
2708 "build out: cat in1\n"
2710 " depfile = in1.d\n";
2712 fs_.Create(
"out",
"");
2714 fs_.Create(
"in1",
"");
2717 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2718 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2721 config_.dry_run =
true;
2722 Builder builder(&state, config_, NULL, NULL, &fs_, &status_, 0);
2724 command_runner_.commands_ran_.clear();
2727 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2730 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2737 const char* manifest =
2739 " command = long-cc\n"
2740 "build out: long-cc in1\n"
2741 " test_dependency = in1\n";
2744 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2745 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2748 ASSERT_TRUE(build_log.
Load(build_log_file_.path(), &err));
2749 ASSERT_TRUE(build_log.
OpenForWrite(build_log_file_.path(), *
this, &err));
2752 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
2753 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2757 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2759 command_runner_.commands_ran_.clear();
2762 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2765 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2770 ASSERT_TRUE(NULL != log_entry);
2771 ASSERT_EQ(1u, log_entry->
mtime);
2777 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2779 command_runner_.commands_ran_.clear();
2784 command_runner_.commands_ran_.clear();
2786 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2789 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2793 ASSERT_TRUE(NULL != log_entry);
2794 ASSERT_TRUE(fs_.files_[
"in1"].mtime < log_entry->
mtime);
2799 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2801 command_runner_.commands_ran_.clear();
2804 command_runner_.commands_ran_.clear();
2806 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2816 const char* manifest =
2818 " command = long-cc\n"
2819 "build out: long-cc\n"
2821 " depfile = out.d\n"
2822 " test_dependency = header.h\n";
2824 fs_.Create(
"header.h",
"");
2827 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2830 ASSERT_TRUE(build_log.
Load(build_log_file_.path(), &err));
2831 ASSERT_TRUE(build_log.
OpenForWrite(build_log_file_.path(), *
this, &err));
2834 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
2835 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2838 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2842 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2845 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2850 ASSERT_TRUE(NULL != log_entry);
2851 ASSERT_EQ(1u, log_entry->
mtime);
2859 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2861 command_runner_.commands_ran_.clear();
2864 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2867 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2875 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2877 command_runner_.commands_ran_.clear();
2880 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2888 fs_.Create(
"header.h",
"");
2889 ASSERT_EQ(fs_.now_, 7);
2894 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2896 command_runner_.commands_ran_.clear();
2899 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2902 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2910 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2912 command_runner_.commands_ran_.clear();
2915 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2918 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
2926 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
2928 command_runner_.commands_ran_.clear();
2931 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2945"build header.h: true header.in\n"
2946"build out: cat in1\n"
2947" depfile = in1.d\n"));
2949 fs_.Create(
"header.h",
"");
2950 fs_.Create(
"in1.d",
"out: header.h");
2952 fs_.Create(
"header.in",
"");
2955 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
2966 const char* manifest =
2970 "build header.h: true header.in\n"
2971 "build out: cat in1\n"
2973 " depfile = in1.d\n";
2976 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2977 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
2981 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
2984 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
2986 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
2988 fs_.Create(
"in1.d",
"out: header.h");
2998 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
2999 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3003 fs_.Create(
"header.in",
"");
3007 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
3008 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3010 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3012 command_runner_.commands_ran_.clear();
3013 EXPECT_TRUE(builder.
AddTarget(
"out", &err));
3020 EXPECT_EQ(1u, command_runner_.commands_ran_.size());
3028 const char* manifest =
3029 "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
3030 "build fo$ o.o: cc foo.c\n";
3032 fs_.Create(
"foo.c",
"");
3036 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3040 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3043 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3045 EXPECT_TRUE(builder.
AddTarget(
"fo o.o", &err));
3047 fs_.Create(
"fo o.o.d",
"fo\\ o.o: blah.h bar.h\n");
3057 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3060 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
3061 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3064 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3070 EXPECT_TRUE(builder.
AddTarget(
"fo o.o", &err));
3075 ASSERT_EQ(1u, state.
edges_.size());
3077 ASSERT_EQ(3u, edge->
inputs_.size());
3089 const char* manifest =
3090 "rule touch-out-implicit-dep\n"
3091 " command = touch $out ; sleep 1 ; touch $test_dependency\n"
3092 "rule generate-depfile\n"
3093 " command = touch $out ; echo \"$out: $test_dependency\" > $depfile\n"
3094 "build out1: touch-out-implicit-dep in1\n"
3095 " test_dependency = inimp\n"
3096 "build out2: generate-depfile in1 || out1\n"
3097 " test_dependency = inimp\n"
3098 " depfile = out2.d\n"
3101 fs_.Create(
"in1",
"");
3108 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3111 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3114 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
3116 EXPECT_TRUE(builder.
AddTarget(
"out2", &err));
3127 fs_.Create(
"in1",
"");
3131 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3134 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
3135 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3138 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
3140 EXPECT_TRUE(builder.
AddTarget(
"out2", &err));
3154 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3157 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
3158 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3161 Builder builder(&state, config_, &build_log, &deps_log, &fs_, &status_, 0);
3163 EXPECT_TRUE(builder.
AddTarget(
"out2", &err));
3174 const char* manifest =
3175 "rule cc\n command = cc $in\n depfile = $out.d\n deps = gcc\n"
3176 "build a/b\\c\\d/e/fo$ o.o: cc x\\y/z\\foo.c\n";
3178 fs_.Create(
"x/y/z/foo.c",
"");
3182 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3186 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3189 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3190 builder.command_runner_.reset(&command_runner_);
3191 EXPECT_TRUE(builder.AddTarget(
"a/b/c/d/e/fo o.o", &err));
3194 fs_.Create(
"a/b\\c\\d/e/fo o.o.d",
3195 "a\\b\\c\\d\\e\\fo\\ o.o: blah.h bar.h\n");
3200 builder.command_runner_.release();
3205 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
3208 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
3209 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
3212 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
3213 builder.command_runner_.reset(&command_runner_);
3216 EXPECT_TRUE(builder.AddTarget(
"a/b/c/d/e/fo o.o", &err));
3220 ASSERT_EQ(1u, state.
edges_.size());
3223 ASSERT_EQ(3u, edge->
inputs_.size());
3230 builder.command_runner_.release();
3238const char* manifest =
3242"build header.h: true header.in\n"
3243"build out: cat header.h\n"
3244" depfile = out.d\n";
3246 fs_.Create(
"header.h",
"");
3248 fs_.Create(
"out",
"");
3249 fs_.Create(
"header.in",
"");
3255 RebuildTarget(
"out", manifest);
3256 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3263 const char* manifest =
3267"build header.h: true header.in\n"
3268"build out: cat header.h\n"
3270" depfile = out.d\n";
3273 fs_.Create(
"header.in",
"");
3274 fs_.Create(
"out.d",
"out: header.h");
3275 fs_.Create(
"header.h",
"");
3277 RebuildTarget(
"out", manifest, build_log_file_.c_str(),
3278 deps_log_file_.c_str());
3279 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3282 RebuildTarget(
"out", manifest, build_log_file_.c_str(),
3283 deps_log_file_.c_str());
3284 ASSERT_EQ(0u, command_runner_.commands_ran_.size());
3290 fs_.Create(
"header.in",
"");
3295 RebuildTarget(
"out", manifest, build_log_file_.c_str(), deps2_file_.
c_str());
3296 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3299 RebuildTarget(
"out", manifest, build_log_file_.c_str(), deps2_file_.
c_str());
3300 ASSERT_EQ(0u, command_runner_.commands_ran_.size());
3305 fs_.Create(
"header.in",
"");
3306 fs_.Create(
"out",
"");
3307 RebuildTarget(
"out", manifest, build_log_file_.c_str(), deps2_file_.
c_str());
3308 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3311 RebuildTarget(
"out", manifest, build_log_file_.c_str(), deps2_file_.
c_str());
3312 ASSERT_EQ(0u, command_runner_.commands_ran_.size());
3317 const char* manifest =
3319" command = cc $in\n"
3320" depfile = $out.d\n"
3321"build foo.o: cc foo.c\n";
3323 fs_.Create(
"foo.c",
"");
3324 fs_.Create(
"foo.o",
"");
3325 fs_.Create(
"header.h",
"");
3326 fs_.Create(
"foo.o.d",
"bar.o.d: header.h\n");
3331 RebuildTarget(
"foo.o", manifest, build_log.
c_str(), deps_file.
c_str());
3332 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3338" command = console\n"
3340"build cons: console in.txt\n"));
3342 fs_.Create(
"in.txt",
"");
3345 EXPECT_TRUE(builder_.AddTarget(
"cons", &err));
3349 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3357" command = touch $out\n"
3358"build out: touch || dd\n"
3363 EXPECT_FALSE(builder_.AddTarget(
"out", &err));
3364 EXPECT_EQ(
"loading 'dd': No such file or directory", err);
3373" command = touch $out $out.imp\n"
3374"build tmp: touch || dd\n"
3376"build out: touch || dd\n"
3380"ninja_dyndep_version = 1\n"
3381"build out | out.imp: dyndep | tmp.imp\n"
3382"build tmp | tmp.imp: dyndep\n"
3386 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3390 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3391 EXPECT_EQ(
"touch tmp tmp.imp", command_runner_.commands_ran_[0]);
3392 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[1]);
3400" command = touch $out\n"
3401"build out: touch || dd\n"
3405"build out: dyndep\n"
3409 EXPECT_FALSE(builder_.AddTarget(
"out", &err));
3410 EXPECT_EQ(
"dd:1: expected 'ninja_dyndep_version = ...'\n", err);
3418" command = unused\n"
3419"build out: r in || dd\n"
3424"ninja_dyndep_version = 1\n"
3425"build out | circ: dyndep\n"
3427 fs_.Create(
"out",
"");
3430 EXPECT_FALSE(builder_.AddTarget(
"out", &err));
3431 EXPECT_EQ(
"dependency cycle: circ -> in -> circ", err);
3438" command = touch $out\n"
3440" command = cp $in $out\n"
3441"build dd: cp dd-in\n"
3442"build out: touch || dd\n"
3446"ninja_dyndep_version = 1\n"
3447"build out: dyndep\n"
3451 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3454 size_t files_created = fs_.files_created_.size();
3458 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3459 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3460 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[1]);
3461 ASSERT_EQ(2u, fs_.files_read_.size());
3462 EXPECT_EQ(
"dd-in", fs_.files_read_[0]);
3463 EXPECT_EQ(
"dd", fs_.files_read_[1]);
3464 ASSERT_EQ(3u + files_created, fs_.files_created_.size());
3465 EXPECT_EQ(1u, fs_.files_created_.count(
"dd"));
3466 EXPECT_EQ(1u, fs_.files_created_.count(
"out"));
3467 EXPECT_EQ(1u, fs_.files_created_.count(
".ninja_lock"));
3475" command = touch $out\n"
3477" command = cp $in $out\n"
3478"build dd: cp dd-in\n"
3479"build out: touch || dd\n"
3483"build out: dyndep\n"
3487 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3491 EXPECT_EQ(
"dd:1: expected 'ninja_dyndep_version = ...'\n", err);
3499" command = touch $out\n"
3501" command = cp $in $out\n"
3502"build dd: cp dd-in\n"
3503"build unrelated: touch || dd\n"
3504"build out: touch unrelated || dd\n"
3508"ninja_dyndep_version = 1\n"
3509"build out: dyndep\n"
3512 fs_.Create(
"out",
"");
3515 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3520 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3521 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3522 EXPECT_EQ(
"touch unrelated", command_runner_.commands_ran_[1]);
3523 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[2]);
3531" command = touch $out $out.imp\n"
3533" command = cp $in $out\n"
3534"build dd: cp dd-in\n"
3535"build out: touch in || dd\n"
3538 fs_.Create(
"in",
"");
3540"ninja_dyndep_version = 1\n"
3541"build out | out.imp: dyndep\n"
3544 fs_.Create(
"out",
"");
3547 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3552 ASSERT_EQ(2u, command_runner_.commands_ran_.size());
3553 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3554 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[1]);
3562" command = touch $out $out.imp\n"
3564" command = cp $in $out\n"
3565"build dd: cp dd-in\n"
3566"build out1 | out-twice.imp: touch in\n"
3567"build out2: touch in || dd\n"
3570 fs_.Create(
"in",
"");
3572"ninja_dyndep_version = 1\n"
3573"build out2 | out-twice.imp: dyndep\n"
3576 fs_.Create(
"out1",
"");
3577 fs_.Create(
"out2",
"");
3580 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
3581 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
3585 EXPECT_EQ(
"multiple rules generate out-twice.imp", err);
3594" command = touch $out $out.imp\n"
3596" command = cp $in $out\n"
3597"build dd1: cp dd1-in\n"
3598"build out1: touch || dd1\n"
3600"build dd2: cp dd2-in || dd1\n"
3601"build out2: touch || dd2\n"
3604 fs_.Create(
"out1",
"");
3605 fs_.Create(
"out2",
"");
3606 fs_.Create(
"dd1-in",
3607"ninja_dyndep_version = 1\n"
3608"build out1 | out-twice.imp: dyndep\n"
3610 fs_.Create(
"dd2-in",
"");
3612"ninja_dyndep_version = 1\n"
3613"build out2 | out-twice.imp: dyndep\n"
3616 fs_.Create(
"out1",
"");
3617 fs_.Create(
"out2",
"");
3620 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
3621 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
3625 EXPECT_EQ(
"multiple rules generate out-twice.imp", err);
3633" command = touch $out\n"
3635" command = cp $in $out\n"
3636"build dd: cp dd-in\n"
3638"build out: touch || dd\n"
3642"ninja_dyndep_version = 1\n"
3643"build out: dyndep | in\n"
3646 fs_.Create(
"out",
"");
3649 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3654 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3655 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3656 EXPECT_EQ(
"touch in", command_runner_.commands_ran_[1]);
3657 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[2]);
3665" command = touch $out\n"
3667" command = cp $in $out\n"
3668"build dd: cp dd-in\n"
3669"build out: touch || dd\n"
3673"ninja_dyndep_version = 1\n"
3674"build out: dyndep |@ validation\n"
3678 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3683 string err_first_line = err.substr(0, err.find(
"\n"));
3684 EXPECT_EQ(
"dd:2: expected newline, got '|@'", err_first_line);
3692" command = touch $out\n"
3694" command = cp $in $out\n"
3695"build dd: cp dd-in\n"
3696"build in: touch |@ validation\n"
3697"build validation: touch in out\n"
3698"build out: touch || dd\n"
3702"ninja_dyndep_version = 1\n"
3703"build out: dyndep | in\n"
3706 fs_.Create(
"out",
"");
3709 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3714 ASSERT_EQ(4u, command_runner_.commands_ran_.size());
3715 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3716 EXPECT_EQ(
"touch in", command_runner_.commands_ran_[1]);
3717 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[2]);
3718 EXPECT_EQ(
"touch validation", command_runner_.commands_ran_[3]);
3727" command = touch $out $out.imp\n"
3729" command = cp $in $out\n"
3730"build dd: cp dd-in\n"
3731"build tmp: touch || dd\n"
3733"build out: touch || dd\n"
3737"ninja_dyndep_version = 1\n"
3738"build out | out.imp: dyndep | tmp.imp\n"
3739"build tmp | tmp.imp: dyndep\n"
3743 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3747 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3748 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3749 EXPECT_EQ(
"touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3750 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[2]);
3759" command = touch $out $out.imp\n"
3761" command = cp $in $out\n"
3762"build dd: cp dd-in\n"
3763"build tmp: touch || dd\n"
3765"build out: cp tmp\n"
3768 fs_.Create(
"out.d",
"out: tmp.imp\n");
3770"ninja_dyndep_version = 1\n"
3771"build tmp | tmp.imp: dyndep\n"
3775 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3779 ASSERT_FALSE(GetNode(
"tmp.imp")->in_edge());
3785 ASSERT_FALSE(GetNode(
"tmp.imp")->in_edge()->is_phony());
3787 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3788 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3789 EXPECT_EQ(
"touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3790 EXPECT_EQ(
"cp tmp out", command_runner_.commands_ran_[2]);
3791 EXPECT_EQ(1u, fs_.files_created_.count(
"tmp.imp"));
3792 EXPECT_TRUE(builder_.AlreadyUpToDate());
3800" command = touch $out $out.imp\n"
3802" command = cp $in $out\n"
3803"build dd: cp dd-in\n"
3804"build tmp: touch || dd\n"
3806"build out: touch tmp || dd\n"
3809 fs_.Create(
"tmp",
"");
3810 fs_.Create(
"out",
"");
3812"ninja_dyndep_version = 1\n"
3813"build out: dyndep\n"
3814"build tmp | tmp.imp: dyndep\n"
3818 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3822 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3823 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3824 EXPECT_EQ(
"touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3825 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[2]);
3833" command = touch $out $out.imp\n"
3835" command = cp $in $out\n"
3836"build dd: cp dd-in\n"
3837"build tmp: touch || dd\n"
3839"build out: touch tmp\n"
3841 fs_.Create(
"tmp",
"");
3842 fs_.Create(
"out",
"");
3844"ninja_dyndep_version = 1\n"
3845"build tmp | tmp.imp: dyndep\n"
3849 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3853 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3854 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3855 EXPECT_EQ(
"touch tmp tmp.imp", command_runner_.commands_ran_[1]);
3856 EXPECT_EQ(
"touch out out.imp", command_runner_.commands_ran_[2]);
3864" command = unused\n"
3866" command = cp $in $out\n"
3867"build dd: cp dd-in\n"
3868"build out: r in || dd\n"
3871"build in: r || dd\n"
3874 fs_.Create(
"out.d",
"out: inimp\n");
3876"ninja_dyndep_version = 1\n"
3877"build out | circ: dyndep\n"
3878"build in: dyndep | circ\n"
3880 fs_.Create(
"out",
"");
3883 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
3889 EXPECT_TRUE(err ==
"dependency cycle: circ -> in -> circ" ||
3890 err ==
"dependency cycle: in -> circ -> in");
3900" command = cp $in $out\n"
3901"build dd: cp dd-in\n"
3902"build out1: true in || dd\n"
3904"build out2: cat out1\n"));
3906 fs_.Create(
"out1",
"");
3907 fs_.Create(
"out2",
"");
3909"ninja_dyndep_version = 1\n"
3910"build out1: dyndep\n"
3914 fs_.Create(
"in",
"");
3920 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
3924 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3925 EXPECT_EQ(
"cp dd-in dd", command_runner_.commands_ran_[0]);
3926 EXPECT_EQ(
"true", command_runner_.commands_ran_[1]);
3927 EXPECT_EQ(
"cat out1 > out2", command_runner_.commands_ran_[2]);
3929 command_runner_.commands_ran_.clear();
3932 fs_.Create(
"in",
"");
3936 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
3939 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
3940 EXPECT_EQ(
"true", command_runner_.commands_ran_[0]);
3949" command = touch $out $out.imp\n"
3951" command = cp $in $out\n"
3952"build out1 | out1.imp: touch\n"
3953"build zdd: cp zdd-in\n"
3954" verify_active_edge = out1\n"
3955"build out2: cp out1 || zdd\n"
3958 fs_.Create(
"zdd-in",
3959"ninja_dyndep_version = 1\n"
3960"build out2: dyndep | out1.imp\n"
3965 command_runner_.max_active_edges_ = 2;
3976 EXPECT_TRUE(builder_.AddTarget(
"out1", &err));
3977 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
3981 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
3984 EXPECT_TRUE((command_runner_.commands_ran_[0] ==
"touch out1 out1.imp" &&
3985 command_runner_.commands_ran_[1] ==
"cp zdd-in zdd") ||
3986 (command_runner_.commands_ran_[1] ==
"touch out1 out1.imp" &&
3987 command_runner_.commands_ran_[0] ==
"cp zdd-in zdd"));
3988 EXPECT_EQ(
"cp out1 out2", command_runner_.commands_ran_[2]);
3996" command = touch $out $out.imp\n"
3998" command = cp $in $out\n"
3999"build dd1: cp dd1-in\n"
4000"build out1 | out1.imp: touch || dd1\n"
4002"build dd2: cp dd2-in || dd1\n"
4003"build out2: touch || dd2\n"
4006 fs_.Create(
"out1.imp",
"");
4007 fs_.Create(
"out2",
"");
4008 fs_.Create(
"out2.imp",
"");
4009 fs_.Create(
"dd1-in",
4010"ninja_dyndep_version = 1\n"
4011"build out1: dyndep\n"
4013 fs_.Create(
"dd2-in",
"");
4015"ninja_dyndep_version = 1\n"
4016"build out2 | out2.imp: dyndep | out1.imp\n"
4028 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
4032 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
4033 EXPECT_EQ(
"cp dd1-in dd1", command_runner_.commands_ran_[0]);
4034 EXPECT_EQ(
"touch out1 out1.imp", command_runner_.commands_ran_[1]);
4035 EXPECT_EQ(
"touch out2 out2.imp", command_runner_.commands_ran_[2]);
4044" command = touch $out $out.imp\n"
4046" command = cp $in $out\n"
4047"build dd1: cp dd1-in\n"
4048"build out1: touch || dd1\n"
4050"build dd2: cp dd2-in || out1\n"
4051"build out2: touch || dd2\n"
4054 fs_.Create(
"out1.imp",
"");
4055 fs_.Create(
"out2",
"");
4056 fs_.Create(
"out2.imp",
"");
4057 fs_.Create(
"dd1-in",
4058"ninja_dyndep_version = 1\n"
4059"build out1 | out1.imp: dyndep\n"
4061 fs_.Create(
"dd2-in",
"");
4063"ninja_dyndep_version = 1\n"
4064"build out2 | out2.imp: dyndep | out1.imp\n"
4073 EXPECT_TRUE(builder_.AddTarget(
"out2", &err));
4077 ASSERT_EQ(3u, command_runner_.commands_ran_.size());
4078 EXPECT_EQ(
"cp dd1-in dd1", command_runner_.commands_ran_[0]);
4079 EXPECT_EQ(
"touch out1 out1.imp", command_runner_.commands_ran_[1]);
4080 EXPECT_EQ(
"touch out2 out2.imp", command_runner_.commands_ran_[2]);
4088" command = touch $out\n"
4090" command = cp $in $out\n"
4091"build dd0: cp dd0-in\n"
4092"build dd1: cp dd1-in\n"
4094"build tmp: touch || dd0\n"
4096"build out: touch || dd1\n"
4099 fs_.Create(
"dd1-in",
4100"ninja_dyndep_version = 1\n"
4101"build out: dyndep | tmp\n"
4103 fs_.Create(
"dd0-in",
"");
4105"ninja_dyndep_version = 1\n"
4106"build tmp: dyndep | in\n"
4109 fs_.Create(
"out",
"");
4112 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4117 ASSERT_EQ(4u, command_runner_.commands_ran_.size());
4118 EXPECT_EQ(
"cp dd1-in dd1", command_runner_.commands_ran_[0]);
4119 EXPECT_EQ(
"touch in", command_runner_.commands_ran_[1]);
4120 EXPECT_EQ(
"touch tmp", command_runner_.commands_ran_[2]);
4121 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[3]);
4129" command = touch $out\n"
4131" command = cp $in $out\n"
4132"build dd0: cp dd0-in\n"
4133"build dd1: cp dd1-in\n"
4135"build tmp: touch || dd0\n"
4137"build out: touch || dd1\n"
4140 fs_.Create(
"dd1-in",
4141"ninja_dyndep_version = 1\n"
4142"build out: dyndep | tmp\n"
4144 fs_.Create(
"dd0-in",
4145"ninja_dyndep_version = 1\n"
4146"build tmp: dyndep | in\n"
4149 fs_.Create(
"out",
"");
4152 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4157 ASSERT_EQ(5u, command_runner_.commands_ran_.size());
4158 EXPECT_EQ(
"cp dd1-in dd1", command_runner_.commands_ran_[0]);
4159 EXPECT_EQ(
"cp dd0-in dd0", command_runner_.commands_ran_[1]);
4160 EXPECT_EQ(
"touch in", command_runner_.commands_ran_[2]);
4161 EXPECT_EQ(
"touch tmp", command_runner_.commands_ran_[3]);
4162 EXPECT_EQ(
"touch out", command_runner_.commands_ran_[4]);
4167 "build out: cat in |@ validate\n"
4168 "build validate: cat in2\n"));
4170 fs_.Create(
"in",
"");
4171 fs_.Create(
"in2",
"");
4174 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4180 EXPECT_EQ(2u, command_runner_.commands_ran_.size());
4185 fs_.Create(
"in",
"");
4188 command_runner_.commands_ran_.clear();
4190 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4196 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
4197 EXPECT_EQ(
"cat in > out", command_runner_.commands_ran_[0]);
4202 fs_.Create(
"in2",
"");
4205 command_runner_.commands_ran_.clear();
4207 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4213 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
4214 EXPECT_EQ(
"cat in2 > validate", command_runner_.commands_ran_[0]);
4219 "build out: cat in |@ validate\n"
4220 "build validate: cat in2 | out\n"));
4222 fs_.Create(
"in",
"");
4223 fs_.Create(
"in2",
"");
4226 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4232 EXPECT_EQ(2u, command_runner_.commands_ran_.size());
4236 fs_.Create(
"in",
"");
4239 command_runner_.commands_ran_.clear();
4241 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4247 EXPECT_EQ(2u, command_runner_.commands_ran_.size());
4252 fs_.Create(
"in2",
"");
4255 command_runner_.commands_ran_.clear();
4257 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4263 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
4264 EXPECT_EQ(
"cat in2 > validate", command_runner_.commands_ran_[0]);
4268 const char* manifest =
4269 "build out: cat in |@ validate\n"
4270 "build validate: cat in2 | out\n"
4271 "build out2: cat in3\n"
4273 " depfile = out2.d\n";
4278 fs_.Create(
"in",
"");
4279 fs_.Create(
"in2",
"");
4280 fs_.Create(
"in3",
"");
4281 fs_.Create(
"out2.d",
"out: out");
4284 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
4285 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
4288 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
4291 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
4294 EXPECT_TRUE(builder.
AddTarget(
"out2", &err));
4301 ASSERT_EQ(command_runner_.commands_ran_.size(),
size_t(1));
4302 EXPECT_EQ(
"cat in3 > out2", command_runner_.commands_ran_[0]);
4305 EXPECT_EQ(0, fs_.Stat(
"out2.d", &err));
4312 command_runner_.commands_ran_.clear();
4315 fs_.Create(
"in2",
"");
4316 fs_.Create(
"in3",
"");
4319 ASSERT_NO_FATAL_FAILURE(AddCatRule(&state));
4320 ASSERT_NO_FATAL_FAILURE(
AssertParse(&state, manifest));
4323 ASSERT_TRUE(deps_log.
Load(deps_log_file_.path(), &state, &err));
4324 ASSERT_TRUE(deps_log.
OpenForWrite(deps_log_file_.path(), &err));
4327 Builder builder(&state, config_, NULL, &deps_log, &fs_, &status_, 0);
4330 EXPECT_TRUE(builder.
AddTarget(
"out2", &err));
4337 ASSERT_EQ(command_runner_.commands_ran_.size(),
size_t(3));
4339 EXPECT_EQ(
"cat in > out", command_runner_.commands_ran_[0]);
4348 "build out: cat in |@ out2\n"
4349 "build out2: cat in2 |@ out\n"));
4351 fs_.Create(
"in",
"");
4352 fs_.Create(
"in2",
"");
4355 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4361 EXPECT_EQ(2u, command_runner_.commands_ran_.size());
4365 fs_.Create(
"in",
"");
4368 command_runner_.commands_ran_.clear();
4370 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4376 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
4377 EXPECT_EQ(
"cat in > out", command_runner_.commands_ran_[0]);
4381 fs_.Create(
"in2",
"");
4384 command_runner_.commands_ran_.clear();
4386 EXPECT_TRUE(builder_.AddTarget(
"out", &err));
4392 ASSERT_EQ(1u, command_runner_.commands_ran_.size());
4393 EXPECT_EQ(
"cat in2 > out2", command_runner_.commands_ran_[0]);
4398 "build out: cat in |@ validate\n"
4399 "build validate: cat validate_in | out\n"
4400 "build validate_in: cat validate\n"));
4402 fs_.Create(
"in",
"");
4405 EXPECT_FALSE(builder_.AddTarget(
"out", &err));
4406 EXPECT_EQ(
"dependency cycle: validate -> validate_in -> validate", err);
void TestPhonyUseCase(BuildTest *t, int i)
Options (e.g. verbosity, parallelism) passed to a build.
Can answer questions about the manifest for the BuildLog.
Store a log of every command ran for every build.
LogEntry * LookupByOutput(const std::string &path)
Lookup a previously-run command by its output path.
LoadStatus Load(const std::string &path, std::string *err)
Load the on-disk log.
bool OpenForWrite(const std::string &path, const BuildLogUser &user, std::string *err)
Prepares writing to the log file without actually opening it - that will happen when/if it's needed.
void Dirty(const string &path)
FakeCommandRunner command_runner_
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_).
virtual bool IsPathDead(StringPiece s) const
Return if a given output is no longer part of the build manifest.
Tests of builds involving deps logs necessarily must span multiple builds.
void * builder_
Shadow parent class builder_ so we don't accidentally use it.
ScopedFilePath build_log_file_
ScopedFilePath deps_log_file_
ScopedFilePath deps_log_file_
~BuildWithQueryDepsLogTest()
BuildWithQueryDepsLogTest()
Builder wraps the build process: starting commands, updating status.
Node * AddTarget(const std::string &name, std::string *err)
bool AlreadyUpToDate() const
Returns true if the build targets are already up to date.
ExitStatus Build(std::string *err)
Run the build.
std::unique_ptr< CommandRunner > command_runner_
The result of waiting for a command.
CommandRunner is an interface that wraps running the build subcommands.
static bool cmp(const Edge *a, const Edge *b)
As build commands run they can output extra dependency information (e.g.
bool OpenForWrite(const std::string &path, std::string *err)
LoadStatus Load(const std::string &path, State *state, std::string *err)
An edge in the dependency graph; links between Nodes using Rules.
std::string GetBinding(const std::string &key) const
Returns the shell-escaped value of |key|.
std::vector< Node * > outputs_
bool GetBindingBool(const std::string &key) const
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
const Rule & rule() const
std::vector< Node * > inputs_
std::string GetUnescapedDepfile() const
Like GetBinding("depfile"), but without shell escaping.
Fake implementation of CommandRunner, useful for tests.
virtual bool WaitForCommand(Result *result)
Wait for a command to complete, or return false if interrupted.
virtual vector< Edge * > GetActiveEdges()
vector< Edge * > active_edges_
virtual size_t CanRunMore() const
virtual bool StartCommand(Edge *edge)
vector< string > commands_ran_
FakeCommandRunner(VirtualFileSystem *fs)
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
const std::string & path() const
void MarkMissing()
Mark the Node as already-stat()ed and missing.
bool Stat(DiskInterface *disk_interface, std::string *err)
Return false on error.
Fixture for tests involving Plan.
void PrepareForTarget(const char *node, BuildLog *log=NULL)
void TestPoolWithDepthOne(const char *test_case)
void FindWorkSorted(deque< Edge * > *ret, int count)
Because FindWork does not return Edges in any sort of predictable order,.
Plan stores the state of a build plan: what we intend to build, which steps we're ready to execute.
const std::string & name() const
A class that records a file path and ensures that it is removed on destruction.
const char * c_str() const
void AddCatRule(State *state)
Add a "cat" rule to state.
StateTestWithBuiltinRules()
Node * GetNode(const std::string &path)
Short way to get a Node by its path from state_.
Global state (file status) for a single run.
std::vector< Edge * > edges_
All the edges of the graph.
Node * GetNode(StringPiece path, uint64_t slash_bits)
Pool * LookupPool(const std::string &pool_name)
Implementation of the Status interface that prints the status as human-readable strings to stdout.
StringPiece represents a slice of a string whose memory is managed externally.
An implementation of DiskInterface that uses an in-memory representation of disk state.
int Tick()
Tick "time" forwards; subsequent file operations will be newer than previous ones.
int now_
A simple fake timestamp for file operations.
void Create(const std::string &path, const std::string &contents)
"Create" a file with contents.
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
void AssertHash(const char *expected, uint64_t actual)