blob: 8da6156941dff620dcbe3959b395802cd6c2a5d5 [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 Hamaji0a6e2a42016-02-16 19:21:26 +0900365 static bool IsIgnorableImplicitRule(const Rule* rule) {
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900366 // As kati doesn't have RCS/SCCS related default rules, we can
367 // safely ignore suppression for them.
368 if (rule->inputs.size() != 1)
369 return false;
370 if (!rule->order_only_inputs.empty())
371 return false;
372 if (!rule->cmds.empty())
373 return false;
374 const string& i = rule->inputs[0].str();
375 return (i == "RCS/%,v" || i == "RCS/%" || i == "%,v" ||
376 i == "s.%" || i == "SCCS/s.%");
377 }
378
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900379 void PopulateImplicitRule(const Rule* rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900380 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0a6e2a42016-02-16 19:21:26 +0900381 if (output_pattern.str() != "%" || !IsIgnorableImplicitRule(rule))
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900382 implicit_rules_->Add(output_pattern.str(), rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900383 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900384 }
385
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900386 shared_ptr<Rule> LookupRule(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900387 auto found = rules_.find(o);
388 if (found != rules_.end())
389 return found->second;
390 return NULL;
391 }
392
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900393 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900394 auto found = rule_vars_.find(o);
395 if (found != rule_vars_.end())
396 return found->second;
397 return NULL;
398 }
399
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900400 bool CanPickImplicitRule(const Rule* rule, Symbol output, DepNode* n,
401 shared_ptr<Rule>* out_rule) {
402 Symbol matched(Symbol::IsUninitialized{});
403 for (Symbol output_pattern : rule->output_patterns) {
404 Pattern pat(output_pattern.str());
405 if (pat.Match(output.str())) {
406 bool ok = true;
407 for (Symbol input : rule->inputs) {
408 string buf;
409 pat.AppendSubst(output.str(), input.str(), &buf);
410 if (!Exists(Intern(buf))) {
411 ok = false;
412 break;
413 }
414 }
415
416 if (ok) {
417 matched = output_pattern;
418 break;
419 }
420 }
421 }
422 if (!matched.IsValid())
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900423 return false;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900424
425 *out_rule = make_shared<Rule>(*rule);
426 if ((*out_rule)->output_patterns.size() > 1) {
427 // We should mark all other output patterns as used.
428 Pattern pat(matched.str());
429 for (Symbol output_pattern : rule->output_patterns) {
430 if (output_pattern == matched)
431 continue;
432 string buf;
433 pat.AppendSubst(output.str(), output_pattern.str(), &buf);
434 done_[Intern(buf)] = n;
435 }
436 (*out_rule)->output_patterns.clear();
437 (*out_rule)->output_patterns.push_back(matched);
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900438 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900439
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900440 return true;
441 }
442
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900443 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900444 auto found = rule_vars_.find(output);
445 if (found == rule_vars_.end())
446 return vars;
447 if (vars == NULL)
448 return found->second;
449 // TODO: leak.
450 Vars* r = new Vars(*found->second);
451 for (auto p : *vars) {
452 (*r)[p.first] = p.second;
453 }
454 return r;
455 }
456
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900457 bool PickRule(Symbol output, DepNode* n,
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900458 shared_ptr<Rule>* out_rule, Vars** out_var) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900459 COLLECT_STATS("make dep (pick rule)");
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900460 shared_ptr<Rule> rule = LookupRule(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900461 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900462 *out_rule = rule;
463 *out_var = vars;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900464 if (rule) {
465 if (!rule->cmds.empty()) {
466 return true;
467 }
468 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900469
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900470 vector<const Rule*> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900471 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900472 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900473 shared_ptr<Rule> irule;
474 if (!CanPickImplicitRule(*iter, output, n, &irule))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900475 continue;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900476 if (rule) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900477 shared_ptr<Rule> r = make_shared<Rule>(*rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900478 r->output_patterns = irule->output_patterns;
Shinichiro Hamajid2c0fe12015-06-26 07:42:53 +0900479 r->inputs.clear();
480 r->inputs = irule->inputs;
481 copy(rule->inputs.begin(), rule->inputs.end(),
482 back_inserter(r->inputs));
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900483 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900484 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900485 r->loc = irule->loc;
486 r->cmd_lineno = irule->cmd_lineno;
487 *out_rule = r;
488 return true;
489 }
Shinichiro Hamaji271c5802016-01-26 15:11:57 +0900490 CHECK(irule->output_patterns.size() == 1);
491 vars = MergeImplicitRuleVars(irule->output_patterns[0], vars);
492 *out_var = vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900493 *out_rule = make_shared<Rule>(*irule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900494 return true;
495 }
496
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900497 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900498 if (output_suffix.get(0) != '.')
499 return rule.get();
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900500 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900501
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900502 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
503 if (found == suffix_rules_.end())
504 return rule.get();
505
506 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900507 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900508 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900509 if (!Exists(input))
510 continue;
511
512 if (rule) {
513 shared_ptr<Rule> r = make_shared<Rule>(*rule);
514 r->inputs.insert(r->inputs.begin(), input);
515 r->cmds = irule->cmds;
Shinichiro Hamajiaf2b7c62015-10-03 11:24:39 +0900516 r->is_default_target |= irule->is_default_target;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900517 r->loc = irule->loc;
518 r->cmd_lineno = irule->cmd_lineno;
519 *out_rule = r;
520 return true;
521 }
522 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900523 CHECK(irule->outputs.size() == 1);
524 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
525 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900526 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900527 *out_rule = irule;
528 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900529 }
530
531 return rule.get();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900532 }
533
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900534 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900535 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900536 output.c_str(),
537 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900538
539 auto found = done_.find(output);
540 if (found != done_.end()) {
541 return found->second;
542 }
543
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900544 DepNode* n = new DepNode(output,
545 phony_.count(output),
546 restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900547 done_[output] = n;
548
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900549 shared_ptr<Rule> rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900550 Vars* vars;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900551 if (!PickRule(output, n, &rule, &vars)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900552 return n;
553 }
554
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900555 if (rule->output_patterns.size() >= 1) {
556 CHECK(rule->output_patterns.size() == 1);
557 n->output_pattern = rule->output_patterns[0];
558 }
559
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900560 vector<unique_ptr<ScopedVar>> sv;
561 if (vars) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900562 COLLECT_STATS("make dep (create scope)");
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900563 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900564 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900565 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
566 CHECK(var);
567 Var* new_var = var->v();
568 if (var->op() == AssignOp::PLUS_EQ) {
569 Var* old_var = ev_->LookupVar(name);
570 if (old_var->IsDefined()) {
571 // TODO: This would be incorrect and has a leak.
572 shared_ptr<string> s = make_shared<string>();
573 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900574 if (!s->empty())
575 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900576 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900577 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900578 }
579 } else if (var->op() == AssignOp::QUESTION_EQ) {
580 Var* old_var = ev_->LookupVar(name);
581 if (old_var->IsDefined()) {
582 continue;
583 }
584 }
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900585
586 if (name == depfile_var_name_) {
587 n->depfile_var = new_var;
588 } else {
589 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
590 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900591 }
592 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900593
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900594 ApplyOutputPattern(*rule, output, rule->inputs, &n->actual_inputs);
595 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900596 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900597 n->deps.push_back(c);
598 }
599
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900600 vector<Symbol> order_only_inputs;
601 ApplyOutputPattern(*rule, output, rule->order_only_inputs,
602 &order_only_inputs);
603 for (Symbol input : order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900604 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900605 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900606 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900607
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900608 n->has_rule = true;
609 n->cmds = rule->cmds;
Colin Cross5b26db32015-09-29 16:51:02 -0700610 n->is_default_target = rule->is_default_target;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900611 if (cur_rule_vars_->empty()) {
612 n->rule_vars = NULL;
613 } else {
614 n->rule_vars = new Vars;
615 for (auto p : *cur_rule_vars_) {
616 n->rule_vars->insert(p);
617 }
618 }
619 n->loc = rule->loc;
620 if (!rule->cmds.empty() && rule->cmd_lineno)
621 n->loc.lineno = rule->cmd_lineno;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900622
623 return n;
624 }
625
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900626 Evaluator* ev_;
Dan Willemsenb248caa2015-10-01 16:07:48 -0700627 map<Symbol, shared_ptr<Rule>> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900628 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900629 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900630
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900631 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900632 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
633 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900634
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900635 shared_ptr<Rule> first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900636 unordered_map<Symbol, DepNode*> done_;
637 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900638 unordered_set<Symbol> restat_;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900639 Symbol depfile_var_name_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900640};
641
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900642void MakeDep(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900643 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900644 const unordered_map<Symbol, Vars*>& rule_vars,
645 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900646 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900647 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900648 ScopedTimeReporter tr("make dep (build)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900649 db.Build(targets, nodes);
650}
651
652void InitDepNodePool() {
653 g_dep_node_pool = new vector<DepNode*>;
654}
655
656void QuitDepNodePool() {
657 for (DepNode* n : *g_dep_node_pool)
658 delete n;
659 delete g_dep_node_pool;
660}