30 EXPECT_TRUE(parser.
ParseTest(input, &err));
46 " command = cat $in > $out\n"
49 " command = date > $out\n"
51 "build result: cat in_1.cc in-2.O\n"));
53 ASSERT_EQ(3u, state.bindings_.GetRules().size());
54 const auto& rule = state.bindings_.GetRules().begin()->second;
55 EXPECT_EQ(
"cat", rule->name());
56 EXPECT_EQ(
"[cat ][$in][ > ][$out]",
57 rule->GetBinding(
"command")->Serialize());
71 " rspfile_content = a\n"
77 " #indented comment\n"
79 " command = cat $in > $out\n"
81 " restat = 1 # comment\n"
83 "build result: cat in_1.cc in-2.O\n"
86 ASSERT_EQ(2u, state.bindings_.GetRules().size());
87 const auto& rule = state.bindings_.GetRules().begin()->second;
88 EXPECT_EQ(
"cat", rule->name());
89 Edge* edge = state.GetNode(
"result", 0)->in_edge();
99 " command = cat $in > $out\n"
101 "build result: cat in_1.cc in-2.O\n"
106 EXPECT_EQ(
"1", state.bindings_.LookupVariable(
"variable"));
112 " command = cat $rspfile > $out\n"
113 " rspfile = $rspfile\n"
114 " rspfile_content = $in\n"
116 "build out: cat_rsp in\n"
117 " rspfile=out.rsp\n"));
119 ASSERT_EQ(2u, state.bindings_.GetRules().size());
120 const auto& rule = state.bindings_.GetRules().begin()->second;
121 EXPECT_EQ(
"cat_rsp", rule->name());
122 EXPECT_EQ(
"[cat ][$rspfile][ > ][$out]",
123 rule->GetBinding(
"command")->Serialize());
124 EXPECT_EQ(
"[$rspfile]", rule->GetBinding(
"rspfile")->Serialize());
125 EXPECT_EQ(
"[$in]", rule->GetBinding(
"rspfile_content")->Serialize());
131 " command = cat $in_newline > $out\n"
133 "build out: cat_rsp in in2\n"
134 " rspfile=out.rsp\n"));
136 ASSERT_EQ(2u, state.bindings_.GetRules().size());
137 const auto& rule = state.bindings_.GetRules().begin()->second;
138 EXPECT_EQ(
"cat_rsp", rule->name());
139 EXPECT_EQ(
"[cat ][$in_newline][ > ][$out]",
140 rule->GetBinding(
"command")->Serialize());
142 Edge* edge = state.edges_[0];
148 "l = one-letter-test\n"
150 " command = ld $l $extra $with_under -o $out $in\n"
153 "with_under = -under\n"
154 "build a: link b c\n"
156 "nested2 = $nested1/2\n"
157 "build supernested: link x\n"
158 " extra = $nested2/3\n"));
160 ASSERT_EQ(2u, state.edges_.size());
161 Edge* edge = state.edges_[0];
162 EXPECT_EQ(
"ld one-letter-test -pthread -under -o a b c",
164 EXPECT_EQ(
"1/2", state.bindings_.LookupVariable(
"nested2"));
166 edge = state.edges_[1];
167 EXPECT_EQ(
"ld one-letter-test 1/2/3 -under -o supernested x",
175 " command = cmd $foo $in $out\n"
177 "build inner: cmd a\n"
179 "build outer: cmd b\n"
183 ASSERT_EQ(2u, state.edges_.size());
184 EXPECT_EQ(
"cmd baz a inner", state.edges_[0]->EvaluateCommand());
185 EXPECT_EQ(
"cmd bar b outer", state.edges_[1]->EvaluateCommand());
191 " command = foo bar $\n"
194 "build a: link c $\n"
197 ASSERT_EQ(2u, state.bindings_.GetRules().size());
198 const auto& rule = state.bindings_.GetRules().begin()->second;
199 EXPECT_EQ(
"link", rule->name());
200 EXPECT_EQ(
"[foo bar baz]", rule->GetBinding(
"command")->Serialize());
208 EXPECT_EQ(
"bar\\baz", state.bindings_.LookupVariable(
"foo"));
209 EXPECT_EQ(
"bar\\ baz", state.bindings_.LookupVariable(
"foo2"));
214 "# this is a comment\n"
215 "foo = not # a comment\n"));
216 EXPECT_EQ(
"not # a comment", state.bindings_.LookupVariable(
"foo"));
222 " command = ${out}bar$$baz$$$\n"
227 EXPECT_EQ(
"$dollar", state.bindings_.LookupVariable(
"x"));
229 EXPECT_EQ(
"$dollarbar$baz$blah", state.edges_[0]->EvaluateCommand());
231 EXPECT_EQ(
"'$dollar'bar$baz$blah", state.edges_[0]->EvaluateCommand());
238 " command = something\n"
239 "build foo$ bar: spaces $$one two$$$ three\n"
241 EXPECT_TRUE(state.LookupNode(
"foo bar"));
242 EXPECT_EQ(state.edges_[0]->outputs_[0]->path(),
"foo bar");
243 EXPECT_EQ(state.edges_[0]->inputs_[0]->path(),
"$one");
244 EXPECT_EQ(state.edges_[0]->inputs_[1]->path(),
"two$ three");
245 EXPECT_EQ(state.edges_[0]->EvaluateCommand(),
"something");
251 " command = cat $in > $out\n"
252 "build out: cat in/1 in//2\n"
254 "build in/2: cat\n"));
256 EXPECT_TRUE(state.LookupNode(
"in/1"));
257 EXPECT_TRUE(state.LookupNode(
"in/2"));
258 EXPECT_FALSE(state.LookupNode(
"in//1"));
259 EXPECT_FALSE(state.LookupNode(
"in//2"));
266 " command = cat $in > $out\n"
267 "build out: cat in\\1 in\\\\2\n"
269 "build in\\2: cat\n"));
271 Node* node = state.LookupNode(
"in/1");;
274 node = state.LookupNode(
"in/2");
277 EXPECT_FALSE(state.LookupNode(
"in//1"));
278 EXPECT_FALSE(state.LookupNode(
"in//2"));
285 " command = cat $in > $out\n"
287 "build $dir/exe: cat src\n"));
289 EXPECT_FALSE(state.LookupNode(
"$dir/exe"));
290 EXPECT_TRUE(state.LookupNode(
"out/exe"));
296 " command = cat $in > $out\n"
297 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
299 EXPECT_FALSE(state.LookupNode(
"./out.o"));
300 EXPECT_TRUE(state.LookupNode(
"out.o"));
301 EXPECT_FALSE(state.LookupNode(
"./bar/baz/../foo.cc"));
302 EXPECT_TRUE(state.LookupNode(
"bar/foo.cc"));
309 " command = cat $in > $out\n"
310 "build ./out.o: cat ./bar/baz/../foo.cc\n"
311 "build .\\out2.o: cat .\\bar/baz\\..\\foo.cc\n"
312 "build .\\out3.o: cat .\\bar\\baz\\..\\foo3.cc\n"
315 EXPECT_FALSE(state.LookupNode(
"./out.o"));
316 EXPECT_FALSE(state.LookupNode(
".\\out2.o"));
317 EXPECT_FALSE(state.LookupNode(
".\\out3.o"));
318 EXPECT_TRUE(state.LookupNode(
"out.o"));
319 EXPECT_TRUE(state.LookupNode(
"out2.o"));
320 EXPECT_TRUE(state.LookupNode(
"out3.o"));
321 EXPECT_FALSE(state.LookupNode(
"./bar/baz/../foo.cc"));
322 EXPECT_FALSE(state.LookupNode(
".\\bar/baz\\..\\foo.cc"));
323 EXPECT_FALSE(state.LookupNode(
".\\bar/baz\\..\\foo3.cc"));
324 Node* node = state.LookupNode(
"bar/foo.cc");
327 node = state.LookupNode(
"bar/foo3.cc");
334 const char kInput[] =
336 " command = cat $in > $out\n"
337 "build out1 out2: cat in1\n"
338 "build out1: cat in2\n"
339 "build final: cat out1\n";
342 EXPECT_FALSE(parser.
ParseTest(kInput, &err));
343 EXPECT_EQ(
"input:5: multiple rules generate out1\n", err);
347 fs_.Create(
"sub.ninja",
349 " command = cat $in > $out\n"
350 "build out1 out2: cat in1\n"
351 "build out1: cat in2\n"
352 "build final: cat out1\n");
353 const char kInput[] =
354 "subninja sub.ninja\n";
357 EXPECT_FALSE(parser.
ParseTest(kInput, &err));
358 EXPECT_EQ(
"sub.ninja:5: multiple rules generate out1\n", err);
366 Node* node = state.LookupNode(
"a");
368 ASSERT_TRUE(edge->
inputs_.empty());
372 const char kInput[] =
373 "build a: phony a\n";
378 EXPECT_TRUE(parser.
ParseTest(kInput, &err));
381 Node* node = state.LookupNode(
"a");
383 ASSERT_EQ(edge->
inputs_.size(),
size_t(1));
384 ASSERT_EQ(edge->
inputs_[0], node);
390 " command = rule run $out\n"
391 "build subninja: build include default foo.cc\n"
392 "default subninja\n"));
400 EXPECT_FALSE(parser.
ParseTest(
string(
"subn", 4), &err));
401 EXPECT_EQ(
"input:1: expected '=', got eof\n"
411 EXPECT_FALSE(parser.
ParseTest(
"foobar", &err));
412 EXPECT_EQ(
"input:1: expected '=', got eof\n"
422 EXPECT_FALSE(parser.
ParseTest(
"x 3", &err));
423 EXPECT_EQ(
"input:1: expected '=', got identifier\n"
433 EXPECT_FALSE(parser.
ParseTest(
"x = 3", &err));
434 EXPECT_EQ(
"input:1: unexpected EOF\n"
444 EXPECT_FALSE(parser.
ParseTest(
"x = 3\ny 2", &err));
445 EXPECT_EQ(
"input:2: expected '=', got identifier\n"
455 EXPECT_FALSE(parser.
ParseTest(
"x = $", &err));
456 EXPECT_EQ(
"input:1: bad $-escape (literal $ must be written as $$)\n"
466 EXPECT_FALSE(parser.
ParseTest(
"x = $\n $[\n", &err));
467 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n"
477 EXPECT_FALSE(parser.
ParseTest(
"x = a$\n b$\n $\n", &err));
478 EXPECT_EQ(
"input:4: unexpected EOF\n"
486 EXPECT_FALSE(parser.
ParseTest(
"build\n", &err));
487 EXPECT_EQ(
"input:1: expected path\n"
497 EXPECT_FALSE(parser.
ParseTest(
"build x: y z\n", &err));
498 EXPECT_EQ(
"input:1: unknown build rule 'y'\n"
508 EXPECT_FALSE(parser.
ParseTest(
"build x:: y z\n", &err));
509 EXPECT_EQ(
"input:1: expected build command name\n"
519 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n command = cat ok\n"
520 "build x: cat $\n :\n",
522 EXPECT_EQ(
"input:4: expected newline, got ':'\n"
532 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n",
534 EXPECT_EQ(
"input:2: expected 'command =' line\n", err);
541 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n"
544 " command = echo\n", &err));
545 EXPECT_EQ(
"input:3: duplicate rule 'cat'\n"
555 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n"
557 " rspfile = cat.rsp\n", &err));
559 "input:4: rspfile and rspfile_content need to be both specified\n",
567 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n"
568 " command = ${fafsd\n"
571 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n"
572 " command = ${fafsd\n"
582 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n"
584 "build $.: cat foo\n",
586 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n"
587 "build $.: cat foo\n"
597 EXPECT_FALSE(parser.
ParseTest(
"rule cat\n"
599 "build $: cat foo\n",
601 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n"
611 EXPECT_FALSE(parser.
ParseTest(
"rule %foo\n",
613 EXPECT_EQ(
"input:1: expected rule name\n"
623 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n"
627 EXPECT_EQ(
"input:3: unexpected variable 'othervar'\n"
637 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n"
638 "build $.: cc bar.cc\n",
640 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n"
641 "build $.: cc bar.cc\n"
650 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n && bar",
652 EXPECT_EQ(
"input:3: expected variable name\n"
662 EXPECT_FALSE(parser.
ParseTest(
"rule cc\n command = foo\n"
663 "build $: cc bar.cc\n",
665 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n"
666 "build $: cc bar.cc\n"
675 EXPECT_FALSE(parser.
ParseTest(
"default\n",
677 EXPECT_EQ(
"input:1: expected target name\n"
687 EXPECT_FALSE(parser.
ParseTest(
"default nonexistent\n",
689 EXPECT_EQ(
"input:1: unknown target 'nonexistent'\n"
690 "default nonexistent\n"
699 EXPECT_FALSE(parser.
ParseTest(
"rule r\n command = r\n"
703 EXPECT_EQ(
"input:4: expected newline, got ':'\n"
713 EXPECT_FALSE(parser.
ParseTest(
"default $a\n", &err));
714 EXPECT_EQ(
"input:1: empty path\n"
726 "build $a: r $c\n", &err));
729 EXPECT_EQ(
"input:4: empty path\n", err);
741 " generator = 1\n", &err));
742 EXPECT_EQ(
"input:4: unexpected indent\n", err);
749 EXPECT_FALSE(parser.
ParseTest(
"pool\n", &err));
750 EXPECT_EQ(
"input:1: expected pool name\n"
752 " ^ near here", err);
759 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n", &err));
760 EXPECT_EQ(
"input:2: expected 'depth =' line\n", err);
767 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n"
769 "pool foo\n", &err));
770 EXPECT_EQ(
"input:3: duplicate pool 'foo'\n"
780 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n"
781 " depth = -1\n", &err));
782 EXPECT_EQ(
"input:2: invalid pool depth\n"
792 EXPECT_FALSE(parser.
ParseTest(
"pool foo\n"
793 " bar = 1\n", &err));
794 EXPECT_EQ(
"input:2: unexpected variable 'bar'\n"
805 EXPECT_FALSE(parser.
ParseTest(
"rule run\n"
807 " pool = unnamed_pool\n"
808 "build out: run in\n", &err));
809 EXPECT_EQ(
"input:5: unknown pool name 'unnamed_pool'\n", err);
817 EXPECT_FALSE(parser.
Load(
"build.ninja", &err));
818 EXPECT_EQ(
"loading 'build.ninja': No such file or directory", err);
825 EXPECT_TRUE(parser.
ParseTest(
"rule cc\n command = foo\n depfile = bar\n"
826 "build a.o b.o: cc c.cc\n",
835 EXPECT_TRUE(parser.
ParseTest(
"rule cc\n command = foo\n deps = gcc\n"
836 "build a.o b.o: cc c.cc\n",
842 fs_.Create(
"test.ninja",
844 "build $builddir/inner: varref\n");
846 "builddir = some_dir/\n"
848 " command = varref $var\n"
850 "build $builddir/outer: varref\n"
851 "subninja test.ninja\n"
852 "build $builddir/outer2: varref\n"));
853 ASSERT_EQ(1u, fs_.files_read_.size());
855 EXPECT_EQ(
"test.ninja", fs_.files_read_[0]);
856 EXPECT_TRUE(state.LookupNode(
"some_dir/outer"));
858 EXPECT_TRUE(state.LookupNode(
"some_dir/inner"));
860 ASSERT_EQ(3u, state.edges_.size());
861 EXPECT_EQ(
"varref outer", state.edges_[0]->EvaluateCommand());
862 EXPECT_EQ(
"varref inner", state.edges_[1]->EvaluateCommand());
863 EXPECT_EQ(
"varref outer", state.edges_[2]->EvaluateCommand());
869 EXPECT_FALSE(parser.
ParseTest(
"subninja foo.ninja\n", &err));
870 EXPECT_EQ(
"input:1: loading 'foo.ninja': No such file or directory\n"
871 "subninja foo.ninja\n"
878 fs_.Create(
"test.ninja",
"rule cat\n"
882 EXPECT_TRUE(parser.
ParseTest(
"rule cat\n"
884 "subninja test.ninja\n", &err));
889 fs_.Create(
"rules.ninja",
"rule cat\n"
891 fs_.Create(
"test.ninja",
"include rules.ninja\n"
895 EXPECT_TRUE(parser.
ParseTest(
"include rules.ninja\n"
896 "subninja test.ninja\n"
897 "build y : cat\n", &err));
901 fs_.Create(
"include.ninja",
"var = inner\n");
904 "include include.ninja\n"));
906 ASSERT_EQ(1u, fs_.files_read_.size());
907 EXPECT_EQ(
"include.ninja", fs_.files_read_[0]);
908 EXPECT_EQ(
"inner", state.bindings_.LookupVariable(
"var"));
912 fs_.Create(
"include.ninja",
"build\n");
915 EXPECT_FALSE(parser.
ParseTest(
"include include.ninja\n", &err));
916 EXPECT_EQ(
"include.ninja:1: expected path\n"
925 " command = cat $in > $out\n"
926 "build foo: cat bar | baz\n"));
928 Edge* edge = state.LookupNode(
"foo")->in_edge();
934 "rule cat\n command = cat $in > $out\n"
935 "build foo: cat bar || baz\n"));
937 Edge* edge = state.LookupNode(
"foo")->in_edge();
943 "rule cat\n command = cat $in > $out\n"
944 "build foo: cat bar |@ baz\n"));
946 Edge* edge = state.LookupNode(
"foo")->in_edge();
954 " command = cat $in > $out\n"
955 "build foo | imp: cat bar\n"));
957 Edge* edge = state.LookupNode(
"imp")->in_edge();
958 ASSERT_EQ(edge->
outputs_.size(),
size_t(2));
965 " command = cat $in > $out\n"
966 "build foo | : cat bar\n"));
968 Edge* edge = state.LookupNode(
"foo")->in_edge();
969 ASSERT_EQ(edge->
outputs_.size(),
size_t(1));
974 const char kInput[] =
976 " command = cat $in > $out\n"
977 "build foo baz | foo baq foo: cat bar\n";
980 EXPECT_FALSE(parser.
ParseTest(kInput, &err));
981 EXPECT_EQ(
"input:4: foo is defined as an output multiple times\n", err);
985 const char kInput[] =
987 " command = cat $in > $out\n"
988 "build foo foo foo | foo foo foo foo: cat bar\n";
991 EXPECT_FALSE(parser.
ParseTest(kInput, &err));
992 EXPECT_EQ(
"input:4: foo is defined as an output multiple times\n", err);
1000 " command = cat $in > $out\n"
1001 "build | imp : cat bar\n", &err));
1006 "rule cat\n command = cat $in > $out\n"
1007 "build a: cat foo\n"
1008 "build b: cat foo\n"
1009 "build c: cat foo\n"
1010 "build d: cat foo\n"));
1013 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
1019 "rule cat\n command = cat $in > $out\n"
1020 "build a: cat a\n"));
1023 EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1024 EXPECT_EQ(
"could not determine root nodes of build graph", err);
1029 "rule cat\n command = cat $in > $out\n"
1030 "build a: cat foo\n"
1031 "build b: cat foo\n"
1032 "build c: cat foo\n"
1033 "build d: cat foo\n"
1036 "default $third\n"));
1039 vector<Node*> nodes = state.DefaultNodes(&err);
1041 ASSERT_EQ(3u, nodes.size());
1042 EXPECT_EQ(
"a", nodes[0]->path());
1043 EXPECT_EQ(
"b", nodes[1]->path());
1044 EXPECT_EQ(
"c", nodes[2]->path());
1051 " description = compilaci\xC3\xB3\n"));
1059 EXPECT_TRUE(parser.
ParseTest(
"# comment with crlf\r\n", &err));
1060 EXPECT_TRUE(parser.
ParseTest(
"foo = foo\nbar = bar\r\n", &err));
1062 "pool link_pool\r\n"
1063 " depth = 15\r\n\r\n"
1065 " command = something$expand \r\n"
1066 " description = YAY!\r\n",
1073 " command = cat $in > $out\n"
1074 "build result: cat in\n"));
1075 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1085 " command = touch $out\n"
1086 "build result: touch\n"
1087 " dyndep = notin\n",
1089 EXPECT_EQ(
"input:5: dyndep 'notin' is not an input\n", err);
1095 " command = cat $in > $out\n"
1096 "build result: cat in\n"
1098 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1107 " command = cat $in > $out\n"
1108 "build result: cat in | dd\n"
1110 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1119 " command = cat $in > $out\n"
1120 "build result: cat in || dd\n"
1122 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1131 " command = cat $in > $out\n"
1133 "build result: cat in\n"));
1134 Edge* edge = state.GetNode(
"result", 0)->in_edge();
TEST_F(ParserTest, Empty)
An edge in the dependency graph; links between Nodes using Rules.
std::vector< Node * > outputs_
bool is_order_only(size_t index)
bool GetBindingBool(const std::string &key) const
bool is_implicit(size_t index)
bool is_implicit_out(size_t index) const
std::string EvaluateCommand(bool incl_rsp_file=false) const
Expand all variables in a command and return it as a string.
std::vector< Node * > validations_
std::vector< Node * > inputs_
PhonyCycleAction phony_cycle_action_
bool ParseTest(const std::string &input, std::string *err)
Parse a text string of input. Used by tests.
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
const std::string & path() const
bool dyndep_pending() const
uint64_t slash_bits() const
void AssertParse(const char *input)
bool Load(const std::string &filename, std::string *err, Lexer *parent=NULL)
Load and parse a file.
Global state (file status) for a single run.
An implementation of DiskInterface that uses an in-memory representation of disk state.
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
void VerifyGraph(const State &state)