blob: 585bcb9190ccbd03c405b24dbaf33a032d7fb98c [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"
Stefan Becker187bf082016-04-07 13:28:42 +030028#include "flags.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090029#include "log.h"
30#include "rule.h"
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +090031#include "stats.h"
Shinichiro Hamaji4a711312015-06-19 14:44:20 +090032#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090033#include "symtab.h"
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +090034#include "timeutil.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090035#include "var.h"
36
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090037namespace {
38
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090039static vector<DepNode*>* g_dep_node_pool;
40
Shinichiro Hamajie7992752015-06-29 18:38:35 +090041static Symbol ReplaceSuffix(Symbol s, Symbol newsuf) {
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090042 string r;
Shinichiro Hamajie7992752015-06-29 18:38:35 +090043 AppendString(StripExt(s.str()), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090044 r += '.';
Shinichiro Hamajie7992752015-06-29 18:38:35 +090045 AppendString(newsuf.str(), &r);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +090046 return Intern(r);
47}
48
Shinichiro Hamaji3727d212016-02-19 15:21:32 +090049void ApplyOutputPattern(const Rule& r,
50 Symbol output,
51 const vector<Symbol>& inputs,
52 vector<Symbol>* out_inputs) {
53 if (inputs.empty())
54 return;
55 if (r.is_suffix_rule) {
56 for (Symbol input : inputs) {
57 out_inputs->push_back(ReplaceSuffix(output, input));
58 }
59 return;
60 }
61 if (r.output_patterns.empty()) {
62 copy(inputs.begin(), inputs.end(), back_inserter(*out_inputs));
63 return;
64 }
65 CHECK(r.output_patterns.size() == 1);
66 Pattern pat(r.output_patterns[0].str());
67 for (Symbol input : inputs) {
68 string buf;
69 pat.AppendSubst(output.str(), input.str(), &buf);
70 out_inputs->push_back(Intern(buf));
71 }
72}
73
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090074class RuleTrie {
75 struct Entry {
Dan Willemsen3ce083f2017-10-11 22:17:48 -070076 Entry(const Rule* r, StringPiece s) : rule(r), suffix(s) {}
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090077 const Rule* rule;
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090078 StringPiece suffix;
79 };
80
81 public:
82 RuleTrie() {}
83 ~RuleTrie() {
84 for (auto& p : children_)
85 delete p.second;
86 }
87
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +090088 void Add(StringPiece name, const Rule* rule) {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +090089 if (name.empty() || name[0] == '%') {
90 rules_.push_back(Entry(rule, name));
91 return;
92 }
93 const char c = name[0];
94 auto p = children_.emplace(c, nullptr);
95 if (p.second) {
96 p.first->second = new RuleTrie();
97 }
98 p.first->second->Add(name.substr(1), rule);
99 }
100
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900101 void Get(StringPiece name, vector<const Rule*>* rules) const {
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900102 for (const Entry& ent : rules_) {
103 if ((ent.suffix.empty() && name.empty()) ||
104 HasSuffix(name, ent.suffix.substr(1))) {
105 rules->push_back(ent.rule);
106 }
107 }
Shinichiro Hamajif772b172015-06-29 16:05:44 +0900108 if (name.empty())
109 return;
110 auto found = children_.find(name[0]);
111 if (found != children_.end()) {
112 found->second->Get(name.substr(1), rules);
113 }
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900114 }
115
116 size_t size() const {
117 size_t r = rules_.size();
118 for (const auto& c : children_)
119 r += c.second->size();
120 return r;
121 }
122
123 private:
124 vector<Entry> rules_;
125 unordered_map<char, RuleTrie*> children_;
126};
127
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900128bool IsSuffixRule(Symbol output) {
129 if (output.empty() || output.str()[0] != '.')
130 return false;
131 const StringPiece rest = StringPiece(output.str()).substr(1);
132 size_t dot_index = rest.find('.');
133 // If there is only a single dot or the third dot, this is not a
134 // suffix rule.
135 if (dot_index == string::npos ||
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700136 rest.substr(dot_index + 1).find('.') != string::npos) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900137 return false;
138 }
139 return true;
140}
141
142struct RuleMerger {
143 vector<const Rule*> rules;
Dan Willemsen72a8e012017-08-13 22:06:47 -0700144 vector<pair<Symbol, RuleMerger*>> implicit_outputs;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900145 const Rule* primary_rule;
Dan Willemsen72a8e012017-08-13 22:06:47 -0700146 const RuleMerger* parent;
147 Symbol parent_sym;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900148 bool is_double_colon;
149
150 RuleMerger()
151 : primary_rule(nullptr),
Dan Willemsen72a8e012017-08-13 22:06:47 -0700152 parent(nullptr),
153 parent_sym(Symbol::IsUninitialized()),
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700154 is_double_colon(false) {}
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900155
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700156 void AddImplicitOutput(Symbol output, RuleMerger* merger) {
Dan Willemsen72a8e012017-08-13 22:06:47 -0700157 implicit_outputs.push_back(make_pair(output, merger));
158 }
159
160 void SetImplicitOutput(Symbol output, Symbol p, const RuleMerger* merger) {
161 if (!merger->primary_rule) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700162 ERROR("*** implicit output `%s' on phony target `%s'", output.c_str(),
163 p.c_str());
Dan Willemsen72a8e012017-08-13 22:06:47 -0700164 }
165 if (parent) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700166 ERROR_LOC(merger->primary_rule->cmd_loc(),
167 "*** implicit output `%s' of `%s' was already defined by `%s' "
168 "at %s:%d",
169 output.c_str(), p.c_str(), parent_sym.c_str(),
170 parent->primary_rule->cmd_loc());
Dan Willemsen72a8e012017-08-13 22:06:47 -0700171 }
172 if (primary_rule) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700173 ERROR_LOC(primary_rule->cmd_loc(),
174 "*** implicit output `%s' may not have commands",
Dan Willemsen72a8e012017-08-13 22:06:47 -0700175 output.c_str());
176 }
177 parent = merger;
178 parent_sym = p;
179 }
180
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900181 void AddRule(Symbol output, const Rule* r) {
182 if (rules.empty()) {
183 is_double_colon = r->is_double_colon;
184 } else if (is_double_colon != r->is_double_colon) {
Dan Willemsene41c7552017-02-22 14:31:16 -0800185 ERROR_LOC(r->loc, "*** target file `%s' has both : and :: entries.",
186 output.c_str());
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900187 }
188
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700189 if (primary_rule && !r->cmds.empty() && !IsSuffixRule(output) &&
190 !r->is_double_colon) {
Dan Willemsenf63a3fd2017-04-27 23:39:57 -0700191 if (g_flags.werror_overriding_commands) {
192 ERROR_LOC(r->cmd_loc(),
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700193 "*** overriding commands for target `%s', previously defined "
194 "at %s:%d",
Dan Willemsenf63a3fd2017-04-27 23:39:57 -0700195 output.c_str(), LOCF(primary_rule->cmd_loc()));
196 } else {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700197 WARN_LOC(r->cmd_loc(), "warning: overriding commands for target `%s'",
Dan Willemsenf63a3fd2017-04-27 23:39:57 -0700198 output.c_str());
199 WARN_LOC(primary_rule->cmd_loc(),
200 "warning: ignoring old commands for target `%s'",
201 output.c_str());
202 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900203 primary_rule = r;
204 }
205 if (!primary_rule && !r->cmds.empty()) {
206 primary_rule = r;
207 }
208
209 rules.push_back(r);
210 }
211
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700212 void FillDepNodeFromRule(Symbol output, const Rule* r, DepNode* n) const {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900213 if (is_double_colon)
214 copy(r->cmds.begin(), r->cmds.end(), back_inserter(n->cmds));
215
216 ApplyOutputPattern(*r, output, r->inputs, &n->actual_inputs);
217 ApplyOutputPattern(*r, output, r->order_only_inputs,
218 &n->actual_order_only_inputs);
219
220 if (r->output_patterns.size() >= 1) {
221 CHECK(r->output_patterns.size() == 1);
222 n->output_pattern = r->output_patterns[0];
223 }
224 }
225
226 void FillDepNodeLoc(const Rule* r, DepNode* n) const {
227 n->loc = r->loc;
228 if (!r->cmds.empty() && r->cmd_lineno)
229 n->loc.lineno = r->cmd_lineno;
230 }
231
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700232 void FillDepNode(Symbol output, const Rule* pattern_rule, DepNode* n) const {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900233 if (primary_rule) {
234 CHECK(!pattern_rule);
235 FillDepNodeFromRule(output, primary_rule, n);
236 FillDepNodeLoc(primary_rule, n);
237 n->cmds = primary_rule->cmds;
238 } else if (pattern_rule) {
239 FillDepNodeFromRule(output, pattern_rule, n);
240 FillDepNodeLoc(pattern_rule, n);
241 n->cmds = pattern_rule->cmds;
242 }
243
244 for (const Rule* r : rules) {
245 if (r == primary_rule)
246 continue;
247 FillDepNodeFromRule(output, r, n);
Shinichiro Hamajic58db9a2016-05-12 15:16:12 +0900248 if (n->loc.filename == NULL)
249 n->loc = r->loc;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900250 }
Dan Willemsen72a8e012017-08-13 22:06:47 -0700251
252 for (auto& implicit_output : implicit_outputs) {
253 n->implicit_outputs.push_back(implicit_output.first);
254 for (const Rule* r : implicit_output.second->rules) {
255 FillDepNodeFromRule(output, r, n);
256 }
257 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900258 }
259};
260
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900261} // namespace
262
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900263DepNode::DepNode(Symbol o, bool p, bool r)
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900264 : output(o),
265 has_rule(false),
Colin Cross5b26db32015-09-29 16:51:02 -0700266 is_default_target(false),
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900267 is_phony(p),
268 is_restat(r),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900269 rule_vars(NULL),
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900270 depfile_var(NULL),
Dan Willemsen2f75ffa2016-11-04 16:57:57 -0700271 ninja_pool_var(NULL),
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900272 output_pattern(Symbol::IsUninitialized()) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900273 g_dep_node_pool->push_back(this);
274}
275
276class DepBuilder {
277 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900278 DepBuilder(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900279 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900280 const unordered_map<Symbol, Vars*>& rule_vars)
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900281 : ev_(ev),
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900282 rule_vars_(rule_vars),
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900283 implicit_rules_(new RuleTrie()),
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900284 first_rule_(Symbol::IsUninitialized{}),
Dan Willemsen2f75ffa2016-11-04 16:57:57 -0700285 depfile_var_name_(Intern(".KATI_DEPFILE")),
Dan Willemsenb78d16f2017-08-09 16:51:34 -0700286 implicit_outputs_var_name_(Intern(".KATI_IMPLICIT_OUTPUTS")),
Dan Willemsen2f75ffa2016-11-04 16:57:57 -0700287 ninja_pool_var_name_(Intern(".KATI_NINJA_POOL")) {
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900288 ScopedTimeReporter tr("make dep (populate)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900289 PopulateRules(rules);
Shinichiro Hamajic9b9e5e2016-02-18 18:18:54 +0900290 // TODO?
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700291 // LOG_STAT("%zu variables", ev->mutable_vars()->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900292 LOG_STAT("%zu explicit rules", rules_.size());
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900293 LOG_STAT("%zu implicit rules", implicit_rules_->size());
Shinichiro Hamajib4969af2015-06-28 02:06:54 +0900294 LOG_STAT("%zu suffix rules", suffix_rules_.size());
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900295
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900296 HandleSpecialTargets();
297 }
298
299 void HandleSpecialTargets() {
300 Loc loc;
301 vector<Symbol> targets;
302
303 if (GetRuleInputs(Intern(".PHONY"), &targets, &loc)) {
304 for (Symbol t : targets)
305 phony_.insert(t);
Shinichiro Hamajid40b6fe2015-06-29 17:08:42 +0900306 }
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900307 if (GetRuleInputs(Intern(".KATI_RESTAT"), &targets, &loc)) {
308 for (Symbol t : targets)
309 restat_.insert(t);
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900310 }
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900311 if (GetRuleInputs(Intern(".SUFFIXES"), &targets, &loc)) {
312 if (targets.empty()) {
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900313 suffix_rules_.clear();
314 } else {
Dan Willemsene41c7552017-02-22 14:31:16 -0800315 WARN_LOC(loc, "kati doesn't support .SUFFIXES with prerequisites");
Shinichiro Hamajicbe9f492015-11-30 16:39:35 +0900316 }
317 }
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900318
319 // Note we can safely ignore .DELETE_ON_ERROR for --ninja mode.
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700320 static const char* kUnsupportedBuiltinTargets[] = {".DEFAULT",
321 ".PRECIOUS",
322 ".INTERMEDIATE",
323 ".SECONDARY",
324 ".SECONDEXPANSION",
325 ".IGNORE",
326 ".LOW_RESOLUTION_TIME",
327 ".SILENT",
328 ".EXPORT_ALL_VARIABLES",
329 ".NOTPARALLEL",
330 ".ONESHELL",
331 NULL};
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900332 for (const char** p = kUnsupportedBuiltinTargets; *p; p++) {
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900333 if (GetRuleInputs(Intern(*p), &targets, &loc)) {
Dan Willemsene41c7552017-02-22 14:31:16 -0800334 WARN_LOC(loc, "kati doesn't support %s", *p);
Shinichiro Hamaji77be80d2015-11-30 16:43:05 +0900335 }
336 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900337 }
338
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700339 ~DepBuilder() {}
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900340
Shinichiro Hamajia62b02a2015-10-01 14:21:40 +0900341 void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900342 if (!first_rule_.IsValid()) {
Colin Cross5b26db32015-09-29 16:51:02 -0700343 ERROR("*** No targets.");
344 }
Shinichiro Hamaji43defe02015-07-11 07:06:43 +0900345
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900346 if (!g_flags.gen_all_targets && targets.empty()) {
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900347 targets.push_back(first_rule_);
Shinichiro Hamaji319b6492015-09-24 14:23:55 +0900348 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900349 if (g_flags.gen_all_targets) {
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900350 unordered_set<Symbol> non_root_targets;
351 for (const auto& p : rules_) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900352 for (const Rule* r : p.second.rules) {
353 for (Symbol t : r->inputs)
354 non_root_targets.insert(t);
355 for (Symbol t : r->order_only_inputs)
356 non_root_targets.insert(t);
357 }
Shinichiro Hamaji6ff74ce2015-10-03 11:58:35 +0900358 }
359
360 for (const auto& p : rules_) {
361 Symbol t = p.first;
362 if (!non_root_targets.count(t)) {
363 targets.push_back(p.first);
364 }
365 }
Shinichiro Hamaji7223e7b2015-09-28 15:17:27 +0900366 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900367
368 // TODO: LogStats?
369
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900370 for (Symbol target : targets) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900371 cur_rule_vars_.reset(new Vars);
372 ev_->set_current_scope(cur_rule_vars_.get());
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900373 DepNode* n = BuildPlan(target, Intern(""));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900374 nodes->push_back(n);
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900375 ev_->set_current_scope(NULL);
376 cur_rule_vars_.reset(NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900377 }
378 }
379
380 private:
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900381 bool Exists(Symbol target) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900382 auto found = rules_.find(target);
383 if (found != rules_.end())
384 return true;
385 if (phony_.count(target))
386 return true;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900387 return ::Exists(target.str());
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900388 }
389
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900390 bool GetRuleInputs(Symbol s, vector<Symbol>* o, Loc* l) {
391 auto found = rules_.find(s);
392 if (found == rules_.end())
393 return false;
394
395 o->clear();
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900396 CHECK(!found->second.rules.empty());
397 *l = found->second.rules.front()->loc;
398 for (const Rule* r : found->second.rules) {
399 for (Symbol i : r->inputs)
400 o->push_back(i);
Shinichiro Hamajia5ac4d92016-02-19 14:47:23 +0900401 }
402 return true;
403 }
404
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900405 void PopulateRules(const vector<const Rule*>& rules) {
406 for (const Rule* rule : rules) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900407 if (rule->outputs.empty()) {
408 PopulateImplicitRule(rule);
409 } else {
410 PopulateExplicitRule(rule);
411 }
412 }
Shinichiro Hamaji65657d92015-06-24 17:05:50 +0900413 for (auto& p : suffix_rules_) {
414 reverse(p.second.begin(), p.second.end());
415 }
Dan Willemsen72a8e012017-08-13 22:06:47 -0700416 for (auto& p : rules_) {
417 auto vars = LookupRuleVars(p.first);
418 if (!vars) {
419 continue;
420 }
421 auto var = vars->Lookup(implicit_outputs_var_name_);
422 if (!var->IsDefined()) {
423 continue;
424 }
425
426 string implicit_outputs;
427 var->Eval(ev_, &implicit_outputs);
428
429 for (StringPiece output : WordScanner(implicit_outputs)) {
430 Symbol sym = Intern(TrimLeadingCurdir(output));
431 rules_[sym].SetImplicitOutput(sym, p.first, &p.second);
432 p.second.AddImplicitOutput(sym, &rules_[sym]);
433 }
434 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900435 }
436
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900437 bool PopulateSuffixRule(const Rule* rule, Symbol output) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900438 if (!IsSuffixRule(output))
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900439 return false;
440
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900441 const StringPiece rest = StringPiece(output.str()).substr(1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900442 size_t dot_index = rest.find('.');
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900443
444 StringPiece input_suffix = rest.substr(0, dot_index);
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700445 StringPiece output_suffix = rest.substr(dot_index + 1);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900446 shared_ptr<Rule> r = make_shared<Rule>(*rule);
447 r->inputs.clear();
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900448 r->inputs.push_back(Intern(input_suffix));
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900449 r->is_suffix_rule = true;
450 suffix_rules_[output_suffix].push_back(r);
451 return true;
452 }
453
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900454 void PopulateExplicitRule(const Rule* rule) {
455 for (Symbol output : rule->outputs) {
456 if (!first_rule_.IsValid() && output.get(0) != '.') {
457 first_rule_ = output;
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900458 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900459 rules_[output].AddRule(output, rule);
460 PopulateSuffixRule(rule, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900461 }
462 }
463
Shinichiro Hamaji0a6e2a42016-02-16 19:21:26 +0900464 static bool IsIgnorableImplicitRule(const Rule* rule) {
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900465 // As kati doesn't have RCS/SCCS related default rules, we can
466 // safely ignore suppression for them.
467 if (rule->inputs.size() != 1)
468 return false;
469 if (!rule->order_only_inputs.empty())
470 return false;
471 if (!rule->cmds.empty())
472 return false;
473 const string& i = rule->inputs[0].str();
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700474 return (i == "RCS/%,v" || i == "RCS/%" || i == "%,v" || i == "s.%" ||
475 i == "SCCS/s.%");
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900476 }
477
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900478 void PopulateImplicitRule(const Rule* rule) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900479 for (Symbol output_pattern : rule->output_patterns) {
Shinichiro Hamaji0a6e2a42016-02-16 19:21:26 +0900480 if (output_pattern.str() != "%" || !IsIgnorableImplicitRule(rule))
Shinichiro Hamaji6ba79642016-02-16 19:13:29 +0900481 implicit_rules_->Add(output_pattern.str(), rule);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900482 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900483 }
484
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900485 const RuleMerger* LookupRuleMerger(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900486 auto found = rules_.find(o);
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900487 if (found != rules_.end()) {
488 return &found->second;
489 }
490 return nullptr;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900491 }
492
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900493 Vars* LookupRuleVars(Symbol o) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900494 auto found = rule_vars_.find(o);
495 if (found != rule_vars_.end())
496 return found->second;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900497 return nullptr;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900498 }
499
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700500 bool CanPickImplicitRule(const Rule* rule,
501 Symbol output,
502 DepNode* n,
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900503 shared_ptr<Rule>* out_rule) {
504 Symbol matched(Symbol::IsUninitialized{});
505 for (Symbol output_pattern : rule->output_patterns) {
506 Pattern pat(output_pattern.str());
507 if (pat.Match(output.str())) {
508 bool ok = true;
509 for (Symbol input : rule->inputs) {
510 string buf;
511 pat.AppendSubst(output.str(), input.str(), &buf);
512 if (!Exists(Intern(buf))) {
513 ok = false;
514 break;
515 }
516 }
517
518 if (ok) {
519 matched = output_pattern;
520 break;
521 }
522 }
523 }
524 if (!matched.IsValid())
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900525 return false;
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900526
527 *out_rule = make_shared<Rule>(*rule);
528 if ((*out_rule)->output_patterns.size() > 1) {
529 // We should mark all other output patterns as used.
530 Pattern pat(matched.str());
531 for (Symbol output_pattern : rule->output_patterns) {
532 if (output_pattern == matched)
533 continue;
534 string buf;
535 pat.AppendSubst(output.str(), output_pattern.str(), &buf);
536 done_[Intern(buf)] = n;
537 }
538 (*out_rule)->output_patterns.clear();
539 (*out_rule)->output_patterns.push_back(matched);
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900540 }
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900541
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900542 return true;
543 }
544
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900545 Vars* MergeImplicitRuleVars(Symbol output, Vars* vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900546 auto found = rule_vars_.find(output);
547 if (found == rule_vars_.end())
548 return vars;
549 if (vars == NULL)
550 return found->second;
551 // TODO: leak.
552 Vars* r = new Vars(*found->second);
553 for (auto p : *vars) {
554 (*r)[p.first] = p.second;
555 }
556 return r;
557 }
558
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900559 bool PickRule(Symbol output,
560 DepNode* n,
561 const RuleMerger** out_rule_merger,
562 shared_ptr<Rule>* pattern_rule,
563 Vars** out_var) {
564 const RuleMerger* rule_merger = LookupRuleMerger(output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900565 Vars* vars = LookupRuleVars(output);
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900566 *out_rule_merger = rule_merger;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900567 *out_var = vars;
Dan Willemsen72a8e012017-08-13 22:06:47 -0700568 if (rule_merger && rule_merger->primary_rule) {
569 for (auto implicit_output : rule_merger->implicit_outputs) {
570 vars = MergeImplicitRuleVars(implicit_output.first, vars);
571 }
572 *out_var = vars;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900573 return true;
Dan Willemsen72a8e012017-08-13 22:06:47 -0700574 }
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900575
Shinichiro Hamaji7eac6652016-02-02 12:25:08 +0900576 vector<const Rule*> irules;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900577 implicit_rules_->Get(output.str(), &irules);
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900578 for (auto iter = irules.rbegin(); iter != irules.rend(); ++iter) {
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900579 if (!CanPickImplicitRule(*iter, output, n, pattern_rule))
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900580 continue;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900581 if (rule_merger) {
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900582 return true;
583 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900584 CHECK((*pattern_rule)->output_patterns.size() == 1);
585 vars = MergeImplicitRuleVars((*pattern_rule)->output_patterns[0], vars);
Shinichiro Hamaji271c5802016-01-26 15:11:57 +0900586 *out_var = vars;
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900587 return true;
588 }
589
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900590 StringPiece output_suffix = GetExt(output.str());
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900591 if (output_suffix.get(0) != '.')
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900592 return rule_merger;
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900593 output_suffix = output_suffix.substr(1);
Shinichiro Hamaji4a711312015-06-19 14:44:20 +0900594
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900595 SuffixRuleMap::const_iterator found = suffix_rules_.find(output_suffix);
596 if (found == suffix_rules_.end())
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900597 return rule_merger;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900598
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700599 for (const shared_ptr<Rule>& irule : found->second) {
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900600 CHECK(irule->inputs.size() == 1);
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900601 Symbol input = ReplaceSuffix(output, irule->inputs[0]);
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900602 if (!Exists(input))
603 continue;
604
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900605 *pattern_rule = irule;
606 if (rule_merger)
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900607 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900608 if (vars) {
Shinichiro Hamajidca79a32015-06-24 15:27:33 +0900609 CHECK(irule->outputs.size() == 1);
610 vars = MergeImplicitRuleVars(irule->outputs[0], vars);
611 *out_var = vars;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900612 }
Shinichiro Hamaji52dbb602015-06-19 15:57:07 +0900613 return true;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900614 }
615
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900616 return rule_merger;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900617 }
618
Shinichiro Hamaji8d503012015-07-03 16:26:15 +0900619 DepNode* BuildPlan(Symbol output, Symbol needed_by UNUSED) {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700620 LOG("BuildPlan: %s for %s", output.c_str(), needed_by.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900621
622 auto found = done_.find(output);
623 if (found != done_.end()) {
624 return found->second;
625 }
626
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700627 DepNode* n =
628 new DepNode(output, phony_.count(output), restat_.count(output));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900629 done_[output] = n;
630
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900631 const RuleMerger* rule_merger = nullptr;
632 shared_ptr<Rule> pattern_rule;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900633 Vars* vars;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900634 if (!PickRule(output, n, &rule_merger, &pattern_rule, &vars)) {
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900635 return n;
636 }
Dan Willemsen72a8e012017-08-13 22:06:47 -0700637 if (rule_merger && rule_merger->parent) {
638 output = rule_merger->parent_sym;
639 done_[output] = n;
640 n->output = output;
641 if (!PickRule(output, n, &rule_merger, &pattern_rule, &vars)) {
642 return n;
643 }
644 }
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900645 if (rule_merger)
646 rule_merger->FillDepNode(output, pattern_rule.get(), n);
647 else
648 RuleMerger().FillDepNode(output, pattern_rule.get(), n);
Shinichiro Hamajia7984ad2015-09-11 16:33:16 +0900649
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900650 vector<unique_ptr<ScopedVar>> sv;
651 if (vars) {
652 for (const auto& p : *vars) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900653 Symbol name = p.first;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900654 RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
655 CHECK(var);
656 Var* new_var = var->v();
657 if (var->op() == AssignOp::PLUS_EQ) {
658 Var* old_var = ev_->LookupVar(name);
659 if (old_var->IsDefined()) {
660 // TODO: This would be incorrect and has a leak.
661 shared_ptr<string> s = make_shared<string>();
662 old_var->Eval(ev_, s.get());
Shinichiro Hamaji3c785c72015-06-23 19:22:34 +0900663 if (!s->empty())
664 *s += ' ';
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900665 new_var->Eval(ev_, s.get());
Shinichiro Hamaji5081c712015-08-14 16:49:20 +0900666 new_var = new SimpleVar(*s, old_var->Origin());
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900667 }
668 } else if (var->op() == AssignOp::QUESTION_EQ) {
669 Var* old_var = ev_->LookupVar(name);
670 if (old_var->IsDefined()) {
671 continue;
672 }
673 }
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900674
675 if (name == depfile_var_name_) {
676 n->depfile_var = new_var;
Dan Willemsenb78d16f2017-08-09 16:51:34 -0700677 } else if (name == implicit_outputs_var_name_) {
Dan Willemsen2f75ffa2016-11-04 16:57:57 -0700678 } else if (name == ninja_pool_var_name_) {
679 n->ninja_pool_var = new_var;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900680 } else {
681 sv.emplace_back(new ScopedVar(cur_rule_vars_.get(), name, new_var));
682 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900683 }
684 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900685
Dan Willemsen72a8e012017-08-13 22:06:47 -0700686 for (Symbol output : n->implicit_outputs) {
687 done_[output] = n;
688 }
689
Shinichiro Hamaji53ffb072015-09-26 12:07:22 +0900690 for (Symbol input : n->actual_inputs) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900691 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900692 n->deps.push_back(c);
693 }
694
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900695 for (Symbol input : n->actual_order_only_inputs) {
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900696 DepNode* c = BuildPlan(input, output);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +0900697 n->order_onlys.push_back(c);
Shinichiro Hamaji704e4fe2015-06-24 17:37:47 +0900698 }
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900699
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900700 n->has_rule = true;
Shinichiro Hamaji0325b162016-02-19 14:55:09 +0900701 n->is_default_target = first_rule_ == output;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900702 if (cur_rule_vars_->empty()) {
703 n->rule_vars = NULL;
704 } else {
705 n->rule_vars = new Vars;
706 for (auto p : *cur_rule_vars_) {
707 n->rule_vars->insert(p);
708 }
709 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900710
711 return n;
712 }
713
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900714 Evaluator* ev_;
Shinichiro Hamaji3727d212016-02-19 15:21:32 +0900715 map<Symbol, RuleMerger> rules_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900716 const unordered_map<Symbol, Vars*>& rule_vars_;
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900717 unique_ptr<Vars> cur_rule_vars_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900718
Shinichiro Hamaji2a047892015-06-29 13:56:41 +0900719 unique_ptr<RuleTrie> implicit_rules_;
Shinichiro Hamaji0562c302015-06-19 15:30:49 +0900720 typedef unordered_map<StringPiece, vector<shared_ptr<Rule>>> SuffixRuleMap;
721 SuffixRuleMap suffix_rules_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900722
Shinichiro Hamaji8f813fe2016-02-19 14:32:51 +0900723 Symbol first_rule_;
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900724 unordered_map<Symbol, DepNode*> done_;
725 unordered_set<Symbol> phony_;
Shinichiro Hamaji3ac2a092015-10-01 18:38:02 +0900726 unordered_set<Symbol> restat_;
Shinichiro Hamaji85e5ed02016-01-20 16:25:32 +0900727 Symbol depfile_var_name_;
Dan Willemsenb78d16f2017-08-09 16:51:34 -0700728 Symbol implicit_outputs_var_name_;
Dan Willemsen2f75ffa2016-11-04 16:57:57 -0700729 Symbol ninja_pool_var_name_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900730};
731
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900732void MakeDep(Evaluator* ev,
Shinichiro Hamaji7a2659e2016-02-08 14:32:56 +0900733 const vector<const Rule*>& rules,
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900734 const unordered_map<Symbol, Vars*>& rule_vars,
735 const vector<Symbol>& targets,
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900736 vector<DepNode*>* nodes) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900737 DepBuilder db(ev, rules, rule_vars);
Shinichiro Hamaji54a3d532016-02-16 17:33:27 +0900738 ScopedTimeReporter tr("make dep (build)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900739 db.Build(targets, nodes);
740}
741
742void InitDepNodePool() {
743 g_dep_node_pool = new vector<DepNode*>;
744}
745
746void QuitDepNodePool() {
747 for (DepNode* n : *g_dep_node_pool)
748 delete n;
749 delete g_dep_node_pool;
750}