diff options
-rw-r--r-- | dep.cc | 10 | ||||
-rw-r--r-- | dep.h | 11 | ||||
-rw-r--r-- | exec.cc | 20 | ||||
-rw-r--r-- | exec.h | 5 | ||||
-rw-r--r-- | main.cc | 2 | ||||
-rw-r--r-- | ninja.cc | 26 | ||||
-rw-r--r-- | ninja.h | 4 | ||||
-rwxr-xr-x | runtest.rb | 8 | ||||
-rwxr-xr-x | testcase/ninja_implicit_dependent.sh | 48 |
9 files changed, 92 insertions, 42 deletions
@@ -338,7 +338,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."); } @@ -373,7 +373,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); } @@ -775,7 +775,7 @@ class DepBuilder { 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) { @@ -792,7 +792,7 @@ class DepBuilder { 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; @@ -831,7 +831,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); @@ -29,14 +29,17 @@ class Value; class Var; class Vars; +typedef pair<Symbol,struct DepNode *> NamedDepNode; + struct DepNode { DepNode(Symbol output, bool is_phony, bool is_restat); + string DebugString(); Symbol output; vector<Value*> cmds; - vector<DepNode*> deps; - vector<DepNode*> order_onlys; - vector<DepNode*> parents; + vector<NamedDepNode> deps; + vector<NamedDepNode> order_onlys; + vector<NamedDepNode> parents; bool has_rule; bool is_default_target; bool is_phony; @@ -58,6 +61,6 @@ 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); #endif // DEP_H_ @@ -75,17 +75,17 @@ class Executor { } double latest = kProcessing; - for (DepNode* d : n->order_onlys) { - if (Exists(d->output.str())) { + for (auto const& d : n->order_onlys) { + if (Exists(d.second->output.str())) { continue; } - double ts = ExecNode(d, n); + double ts = ExecNode(d.second, n); if (latest < ts) latest = ts; } - for (DepNode* d : n->deps) { - double ts = ExecNode(d, n); + for (auto const& d : n->deps) { + double ts = ExecNode(d.second, n); if (latest < ts) latest = ts; } @@ -138,14 +138,14 @@ class Executor { } // namespace -void Exec(const vector<DepNode*>& roots, Evaluator* ev) { +void Exec(const vector<NamedDepNode>& roots, Evaluator* ev) { unique_ptr<Executor> executor(new Executor(ev)); - for (DepNode* root : roots) { - executor->ExecNode(root, NULL); + for (auto const& root : roots) { + executor->ExecNode(root.second, NULL); } if (executor->Count() == 0) { - for (DepNode* root : roots) { - printf("kati: Nothing to be done for `%s'.\n", root->output.c_str()); + for (auto const & root : roots) { + printf("kati: Nothing to be done for `%s'.\n", root.first.c_str()); } } } @@ -18,10 +18,9 @@ #include <vector> using namespace std; - -struct DepNode; +#include "dep.h" class Evaluator; -void Exec(const vector<DepNode*>& roots, Evaluator* ev); +void Exec(const vector<NamedDepNode>& roots, Evaluator* ev); #endif // EXEC_H_ @@ -280,7 +280,7 @@ static int Run(const vector<Symbol>& targets, err->msg.c_str()); } - vector<DepNode*> nodes; + vector<NamedDepNode> nodes; { ScopedTimeReporter tr("make dep time"); MakeDep(ev.get(), ev->rules(), ev->rule_vars(), targets, &nodes); @@ -200,7 +200,7 @@ class NinjaGenerator { delete nn; } - void Generate(const vector<DepNode*>& nodes, const string& orig_args) { + void Generate(const vector<NamedDepNode>& nodes, const string& orig_args) { unlink(GetNinjaStampFilename().c_str()); PopulateNinjaNodes(nodes); GenerateNinja(); @@ -220,10 +220,10 @@ class NinjaGenerator { } private: - void PopulateNinjaNodes(const vector<DepNode*>& nodes) { + void PopulateNinjaNodes(const vector<NamedDepNode>& nodes) { ScopedTimeReporter tr("ninja gen (eval)"); - for (DepNode* node : nodes) { - PopulateNinjaNode(node); + for (auto const& node : nodes) { + PopulateNinjaNode(node.second); } } @@ -248,11 +248,11 @@ class NinjaGenerator { nn->rule_id = nn->commands.empty() ? -1 : rule_id_++; nodes_.push_back(nn); - for (DepNode* d : node->deps) { - PopulateNinjaNode(d); + for (auto const& d : node->deps) { + PopulateNinjaNode(d.second); } - for (DepNode* d : node->order_onlys) { - PopulateNinjaNode(d); + for (auto const& d : node->order_onlys) { + PopulateNinjaNode(d.second); } } @@ -557,13 +557,13 @@ class NinjaGenerator { if (node->is_phony) { *o << " _kati_always_build_"; } - for (DepNode* d : node->deps) { - *o << " " << EscapeBuildTarget(d->output).c_str(); + for (auto const& d : node->deps) { + *o << " " << EscapeBuildTarget(d.first).c_str(); } if (!node->order_onlys.empty()) { *o << " ||"; - for (DepNode* d : node->order_onlys) { - *o << " " << EscapeBuildTarget(d->output).c_str(); + for (auto const& d : node->order_onlys) { + *o << " " << EscapeBuildTarget(d.first).c_str(); } } *o << "\n"; @@ -812,7 +812,7 @@ string GetNinjaStampFilename() { return NinjaGenerator::GetFilename(".kati_stamp%s"); } -void GenerateNinja(const vector<DepNode*>& nodes, +void GenerateNinja(const vector<NamedDepNode>& nodes, Evaluator* ev, const string& orig_args, double start_time) { @@ -21,13 +21,13 @@ #include <vector> #include "string_piece.h" +#include "dep.h" using namespace std; -struct DepNode; class Evaluator; -void GenerateNinja(const vector<DepNode*>& nodes, +void GenerateNinja(const vector<NamedDepNode>& nodes, Evaluator* ev, const string& orig_args, double start_time); @@ -342,7 +342,7 @@ run_shell_test = proc do |sh| run_in_testdir(sh) do |name| cleanup - cmd = "sh ../../#{sh} make" + cmd = "bash ../../#{sh} make" if is_ninja_test cmd += ' -s' end @@ -352,15 +352,15 @@ run_shell_test = proc do |sh| if is_ninja_test if ckati - cmd = "sh ../../#{sh} ../../ckati --ninja --regen" + cmd = "bash ../../#{sh} ../../ckati --ninja --regen" else next end else if ckati - cmd = "sh ../../#{sh} ../../ckati" + cmd = "bash ../../#{sh} ../../ckati" else - cmd = "sh ../../#{sh} ../../kati --use_cache -log_dir=." + cmd = "bash ../../#{sh} ../../kati --use_cache -log_dir=." end end cmd += bash_var diff --git a/testcase/ninja_implicit_dependent.sh b/testcase/ninja_implicit_dependent.sh new file mode 100755 index 0000000..e036032 --- /dev/null +++ b/testcase/ninja_implicit_dependent.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# +# Copyright 2018 Google Inc. All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e +mk="$@" + +cat <<EOF >Makefile +all: secondary_dep + +secondary_dep: secondary + @touch \$@ + @echo Made \$@ + +primary: .KATI_IMPLICIT_OUTPUTS := secondary +primary: + @touch primary secondary + @echo Made primary+secondary +EOF + +if [[ "${mk}" =~ ^make ]]; then + echo Made primary+secondary + echo Made secondary_dep + echo Made secondary_dep + echo Nothing to do +else + ${mk} -j1 + ./ninja.sh -j1 -w dupbuild=err; + sleep 1 + touch secondary + ./ninja.sh -j1 -w dupbuild=err; + sleep 1 + echo Nothing to do + touch primary + ./ninja.sh -j1 -w dupbuild=err; +fi |