blob: 88e84d27bd0bf848da2e835e1e5ab823fb429a25 [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 {
48 Entry(shared_ptr<Rule> r, StringPiece s)
49 : rule(r), suffix(s) {
50 }
51 shared_ptr<Rule> rule;
52 StringPiece suffix;
53 };
54
55 public:
56 RuleTrie() {}
57 ~RuleTrie() {
58 for (auto& p : children_)
59 delete p.second;
60 }
61
62 void Add(StringPiece name, shared_ptr<Rule> rule) {
63 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 Hamajif772b172015-06-29 16:05:44 +090075 void Get(StringPiece name, vector<shared_ptr<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),
111 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900112 g_dep_node_pool->push_back(this);
113}
114
115class DepBuilder {
116 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900117 DepBuilder(Evaluator* ev,
118 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900119 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900120 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900121 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900122 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900123 first_rule_(NULL) {
124 PopulateRules(rules);
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900125 LOG_STAT("%zu variables", ev->mutable_vars()->size());
126 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900127 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900128 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900129
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900130 auto found = rules_.find(Intern(".PHONY"));
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900131 if (found != rules_.end()) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900132 for (Symbol input : found->second->inputs) {
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900133 phony_.insert(input);
134 }
135 }
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900136 found = rules_.find(Intern(".KATI_RESTAT"));
137 if (found != rules_.end()) {
138 for (Symbol input : found->second->inputs) {
139 restat_.insert(input);
140 }
141 }
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900142 found = rules_.find(Intern(".SUFFIXES"));
143 if (found != rules_.end()) {
144 if (found->second->inputs.empty()) {
145 suffix_rules_.clear();
146 } else {
147 WARN("%s:%d: kati doesn't support .SUFFIXES with prerequisites",
148 LOCF(found->second->loc));
149 }
150 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900151 }
152
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900153 ~DepBuilder() {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900154 }
155
Shinichiro Hamajia62b02a2015-10-01 14:21:40 +0900156 void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
Colin Cross5b26db32015-09-29 16:51:02 -0700157 if (!first_rule_) {
158 ERROR("*** No targets.");
159 }
160 CHECK(!first_rule_->outputs.empty());
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900161
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900162 if (!g_flags.gen_all_targets && targets.empty()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900163 targets.push_back(first_rule_->outputs[0]);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900164 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900165 if (g_flags.gen_all_targets) {
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900166 unordered_set<Symbol> non_root_targets;
167 for (const auto& p : rules_) {
168 for (Symbol t : p.second->inputs)
169 non_root_targets.insert(t);
170 for (Symbol t : p.second->order_only_inputs)
171 non_root_targets.insert(t);
172 }
173
174 for (const auto& p : rules_) {
175 Symbol t = p.first;
176 if (!non_root_targets.count(t)) {
177 targets.push_back(p.first);
178 }
179 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900180 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900181
182 // TODO: LogStats?
183
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900184 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900185 cur_rule_vars_.reset(new Vars);
186 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900187 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900188 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900189 ev_->set_current_scope(NULL);
190 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900191 }
192 }
193
194 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900195 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900196 auto found = rules_.find(target);
197 if (found != rules_.end())
198 return true;
199 if (phony_.count(target))
200 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900201 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900202 }
203
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900204 void PopulateRules(const vector<shared_ptr<Rule>>& rules) {
205 for (shared_ptr<Rule> rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900206 if (rule->outputs.empty()) {
207 PopulateImplicitRule(rule);
208 } else {
209 PopulateExplicitRule(rule);
210 }
211 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900212 for (auto& p : suffix_rules_) {
213 reverse(p.second.begin(), p.second.end());
214 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900215 }
216
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900217 bool PopulateSuffixRule(shared_ptr<Rule> rule, Symbol output) {
218 if (output.empty() || output.str()[0] != '.')
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900219 return false;
220
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900221 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900222 size_t dot_index = rest.find('.');
223 // If there is only a single dot or the third dot, this is not a
224 // suffix rule.
225 if (dot_index == string::npos ||
226 rest.substr(dot_index+1).find('.') != string::npos) {
227 return false;
228 }
229
230 StringPiece input_suffix = rest.substr(0, dot_index);
231 StringPiece output_suffix = rest.substr(dot_index+1);
232 shared_ptr<Rule> r = make_shared<Rule>(*rule);
233 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900234 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900235 r->is_suffix_rule = true;
236 suffix_rules_[output_suffix].push_back(r);
237 return true;
238 }
239
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900240 void ApplyOutputPattern(const Rule& r,
241 Symbol output,
242 const vector<Symbol>& inputs,
243 vector<Symbol>* out_inputs) {
244 if (inputs.empty())
245 return;
246 if (r.is_suffix_rule) {
247 for (Symbol input : inputs) {
248 out_inputs->push_back(ReplaceSuffix(output, input));
249 }
250 return;
251 }
252 if (r.output_patterns.empty()) {
253 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
254 return;
255 }
256 CHECK(r.output_patterns.size() == 1);
257 Pattern pat(r.output_patterns[0].str());
258 for (Symbol input : inputs) {
259 string buf;
260 pat.AppendSubst(output.str(), input.str(), &buf);
261 out_inputs->push_back(Intern(buf));
262 }
263 }
264
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900265 shared_ptr<Rule> MergeRules(const Rule& old_rule,
266 const Rule& rule,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900267 Symbol output,
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900268 bool is_suffix_rule) {
269 if (old_rule.is_double_colon != rule.is_double_colon) {
270 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900271 LOCF(rule.loc), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900272 }
273 if (!old_rule.cmds.empty() && !rule.cmds.empty() &&
274 !is_suffix_rule && !rule.is_double_colon) {
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900275 WARN("%s:%d: warning: overriding commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900276 LOCF(rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900277 WARN("%s:%d: warning: ignoring old commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900278 LOCF(old_rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900279 }
280
281 shared_ptr<Rule> r = make_shared<Rule>(rule);
282 if (rule.is_double_colon) {
283 r->cmds.clear();
284 for (Value* c : old_rule.cmds)
285 r->cmds.push_back(c);
286 for (Value* c : rule.cmds)
287 r->cmds.push_back(c);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900288 if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
289 rule.output_patterns != old_rule.output_patterns) {
290 ERROR("%s:%d: TODO: merging two double rules with output patterns "
291 "is not supported", LOCF(rule.loc));
292 }
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900293 } else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
294 r->cmds = old_rule.cmds;
295 }
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900296
Shinichiro Hamaji2e23e4a2015-06-26 07:33:16 +0900297 // If the latter rule has a command (regardless of the commands in
298 // |old_rule|), inputs in the latter rule has a priority.
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900299 if (rule.cmds.empty()) {
300 r->inputs = old_rule.inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900301 ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900302 r->order_only_inputs = old_rule.order_only_inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900303 ApplyOutputPattern(rule, output, rule.order_only_inputs,
304 &r->order_only_inputs);
305 r->output_patterns = old_rule.output_patterns;
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900306 } else {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900307 ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
308 ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
309 &r->order_only_inputs);
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900310 }
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900311 r->is_default_target |= old_rule.is_default_target;
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900312 return r;
313 }
314
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900315 void PopulateExplicitRule(shared_ptr<Rule> orig_rule) {
316 for (Symbol output : orig_rule->outputs) {
317 const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900318
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900319 shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900320 rule->outputs.clear();
321 rule->outputs.push_back(output);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900322
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900323 auto p = rules_.insert(make_pair(output, rule));
324 if (p.second) {
325 if (!first_rule_ && output.get(0) != '.') {
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900326 rule->is_default_target = true;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900327 first_rule_ = rule;
328 }
329 } else {
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900330 p.first->second =
331 MergeRules(*p.first->second, *rule, output, is_suffix_rule);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900332 }
333 }
334 }
335
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900336 void PopulateImplicitRule(shared_ptr<Rule> rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900337 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900338 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900339 r->output_patterns.clear();
340 r->output_patterns.push_back(output_pattern);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900341 implicit_rules_->Add(output_pattern.str(), r);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900342 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900343 }
344
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900345 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900346 auto found = rules_.find(o);
347 if (found != rules_.end())
348 return found->second;
349 return NULL;
350 }
351
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900352 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900353 auto found = rule_vars_.find(o);
354 if (found != rule_vars_.end())
355 return found->second;
356 return NULL;
357 }
358
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900359 bool CanPickImplicitRule(shared_ptr<Rule> rule, Symbol output) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900360 CHECK(rule->output_patterns.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900361 Pattern pat(rule->output_patterns[0].str());
362 if (!pat.Match(output.str())) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900363 return false;
364 }
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900365 for (Symbol input : rule->inputs) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900366 string buf;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900367 pat.AppendSubst(output.str(), input.str(), &buf);
368 if (!Exists(Intern(buf)))
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900369 return false;
370 }
371 return true;
372 }
373
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900374 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900375 auto found = rule_vars_.find(output);
376 if (found == rule_vars_.end())
377 return vars;
378 if (vars == NULL)
379 return found->second;
380 // TODO: leak.
381 Vars* r = new Vars(*found->second);
382 for (auto p : *vars) {
383 (*r)[p.first] = p.second;
384 }
385 return r;
386 }
387
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900388 bool PickRule(Symbol output,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900389 shared_ptr<Rule>* out_rule, Vars** out_var) {
390 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900391 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900392 *out_rule = rule;
393 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900394 if (rule) {
395 if (!rule->cmds.empty()) {
396 return true;
397 }
398 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900399
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900400 vector<shared_ptr<Rule>> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900401 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900402 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
403 shared_ptr<Rule> irule = *iter;
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900404 if (!CanPickImplicitRule(irule, output))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900405 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900406 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900407 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900408 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900409 r->inputs.clear();
410 r->inputs = irule->inputs;
411 copy(rule->inputs.begin(), rule->inputs.end(),
412 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900413 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900414 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900415 r->loc = irule->loc;
416 r->cmd_lineno = irule->cmd_lineno;
417 *out_rule = r;
418 return true;
419 }
420 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900421 CHECK(irule->output_patterns.size() == 1);
422 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
423 *out_var = vars;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900424 }
425 *out_rule = irule;
426 return true;
427 }
428
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900429 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900430 if (output_suffix.get(0) != '.')
431 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900432 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900433
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900434 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
435 if (found == suffix_rules_.end())
436 return rule.get();
437
438 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900439 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900440 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900441 if (!Exists(input))
442 continue;
443
444 if (rule) {
445 shared_ptr<Rule> r = make_shared<Rule>(*rule);
446 r->inputs.insert(r->inputs.begin(), input);
447 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900448 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900449 r->loc = irule->loc;
450 r->cmd_lineno = irule->cmd_lineno;
451 *out_rule = r;
452 return true;
453 }
454 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900455 CHECK(irule->outputs.size() == 1);
456 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
457 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900458 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900459 *out_rule = irule;
460 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900461 }
462
463 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900464 }
465
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900466 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900467 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900468 output.c_str(),
469 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900470
471 auto found = done_.find(output);
472 if (found != done_.end()) {
473 return found->second;
474 }
475
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900476 DepNode* n = new DepNode(output,
477 phony_.count(output),
478 restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900479 done_[output] = n;
480
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900481 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900482 Vars* vars;
483 if (!PickRule(output, &rule, &vars)) {
484 return n;
485 }
486
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900487 if (rule->output_patterns.size() >= 1) {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900488 if (rule->output_patterns.size() != 1) {
489 fprintf(stderr, "hmm %s\n", rule->DebugString().c_str());
490 }
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900491 CHECK(rule->output_patterns.size() == 1);
492 n->output_pattern = rule->output_patterns[0];
493 }
494
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900495 vector<unique_ptr<ScopedVar>> sv;
496 if (vars) {
497 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900498 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900499 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
500 CHECK(var);
501 Var* new_var = var->v();
502 if (var->op() == AssignOp::PLUS_EQ) {
503 Var* old_var = ev_->LookupVar(name);
504 if (old_var->IsDefined()) {
505 // TODO: This would be incorrect and has a leak.
506 shared_ptr<string> s = make_shared<string>();
507 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900508 if (!s->empty())
509 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900510 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900511 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900512 }
513 } else if (var->op() == AssignOp::QUESTION_EQ) {
514 Var* old_var = ev_->LookupVar(name);
515 if (old_var->IsDefined()) {
516 continue;
517 }
518 }
Shinichiro Hamajie978a892015-08-17 16:53:40 +0900519 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900520 }
521 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900522
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900523 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
524 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900525 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900526 n->deps.push_back(c);
527 }
528
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900529 vector<Symbol> order_only_inputs;
530 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
531 &order_only_inputs);
532 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900533 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900534 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900535 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900536
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900537 n->has_rule = true;
538 n->cmds = rule->cmds;
Colin Cross5b26db32015-09-29 16:51:02 -0700539 n->is_default_target = rule->is_default_target;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900540 if (cur_rule_vars_->empty()) {
541 n->rule_vars = NULL;
542 } else {
543 n->rule_vars = new Vars;
544 for (auto p : *cur_rule_vars_) {
545 n->rule_vars->insert(p);
546 }
547 }
548 n->loc = rule->loc;
549 if (!rule->cmds.empty() && rule->cmd_lineno)
550 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900551
552 return n;
553 }
554
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900555 Evaluator* ev_;
Dan Willemsenb248caa2015-10-01 16:07:48 -0700556 map<Symbol, shared_ptr<Rule>> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900557 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900558 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900559
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900560 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900561 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
562 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900563
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900564 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900565 unordered_map<Symbol, DepNode*> done_;
566 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900567 unordered_set<Symbol> restat_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900568};
569
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900570void MakeDep(Evaluator* ev,
571 const vector<shared_ptr<Rule>>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900572 const unordered_map<Symbol, Vars*>& rule_vars,
573 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900574 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900575 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900576 db.Build(targets, nodes);
577}
578
579void InitDepNodePool() {
580 g_dep_node_pool = new vector<DepNode*>;
581}
582
583void QuitDepNodePool() {
584 for (DepNode* n : *g_dep_node_pool)
585 delete n;
586 delete g_dep_node_pool;
587}