aboutsummaryrefslogtreecommitdiff
path: root/dep.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dep.cc')
-rw-r--r--dep.cc139
1 files changed, 115 insertions, 24 deletions
diff --git a/dep.cc b/dep.cc
index 585bcb9..6223a69 100644
--- a/dep.cc
+++ b/dep.cc
@@ -150,7 +150,6 @@ struct RuleMerger {
RuleMerger()
: primary_rule(nullptr),
parent(nullptr),
- parent_sym(Symbol::IsUninitialized()),
is_double_colon(false) {}
void AddImplicitOutput(Symbol output, RuleMerger* merger) {
@@ -268,8 +267,7 @@ DepNode::DepNode(Symbol o, bool p, bool r)
is_restat(r),
rule_vars(NULL),
depfile_var(NULL),
- ninja_pool_var(NULL),
- output_pattern(Symbol::IsUninitialized()) {
+ ninja_pool_var(NULL) {
g_dep_node_pool->push_back(this);
}
@@ -281,7 +279,6 @@ class DepBuilder {
: ev_(ev),
rule_vars_(rule_vars),
implicit_rules_(new RuleTrie()),
- first_rule_(Symbol::IsUninitialized{}),
depfile_var_name_(Intern(".KATI_DEPFILE")),
implicit_outputs_var_name_(Intern(".KATI_IMPLICIT_OUTPUTS")),
ninja_pool_var_name_(Intern(".KATI_NINJA_POOL")) {
@@ -338,7 +335,7 @@ class DepBuilder {
~DepBuilder() {}
- void Build(vector<Symbol> targets, vector<DepNode*>* nodes) {
+ void Build(vector<Symbol> targets, vector<NamedDepNode>* nodes) {
if (!first_rule_.IsValid()) {
ERROR("*** No targets.");
}
@@ -347,8 +344,10 @@ class DepBuilder {
targets.push_back(first_rule_);
}
if (g_flags.gen_all_targets) {
- unordered_set<Symbol> non_root_targets;
+ SymbolSet non_root_targets;
for (const auto& p : rules_) {
+ if (p.first.get(0) == '.')
+ continue;
for (const Rule* r : p.second.rules) {
for (Symbol t : r->inputs)
non_root_targets.insert(t);
@@ -359,7 +358,7 @@ class DepBuilder {
for (const auto& p : rules_) {
Symbol t = p.first;
- if (!non_root_targets.count(t)) {
+ if (!non_root_targets.exists(t) && t.get(0) != '.') {
targets.push_back(p.first);
}
}
@@ -371,7 +370,7 @@ class DepBuilder {
cur_rule_vars_.reset(new Vars);
ev_->set_current_scope(cur_rule_vars_.get());
DepNode* n = BuildPlan(target, Intern(""));
- nodes->push_back(n);
+ nodes->push_back({target,n});
ev_->set_current_scope(NULL);
cur_rule_vars_.reset(NULL);
}
@@ -379,12 +378,8 @@ class DepBuilder {
private:
bool Exists(Symbol target) {
- auto found = rules_.find(target);
- if (found != rules_.end())
- return true;
- if (phony_.count(target))
- return true;
- return ::Exists(target.str());
+ return (rules_.find(target) != rules_.end()) || phony_.exists(target) ||
+ ::Exists(target.str());
}
bool GetRuleInputs(Symbol s, vector<Symbol>* o, Loc* l) {
@@ -438,6 +433,13 @@ class DepBuilder {
if (!IsSuffixRule(output))
return false;
+ if (g_flags.werror_suffix_rules) {
+ ERROR_LOC(rule->loc, "*** suffix rules are obsolete: %s", output.c_str());
+ } else if (g_flags.warn_suffix_rules) {
+ WARN_LOC(rule->loc, "warning: suffix rules are deprecated: %s",
+ output.c_str());
+ }
+
const StringPiece rest = StringPiece(output.str()).substr(1);
size_t dot_index = rest.find('.');
@@ -477,8 +479,17 @@ class DepBuilder {
void PopulateImplicitRule(const Rule* rule) {
for (Symbol output_pattern : rule->output_patterns) {
- if (output_pattern.str() != "%" || !IsIgnorableImplicitRule(rule))
+ if (output_pattern.str() != "%" || !IsIgnorableImplicitRule(rule)) {
+ if (g_flags.werror_implicit_rules) {
+ ERROR_LOC(rule->loc, "*** implicit rules are obsolete: %s",
+ output_pattern.c_str());
+ } else if (g_flags.warn_implicit_rules) {
+ WARN_LOC(rule->loc, "warning: implicit rules are deprecated: %s",
+ output_pattern.c_str());
+ }
+
implicit_rules_->Add(output_pattern.str(), rule);
+ }
}
}
@@ -501,7 +512,7 @@ class DepBuilder {
Symbol output,
DepNode* n,
shared_ptr<Rule>* out_rule) {
- Symbol matched(Symbol::IsUninitialized{});
+ Symbol matched;
for (Symbol output_pattern : rule->output_patterns) {
Pattern pat(output_pattern.str());
if (pat.Match(output.str())) {
@@ -625,7 +636,7 @@ class DepBuilder {
}
DepNode* n =
- new DepNode(output, phony_.count(output), restat_.count(output));
+ new DepNode(output, phony_.exists(output), restat_.exists(output));
done_[output] = n;
const RuleMerger* rule_merger = nullptr;
@@ -651,9 +662,9 @@ class DepBuilder {
if (vars) {
for (const auto& p : *vars) {
Symbol name = p.first;
- RuleVar* var = reinterpret_cast<RuleVar*>(p.second);
+ Var* var = p.second;
CHECK(var);
- Var* new_var = var->v();
+ Var* new_var = var;
if (var->op() == AssignOp::PLUS_EQ) {
Var* old_var = ev_->LookupVar(name);
if (old_var->IsDefined()) {
@@ -683,18 +694,98 @@ class DepBuilder {
}
}
+ if (g_flags.warn_phony_looks_real && n->is_phony &&
+ output.str().find("/") != string::npos) {
+ if (g_flags.werror_phony_looks_real) {
+ ERROR_LOC(
+ n->loc,
+ "*** PHONY target \"%s\" looks like a real file (contains a \"/\")",
+ output.c_str());
+ } else {
+ WARN_LOC(n->loc,
+ "warning: PHONY target \"%s\" looks like a real file "
+ "(contains a \"/\")",
+ output.c_str());
+ }
+ }
+
+ if (!g_flags.writable.empty() && !n->is_phony) {
+ bool found = false;
+ for (const auto& w : g_flags.writable) {
+ if (StringPiece(output.str()).starts_with(w)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ if (g_flags.werror_writable) {
+ ERROR_LOC(n->loc, "*** writing to readonly directory: \"%s\"",
+ output.c_str());
+ } else {
+ WARN_LOC(n->loc, "warning: writing to readonly directory: \"%s\"",
+ output.c_str());
+ }
+ }
+ }
+
for (Symbol output : n->implicit_outputs) {
done_[output] = n;
+
+ if (g_flags.warn_phony_looks_real && n->is_phony &&
+ output.str().find("/") != string::npos) {
+ if (g_flags.werror_phony_looks_real) {
+ ERROR_LOC(n->loc,
+ "*** PHONY target \"%s\" looks like a real file (contains "
+ "a \"/\")",
+ output.c_str());
+ } else {
+ WARN_LOC(n->loc,
+ "warning: PHONY target \"%s\" looks like a real file "
+ "(contains a \"/\")",
+ output.c_str());
+ }
+ }
+
+ if (!g_flags.writable.empty() && !n->is_phony) {
+ bool found = false;
+ for (const auto& w : g_flags.writable) {
+ if (StringPiece(output.str()).starts_with(w)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ if (g_flags.werror_writable) {
+ ERROR_LOC(n->loc, "*** writing to readonly directory: \"%s\"",
+ output.c_str());
+ } else {
+ WARN_LOC(n->loc, "warning: writing to readonly directory: \"%s\"",
+ output.c_str());
+ }
+ }
+ }
}
for (Symbol input : n->actual_inputs) {
DepNode* c = BuildPlan(input, output);
- n->deps.push_back(c);
+ n->deps.push_back({input, c});
+
+ if (!n->is_phony && c->is_phony) {
+ if (g_flags.werror_real_to_phony) {
+ ERROR_LOC(n->loc,
+ "*** real file \"%s\" depends on PHONY target \"%s\"",
+ output.c_str(), input.c_str());
+ } else if (g_flags.warn_real_to_phony) {
+ WARN_LOC(n->loc,
+ "warning: real file \"%s\" depends on PHONY target \"%s\"",
+ output.c_str(), input.c_str());
+ }
+ }
}
for (Symbol input : n->actual_order_only_inputs) {
DepNode* c = BuildPlan(input, output);
- n->order_onlys.push_back(c);
+ n->order_onlys.push_back({input,c});
}
n->has_rule = true;
@@ -722,8 +813,8 @@ class DepBuilder {
Symbol first_rule_;
unordered_map<Symbol, DepNode*> done_;
- unordered_set<Symbol> phony_;
- unordered_set<Symbol> restat_;
+ SymbolSet phony_;
+ SymbolSet restat_;
Symbol depfile_var_name_;
Symbol implicit_outputs_var_name_;
Symbol ninja_pool_var_name_;
@@ -733,7 +824,7 @@ void MakeDep(Evaluator* ev,
const vector<const Rule*>& rules,
const unordered_map<Symbol, Vars*>& rule_vars,
const vector<Symbol>& targets,
- vector<DepNode*>* nodes) {
+ vector<NamedDepNode>* nodes) {
DepBuilder db(ev, rules, rule_vars);
ScopedTimeReporter tr("make dep (build)");
db.Build(targets, nodes);