blob: faa103d7ca8faeffb320517f31c3a9a77d679453 [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 Hamaji54a3d532016-02-16 17:33:27 +090030#include "stats.h"
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090031#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090032#include "symtab.h"
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +090033#include "timeutil.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090034#include "var.h"
35
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090036namespace {
37
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090038static vector<DepNode*>* g_dep_node_pool;
39
Shinichiro Hamajie7992752015-06-29 18:38:35 +090040static Symbol ReplaceSuffix(Symbol s, Symbol newsuf) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090041 string r;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090042 AppendString(StripExt(s.str()), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090043 r += '.';
Shinichiro Hamajie7992752015-06-29 18:38:35 +090044 AppendString(newsuf.str(), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090045 return Intern(r);
46}
47
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090048class RuleTrie {
49 struct Entry {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090050 Entry(const Rule* r, StringPiece s)
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090051 : rule(r), suffix(s) {
52 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090053 const Rule* rule;
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090054 StringPiece suffix;
55 };
56
57 public:
58 RuleTrie() {}
59 ~RuleTrie() {
60 for (auto& p : children_)
61 delete p.second;
62 }
63
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090064 void Add(StringPiece name, const Rule* rule) {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090065 if (name.empty() || name[0] == '%') {
66 rules_.push_back(Entry(rule, name));
67 return;
68 }
69 const char c = name[0];
70 auto p = children_.emplace(c, nullptr);
71 if (p.second) {
72 p.first->second = new RuleTrie();
73 }
74 p.first->second->Add(name.substr(1), rule);
75 }
76
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090077 void Get(StringPiece name, vector<const Rule*>* rules) const {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090078 for (const Entry& ent : rules_) {
79 if ((ent.suffix.empty() && name.empty()) ||
80 HasSuffix(name, ent.suffix.substr(1))) {
81 rules->push_back(ent.rule);
82 }
83 }
Shinichiro Hamajif772b172015-06-29 16:05:44 +090084 if (name.empty())
85 return;
86 auto found = children_.find(name[0]);
87 if (found != children_.end()) {
88 found->second->Get(name.substr(1), rules);
89 }
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090090 }
91
92 size_t size() const {
93 size_t r = rules_.size();
94 for (const auto& c : children_)
95 r += c.second->size();
96 return r;
97 }
98
99 private:
100 vector<Entry> rules_;
101 unordered_map<char, RuleTrie*> children_;
102};
103
104} // namespace
105
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900106DepNode::DepNode(Symbol o, bool p, bool r)
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900107 : output(o),
108 has_rule(false),
Colin Cross5b26db32015-09-29 16:51:02 -0700109 is_default_target(false),
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900110 is_phony(p),
111 is_restat(r),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900112 rule_vars(NULL),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900113 depfile_var(NULL),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900114 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900115 g_dep_node_pool->push_back(this);
116}
117
118class DepBuilder {
119 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900120 DepBuilder(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900121 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900122 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900123 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900124 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900125 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900126 first_rule_(NULL),
127 depfile_var_name_(Intern(".KATI_DEPFILE")) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900128 ScopedTimeReporter tr("make dep (populate)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900129 PopulateRules(rules);
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900130 LOG_STAT("%zu variables", ev->mutable_vars()->size());
131 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900132 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900133 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900134
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900135 auto found = rules_.find(Intern(".PHONY"));
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900136 if (found != rules_.end()) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900137 for (Symbol input : found->second->inputs) {
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900138 phony_.insert(input);
139 }
140 }
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900141 found = rules_.find(Intern(".KATI_RESTAT"));
142 if (found != rules_.end()) {
143 for (Symbol input : found->second->inputs) {
144 restat_.insert(input);
145 }
146 }
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900147 found = rules_.find(Intern(".SUFFIXES"));
148 if (found != rules_.end()) {
149 if (found->second->inputs.empty()) {
150 suffix_rules_.clear();
151 } else {
152 WARN("%s:%d: kati doesn't support .SUFFIXES with prerequisites",
153 LOCF(found->second->loc));
154 }
155 }
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900156
157 // Note we can safely ignore .DELETE_ON_ERROR for --ninja mode.
158 static const char* kUnsupportedBuiltinTargets[] = {
159 ".DEFAULT",
160 ".PRECIOUS",
161 ".INTERMEDIATE",
162 ".SECONDARY",
163 ".SECONDEXPANSION",
164 ".IGNORE",
165 ".LOW_RESOLUTION_TIME",
166 ".SILENT",
167 ".EXPORT_ALL_VARIABLES",
168 ".NOTPARALLEL",
169 ".ONESHELL",
170 ".POSIX",
171 NULL
172 };
173 for (const char** p = kUnsupportedBuiltinTargets; *p; p++) {
174 auto found = rules_.find(Intern(*p));
175 if (found != rules_.end()) {
176 WARN("%s:%d: kati doesn't support %s", LOCF(found->second->loc), *p);
177 }
178 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900179 }
180
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900181 ~DepBuilder() {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900182 }
183
Shinichiro Hamajia62b02a2015-10-01 14:21:40 +0900184 void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
Colin Cross5b26db32015-09-29 16:51:02 -0700185 if (!first_rule_) {
186 ERROR("*** No targets.");
187 }
188 CHECK(!first_rule_->outputs.empty());
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900189
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900190 if (!g_flags.gen_all_targets && targets.empty()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900191 targets.push_back(first_rule_->outputs[0]);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900192 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900193 if (g_flags.gen_all_targets) {
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900194 unordered_set<Symbol> non_root_targets;
195 for (const auto& p : rules_) {
196 for (Symbol t : p.second->inputs)
197 non_root_targets.insert(t);
198 for (Symbol t : p.second->order_only_inputs)
199 non_root_targets.insert(t);
200 }
201
202 for (const auto& p : rules_) {
203 Symbol t = p.first;
204 if (!non_root_targets.count(t)) {
205 targets.push_back(p.first);
206 }
207 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900208 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900209
210 // TODO: LogStats?
211
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900212 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900213 cur_rule_vars_.reset(new Vars);
214 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900215 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900216 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900217 ev_->set_current_scope(NULL);
218 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900219 }
220 }
221
222 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900223 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900224 auto found = rules_.find(target);
225 if (found != rules_.end())
226 return true;
227 if (phony_.count(target))
228 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900229 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900230 }
231
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900232 void PopulateRules(const vector<const Rule*>& rules) {
233 for (const Rule* rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900234 if (rule->outputs.empty()) {
235 PopulateImplicitRule(rule);
236 } else {
237 PopulateExplicitRule(rule);
238 }
239 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900240 for (auto& p : suffix_rules_) {
241 reverse(p.second.begin(), p.second.end());
242 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900243 }
244
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900245 bool PopulateSuffixRule(const Rule* rule, Symbol output) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900246 if (output.empty() || output.str()[0] != '.')
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900247 return false;
248
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900249 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900250 size_t dot_index = rest.find('.');
251 // If there is only a single dot or the third dot, this is not a
252 // suffix rule.
253 if (dot_index == string::npos ||
254 rest.substr(dot_index+1).find('.') != string::npos) {
255 return false;
256 }
257
258 StringPiece input_suffix = rest.substr(0, dot_index);
259 StringPiece output_suffix = rest.substr(dot_index+1);
260 shared_ptr<Rule> r = make_shared<Rule>(*rule);
261 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900262 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900263 r->is_suffix_rule = true;
264 suffix_rules_[output_suffix].push_back(r);
265 return true;
266 }
267
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900268 void ApplyOutputPattern(const Rule& r,
269 Symbol output,
270 const vector<Symbol>& inputs,
271 vector<Symbol>* out_inputs) {
272 if (inputs.empty())
273 return;
274 if (r.is_suffix_rule) {
275 for (Symbol input : inputs) {
276 out_inputs->push_back(ReplaceSuffix(output, input));
277 }
278 return;
279 }
280 if (r.output_patterns.empty()) {
281 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
282 return;
283 }
284 CHECK(r.output_patterns.size() == 1);
285 Pattern pat(r.output_patterns[0].str());
286 for (Symbol input : inputs) {
287 string buf;
288 pat.AppendSubst(output.str(), input.str(), &buf);
289 out_inputs->push_back(Intern(buf));
290 }
291 }
292
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900293 shared_ptr<Rule> MergeRules(const Rule& old_rule,
294 const Rule& rule,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900295 Symbol output,
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900296 bool is_suffix_rule) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900297 COLLECT_STATS("make dep (merge rule)");
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900298 if (old_rule.is_double_colon != rule.is_double_colon) {
299 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900300 LOCF(rule.loc), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900301 }
302 if (!old_rule.cmds.empty() && !rule.cmds.empty() &&
303 !is_suffix_rule && !rule.is_double_colon) {
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900304 WARN("%s:%d: warning: overriding commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900305 LOCF(rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajiff4584d2015-06-24 17:45:14 +0900306 WARN("%s:%d: warning: ignoring old commands for target `%s'",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900307 LOCF(old_rule.cmd_loc()), output.str().c_str());
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900308 }
309
310 shared_ptr<Rule> r = make_shared<Rule>(rule);
311 if (rule.is_double_colon) {
312 r->cmds.clear();
313 for (Value* c : old_rule.cmds)
314 r->cmds.push_back(c);
315 for (Value* c : rule.cmds)
316 r->cmds.push_back(c);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900317 if (!rule.output_patterns.empty() && !old_rule.output_patterns.empty() &&
318 rule.output_patterns != old_rule.output_patterns) {
Shinichiro Hamaji88150d42016-02-01 16:51:29 +0900319 ERROR("%s:%d: TODO: merging two double colon rules with output "
320 "patterns is not supported", LOCF(rule.loc));
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900321 }
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900322 } else if (!old_rule.cmds.empty() && rule.cmds.empty()) {
323 r->cmds = old_rule.cmds;
324 }
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900325
Shinichiro Hamaji2e23e4a2015-06-26 07:33:16 +0900326 // If the latter rule has a command (regardless of the commands in
327 // |old_rule|), inputs in the latter rule has a priority.
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900328 if (rule.cmds.empty()) {
329 r->inputs = old_rule.inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900330 ApplyOutputPattern(rule, output, rule.inputs, &r->inputs);
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900331 r->order_only_inputs = old_rule.order_only_inputs;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900332 ApplyOutputPattern(rule, output, rule.order_only_inputs,
333 &r->order_only_inputs);
334 r->output_patterns = old_rule.output_patterns;
Shinichiro Hamaji485f9122015-06-26 07:06:14 +0900335 } else {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900336 ApplyOutputPattern(old_rule, output, old_rule.inputs, &r->inputs);
337 ApplyOutputPattern(old_rule, output, old_rule.order_only_inputs,
338 &r->order_only_inputs);
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900339 }
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900340 r->is_default_target |= old_rule.is_default_target;
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900341 return r;
342 }
343
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900344 void PopulateExplicitRule(const Rule* orig_rule) {
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900345 for (Symbol output : orig_rule->outputs) {
346 const bool is_suffix_rule = PopulateSuffixRule(orig_rule, output);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900347
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900348 shared_ptr<Rule> rule = make_shared<Rule>(*orig_rule);
Shinichiro Hamajie36dd562015-06-27 16:34:48 +0900349 rule->outputs.clear();
350 rule->outputs.push_back(output);
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900351
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900352 auto p = rules_.insert(make_pair(output, rule));
353 if (p.second) {
354 if (!first_rule_ && output.get(0) != '.') {
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900355 rule->is_default_target = true;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900356 first_rule_ = rule;
357 }
358 } else {
Shinichiro Hamajie30b3be2015-06-19 16:15:42 +0900359 p.first->second =
360 MergeRules(*p.first->second, *rule, output, is_suffix_rule);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900361 }
362 }
363 }
364
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900365 void PopulateImplicitRule(const Rule* rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900366 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900367 implicit_rules_->Add(output_pattern.str(), rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900368 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900369 }
370
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900371 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900372 auto found = rules_.find(o);
373 if (found != rules_.end())
374 return found->second;
375 return NULL;
376 }
377
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900378 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900379 auto found = rule_vars_.find(o);
380 if (found != rule_vars_.end())
381 return found->second;
382 return NULL;
383 }
384
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900385 bool CanPickImplicitRule(const Rule* rule, Symbol output, DepNode* n,
386 shared_ptr<Rule>* out_rule) {
387 Symbol matched(Symbol::IsUninitialized{});
388 for (Symbol output_pattern : rule->output_patterns) {
389 Pattern pat(output_pattern.str());
390 if (pat.Match(output.str())) {
391 bool ok = true;
392 for (Symbol input : rule->inputs) {
393 string buf;
394 pat.AppendSubst(output.str(), input.str(), &buf);
395 if (!Exists(Intern(buf))) {
396 ok = false;
397 break;
398 }
399 }
400
401 if (ok) {
402 matched = output_pattern;
403 break;
404 }
405 }
406 }
407 if (!matched.IsValid())
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900408 return false;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900409
410 *out_rule = make_shared<Rule>(*rule);
411 if ((*out_rule)->output_patterns.size() > 1) {
412 // We should mark all other output patterns as used.
413 Pattern pat(matched.str());
414 for (Symbol output_pattern : rule->output_patterns) {
415 if (output_pattern == matched)
416 continue;
417 string buf;
418 pat.AppendSubst(output.str(), output_pattern.str(), &buf);
419 done_[Intern(buf)] = n;
420 }
421 (*out_rule)->output_patterns.clear();
422 (*out_rule)->output_patterns.push_back(matched);
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900423 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900424
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900425 return true;
426 }
427
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900428 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900429 auto found = rule_vars_.find(output);
430 if (found == rule_vars_.end())
431 return vars;
432 if (vars == NULL)
433 return found->second;
434 // TODO: leak.
435 Vars* r = new Vars(*found->second);
436 for (auto p : *vars) {
437 (*r)[p.first] = p.second;
438 }
439 return r;
440 }
441
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900442 bool PickRule(Symbol output, DepNode* n,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900443 shared_ptr<Rule>* out_rule, Vars** out_var) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900444 COLLECT_STATS("make dep (pick rule)");
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900445 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900446 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900447 *out_rule = rule;
448 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900449 if (rule) {
450 if (!rule->cmds.empty()) {
451 return true;
452 }
453 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900454
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900455 vector<const Rule*> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900456 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900457 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900458 shared_ptr<Rule> irule;
459 if (!CanPickImplicitRule(*iter, output, n, &irule))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900460 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900461 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900462 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900463 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900464 r->inputs.clear();
465 r->inputs = irule->inputs;
466 copy(rule->inputs.begin(), rule->inputs.end(),
467 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900468 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900469 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900470 r->loc = irule->loc;
471 r->cmd_lineno = irule->cmd_lineno;
472 *out_rule = r;
473 return true;
474 }
Shinichiro Hamaji271c5802016-01-26 15:11:57 +0900475 CHECK(irule->output_patterns.size() == 1);
476 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
477 *out_var = vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900478 *out_rule = make_shared<Rule>(*irule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900479 return true;
480 }
481
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900482 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900483 if (output_suffix.get(0) != '.')
484 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900485 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900486
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900487 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
488 if (found == suffix_rules_.end())
489 return rule.get();
490
491 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900492 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900493 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900494 if (!Exists(input))
495 continue;
496
497 if (rule) {
498 shared_ptr<Rule> r = make_shared<Rule>(*rule);
499 r->inputs.insert(r->inputs.begin(), input);
500 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900501 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900502 r->loc = irule->loc;
503 r->cmd_lineno = irule->cmd_lineno;
504 *out_rule = r;
505 return true;
506 }
507 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900508 CHECK(irule->outputs.size() == 1);
509 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
510 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900511 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900512 *out_rule = irule;
513 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900514 }
515
516 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900517 }
518
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900519 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900520 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900521 output.c_str(),
522 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900523
524 auto found = done_.find(output);
525 if (found != done_.end()) {
526 return found->second;
527 }
528
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900529 DepNode* n = new DepNode(output,
530 phony_.count(output),
531 restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900532 done_[output] = n;
533
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900534 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900535 Vars* vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900536 if (!PickRule(output, n, &rule, &vars)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900537 return n;
538 }
539
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900540 if (rule->output_patterns.size() >= 1) {
541 CHECK(rule->output_patterns.size() == 1);
542 n->output_pattern = rule->output_patterns[0];
543 }
544
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900545 vector<unique_ptr<ScopedVar>> sv;
546 if (vars) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900547 COLLECT_STATS("make dep (create scope)");
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900548 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900549 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900550 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
551 CHECK(var);
552 Var* new_var = var->v();
553 if (var->op() == AssignOp::PLUS_EQ) {
554 Var* old_var = ev_->LookupVar(name);
555 if (old_var->IsDefined()) {
556 // TODO: This would be incorrect and has a leak.
557 shared_ptr<string> s = make_shared<string>();
558 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900559 if (!s->empty())
560 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900561 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900562 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900563 }
564 } else if (var->op() == AssignOp::QUESTION_EQ) {
565 Var* old_var = ev_->LookupVar(name);
566 if (old_var->IsDefined()) {
567 continue;
568 }
569 }
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900570
571 if (name == depfile_var_name_) {
572 n->depfile_var = new_var;
573 } else {
574 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
575 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900576 }
577 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900578
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900579 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
580 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900581 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900582 n->deps.push_back(c);
583 }
584
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900585 vector<Symbol> order_only_inputs;
586 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
587 &order_only_inputs);
588 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900589 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900590 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900591 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900592
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900593 n->has_rule = true;
594 n->cmds = rule->cmds;
Colin Cross5b26db32015-09-29 16:51:02 -0700595 n->is_default_target = rule->is_default_target;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900596 if (cur_rule_vars_->empty()) {
597 n->rule_vars = NULL;
598 } else {
599 n->rule_vars = new Vars;
600 for (auto p : *cur_rule_vars_) {
601 n->rule_vars->insert(p);
602 }
603 }
604 n->loc = rule->loc;
605 if (!rule->cmds.empty() && rule->cmd_lineno)
606 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900607
608 return n;
609 }
610
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900611 Evaluator* ev_;
Dan Willemsenb248caa2015-10-01 16:07:48 -0700612 map<Symbol, shared_ptr<Rule>> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900613 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900614 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900615
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900616 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900617 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
618 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900619
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900620 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900621 unordered_map<Symbol, DepNode*> done_;
622 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900623 unordered_set<Symbol> restat_;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900624 Symbol depfile_var_name_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900625};
626
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900627void MakeDep(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900628 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900629 const unordered_map<Symbol, Vars*>& rule_vars,
630 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900631 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900632 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900633 ScopedTimeReporter tr("make dep (build)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900634 db.Build(targets, nodes);
635}
636
637void InitDepNodePool() {
638 g_dep_node_pool = new vector<DepNode*>;
639}
640
641void QuitDepNodePool() {
642 for (DepNode* n : *g_dep_node_pool)
643 delete n;
644 delete g_dep_node_pool;
645}