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 [-w dupbuild=err]\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 [-w dupbuild=err]\n",
394 Node* node = state.LookupNode(
"a");
400 const char kInput[] =
401 "build a: phony a\n";
409 Node* node = state.LookupNode(
"a");
418 " command = rule run $out\n" 419 "build subninja: build include default foo.cc\n" 420 "default subninja\n"));
429 EXPECT_EQ(
"input:1: expected '=', got eof\n" 440 EXPECT_EQ(
"input:1: expected '=', got eof\n" 451 EXPECT_EQ(
"input:1: expected '=', got identifier\n" 473 EXPECT_EQ(
"input:2: expected '=', got identifier\n" 484 EXPECT_EQ(
"input:1: bad $-escape (literal $ must be written as $$)\n" 495 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 526 EXPECT_EQ(
"input:1: unknown build rule 'y'\n" 537 EXPECT_EQ(
"input:1: expected build command name\n" 548 "build x: cat $\n :\n",
550 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 562 EXPECT_EQ(
"input:2: expected 'command =' line\n", err);
572 " command = echo\n", &err));
573 EXPECT_EQ(
"input:3: duplicate rule 'cat'\n" 585 " rspfile = cat.rsp\n", &err));
587 "input:4: rspfile and rspfile_content need to be both specified\n",
596 " command = ${fafsd\n" 599 EXPECT_EQ(
"input:2: bad $-escape (literal $ must be written as $$)\n" 600 " command = ${fafsd\n" 612 "build $.: cat foo\n",
614 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 615 "build $.: cat foo\n" 627 "build $: cat foo\n",
629 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 641 EXPECT_EQ(
"input:1: expected rule name\n" 655 EXPECT_EQ(
"input:3: unexpected variable 'othervar'\n" 666 "build $.: cc bar.cc\n",
668 EXPECT_EQ(
"input:3: bad $-escape (literal $ must be written as $$)\n" 669 "build $.: cc bar.cc\n" 680 EXPECT_EQ(
"input:3: expected variable name\n" 691 "build $: cc bar.cc\n",
693 EXPECT_EQ(
"input:3: expected ':', got newline ($ also escapes ':')\n" 694 "build $: cc bar.cc\n" 705 EXPECT_EQ(
"input:1: expected target name\n" 717 EXPECT_EQ(
"input:1: unknown target 'nonexistent'\n" 718 "default nonexistent\n" 731 EXPECT_EQ(
"input:4: expected newline, got ':'\n" 754 "build $a: r $c\n", &err));
769 " generator = 1\n", &err));
770 EXPECT_EQ(
"input:4: unexpected indent\n", err);
778 EXPECT_EQ(
"input:1: expected pool name\n" 780 " ^ near here", err);
788 EXPECT_EQ(
"input:2: expected 'depth =' line\n", err);
797 "pool foo\n", &err));
798 EXPECT_EQ(
"input:3: duplicate pool 'foo'\n" 809 " depth = -1\n", &err));
810 EXPECT_EQ(
"input:2: invalid pool depth\n" 821 " bar = 1\n", &err));
822 EXPECT_EQ(
"input:2: unexpected variable 'bar'\n" 835 " pool = unnamed_pool\n" 836 "build out: run in\n", &err));
837 EXPECT_EQ(
"input:5: unknown pool name 'unnamed_pool'\n", err);
846 EXPECT_EQ(
"loading 'build.ninja': No such file or directory", err);
854 "build a.o b.o: cc c.cc\n",
864 "build a.o b.o: cc c.cc\n",
870 fs_.Create(
"test.ninja",
872 "build $builddir/inner: varref\n");
874 "builddir = some_dir/\n" 876 " command = varref $var\n" 878 "build $builddir/outer: varref\n" 879 "subninja test.ninja\n" 880 "build $builddir/outer2: varref\n"));
883 EXPECT_EQ(
"test.ninja", fs_.files_read_[0]);
889 EXPECT_EQ(
"varref outer", state.edges_[0]->EvaluateCommand());
890 EXPECT_EQ(
"varref inner", state.edges_[1]->EvaluateCommand());
891 EXPECT_EQ(
"varref outer", state.edges_[2]->EvaluateCommand());
898 EXPECT_EQ(
"input:1: loading 'foo.ninja': No such file or directory\n" 899 "subninja foo.ninja\n" 906 fs_.Create(
"test.ninja",
"rule cat\n" 912 "subninja test.ninja\n", &err));
917 fs_.Create(
"rules.ninja",
"rule cat\n" 919 fs_.Create(
"test.ninja",
"include rules.ninja\n" 924 "subninja test.ninja\n" 925 "build y : cat\n", &err));
929 fs_.Create(
"include.ninja",
"var = inner\n");
932 "include include.ninja\n"));
935 EXPECT_EQ(
"include.ninja", fs_.files_read_[0]);
936 EXPECT_EQ(
"inner", state.bindings_.LookupVariable(
"var"));
940 fs_.Create(
"include.ninja",
"build\n");
944 EXPECT_EQ(
"include.ninja:1: expected path\n" 953 " command = cat $in > $out\n" 954 "build foo: cat bar | baz\n"));
956 Edge* edge = state.LookupNode(
"foo")->in_edge();
962 "rule cat\n command = cat $in > $out\n" 963 "build foo: cat bar || baz\n"));
965 Edge* edge = state.LookupNode(
"foo")->in_edge();
972 " command = cat $in > $out\n" 973 "build foo | imp: cat bar\n"));
975 Edge* edge = state.LookupNode(
"imp")->in_edge();
983 " command = cat $in > $out\n" 984 "build foo | : cat bar\n"));
986 Edge* edge = state.LookupNode(
"foo")->in_edge();
994 " command = cat $in > $out\n" 995 "build foo baz | foo baq foo: cat bar\n"));
997 Edge* edge = state.LookupNode(
"foo")->in_edge();
1007 " command = cat $in > $out\n" 1008 "build foo foo foo | foo foo foo foo: cat bar\n"));
1010 Edge* edge = state.LookupNode(
"foo")->in_edge();
1020 " command = cat $in > $out\n" 1021 "build | imp : cat bar\n", &err));
1026 "rule cat\n command = cat $in > $out\n" 1027 "build a: cat foo\n" 1028 "build b: cat foo\n" 1029 "build c: cat foo\n" 1030 "build d: cat foo\n"));
1033 EXPECT_EQ(4u, state.DefaultNodes(&err).size());
1039 "rule cat\n command = cat $in > $out\n" 1040 "build a: cat a\n"));
1043 EXPECT_EQ(0u, state.DefaultNodes(&err).size());
1044 EXPECT_EQ(
"could not determine root nodes of build graph", err);
1049 "rule cat\n command = cat $in > $out\n" 1050 "build a: cat foo\n" 1051 "build b: cat foo\n" 1052 "build c: cat foo\n" 1053 "build d: cat foo\n" 1056 "default $third\n"));
1059 vector<Node*> nodes = state.DefaultNodes(&err);
1071 " description = compilaci\xC3\xB3\n"));
1082 "pool link_pool\r\n" 1083 " depth = 15\r\n\r\n" 1085 " command = something$expand \r\n" 1086 " description = YAY!\r\n",
1093 " command = cat $in > $out\n" 1094 "build result: cat in\n"));
1095 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1105 " command = touch $out\n" 1106 "build result: touch\n" 1107 " dyndep = notin\n",
1109 EXPECT_EQ(
"input:5: dyndep 'notin' is not an input\n", err);
1115 " command = cat $in > $out\n" 1116 "build result: cat in\n" 1118 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1127 " command = cat $in > $out\n" 1128 "build result: cat in | dd\n" 1130 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1139 " command = cat $in > $out\n" 1140 "build result: cat in || dd\n" 1142 Edge* edge = state.GetNode(
"result", 0)->in_edge();
1151 " command = cat $in > $out\n" 1153 "build result: cat in\n"));
1154 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)
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 invokable 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_