blob: da209c75b9d2e926b9d2ee314dd083489e0fbc89 [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 Hamaji3727d212016-02-19 15:21:32 +090048void ApplyOutputPattern(const Rule& r,
49 Symbol output,
50 const vector<Symbol>& inputs,
51 vector<Symbol>* out_inputs) {
52 if (inputs.empty())
53 return;
54 if (r.is_suffix_rule) {
55 for (Symbol input : inputs) {
56 out_inputs->push_back(ReplaceSuffix(output, input));
57 }
58 return;
59 }
60 if (r.output_patterns.empty()) {
61 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
62 return;
63 }
64 CHECK(r.output_patterns.size() == 1);
65 Pattern pat(r.output_patterns[0].str());
66 for (Symbol input : inputs) {
67 string buf;
68 pat.AppendSubst(output.str(), input.str(), &buf);
69 out_inputs->push_back(Intern(buf));
70 }
71}
72
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090073class RuleTrie {
74 struct Entry {
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090075 Entry(const Rule* r, StringPiece s)
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090076 : rule(r), suffix(s) {
77 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090078 const Rule* rule;
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090079 StringPiece suffix;
80 };
81
82 public:
83 RuleTrie() {}
84 ~RuleTrie() {
85 for (auto& p : children_)
86 delete p.second;
87 }
88
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090089 void Add(StringPiece name, const Rule* rule) {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090090 if (name.empty() || name[0] == '%') {
91 rules_.push_back(Entry(rule, name));
92 return;
93 }
94 const char c = name[0];
95 auto p = children_.emplace(c, nullptr);
96 if (p.second) {
97 p.first->second = new RuleTrie();
98 }
99 p.first->second->Add(name.substr(1), rule);
100 }
101
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900102 void Get(StringPiece name, vector<const Rule*>* rules) const {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900103 for (const Entry& ent : rules_) {
104 if ((ent.suffix.empty() && name.empty()) ||
105 HasSuffix(name, ent.suffix.substr(1))) {
106 rules->push_back(ent.rule);
107 }
108 }
Shinichiro Hamajif772b172015-06-29 16:05:44 +0900109 if (name.empty())
110 return;
111 auto found = children_.find(name[0]);
112 if (found != children_.end()) {
113 found->second->Get(name.substr(1), rules);
114 }
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900115 }
116
117 size_t size() const {
118 size_t r = rules_.size();
119 for (const auto& c : children_)
120 r += c.second->size();
121 return r;
122 }
123
124 private:
125 vector<Entry> rules_;
126 unordered_map<char, RuleTrie*> children_;
127};
128
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900129
130bool IsSuffixRule(Symbol output) {
131 if (output.empty() || output.str()[0] != '.')
132 return false;
133 const StringPiece rest = StringPiece(output.str()).substr(1);
134 size_t dot_index = rest.find('.');
135 // If there is only a single dot or the third dot, this is not a
136 // suffix rule.
137 if (dot_index == string::npos ||
138 rest.substr(dot_index+1).find('.') != string::npos) {
139 return false;
140 }
141 return true;
142}
143
144struct RuleMerger {
145 vector<const Rule*> rules;
146 const Rule* primary_rule;
147 bool is_double_colon;
148
149 RuleMerger()
150 : primary_rule(nullptr),
151 is_double_colon(false) {
152 }
153
154 void AddRule(Symbol output, const Rule* r) {
155 if (rules.empty()) {
156 is_double_colon = r->is_double_colon;
157 } else if (is_double_colon != r->is_double_colon) {
158 ERROR("%s:%d: *** target file `%s' has both : and :: entries.",
159 LOCF(r->loc), output.c_str());
160 }
161
162 if (primary_rule && !r->cmds.empty() &&
163 !IsSuffixRule(output) && !r->is_double_colon) {
164 WARN("%s:%d: warning: overriding commands for target `%s'",
165 LOCF(r->cmd_loc()), output.c_str());
166 WARN("%s:%d: warning: ignoring old commands for target `%s'",
167 LOCF(primary_rule->cmd_loc()), output.c_str());
168 primary_rule = r;
169 }
170 if (!primary_rule && !r->cmds.empty()) {
171 primary_rule = r;
172 }
173
174 rules.push_back(r);
175 }
176
177 void FillDepNodeFromRule(Symbol output,
178 const Rule* r,
179 DepNode* n) const {
180 if (is_double_colon)
181 copy(r->cmds.begin(), r->cmds.end(), back_inserter(n->cmds));
182
183 ApplyOutputPattern(*r, output, r->inputs, &n->actual_inputs);
184 ApplyOutputPattern(*r, output, r->order_only_inputs,
185 &n->actual_order_only_inputs);
186
187 if (r->output_patterns.size() >= 1) {
188 CHECK(r->output_patterns.size() == 1);
189 n->output_pattern = r->output_patterns[0];
190 }
191 }
192
193 void FillDepNodeLoc(const Rule* r, DepNode* n) const {
194 n->loc = r->loc;
195 if (!r->cmds.empty() && r->cmd_lineno)
196 n->loc.lineno = r->cmd_lineno;
197 }
198
199 void FillDepNode(Symbol output,
200 const Rule* pattern_rule,
201 DepNode* n) const {
202 if (primary_rule) {
203 CHECK(!pattern_rule);
204 FillDepNodeFromRule(output, primary_rule, n);
205 FillDepNodeLoc(primary_rule, n);
206 n->cmds = primary_rule->cmds;
207 } else if (pattern_rule) {
208 FillDepNodeFromRule(output, pattern_rule, n);
209 FillDepNodeLoc(pattern_rule, n);
210 n->cmds = pattern_rule->cmds;
211 }
212
213 for (const Rule* r : rules) {
214 if (r == primary_rule)
215 continue;
216 FillDepNodeFromRule(output, r, n);
217 }
218 }
219};
220
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900221} // namespace
222
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900223DepNode::DepNode(Symbol o, bool p, bool r)
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900224 : output(o),
225 has_rule(false),
Colin Cross5b26db32015-09-29 16:51:02 -0700226 is_default_target(false),
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900227 is_phony(p),
228 is_restat(r),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900229 rule_vars(NULL),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900230 depfile_var(NULL),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900231 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900232 g_dep_node_pool->push_back(this);
233}
234
235class DepBuilder {
236 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900237 DepBuilder(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900238 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900239 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900240 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900241 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900242 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900243 first_rule_(Symbol::IsUninitialized{}),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900244 depfile_var_name_(Intern(".KATI_DEPFILE")) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900245 ScopedTimeReporter tr("make dep (populate)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900246 PopulateRules(rules);
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900247 // TODO?
248 //LOG_STAT("%zu variables", ev->mutable_vars()->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900249 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900250 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900251 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900252
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900253 HandleSpecialTargets();
254 }
255
256 void HandleSpecialTargets() {
257 Loc loc;
258 vector<Symbol> targets;
259
260 if (GetRuleInputs(Intern(".PHONY"), &targets, &loc)) {
261 for (Symbol t : targets)
262 phony_.insert(t);
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900263 }
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900264 if (GetRuleInputs(Intern(".KATI_RESTAT"), &targets, &loc)) {
265 for (Symbol t : targets)
266 restat_.insert(t);
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900267 }
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900268 if (GetRuleInputs(Intern(".SUFFIXES"), &targets, &loc)) {
269 if (targets.empty()) {
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900270 suffix_rules_.clear();
271 } else {
272 WARN("%s:%d: kati doesn't support .SUFFIXES with prerequisites",
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900273 LOCF(loc));
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900274 }
275 }
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900276
277 // Note we can safely ignore .DELETE_ON_ERROR for --ninja mode.
278 static const char* kUnsupportedBuiltinTargets[] = {
279 ".DEFAULT",
280 ".PRECIOUS",
281 ".INTERMEDIATE",
282 ".SECONDARY",
283 ".SECONDEXPANSION",
284 ".IGNORE",
285 ".LOW_RESOLUTION_TIME",
286 ".SILENT",
287 ".EXPORT_ALL_VARIABLES",
288 ".NOTPARALLEL",
289 ".ONESHELL",
290 ".POSIX",
291 NULL
292 };
293 for (const char** p = kUnsupportedBuiltinTargets; *p; p++) {
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900294 if (GetRuleInputs(Intern(*p), &targets, &loc)) {
295 WARN("%s:%d: kati doesn't support %s", LOCF(loc), *p);
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900296 }
297 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900298 }
299
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900300 ~DepBuilder() {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900301 }
302
Shinichiro Hamajia62b02a2015-10-01 14:21:40 +0900303 void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900304 if (!first_rule_.IsValid()) {
Colin Cross5b26db32015-09-29 16:51:02 -0700305 ERROR("*** No targets.");
306 }
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900307
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900308 if (!g_flags.gen_all_targets && targets.empty()) {
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900309 targets.push_back(first_rule_);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900310 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900311 if (g_flags.gen_all_targets) {
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900312 unordered_set<Symbol> non_root_targets;
313 for (const auto& p : rules_) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900314 for (const Rule* r : p.second.rules) {
315 for (Symbol t : r->inputs)
316 non_root_targets.insert(t);
317 for (Symbol t : r->order_only_inputs)
318 non_root_targets.insert(t);
319 }
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900320 }
321
322 for (const auto& p : rules_) {
323 Symbol t = p.first;
324 if (!non_root_targets.count(t)) {
325 targets.push_back(p.first);
326 }
327 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900328 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900329
330 // TODO: LogStats?
331
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900332 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900333 cur_rule_vars_.reset(new Vars);
334 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900335 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900336 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900337 ev_->set_current_scope(NULL);
338 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900339 }
340 }
341
342 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900343 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900344 auto found = rules_.find(target);
345 if (found != rules_.end())
346 return true;
347 if (phony_.count(target))
348 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900349 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900350 }
351
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900352 bool GetRuleInputs(Symbol s, vector<Symbol>* o, Loc* l) {
353 auto found = rules_.find(s);
354 if (found == rules_.end())
355 return false;
356
357 o->clear();
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900358 CHECK(!found->second.rules.empty());
359 *l = found->second.rules.front()->loc;
360 for (const Rule* r : found->second.rules) {
361 for (Symbol i : r->inputs)
362 o->push_back(i);
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900363 }
364 return true;
365 }
366
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900367 void PopulateRules(const vector<const Rule*>& rules) {
368 for (const Rule* rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900369 if (rule->outputs.empty()) {
370 PopulateImplicitRule(rule);
371 } else {
372 PopulateExplicitRule(rule);
373 }
374 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900375 for (auto& p : suffix_rules_) {
376 reverse(p.second.begin(), p.second.end());
377 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900378 }
379
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900380 bool PopulateSuffixRule(const Rule* rule, Symbol output) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900381 if (!IsSuffixRule(output))
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900382 return false;
383
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900384 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900385 size_t dot_index = rest.find('.');
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900386
387 StringPiece input_suffix = rest.substr(0, dot_index);
388 StringPiece output_suffix = rest.substr(dot_index+1);
389 shared_ptr<Rule> r = make_shared<Rule>(*rule);
390 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900391 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900392 r->is_suffix_rule = true;
393 suffix_rules_[output_suffix].push_back(r);
394 return true;
395 }
396
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900397 void PopulateExplicitRule(const Rule* rule) {
398 for (Symbol output : rule->outputs) {
399 if (!first_rule_.IsValid() && output.get(0) != '.') {
400 first_rule_ = output;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900401 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900402 rules_[output].AddRule(output, rule);
403 PopulateSuffixRule(rule, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900404 }
405 }
406
Shinichiro Hamaji0a6e2a42016-02-16 19:21:26 +0900407 static bool IsIgnorableImplicitRule(const Rule* rule) {
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900408 // As kati doesn't have RCS/SCCS related default rules, we can
409 // safely ignore suppression for them.
410 if (rule->inputs.size() != 1)
411 return false;
412 if (!rule->order_only_inputs.empty())
413 return false;
414 if (!rule->cmds.empty())
415 return false;
416 const string& i = rule->inputs[0].str();
417 return (i == "RCS/%,v" || i == "RCS/%" || i == "%,v" ||
418 i == "s.%" || i == "SCCS/s.%");
419 }
420
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900421 void PopulateImplicitRule(const Rule* rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900422 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0a6e2a42016-02-16 19:21:26 +0900423 if (output_pattern.str() != "%" || !IsIgnorableImplicitRule(rule))
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900424 implicit_rules_->Add(output_pattern.str(), rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900425 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900426 }
427
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900428 const RuleMerger* LookupRuleMerger(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900429 auto found = rules_.find(o);
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900430 if (found != rules_.end()) {
431 return &found->second;
432 }
433 return nullptr;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900434 }
435
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900436 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900437 auto found = rule_vars_.find(o);
438 if (found != rule_vars_.end())
439 return found->second;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900440 return nullptr;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900441 }
442
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900443 bool CanPickImplicitRule(const Rule* rule, Symbol output, DepNode* n,
444 shared_ptr<Rule>* out_rule) {
445 Symbol matched(Symbol::IsUninitialized{});
446 for (Symbol output_pattern : rule->output_patterns) {
447 Pattern pat(output_pattern.str());
448 if (pat.Match(output.str())) {
449 bool ok = true;
450 for (Symbol input : rule->inputs) {
451 string buf;
452 pat.AppendSubst(output.str(), input.str(), &buf);
453 if (!Exists(Intern(buf))) {
454 ok = false;
455 break;
456 }
457 }
458
459 if (ok) {
460 matched = output_pattern;
461 break;
462 }
463 }
464 }
465 if (!matched.IsValid())
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900466 return false;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900467
468 *out_rule = make_shared<Rule>(*rule);
469 if ((*out_rule)->output_patterns.size() > 1) {
470 // We should mark all other output patterns as used.
471 Pattern pat(matched.str());
472 for (Symbol output_pattern : rule->output_patterns) {
473 if (output_pattern == matched)
474 continue;
475 string buf;
476 pat.AppendSubst(output.str(), output_pattern.str(), &buf);
477 done_[Intern(buf)] = n;
478 }
479 (*out_rule)->output_patterns.clear();
480 (*out_rule)->output_patterns.push_back(matched);
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900481 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900482
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900483 return true;
484 }
485
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900486 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900487 auto found = rule_vars_.find(output);
488 if (found == rule_vars_.end())
489 return vars;
490 if (vars == NULL)
491 return found->second;
492 // TODO: leak.
493 Vars* r = new Vars(*found->second);
494 for (auto p : *vars) {
495 (*r)[p.first] = p.second;
496 }
497 return r;
498 }
499
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900500 bool PickRule(Symbol output,
501 DepNode* n,
502 const RuleMerger** out_rule_merger,
503 shared_ptr<Rule>* pattern_rule,
504 Vars** out_var) {
505 const RuleMerger* rule_merger = LookupRuleMerger(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900506 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900507 *out_rule_merger = rule_merger;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900508 *out_var = vars;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900509 if (rule_merger && rule_merger->primary_rule)
510 return true;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900511
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900512 vector<const Rule*> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900513 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900514 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900515 if (!CanPickImplicitRule(*iter, output, n, pattern_rule))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900516 continue;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900517 if (rule_merger) {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900518 return true;
519 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900520 CHECK((*pattern_rule)->output_patterns.size() == 1);
521 vars = MergeImplicitRuleVars((*pattern_rule)->output_patterns[0], vars);
Shinichiro Hamaji271c5802016-01-26 15:11:57 +0900522 *out_var = vars;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900523 return true;
524 }
525
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900526 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900527 if (output_suffix.get(0) != '.')
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900528 return rule_merger;
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900529 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900530
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900531 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
532 if (found == suffix_rules_.end())
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900533 return rule_merger;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900534
535 for (shared_ptr<Rule> irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900536 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900537 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900538 if (!Exists(input))
539 continue;
540
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900541 *pattern_rule = irule;
542 if (rule_merger)
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900543 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900544 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900545 CHECK(irule->outputs.size() == 1);
546 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
547 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900548 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900549 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900550 }
551
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900552 return rule_merger;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900553 }
554
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900555 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900556 LOG("BuildPlan: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900557 output.c_str(),
558 needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900559
560 auto found = done_.find(output);
561 if (found != done_.end()) {
562 return found->second;
563 }
564
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900565 DepNode* n = new DepNode(output,
566 phony_.count(output),
567 restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900568 done_[output] = n;
569
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900570 const RuleMerger* rule_merger = nullptr;
571 shared_ptr<Rule> pattern_rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900572 Vars* vars;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900573 if (!PickRule(output, n, &rule_merger, &pattern_rule, &vars)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900574 return n;
575 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900576 if (rule_merger)
577 rule_merger->FillDepNode(output, pattern_rule.get(), n);
578 else
579 RuleMerger().FillDepNode(output, pattern_rule.get(), n);
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900580
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900581 vector<unique_ptr<ScopedVar>> sv;
582 if (vars) {
583 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900584 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900585 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
586 CHECK(var);
587 Var* new_var = var->v();
588 if (var->op() == AssignOp::PLUS_EQ) {
589 Var* old_var = ev_->LookupVar(name);
590 if (old_var->IsDefined()) {
591 // TODO: This would be incorrect and has a leak.
592 shared_ptr<string> s = make_shared<string>();
593 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900594 if (!s->empty())
595 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900596 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900597 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900598 }
599 } else if (var->op() == AssignOp::QUESTION_EQ) {
600 Var* old_var = ev_->LookupVar(name);
601 if (old_var->IsDefined()) {
602 continue;
603 }
604 }
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900605
606 if (name == depfile_var_name_) {
607 n->depfile_var = new_var;
608 } else {
609 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
610 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900611 }
612 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900613
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900614 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900615 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900616 n->deps.push_back(c);
617 }
618
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900619 for (Symbol input : n->actual_order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900620 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900621 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900622 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900623
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900624 n->has_rule = true;
Shinichiro Hamaji0325b162016-02-19 14:55:09 +0900625 n->is_default_target = first_rule_ == output;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900626 if (cur_rule_vars_->empty()) {
627 n->rule_vars = NULL;
628 } else {
629 n->rule_vars = new Vars;
630 for (auto p : *cur_rule_vars_) {
631 n->rule_vars->insert(p);
632 }
633 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900634
635 return n;
636 }
637
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900638 Evaluator* ev_;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900639 map<Symbol, RuleMerger> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900640 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900641 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900642
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900643 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900644 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
645 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900646
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900647 Symbol first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900648 unordered_map<Symbol, DepNode*> done_;
649 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900650 unordered_set<Symbol> restat_;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900651 Symbol depfile_var_name_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900652};
653
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900654void MakeDep(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900655 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900656 const unordered_map<Symbol, Vars*>& rule_vars,
657 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900658 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900659 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900660 ScopedTimeReporter tr("make dep (build)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900661 db.Build(targets, nodes);
662}
663
664void InitDepNodePool() {
665 g_dep_node_pool = new vector<DepNode*>;
666}
667
668void QuitDepNodePool() {
669 for (DepNode* n : *g_dep_node_pool)
670 delete n;
671 delete g_dep_node_pool;
672}