blob: 45f9584bdc9fe6d6756c54fd5f7da3fb22001531 [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// Copyright 2015 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
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090015// +build ignore
16
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090017#include "dep.h"
18
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090019#include <algorithm>
Shinichiro Hamaji485f9122015-06-26 07:06:14 +090020#include <iterator>
Dan Willemsenb248caa2015-10-01 16:07:48 -070021#include <map>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090022#include <memory>
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +090023#include <unordered_map>
24#include <unordered_set>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090025
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +090026#include "eval.h"
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090027#include "fileutil.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090028#include "log.h"
29#include "rule.h"
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090030#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090031#include "symtab.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090032#include "var.h"
33
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090034namespace {
35
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090036static vector<DepNode*>* g_dep_node_pool;
37
Shinichiro Hamajie7992752015-06-29 18:38:35 +090038static Symbol ReplaceSuffix(Symbol s, Symbol newsuf) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090039 string r;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090040 AppendString(StripExt(s.str()), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090041 r += '.';
Shinichiro Hamajie7992752015-06-29 18:38:35 +090042 AppendString(newsuf.str(), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090043 return Intern(r);
44}
45
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090046class RuleTrie {
47 struct Entry {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090048 Entry(const Rule* r, StringPiece s)
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090049 : rule(r), suffix(s) {
50 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090051 const Rule* rule;
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090052 StringPiece suffix;
53 };
54
55 public:
56 RuleTrie() {}
57 ~RuleTrie() {
58 for (auto& p : children_)
59 delete p.second;
60 }
61
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090062 void Add(StringPiece name, const Rule* rule) {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090063 if (name.empty() || name[0] == '%') {
64 rules_.push_back(Entry(rule, name));
65 return;
66 }
67 const char c = name[0];
68 auto p = children_.emplace(c, nullptr);
69 if (p.second) {
70 p.first->second = new RuleTrie();
71 }
72 p.first->second->Add(name.substr(1), rule);
73 }
74
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090075 void Get(StringPiece name, vector<const Rule*>* rules) const {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090076 for (const Entry& ent : rules_) {
77 if ((ent.suffix.empty() && name.empty()) ||
78 HasSuffix(name, ent.suffix.substr(1))) {
79 rules->push_back(ent.rule);
80 }
81 }
Shinichiro Hamajif772b172015-06-29 16:05:44 +090082 if (name.empty())
83 return;
84 auto found = children_.find(name[0]);
85 if (found != children_.end()) {
86 found->second->Get(name.substr(1), rules);
87 }
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090088 }
89
90 size_t size() const {
91 size_t r = rules_.size();
92 for (const auto& c : children_)
93 r += c.second->size();
94 return r;
95 }
96
97 private:
98 vector<Entry> rules_;
99 unordered_map<char, RuleTrie*> children_;
100};
101
102} // namespace
103
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900104DepNode::DepNode(Symbol o, bool p, bool r)
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900105 : output(o),
106 has_rule(false),
Colin Cross5b26db32015-09-29 16:51:02 -0700107 is_default_target(false),
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900108 is_phony(p),
109 is_restat(r),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900110 rule_vars(NULL),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900111 depfile_var(NULL),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900112 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900113 g_dep_node_pool->push_back(this);
114}
115
116class DepBuilder {
117 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900118 DepBuilder(Evaluator* ev,
119 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900120 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900121 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900122 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900123 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900124 first_rule_(NULL),
125 depfile_var_name_(Intern(".KATI_DEPFILE")) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900126 PopulateRules(rules);
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900127 LOG_STAT("%zu variables", ev->mutable_vars()->size());
128 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900129 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900130 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900131
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900132 auto found = rules_.find(Intern(".PHONY"));
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900133 if (found != rules_.end()) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900134 for (Symbol input : found->second->inputs) {
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900135 phony_.insert(input);
136 }
137 }
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900138 found = rules_.find(Intern(".KATI_RESTAT"));
139 if (found != rules_.end()) {
140 for (Symbol input : found->second->inputs) {
141 restat_.insert(input);
142 }
143 }
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900144 found = rules_.find(Intern(".SUFFIXES"));
145 if (found != rules_.end()) {
146 if (found->second->inputs.empty()) {
147 suffix_rules_.clear();
148 } else {
149 WARN("%s:%d: kati doesn't support .SUFFIXES with prerequisites",
150 LOCF(found->second->loc));
151 }
152 }
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900153
154 // Note we can safely ignore .DELETE_ON_ERROR for --ninja mode.
155 static const char* kUnsupportedBuiltinTargets[] = {
156 ".DEFAULT",
157 ".PRECIOUS",
158 ".INTERMEDIATE",
159 ".SECONDARY",
160 ".SECONDEXPANSION",
161 ".IGNORE",
162 ".LOW_RESOLUTION_TIME",
163 ".SILENT",
164 ".EXPORT_ALL_VARIABLES",
165 ".NOTPARALLEL",
166 ".ONESHELL",
167 ".POSIX",
168 NULL
169 };
170 for (const char** p = kUnsupportedBuiltinTargets; *p; p++) {
171 auto found = rules_.find(Intern(*p));
172 if (found != rules_.end()) {
173 WARN("%s:%d: kati doesn't support %s", LOCF(found->second->loc), *p);
174 }
175 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900176 }
177
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900178 ~DepBuilder() {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900179 }
180
Shinichiro Hamajia62b02a2015-10-01 14:21:40 +0900181 void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
Colin Cross5b26db32015-09-29 16:51:02 -0700182 if (!first_rule_) {
183 ERROR("*** No targets.");
184 }
185 CHECK(!first_rule_->outputs.empty());
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900186
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900187 if (!g_flags.gen_all_targets && targets.empty()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900188 targets.push_back(first_rule_->outputs[0]);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900189 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900190 if (g_flags.gen_all_targets) {
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900191 unordered_set<Symbol> non_root_targets;
192 for (const auto& p : rules_) {
193 for (Symbol t : p.second->inputs)
194 non_root_targets.insert(t);
195 for (Symbol t : p.second->order_only_inputs)
196 non_root_targets.insert(t);
197 }
198
199 for (const auto& p : rules_) {
200 Symbol t = p.first;
201 if (!non_root_targets.count(t)) {
202 targets.push_back(p.first);
203 }
204 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900205 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900206
207 // TODO: LogStats?
208
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900209 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900210 cur_rule_vars_.reset(new Vars);
211 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900212 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900213 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900214 ev_->set_current_scope(NULL);
215 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900216 }
217 }
218
219 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900220 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900221 auto found = rules_.find(target);
222 if (found != rules_.end())
223 return true;
224 if (phony_.count(target))
225 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900226 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900227 }
228
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900229 void PopulateRules(const vector<shared_ptr<Rule>>& rules) {
230 for (shared_ptr<Rule> rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900231 if (rule->outputs.empty()) {
232 PopulateImplicitRule(rule);
233 } else {
234 PopulateExplicitRule(rule);
235 }
236 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900237 for (auto& p : suffix_rules_) {
238 reverse(p.second.begin(), p.second.end());
239 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900240 }
241
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900242 bool PopulateSuffixRule(shared_ptr<Rule> rule, Symbol output) {
243 if (output.empty() || output.str()[0] != '.')
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900244 return false;
245
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900246 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900247 size_t dot_index = rest.find('.');
248 // If there is only a single dot or the third dot, this is not a
249 // suffix rule.
250 if (dot_index == string::npos ||
251 rest.substr(dot_index+1).find('.') != string::npos) {
252 return false;
253 }
254
255 StringPiece input_suffix = rest.substr(0, dot_index);
256 StringPiece output_suffix = rest.substr(dot_index+1);
257 shared_ptr<Rule> r = make_shared<Rule>(*rule);
258 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900259 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900260 r->is_suffix_rule = true;
261 suffix_rules_[output_suffix].push_back(r);
262 return true;
263 }
264
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900265 void ApplyOutputPattern(const Rule& r,
266 Symbol output,
267 const vector<Symbol>& inputs,
268 vector<Symbol>* out_inputs) {
269 if (inputs.empty())
270 return;
271 if (r.is_suffix_rule) {
272 for (Symbol input : inputs) {
273 out_inputs->push_back(ReplaceSuffix(output, input));
274 }
275 return;
276 }
277 if (r.output_patterns.empty()) {
278 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
279 return;
280 }
281 CHECK(r.output_patterns.size() == 1);
282 Pattern pat(r.output_patterns[0].str());
283 for (Symbol input : inputs) {
284 string buf;
285 pat.AppendSubst(output.str(), input.str(), &buf);
286 out_inputs->push_back(Intern(buf));
287 }
288 }
289
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900290 shared_ptr<Rule> MergeRules(const Rule& old_rule,
291 const Rule& rule,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900292 Symbol output,
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900293 bool is_suffix_rule) {
294 if (old_rule.is_double_colon != rule.is_double_colon) {
295 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900296 LOCF(rule.loc), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900297 }
298 if (!old_rule.cmds.empty() && !rule.cmds.empty() &&
299 !is_suffix_rule && !rule.is_double_colon) {
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900300 WARN("%s:%d: warning: overriding commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900301 LOCF(rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900302 WARN("%s:%d: warning: ignoring old commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900303 LOCF(old_rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900304 }
305
306 shared_ptr<Rule> r = make_shared<Rule>(rule);
307 if (rule.is_double_colon) {
308 r->cmds.clear();
309 for (Value* c : old_rule.cmds)
310 r->cmds.push_back(c);
311 for (Value* c : rule.cmds)
312 r->cmds.push_back(c);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900313 if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
314 rule.output_patterns != old_rule.output_patterns) {
Shinichiro Hamaji88150d42016-02-01 16:51:29 +0900315 ERROR("%s:%d: TODO: merging two double colon rules with output "
316 "patterns is not supported", LOCF(rule.loc));
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900317 }
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900318 } else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
319 r->cmds = old_rule.cmds;
320 }
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900321
Shinichiro Hamaji2e23e4a2015-06-26 07:33:16 +0900322 // If the latter rule has a command (regardless of the commands in
323 // |old_rule|), inputs in the latter rule has a priority.
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900324 if (rule.cmds.empty()) {
325 r->inputs = old_rule.inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900326 ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900327 r->order_only_inputs = old_rule.order_only_inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900328 ApplyOutputPattern(rule, output, rule.order_only_inputs,
329 &r->order_only_inputs);
330 r->output_patterns = old_rule.output_patterns;
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900331 } else {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900332 ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
333 ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
334 &r->order_only_inputs);
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900335 }
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900336 r->is_default_target |= old_rule.is_default_target;
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900337 return r;
338 }
339
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900340 void PopulateExplicitRule(shared_ptr<Rule> orig_rule) {
341 for (Symbol output : orig_rule->outputs) {
342 const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900343
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900344 shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900345 rule->outputs.clear();
346 rule->outputs.push_back(output);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900347
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900348 auto p = rules_.insert(make_pair(output, rule));
349 if (p.second) {
350 if (!first_rule_ && output.get(0) != '.') {
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900351 rule->is_default_target = true;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900352 first_rule_ = rule;
353 }
354 } else {
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900355 p.first->second =
356 MergeRules(*p.first->second, *rule, output, is_suffix_rule);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900357 }
358 }
359 }
360
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900361 void PopulateImplicitRule(shared_ptr<Rule> rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900362 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900363 implicit_rules_->Add(output_pattern.str(), rule.get());
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900364 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900365 }
366
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900367 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900368 auto found = rules_.find(o);
369 if (found != rules_.end())
370 return found->second;
371 return NULL;
372 }
373
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900374 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900375 auto found = rule_vars_.find(o);
376 if (found != rule_vars_.end())
377 return found->second;
378 return NULL;
379 }
380
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900381 bool CanPickImplicitRule(const Rule* rule, Symbol output, DepNode* n,
382 shared_ptr<Rule>* out_rule) {
383 Symbol matched(Symbol::IsUninitialized{});
384 for (Symbol output_pattern : rule->output_patterns) {
385 Pattern pat(output_pattern.str());
386 if (pat.Match(output.str())) {
387 bool ok = true;
388 for (Symbol input : rule->inputs) {
389 string buf;
390 pat.AppendSubst(output.str(), input.str(), &buf);
391 if (!Exists(Intern(buf))) {
392 ok = false;
393 break;
394 }
395 }
396
397 if (ok) {
398 matched = output_pattern;
399 break;
400 }
401 }
402 }
403 if (!matched.IsValid())
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900404 return false;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900405
406 *out_rule = make_shared<Rule>(*rule);
407 if ((*out_rule)->output_patterns.size() > 1) {
408 // We should mark all other output patterns as used.
409 Pattern pat(matched.str());
410 for (Symbol output_pattern : rule->output_patterns) {
411 if (output_pattern == matched)
412 continue;
413 string buf;
414 pat.AppendSubst(output.str(), output_pattern.str(), &buf);
415 done_[Intern(buf)] = n;
416 }
417 (*out_rule)->output_patterns.clear();
418 (*out_rule)->output_patterns.push_back(matched);
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900419 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900420
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900421 return true;
422 }
423
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900424 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900425 auto found = rule_vars_.find(output);
426 if (found == rule_vars_.end())
427 return vars;
428 if (vars == NULL)
429 return found->second;
430 // TODO: leak.
431 Vars* r = new Vars(*found->second);
432 for (auto p : *vars) {
433 (*r)[p.first] = p.second;
434 }
435 return r;
436 }
437
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900438 bool PickRule(Symbol output, DepNode* n,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900439 shared_ptr<Rule>* out_rule, Vars** out_var) {
440 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900441 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900442 *out_rule = rule;
443 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900444 if (rule) {
445 if (!rule->cmds.empty()) {
446 return true;
447 }
448 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900449
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900450 vector<const Rule*> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900451 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900452 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900453 shared_ptr<Rule> irule;
454 if (!CanPickImplicitRule(*iter, output, n, &irule))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900455 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900456 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900457 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900458 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900459 r->inputs.clear();
460 r->inputs = irule->inputs;
461 copy(rule->inputs.begin(), rule->inputs.end(),
462 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900463 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900464 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900465 r->loc = irule->loc;
466 r->cmd_lineno = irule->cmd_lineno;
467 *out_rule = r;
468 return true;
469 }
Shinichiro Hamaji271c5802016-01-26 15:11:57 +0900470 CHECK(irule->output_patterns.size() == 1);
471 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
472 *out_var = vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900473 *out_rule = make_shared<Rule>(*irule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900474 return true;
475 }
476
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900477 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900478 if (output_suffix.get(0) != '.')
479 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900480 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900481
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900482 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
483 if (found == suffix_rules_.end())
484 return rule.get();
485
486 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900487 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900488 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900489 if (!Exists(input))
490 continue;
491
492 if (rule) {
493 shared_ptr<Rule> r = make_shared<Rule>(*rule);
494 r->inputs.insert(r->inputs.begin(), input);
495 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900496 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900497 r->loc = irule->loc;
498 r->cmd_lineno = irule->cmd_lineno;
499 *out_rule = r;
500 return true;
501 }
502 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900503 CHECK(irule->outputs.size() == 1);
504 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
505 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900506 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900507 *out_rule = irule;
508 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900509 }
510
511 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900512 }
513
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900514 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900515 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900516 output.c_str(),
517 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900518
519 auto found = done_.find(output);
520 if (found != done_.end()) {
521 return found->second;
522 }
523
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900524 DepNode* n = new DepNode(output,
525 phony_.count(output),
526 restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900527 done_[output] = n;
528
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900529 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900530 Vars* vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900531 if (!PickRule(output, n, &rule, &vars)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900532 return n;
533 }
534
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900535 if (rule->output_patterns.size() >= 1) {
536 CHECK(rule->output_patterns.size() == 1);
537 n->output_pattern = rule->output_patterns[0];
538 }
539
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900540 vector<unique_ptr<ScopedVar>> sv;
541 if (vars) {
542 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900543 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900544 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
545 CHECK(var);
546 Var* new_var = var->v();
547 if (var->op() == AssignOp::PLUS_EQ) {
548 Var* old_var = ev_->LookupVar(name);
549 if (old_var->IsDefined()) {
550 // TODO: This would be incorrect and has a leak.
551 shared_ptr<string> s = make_shared<string>();
552 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900553 if (!s->empty())
554 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900555 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900556 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900557 }
558 } else if (var->op() == AssignOp::QUESTION_EQ) {
559 Var* old_var = ev_->LookupVar(name);
560 if (old_var->IsDefined()) {
561 continue;
562 }
563 }
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900564
565 if (name == depfile_var_name_) {
566 n->depfile_var = new_var;
567 } else {
568 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
569 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900570 }
571 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900572
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900573 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
574 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900575 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900576 n->deps.push_back(c);
577 }
578
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900579 vector<Symbol> order_only_inputs;
580 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
581 &order_only_inputs);
582 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900583 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900584 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900585 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900586
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900587 n->has_rule = true;
588 n->cmds = rule->cmds;
Colin Cross5b26db32015-09-29 16:51:02 -0700589 n->is_default_target = rule->is_default_target;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900590 if (cur_rule_vars_->empty()) {
591 n->rule_vars = NULL;
592 } else {
593 n->rule_vars = new Vars;
594 for (auto p : *cur_rule_vars_) {
595 n->rule_vars->insert(p);
596 }
597 }
598 n->loc = rule->loc;
599 if (!rule->cmds.empty() && rule->cmd_lineno)
600 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900601
602 return n;
603 }
604
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900605 Evaluator* ev_;
Dan Willemsenb248caa2015-10-01 16:07:48 -0700606 map<Symbol, shared_ptr<Rule>> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900607 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900608 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900609
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900610 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900611 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
612 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900613
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900614 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900615 unordered_map<Symbol, DepNode*> done_;
616 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900617 unordered_set<Symbol> restat_;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900618 Symbol depfile_var_name_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900619};
620
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900621void MakeDep(Evaluator* ev,
622 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900623 const unordered_map<Symbol, Vars*>& rule_vars,
624 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900625 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900626 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900627 db.Build(targets, nodes);
628}
629
630void InitDepNodePool() {
631 g_dep_node_pool = new vector<DepNode*>;
632}
633
634void QuitDepNodePool() {
635 for (DepNode* n : *g_dep_node_pool)
636 delete n;
637 delete g_dep_node_pool;
638}