aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinichiro Hamaji <hamaji@google.com>2015-12-07 12:52:38 +0900
committerShinichiro Hamaji <hamaji@google.com>2015-12-07 12:54:23 +0900
commit5cba87b4b0dfd14374ea31f94d3730c9af1e5e55 (patch)
treeb7c0bf7cc72e67f7c0c3a9dc662dd6821ea27f67
parent07da72e4abf7674a69601263dc7b9351a2871a0a (diff)
parent42ce87c381f6990db9c7ca525d51ff21c052a98d (diff)
downloadkati-brillo-m8-release.tar.gz
Merge remote-tracking branch 'aosp/upstream'brillo-m8-releasebrillo-m8-dev
Mainly for 9dce444 also add a few warnings for unsupported features. 42ce87c [C++] Do not fail by $(shell) in functions for now 9dce444 [C++] Never specify non-positive -j value b8517f7 Add implicit_pattern_rule_chain2.mk 28da237 [C++] Explicitly disallow $(shell) in other make constructs 77be80d [C++] Warn about unsupported builtin targets cbe9f49 [C++] Add a minimal support for .SUFFIXES 3de9ae0 Add delete_on_error.mk Change-Id: Ia19d8d5f8e5bfb22627aaaa7ed7c461f47b34733
-rw-r--r--dep.cc32
-rw-r--r--eval.cc3
-rw-r--r--eval.h12
-rw-r--r--expr.cc8
-rw-r--r--func.cc11
-rw-r--r--main.cc2
-rw-r--r--testcase/delete_on_error.mk9
-rw-r--r--testcase/err_suffixes.mk10
-rw-r--r--testcase/err_suffixes2.mk8
-rw-r--r--testcase/implicit_pattern_rule_chain2.mk13
-rw-r--r--testcase/strip_and_shell.mk1
11 files changed, 106 insertions, 3 deletions
diff --git a/dep.cc b/dep.cc
index 56c45ce..657c97f 100644
--- a/dep.cc
+++ b/dep.cc
@@ -139,6 +139,38 @@ class DepBuilder {
restat_.insert(input);
}
}
+ found = rules_.find(Intern(".SUFFIXES"));
+ if (found != rules_.end()) {
+ if (found->second->inputs.empty()) {
+ suffix_rules_.clear();
+ } else {
+ WARN("%s:%d: kati doesn't support .SUFFIXES with prerequisites",
+ LOCF(found->second->loc));
+ }
+ }
+
+ // Note we can safely ignore .DELETE_ON_ERROR for --ninja mode.
+ static const char* kUnsupportedBuiltinTargets[] = {
+ ".DEFAULT",
+ ".PRECIOUS",
+ ".INTERMEDIATE",
+ ".SECONDARY",
+ ".SECONDEXPANSION",
+ ".IGNORE",
+ ".LOW_RESOLUTION_TIME",
+ ".SILENT",
+ ".EXPORT_ALL_VARIABLES",
+ ".NOTPARALLEL",
+ ".ONESHELL",
+ ".POSIX",
+ NULL
+ };
+ for (const char** p = kUnsupportedBuiltinTargets; *p; p++) {
+ auto found = rules_.find(Intern(*p));
+ if (found != rules_.end()) {
+ WARN("%s:%d: kati doesn't support %s", LOCF(found->second->loc), *p);
+ }
+ }
}
~DepBuilder() {
diff --git a/eval.cc b/eval.cc
index 2ba4a56..3c0eae2 100644
--- a/eval.cc
+++ b/eval.cc
@@ -41,7 +41,8 @@ Evaluator::Evaluator(const Vars* vars)
vars_(new Vars()),
last_rule_(NULL),
current_scope_(NULL),
- avoid_io_(false) {
+ avoid_io_(false),
+ eval_depth_(0) {
}
Evaluator::~Evaluator() {
diff --git a/eval.h b/eval.h
index 3ebb21b..6bc21b9 100644
--- a/eval.h
+++ b/eval.h
@@ -92,6 +92,14 @@ class Evaluator {
return used_undefined_vars_;
}
+ int eval_depth() const { return eval_depth_; }
+ void IncrementEvalDepth() {
+ eval_depth_++;
+ }
+ void DecrementEvalDepth() {
+ eval_depth_--;
+ }
+
private:
Var* EvalRHS(Symbol lhs, Value* rhs, StringPiece orig_rhs, AssignOp op,
bool is_override = false);
@@ -112,6 +120,10 @@ class Evaluator {
bool is_bootstrap_;
bool avoid_io_;
+ // This value tracks the nest level of make expressions. For
+ // example, $(YYY) in $(XXX $(YYY)) is evaluated with depth==2.
+ // This will be used to disallow $(shell) in other make constructs.
+ int eval_depth_;
// Commands which should run at ninja-time (i.e., info, warning, and
// error).
vector<string> delayed_output_commands_;
diff --git a/expr.cc b/expr.cc
index e43d189..d0d3e38 100644
--- a/expr.cc
+++ b/expr.cc
@@ -152,7 +152,9 @@ class VarRef : public Value {
}
virtual void Eval(Evaluator* ev, string* s) const override {
+ ev->IncrementEvalDepth();
const string&& name = name_->Eval(ev);
+ ev->DecrementEvalDepth();
Var* v = ev->LookupVar(Intern(name));
v->Eval(ev, s);
}
@@ -177,11 +179,13 @@ class VarSubst : public Value {
}
virtual void Eval(Evaluator* ev, string* s) const override {
+ ev->IncrementEvalDepth();
const string&& name = name_->Eval(ev);
Var* v = ev->LookupVar(Intern(name));
- const string&& value = v->Eval(ev);
const string&& pat_str = pat_->Eval(ev);
const string&& subst = subst_->Eval(ev);
+ ev->DecrementEvalDepth();
+ const string&& value = v->Eval(ev);
WordWriter ww(s);
Pattern pat(pat_str);
for (StringPiece tok : WordScanner(value)) {
@@ -216,7 +220,9 @@ class Func : public Value {
virtual void Eval(Evaluator* ev, string* s) const override {
LOG("Invoke func %s(%s)", name(), JoinValues(args_, ",").c_str());
+ ev->IncrementEvalDepth();
fi_->func(args_, ev, s);
+ ev->DecrementEvalDepth();
}
virtual string DebugString_() const override {
diff --git a/func.cc b/func.cc
index 33c5013..2e6eb99 100644
--- a/func.cc
+++ b/func.cc
@@ -546,6 +546,12 @@ bool ShouldStoreCommandResult(StringPiece cmd) {
void ShellFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
string cmd = args[0]->Eval(ev);
if (ev->avoid_io() && !HasNoIoInShellScript(cmd)) {
+ if (ev->eval_depth() > 1) {
+ // TODO: Make this an error.
+ WARN("%s:%d: kati doesn't support passing results of $(shell) "
+ "to other make constructs: %s",
+ LOCF(ev->loc()), cmd.c_str());
+ }
StripShellComment(&cmd);
*s += "$(";
*s += cmd;
@@ -609,12 +615,16 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
Intern(tmpvar_name), av[i-1].get()));
}
}
+
+ ev->DecrementEvalDepth();
func->Eval(ev, s);
+ ev->IncrementEvalDepth();
}
void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
const string&& varname = args[0]->Eval(ev);
const string&& list = args[1]->Eval(ev);
+ ev->DecrementEvalDepth();
WordWriter ww(s);
for (StringPiece tok : WordScanner(list)) {
unique_ptr<SimpleVar> v(new SimpleVar(
@@ -623,6 +633,7 @@ void ForeachFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
ww.MaybeAddWhitespace();
args[2]->Eval(ev, s);
}
+ ev->IncrementEvalDepth();
}
void OriginFunc(const vector<Value*>& args, Evaluator* ev, string* s) {
diff --git a/main.cc b/main.cc
index 930348b..ff2b751 100644
--- a/main.cc
+++ b/main.cc
@@ -86,7 +86,7 @@ static void ReadBootstrapMakefile(const vector<Symbol>& targets,
);
if (g_flags.generate_ninja) {
bootstrap += StringPrintf("MAKE?=make -j%d\n",
- g_flags.num_jobs < 1 ? 1 : g_flags.num_jobs / 2);
+ g_flags.num_jobs <= 1 ? 1 : g_flags.num_jobs / 2);
} else {
bootstrap += StringPrintf("MAKE?=%s\n",
JoinStrings(g_flags.subkati_args, " ").c_str());
diff --git a/testcase/delete_on_error.mk b/testcase/delete_on_error.mk
new file mode 100644
index 0000000..f194759
--- /dev/null
+++ b/testcase/delete_on_error.mk
@@ -0,0 +1,9 @@
+# TODO: Fix for non-ninja mode.
+
+.DELETE_ON_ERROR:
+
+test: file
+
+file:
+ touch $@
+ false
diff --git a/testcase/err_suffixes.mk b/testcase/err_suffixes.mk
new file mode 100644
index 0000000..2ac6d09
--- /dev/null
+++ b/testcase/err_suffixes.mk
@@ -0,0 +1,10 @@
+# TODO: Fix
+
+test1:
+ touch a.src
+
+test2: a.out
+
+# This isn't in .SUFFIXES.
+.src.out:
+ echo $< > $@
diff --git a/testcase/err_suffixes2.mk b/testcase/err_suffixes2.mk
new file mode 100644
index 0000000..8f9bacb
--- /dev/null
+++ b/testcase/err_suffixes2.mk
@@ -0,0 +1,8 @@
+# TODO(go): Fix
+
+test1:
+ touch a.c
+
+test2: a.o
+
+.SUFFIXES:
diff --git a/testcase/implicit_pattern_rule_chain2.mk b/testcase/implicit_pattern_rule_chain2.mk
new file mode 100644
index 0000000..65e914b
--- /dev/null
+++ b/testcase/implicit_pattern_rule_chain2.mk
@@ -0,0 +1,13 @@
+# TODO: Fix. We probably need to assume foo.y exists as there's a rule
+# to generate it.
+
+test1:
+ touch foo.x
+
+test2: foo.z
+
+%.z: %.y
+ cp $< $@
+
+%.y: %.x
+ cp $< $@
diff --git a/testcase/strip_and_shell.mk b/testcase/strip_and_shell.mk
index db1bbf2..cb550f3 100644
--- a/testcase/strip_and_shell.mk
+++ b/testcase/strip_and_shell.mk
@@ -1,3 +1,4 @@
+# TODO(c-ninja): $(shell) in another make expression is not supported.
test:
echo $(strip $(shell pwd))