1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "manifest_parser.h"
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <vector>
20
21 #include "disk_interface.h"
22 #include "graph.h"
23 #include "metrics.h"
24 #include "state.h"
25 #include "util.h"
26 #include "version.h"
27
ManifestParser(State * state,FileReader * file_reader,ManifestParserOptions options)28 ManifestParser::ManifestParser(State* state, FileReader* file_reader,
29 ManifestParserOptions options)
30 : state_(state), file_reader_(file_reader),
31 options_(options), quiet_(false) {
32 env_ = &state->bindings_;
33 }
34
Load(const string & filename,string * err,Lexer * parent)35 bool ManifestParser::Load(const string& filename, string* err, Lexer* parent) {
36 METRIC_RECORD(".ninja parse");
37 string contents;
38 string read_err;
39 if (file_reader_->ReadFile(filename, &contents, &read_err) != FileReader::Okay) {
40 *err = "loading '" + filename + "': " + read_err;
41 if (parent)
42 parent->Error(string(*err), err);
43 return false;
44 }
45
46 // The lexer needs a nul byte at the end of its input, to know when it's done.
47 // It takes a StringPiece, and StringPiece's string constructor uses
48 // string::data(). data()'s return value isn't guaranteed to be
49 // null-terminated (although in practice - libc++, libstdc++, msvc's stl --
50 // it is, and C++11 demands that too), so add an explicit nul byte.
51 contents.resize(contents.size() + 1);
52
53 return Parse(filename, contents, err);
54 }
55
Parse(const string & filename,const string & input,string * err)56 bool ManifestParser::Parse(const string& filename, const string& input,
57 string* err) {
58 lexer_.Start(filename, input);
59
60 for (;;) {
61 Lexer::Token token = lexer_.ReadToken();
62 switch (token) {
63 case Lexer::POOL:
64 if (!ParsePool(err))
65 return false;
66 break;
67 case Lexer::BUILD:
68 if (!ParseEdge(err))
69 return false;
70 break;
71 case Lexer::RULE:
72 if (!ParseRule(err))
73 return false;
74 break;
75 case Lexer::DEFAULT:
76 if (!ParseDefault(err))
77 return false;
78 break;
79 case Lexer::IDENT: {
80 lexer_.UnreadToken();
81 string name;
82 EvalString let_value;
83 if (!ParseLet(&name, &let_value, err))
84 return false;
85 string value = let_value.Evaluate(env_);
86 // Check ninja_required_version immediately so we can exit
87 // before encountering any syntactic surprises.
88 if (name == "ninja_required_version")
89 CheckNinjaVersion(value);
90 env_->AddBinding(name, value);
91 break;
92 }
93 case Lexer::INCLUDE:
94 if (!ParseFileInclude(false, err))
95 return false;
96 break;
97 case Lexer::SUBNINJA:
98 if (!ParseFileInclude(true, err))
99 return false;
100 break;
101 case Lexer::ERROR: {
102 return lexer_.Error(lexer_.DescribeLastError(), err);
103 }
104 case Lexer::TEOF:
105 return true;
106 case Lexer::NEWLINE:
107 break;
108 default:
109 return lexer_.Error(string("unexpected ") + Lexer::TokenName(token),
110 err);
111 }
112 }
113 return false; // not reached
114 }
115
116
ParsePool(string * err)117 bool ManifestParser::ParsePool(string* err) {
118 string name;
119 if (!lexer_.ReadIdent(&name))
120 return lexer_.Error("expected pool name", err);
121
122 if (!ExpectToken(Lexer::NEWLINE, err))
123 return false;
124
125 if (state_->LookupPool(name) != NULL)
126 return lexer_.Error("duplicate pool '" + name + "'", err);
127
128 int depth = -1;
129
130 while (lexer_.PeekToken(Lexer::INDENT)) {
131 string key;
132 EvalString value;
133 if (!ParseLet(&key, &value, err))
134 return false;
135
136 if (key == "depth") {
137 string depth_string = value.Evaluate(env_);
138 depth = atol(depth_string.c_str());
139 if (depth < 0)
140 return lexer_.Error("invalid pool depth", err);
141 } else {
142 return lexer_.Error("unexpected variable '" + key + "'", err);
143 }
144 }
145
146 if (depth < 0)
147 return lexer_.Error("expected 'depth =' line", err);
148
149 state_->AddPool(new Pool(name, depth));
150 return true;
151 }
152
153
ParseRule(string * err)154 bool ManifestParser::ParseRule(string* err) {
155 string name;
156 if (!lexer_.ReadIdent(&name))
157 return lexer_.Error("expected rule name", err);
158
159 if (!ExpectToken(Lexer::NEWLINE, err))
160 return false;
161
162 if (env_->LookupRuleCurrentScope(name) != NULL)
163 return lexer_.Error("duplicate rule '" + name + "'", err);
164
165 Rule* rule = new Rule(name); // XXX scoped_ptr
166
167 while (lexer_.PeekToken(Lexer::INDENT)) {
168 string key;
169 EvalString value;
170 if (!ParseLet(&key, &value, err))
171 return false;
172
173 if (Rule::IsReservedBinding(key)) {
174 rule->AddBinding(key, value);
175 } else {
176 // Die on other keyvals for now; revisit if we want to add a
177 // scope here.
178 return lexer_.Error("unexpected variable '" + key + "'", err);
179 }
180 }
181
182 if (rule->bindings_["rspfile"].empty() !=
183 rule->bindings_["rspfile_content"].empty()) {
184 return lexer_.Error("rspfile and rspfile_content need to be "
185 "both specified", err);
186 }
187
188 if (rule->bindings_["command"].empty())
189 return lexer_.Error("expected 'command =' line", err);
190
191 env_->AddRule(rule);
192 return true;
193 }
194
ParseLet(string * key,EvalString * value,string * err)195 bool ManifestParser::ParseLet(string* key, EvalString* value, string* err) {
196 if (!lexer_.ReadIdent(key))
197 return lexer_.Error("expected variable name", err);
198 if (!ExpectToken(Lexer::EQUALS, err))
199 return false;
200 if (!lexer_.ReadVarValue(value, err))
201 return false;
202 return true;
203 }
204
ParseDefault(string * err)205 bool ManifestParser::ParseDefault(string* err) {
206 EvalString eval;
207 if (!lexer_.ReadPath(&eval, err))
208 return false;
209 if (eval.empty())
210 return lexer_.Error("expected target name", err);
211
212 do {
213 string path = eval.Evaluate(env_);
214 string path_err;
215 uint64_t slash_bits; // Unused because this only does lookup.
216 if (!CanonicalizePath(&path, &slash_bits, &path_err))
217 return lexer_.Error(path_err, err);
218 if (!state_->AddDefault(path, &path_err))
219 return lexer_.Error(path_err, err);
220
221 eval.Clear();
222 if (!lexer_.ReadPath(&eval, err))
223 return false;
224 } while (!eval.empty());
225
226 if (!ExpectToken(Lexer::NEWLINE, err))
227 return false;
228
229 return true;
230 }
231
ParseEdge(string * err)232 bool ManifestParser::ParseEdge(string* err) {
233 vector<EvalString> ins, outs;
234
235 {
236 EvalString out;
237 if (!lexer_.ReadPath(&out, err))
238 return false;
239 while (!out.empty()) {
240 outs.push_back(out);
241
242 out.Clear();
243 if (!lexer_.ReadPath(&out, err))
244 return false;
245 }
246 }
247
248 // Add all implicit outs, counting how many as we go.
249 int implicit_outs = 0;
250 if (lexer_.PeekToken(Lexer::PIPE)) {
251 for (;;) {
252 EvalString out;
253 if (!lexer_.ReadPath(&out, err))
254 return err;
255 if (out.empty())
256 break;
257 outs.push_back(out);
258 ++implicit_outs;
259 }
260 }
261
262 if (outs.empty())
263 return lexer_.Error("expected path", err);
264
265 if (!ExpectToken(Lexer::COLON, err))
266 return false;
267
268 string rule_name;
269 if (!lexer_.ReadIdent(&rule_name))
270 return lexer_.Error("expected build command name", err);
271
272 const Rule* rule = env_->LookupRule(rule_name);
273 if (!rule)
274 return lexer_.Error("unknown build rule '" + rule_name + "'", err);
275
276 for (;;) {
277 // XXX should we require one path here?
278 EvalString in;
279 if (!lexer_.ReadPath(&in, err))
280 return false;
281 if (in.empty())
282 break;
283 ins.push_back(in);
284 }
285
286 // Add all implicit deps, counting how many as we go.
287 int implicit = 0;
288 if (lexer_.PeekToken(Lexer::PIPE)) {
289 for (;;) {
290 EvalString in;
291 if (!lexer_.ReadPath(&in, err))
292 return err;
293 if (in.empty())
294 break;
295 ins.push_back(in);
296 ++implicit;
297 }
298 }
299
300 // Add all order-only deps, counting how many as we go.
301 int order_only = 0;
302 if (lexer_.PeekToken(Lexer::PIPE2)) {
303 for (;;) {
304 EvalString in;
305 if (!lexer_.ReadPath(&in, err))
306 return false;
307 if (in.empty())
308 break;
309 ins.push_back(in);
310 ++order_only;
311 }
312 }
313
314 if (!ExpectToken(Lexer::NEWLINE, err))
315 return false;
316
317 // Bindings on edges are rare, so allocate per-edge envs only when needed.
318 bool has_indent_token = lexer_.PeekToken(Lexer::INDENT);
319 BindingEnv* env = has_indent_token ? new BindingEnv(env_) : env_;
320 while (has_indent_token) {
321 string key;
322 EvalString val;
323 if (!ParseLet(&key, &val, err))
324 return false;
325
326 env->AddBinding(key, val.Evaluate(env_));
327 has_indent_token = lexer_.PeekToken(Lexer::INDENT);
328 }
329
330 Edge* edge = state_->AddEdge(rule);
331 edge->env_ = env;
332
333 string pool_name = edge->GetBinding("pool");
334 if (!pool_name.empty()) {
335 Pool* pool = state_->LookupPool(pool_name);
336 if (pool == NULL)
337 return lexer_.Error("unknown pool name '" + pool_name + "'", err);
338 edge->pool_ = pool;
339 }
340
341 edge->outputs_.reserve(outs.size());
342 for (size_t i = 0, e = outs.size(); i != e; ++i) {
343 string path = outs[i].Evaluate(env);
344 string path_err;
345 uint64_t slash_bits;
346 if (!CanonicalizePath(&path, &slash_bits, &path_err))
347 return lexer_.Error(path_err, err);
348 if (!state_->AddOut(edge, path, slash_bits)) {
349 if (options_.dupe_edge_action_ == kDupeEdgeActionError) {
350 lexer_.Error("multiple rules generate " + path + " [-w dupbuild=err]",
351 err);
352 return false;
353 } else {
354 if (!quiet_) {
355 Warning("multiple rules generate %s. "
356 "builds involving this target will not be correct; "
357 "continuing anyway [-w dupbuild=warn]",
358 path.c_str());
359 }
360 if (e - i <= static_cast<size_t>(implicit_outs))
361 --implicit_outs;
362 }
363 }
364 }
365 if (edge->outputs_.empty()) {
366 // All outputs of the edge are already created by other edges. Don't add
367 // this edge. Do this check before input nodes are connected to the edge.
368 state_->edges_.pop_back();
369 delete edge;
370 return true;
371 }
372 edge->implicit_outs_ = implicit_outs;
373
374 edge->inputs_.reserve(ins.size());
375 for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
376 string path = i->Evaluate(env);
377 string path_err;
378 uint64_t slash_bits;
379 if (!CanonicalizePath(&path, &slash_bits, &path_err))
380 return lexer_.Error(path_err, err);
381 state_->AddIn(edge, path, slash_bits);
382 }
383 edge->implicit_deps_ = implicit;
384 edge->order_only_deps_ = order_only;
385
386 if (options_.phony_cycle_action_ == kPhonyCycleActionWarn &&
387 edge->maybe_phonycycle_diagnostic()) {
388 // CMake 2.8.12.x and 3.0.x incorrectly write phony build statements
389 // that reference themselves. Ninja used to tolerate these in the
390 // build graph but that has since been fixed. Filter them out to
391 // support users of those old CMake versions.
392 Node* out = edge->outputs_[0];
393 vector<Node*>::iterator new_end =
394 remove(edge->inputs_.begin(), edge->inputs_.end(), out);
395 if (new_end != edge->inputs_.end()) {
396 edge->inputs_.erase(new_end, edge->inputs_.end());
397 if (!quiet_) {
398 Warning("phony target '%s' names itself as an input; "
399 "ignoring [-w phonycycle=warn]",
400 out->path().c_str());
401 }
402 }
403 }
404
405 // Multiple outputs aren't (yet?) supported with depslog.
406 string deps_type = edge->GetBinding("deps");
407 if (!deps_type.empty() && edge->outputs_.size() > 1) {
408 return lexer_.Error("multiple outputs aren't (yet?) supported by depslog; "
409 "bring this up on the mailing list if it affects you",
410 err);
411 }
412
413 return true;
414 }
415
ParseFileInclude(bool new_scope,string * err)416 bool ManifestParser::ParseFileInclude(bool new_scope, string* err) {
417 EvalString eval;
418 if (!lexer_.ReadPath(&eval, err))
419 return false;
420 string path = eval.Evaluate(env_);
421
422 ManifestParser subparser(state_, file_reader_, options_);
423 if (new_scope) {
424 subparser.env_ = new BindingEnv(env_);
425 } else {
426 subparser.env_ = env_;
427 }
428
429 if (!subparser.Load(path, err, &lexer_))
430 return false;
431
432 if (!ExpectToken(Lexer::NEWLINE, err))
433 return false;
434
435 return true;
436 }
437
ExpectToken(Lexer::Token expected,string * err)438 bool ManifestParser::ExpectToken(Lexer::Token expected, string* err) {
439 Lexer::Token token = lexer_.ReadToken();
440 if (token != expected) {
441 string message = string("expected ") + Lexer::TokenName(expected);
442 message += string(", got ") + Lexer::TokenName(token);
443 message += Lexer::TokenErrorHint(expected);
444 return lexer_.Error(message, err);
445 }
446 return true;
447 }
448