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 Rule* rule = state.
bindings_.GetRules().begin()->second;
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 Rule* rule = state.
bindings_.GetRules().begin()->second;
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 Rule* rule = state.
bindings_.GetRules().begin()->second;
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 Rule* rule = state.
bindings_.GetRules().begin()->second;
139 EXPECT_EQ(
"[cat ][$in_newline][ > ][$out]",
140 rule->GetBinding(
"command")->Serialize());
142 Edge* edge = state.edges_[0];
143 EXPECT_EQ(
"cat in\nin2 > out", edge->EvaluateCommand());
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"));
161 Edge* edge = state.edges_[0];
162 EXPECT_EQ(
"ld one-letter-test -pthread -under -o a b c",
163 edge->EvaluateCommand());
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",
168 edge->EvaluateCommand());
175 " command = cmd $foo $in $out\n" 177 "build inner: cmd a\n" 179 "build outer: cmd b\n" 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 Rule* rule = state.
bindings_.GetRules().begin()->second;
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" 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"));
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");
285 " command = cat $in > $out\n" 287 "build $dir/exe: cat src\n"));
296 " command = cat $in > $out\n" 297 "build ./out.o: cat ./bar/baz/../foo.cc\n"));
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" 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");
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" 348 " command = cat $in > $out\n" 349 "build out: cat in\n" 350 "build out: cat in\n" 357 const char kInput[] =
359 " command = cat $in > $out\n" 360 "build out1 out2: cat in1\n" 361 "build out1: cat in2\n" 362 "build final: cat out1\n";
368 EXPECT_EQ(
"input:5: multiple rules generate out1\n", err);
372 fs_.Create(
"sub.ninja",
374 " command = cat $in > $out\n" 375 "build out1 out2: cat in1\n" 376 "build out1: cat in2\n" 377 "build final: cat out1\n");
378 const char kInput[] =
379 "subninja sub.ninja\n";
385 EXPECT_EQ(
"sub.ninja:5: multiple rules generate out1\n", err);
393 Node* node = state.LookupNode(
"a");
399 const char kInput[] =
400 "build a: phony a\n";
408 Node* node = state.LookupNode(
"a");
417 " command = rule run $out\n" 418 "build subninja: build include default foo.cc\n" 419 "default subninja\n"));
428 EXPECT_EQ(
"input:1: expected '=', got eof\n" 439 EXPECT_EQ(
"input:1: expected '=', got eof\n" 450 EXPECT_EQ(
"input:1: expected '=', got identifier\n" 472 EXPECT_EQ(
"input:2: expected '=', got identifier\n" 483 EXPECT_EQ(
"input:1: bad $-escape (literal $ must be written as $$)\n" 494 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 525 EXPECT_EQ(
"input:1: unknown build rule 'y'\n" 536 EXPECT_EQ(
"input:1: expected build command name\n" 547 "build x: cat $\n :\n",
549 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 561 EXPECT_EQ(
"input:2: expected 'command =' line\n", err);
571 " command = echo\n", &err));
572 EXPECT_EQ(
"input:3: duplicate rule 'cat'\n" 584 " rspfile = cat.rsp\n", &err));
586 "input:4: rspfile and rspfile_content need to be both specified\n",
595 " command = ${fafsd\n" 598 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 599 " command = ${fafsd\n" 611 "build $.: cat foo\n",
613 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 614 "build $.: cat foo\n" 626 "build $: cat foo\n",
628 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 640 EXPECT_EQ(
"input:1: expected rule name\n" 654 EXPECT_EQ(
"input:3: unexpected variable 'othervar'\n" 665 "build $.: cc bar.cc\n",
667 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 668 "build $.: cc bar.cc\n" 679 EXPECT_EQ(
"input:3: expected variable name\n" 690 "build $: cc bar.cc\n",
692 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 693 "build $: cc bar.cc\n" 704 EXPECT_EQ(
"input:1: expected target name\n" 716 EXPECT_EQ(
"input:1: unknown target 'nonexistent'\n" 717 "default nonexistent\n" 730 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 753 "build $a: r $c\n", &err));
768 " generator = 1\n", &err));
769 EXPECT_EQ(
"input:4: unexpected indent\n", err);
777 EXPECT_EQ(
"input:1: expected pool name\n" 779 " ^ near here", err);
787 EXPECT_EQ(
"input:2: expected 'depth =' line\n", err);
796 "pool foo\n", &err));
797 EXPECT_EQ(
"input:3: duplicate pool 'foo'\n" 808 " depth = -1\n", &err));
809 EXPECT_EQ(
"input:2: invalid pool depth\n" 820 " bar = 1\n", &err));
821 EXPECT_EQ(
"input:2: unexpected variable 'bar'\n" 834 " pool = unnamed_pool\n" 835 "build out: run in\n", &err));
836 EXPECT_EQ(
"input:5: unknown pool name 'unnamed_pool'\n", err);
845 EXPECT_EQ(
"loading 'build.ninja': No such file or directory", err);
853 "build a.o b.o: cc c.cc\n",
863 "build a.o b.o: cc c.cc\n",
869 fs_.Create(
"test.ninja",
871 "build $builddir/inner: varref\n");
873 "builddir = some_dir/\n" 875 " command = varref $var\n" 877 "build $builddir/outer: varref\n" 878 "subninja test.ninja\n" 879 "build $builddir/outer2: varref\n"));
882 EXPECT_EQ(
"test.ninja", fs_.files_read_[0]);
888 EXPECT_EQ(
"varref outer", state.edges_[0]->EvaluateCommand());
889 EXPECT_EQ(
"varref inner", state.edges_[1]->EvaluateCommand());
890 EXPECT_EQ(
"varref outer", state.edges_[2]->EvaluateCommand());
897 EXPECT_EQ(
"input:1: loading 'foo.ninja': No such file or directory\n" 898 "subninja foo.ninja\n" 905 fs_.Create(
"test.ninja",
"rule cat\n" 911 "subninja test.ninja\n", &err));
916 fs_.Create(
"rules.ninja",
"rule cat\n" 918 fs_.Create(
"test.ninja",
"include rules.ninja\n" 923 "subninja test.ninja\n" 924 "build y : cat\n", &err));
928 fs_.Create(
"include.ninja",
"var = inner\n");
931 "include include.ninja\n"));
934 EXPECT_EQ(
"include.ninja", fs_.files_read_[0]);
935 EXPECT_EQ(
"inner", state.bindings_.LookupVariable(
"var"));
939 fs_.Create(
"include.ninja",
"build\n");
943 EXPECT_EQ(
"include.ninja:1: expected path\n" 952 " command = cat $in > $out\n" 953 "build foo: cat bar | baz\n"));
955 Edge* edge = state.LookupNode(
"foo")->in_edge();
961 "rule cat\n command = cat $in > $out\n" 962 "build foo: cat bar || baz\n"));
964 Edge* edge = state.LookupNode(
"foo")->in_edge();
970 "rule cat\n command = cat $in > $out\n" 971 "build foo: cat bar |@ baz\n"));
973 Edge* edge = state.LookupNode(
"foo")->in_edge();
981 " command = cat $in > $out\n" 982 "build foo | imp: cat bar\n"));
984 Edge* edge = state.LookupNode(
"imp")->in_edge();
992 " command = cat $in > $out\n" 993 "build foo | : cat bar\n"));
995 Edge* edge = state.LookupNode(
"foo")->in_edge();
1003 " command = cat $in > $out\n" 1004 "build foo baz | foo baq foo: cat bar\n"));
1006 Edge* edge = state.LookupNode(
"foo")->in_edge();
1016 " command = cat $in > $out\n" 1017 "build foo foo foo | foo foo foo foo: cat bar\n"));
1019 Edge* edge = state.LookupNode(
"foo")->in_edge();
1029 " command = cat $in > $out\n" 1030 "build | imp : cat bar\n", &err));
1035 "rule cat\n command = cat $in > $out\n" 1036 "build a: cat foo\n" 1037 "build b: cat foo\n" 1038 "build c: cat foo\n" 1039 "build d: cat foo\n"));
1042 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
1048 "rule cat\n command = cat $in > $out\n" 1049 "build a: cat a\n"));
1052 EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1053 EXPECT_EQ(
"could not determine root nodes of build graph", err);
1058 "rule cat\n command = cat $in > $out\n" 1059 "build a: cat foo\n" 1060 "build b: cat foo\n" 1061 "build c: cat foo\n" 1062 "build d: cat foo\n" 1065 "default $third\n"));
1068 vector<Node*> nodes = state.DefaultNodes(&err);
1080 " description = compilaci\xC3\xB3\n"));
1091 "pool link_pool\r\n" 1092 " depth = 15\r\n\r\n" 1094 " command = something$expand \r\n" 1095 " description = YAY!\r\n",
1102 " command = cat $in > $out\n" 1103 "build result: cat in\n"));
1104 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1114 " command = touch $out\n" 1115 "build result: touch\n" 1116 " dyndep = notin\n",
1118 EXPECT_EQ(
"input:5: dyndep 'notin' is not an input\n", err);
1124 " command = cat $in > $out\n" 1125 "build result: cat in\n" 1127 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1136 " command = cat $in > $out\n" 1137 "build result: cat in | dd\n" 1139 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1148 " command = cat $in > $out\n" 1149 "build result: cat in || dd\n" 1151 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1160 " command = cat $in > $out\n" 1162 "build result: cat in\n"));
1163 Edge* edge = state.GetNode(
"result", 0)->in_edge();
bool dyndep_pending() const
An implementation of DiskInterface that uses an in-memory representation of disk state.
void AssertParse(State *state, const char *input, ManifestParserOptions opts)
std::vector< Node * > validations_
PhonyCycleAction phony_cycle_action_
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
uint64_t slash_bits() const
bool is_implicit_out(size_t index) const
std::vector< Node * > outputs_
bool Load(const std::string &filename, std::string *err, Lexer *parent=NULL)
Load and parse a file.
An edge in the dependency graph; links between Nodes using Rules.
bool is_order_only(size_t index)
const std::string & path() const
bool is_implicit(size_t index)
An invocable build command and associated metadata (description, etc.).
TEST_F(ParserTest, Empty)
void VerifyGraph(const State &state)
void AssertParse(const char *input)
std::vector< Node * > inputs_
bool ParseTest(const std::string &input, std::string *err)
Parse a text string of input. Used by tests.
#define ASSERT_NO_FATAL_FAILURE(a)
Global state (file status) for a single run.
DupeEdgeAction dupe_edge_action_