aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2017-08-17 14:17:54 -0700
committerDan Willemsen <dwillemsen@google.com>2017-08-17 14:17:54 -0700
commitac81d0af5c7f55483a1e2a87d59c42bd6206e7ff (patch)
tree1efcaddb067c25f8e18ad51ed81e35bfd00ed2c1
parent49104c833dd6bcc805ac544d7a9c96a19ab5264c (diff)
parentbd56cbed65d42b8473523600fceab94639ee6eec (diff)
downloadplatform_build_kati-ac81d0af5c7f55483a1e2a87d59c42bd6206e7ff.tar.gz
platform_build_kati-ac81d0af5c7f55483a1e2a87d59c42bd6206e7ff.tar.bz2
platform_build_kati-ac81d0af5c7f55483a1e2a87d59c42bd6206e7ff.zip
Merge remote-tracking branch 'aosp/upstream' into master
* aosp/upstream: Turn off LeakSanitizer by default Include implicit outputs in the DepNode graph Travis: switch to trusty, ninja 1.7 Support Ninja implicit outputs Test: prebuilts/build-tools/build-prebuilts.sh Test: Tried .KATI_IMPLICIT_OUTPUTS with LOCAL_GENERATED_SOURCES
-rw-r--r--.travis.yml8
-rw-r--r--dep.cc73
-rw-r--r--dep.h1
-rw-r--r--main.cc5
-rw-r--r--ninja.cc9
-rw-r--r--testcase/ninja_implicit_output_var.sh35
-rw-r--r--testcase/ninja_implicit_outputs.sh42
7 files changed, 169 insertions, 4 deletions
diff --git a/.travis.yml b/.travis.yml
index 3bbe280..9c14f63 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,18 @@
language: cpp
+dist: trusty
+sudo: required
+
compiler:
- clang
cache: apt
before_script:
- - sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu/ trusty main universe"
- sudo apt-get update -qq
- - sudo apt-get install -y libstdc++-4.8-dev clang-3.5 ninja-build realpath
+ - sudo apt-get install -y realpath
+ - wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip
+ - unzip ninja-linux.zip -d ~/bin
script:
- make -j4 ckati ckati_tests
diff --git a/dep.cc b/dep.cc
index e9aa32b..16aeeec 100644
--- a/dep.cc
+++ b/dep.cc
@@ -144,14 +144,39 @@ bool IsSuffixRule(Symbol output) {
struct RuleMerger {
vector<const Rule*> rules;
+ vector<pair<Symbol, RuleMerger*>> implicit_outputs;
const Rule* primary_rule;
+ const RuleMerger* parent;
+ Symbol parent_sym;
bool is_double_colon;
RuleMerger()
: primary_rule(nullptr),
+ parent(nullptr),
+ parent_sym(Symbol::IsUninitialized()),
is_double_colon(false) {
}
+ void AddImplicitOutput(Symbol output, RuleMerger *merger) {
+ implicit_outputs.push_back(make_pair(output, merger));
+ }
+
+ void SetImplicitOutput(Symbol output, Symbol p, const RuleMerger* merger) {
+ if (!merger->primary_rule) {
+ ERROR("*** implicit output `%s' on phony target `%s'", output.c_str(), p.c_str());
+ }
+ if (parent) {
+ ERROR_LOC(merger->primary_rule->cmd_loc(), "*** implicit output `%s' of `%s' was already defined by `%s' at %s:%d",
+ output.c_str(), p.c_str(), parent_sym.c_str(), parent->primary_rule->cmd_loc());
+ }
+ if (primary_rule) {
+ ERROR_LOC(primary_rule->cmd_loc(), "*** implicit output `%s' may not have commands",
+ output.c_str());
+ }
+ parent = merger;
+ parent_sym = p;
+ }
+
void AddRule(Symbol output, const Rule* r) {
if (rules.empty()) {
is_double_colon = r->is_double_colon;
@@ -226,6 +251,13 @@ struct RuleMerger {
if (n->loc.filename == NULL)
n->loc = r->loc;
}
+
+ for (auto& implicit_output : implicit_outputs) {
+ n->implicit_outputs.push_back(implicit_output.first);
+ for (const Rule* r : implicit_output.second->rules) {
+ FillDepNodeFromRule(output, r, n);
+ }
+ }
}
};
@@ -254,6 +286,7 @@ class DepBuilder {
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")) {
ScopedTimeReporter tr("make dep (populate)");
PopulateRules(rules);
@@ -386,6 +419,25 @@ class DepBuilder {
for (auto& p : suffix_rules_) {
reverse(p.second.begin(), p.second.end());
}
+ for (auto& p : rules_) {
+ auto vars = LookupRuleVars(p.first);
+ if (!vars) {
+ continue;
+ }
+ auto var = vars->Lookup(implicit_outputs_var_name_);
+ if (!var->IsDefined()) {
+ continue;
+ }
+
+ string implicit_outputs;
+ var->Eval(ev_, &implicit_outputs);
+
+ for (StringPiece output : WordScanner(implicit_outputs)) {
+ Symbol sym = Intern(TrimLeadingCurdir(output));
+ rules_[sym].SetImplicitOutput(sym, p.first, &p.second);
+ p.second.AddImplicitOutput(sym, &rules_[sym]);
+ }
+ }
}
bool PopulateSuffixRule(const Rule* rule, Symbol output) {
@@ -517,8 +569,13 @@ class DepBuilder {
Vars* vars = LookupRuleVars(output);
*out_rule_merger = rule_merger;
*out_var = vars;
- if (rule_merger && rule_merger->primary_rule)
+ if (rule_merger && rule_merger->primary_rule) {
+ for (auto implicit_output : rule_merger->implicit_outputs) {
+ vars = MergeImplicitRuleVars(implicit_output.first, vars);
+ }
+ *out_var = vars;
return true;
+ }
vector<const Rule*> irules;
implicit_rules_->Get(output.str(), &irules);
@@ -584,6 +641,14 @@ class DepBuilder {
if (!PickRule(output, n, &rule_merger, &pattern_rule, &vars)) {
return n;
}
+ if (rule_merger && rule_merger->parent) {
+ output = rule_merger->parent_sym;
+ done_[output] = n;
+ n->output = output;
+ if (!PickRule(output, n, &rule_merger, &pattern_rule, &vars)) {
+ return n;
+ }
+ }
if (rule_merger)
rule_merger->FillDepNode(output, pattern_rule.get(), n);
else
@@ -616,6 +681,7 @@ class DepBuilder {
if (name == depfile_var_name_) {
n->depfile_var = new_var;
+ } else if (name == implicit_outputs_var_name_) {
} else if (name == ninja_pool_var_name_) {
n->ninja_pool_var = new_var;
} else {
@@ -624,6 +690,10 @@ class DepBuilder {
}
}
+ for (Symbol output : n->implicit_outputs) {
+ done_[output] = n;
+ }
+
for (Symbol input : n->actual_inputs) {
DepNode* c = BuildPlan(input, output);
n->deps.push_back(c);
@@ -662,6 +732,7 @@ class DepBuilder {
unordered_set<Symbol> phony_;
unordered_set<Symbol> restat_;
Symbol depfile_var_name_;
+ Symbol implicit_outputs_var_name_;
Symbol ninja_pool_var_name_;
};
diff --git a/dep.h b/dep.h
index 5e879e3..c42b380 100644
--- a/dep.h
+++ b/dep.h
@@ -41,6 +41,7 @@ struct DepNode {
bool is_default_target;
bool is_phony;
bool is_restat;
+ vector<Symbol> implicit_outputs;
vector<Symbol> actual_inputs;
vector<Symbol> actual_order_only_inputs;
Vars* rule_vars;
diff --git a/main.cc b/main.cc
index a4df3c0..2e45810 100644
--- a/main.cc
+++ b/main.cc
@@ -44,6 +44,11 @@
#include "timeutil.h"
#include "var.h"
+// We know that there are leaks in Kati. Turn off LeakSanitizer by default.
+extern "C" const char* __asan_default_options() {
+ return "detect_leaks=0";
+}
+
static void Init() {
InitSymtab();
InitFuncTable();
diff --git a/ninja.cc b/ninja.cc
index fca3ace..0d7acc9 100644
--- a/ninja.cc
+++ b/ninja.cc
@@ -546,7 +546,14 @@ class NinjaGenerator {
bool use_local_pool, ostringstream* o) {
const DepNode* node = nn->node;
string target = EscapeBuildTarget(node->output);
- *o << "build " << target << ": " << rule_name;
+ *o << "build " << target;
+ if (!node->implicit_outputs.empty()) {
+ *o << " |";
+ for (Symbol output : node->implicit_outputs) {
+ *o << " " << EscapeBuildTarget(output);
+ }
+ }
+ *o << ": " << rule_name;
vector<Symbol> order_onlys;
if (node->is_phony) {
*o << " _kati_always_build_";
diff --git a/testcase/ninja_implicit_output_var.sh b/testcase/ninja_implicit_output_var.sh
new file mode 100644
index 0000000..63ef6b4
--- /dev/null
+++ b/testcase/ninja_implicit_output_var.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+#
+# Copyright 2015 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: a
+
+a:
+ if ! [ -z "\$(VAR)" ]; then echo \$(VAR); fi
+a: .KATI_IMPLICIT_OUTPUTS := b
+b: VAR := OK
+EOF
+
+${mk} -j1
+if [ -e ninja.sh ]; then
+ ./ninja.sh -j1 -w dupbuild=err;
+else
+ echo OK
+fi
diff --git a/testcase/ninja_implicit_outputs.sh b/testcase/ninja_implicit_outputs.sh
new file mode 100644
index 0000000..43c91a0
--- /dev/null
+++ b/testcase/ninja_implicit_outputs.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# Copyright 2015 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: a b
+
+a b:
+ touch A
+ echo 1 >>A
+d: a
+c: .KATI_IMPLICIT_OUTPUTS := d
+c:
+ touch C
+ echo 1 >>C
+
+c d: b
+EOF
+
+${mk} -j1 all d c
+if [ -e ninja.sh ]; then ./ninja.sh -j1 -w dupbuild=err all d; fi
+
+echo "A:"
+cat A
+echo "C":
+cat C