diff options
author | Dan Willemsen <dwillemsen@google.com> | 2018-02-27 00:25:01 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2018-02-27 03:14:23 -0800 |
commit | c3f6a9791d9b747a49dfd02602bb5662ba6e2783 (patch) | |
tree | e78b0345bfc5a080fb757ba5406cfd0cded2a600 | |
parent | 575ebd04c5a3c305233b6ad8d8952a6295160f25 (diff) | |
download | kati-c3f6a9791d9b747a49dfd02602bb5662ba6e2783.tar.gz |
Add KATI_(deprecate|obsolete)_export
Allow makefiles to mark the `export` and `unexport` keywords as
deprecated or obsolete. In large builds like Android, we've got our own
ways to set global environment variables, it's very unlikely that
individual makefiles need to set an environment variable for every
single rule.
We expect to eventually add environment variables to the list of inputs
that ninja checks to see if a command needs to run again (currently it
just checks the timestamps and commandline). Reducing the ability for
makefiles to export global variables per-configuration means that we're
more likely to share compile steps between configurations.
Change-Id: I8df0630ef264e39fd077b08dcac57e571ebe214f
-rw-r--r-- | eval.cc | 24 | ||||
-rw-r--r-- | eval.h | 14 | ||||
-rw-r--r-- | func.cc | 32 | ||||
-rw-r--r-- | testcase/deprecated_export.mk | 21 | ||||
-rw-r--r-- | testcase/err_obsolete_export.mk | 7 |
5 files changed, 95 insertions, 3 deletions
@@ -38,6 +38,7 @@ Evaluator::Evaluator() eval_depth_(0), posix_sym_(Intern(".POSIX")), is_posix_(false), + export_error_(false), kati_readonly_(Intern(".KATI_READONLY")) { #if defined(__APPLE__) stack_size_ = pthread_get_stacksize_np(pthread_self()); @@ -358,18 +359,35 @@ void Evaluator::EvalExport(const ExportStmt* stmt) { const string&& exports = stmt->expr->Eval(this); for (StringPiece tok : WordScanner(exports)) { size_t equal_index = tok.find('='); + StringPiece lhs; if (equal_index == string::npos) { - exports_[Intern(tok)] = stmt->is_export; + lhs = tok; } else if (equal_index == 0 || (equal_index == 1 && (tok[0] == ':' || tok[0] == '?' || tok[0] == '+'))) { // Do not export tokens after an assignment. break; } else { - StringPiece lhs, rhs; + StringPiece rhs; AssignOp op; ParseAssignStatement(tok, equal_index, &lhs, &rhs, &op); - exports_[Intern(lhs)] = stmt->is_export; + } + Symbol sym = Intern(lhs); + exports_[sym] = stmt->is_export; + + if (export_message_) { + const char* prefix = ""; + if (!stmt->is_export) { + prefix = "un"; + } + + if (export_error_) { + Error(StringPrintf("*** %s: %sexport is obsolete%s.", sym.c_str(), + prefix, export_message_->c_str())); + } else { + WARN_LOC(loc(), "%s: %sexport has been deprecated%s.", sym.c_str(), + prefix, export_message_->c_str()); + } } } } @@ -15,6 +15,7 @@ #ifndef EVAL_H_ #define EVAL_H_ +#include <memory> #include <unordered_map> #include <unordered_set> #include <vector> @@ -98,6 +99,16 @@ class Evaluator { } void DumpStackStats() const; + bool ExportDeprecated() const { return export_message_ && !export_error_; }; + bool ExportObsolete() const { return export_error_; }; + void SetExportDeprecated(StringPiece msg) { + export_message_.reset(new string(msg.as_string())); + } + void SetExportObsolete(StringPiece msg) { + export_message_.reset(new string(msg.as_string())); + export_error_ = true; + } + private: Var* EvalRHS(Symbol lhs, Value* rhs, @@ -139,6 +150,9 @@ class Evaluator { void* lowest_stack_; Loc lowest_loc_; + unique_ptr<string> export_message_; + bool export_error_; + static unordered_set<Symbol> used_undefined_vars_; Symbol kati_readonly_; @@ -892,6 +892,36 @@ void ObsoleteVarFunc(const vector<Value*>& args, Evaluator* ev, string*) { } } +void DeprecateExportFunc(const vector<Value*>& args, Evaluator* ev, string*) { + string msg = ". " + args[0]->Eval(ev); + + if (ev->avoid_io()) { + ev->Error("*** $(KATI_deprecate_export) is not supported in rules."); + } + + if (ev->ExportObsolete()) { + ev->Error("*** Export is already obsolete."); + } else if (ev->ExportDeprecated()) { + ev->Error("*** Export is already deprecated."); + } + + ev->SetExportDeprecated(msg); +} + +void ObsoleteExportFunc(const vector<Value*>& args, Evaluator* ev, string*) { + string msg = ". " + args[0]->Eval(ev); + + if (ev->avoid_io()) { + ev->Error("*** $(KATI_obsolete_export) is not supported in rules."); + } + + if (ev->ExportObsolete()) { + ev->Error("*** Export is already obsolete."); + } + + ev->SetExportObsolete(msg); +} + FuncInfo g_func_infos[] = { {"patsubst", &PatsubstFunc, 3, 3, false, false}, {"strip", &StripFunc, 1, 1, false, false}, @@ -939,6 +969,8 @@ FuncInfo g_func_infos[] = { /* Kati custom extension functions */ {"KATI_deprecated_var", &DeprecatedVarFunc, 2, 1, false, false}, {"KATI_obsolete_var", &ObsoleteVarFunc, 2, 1, false, false}, + {"KATI_deprecate_export", &DeprecateExportFunc, 1, 1, false, false}, + {"KATI_obsolete_export", &ObsoleteExportFunc, 1, 1, false, false}, }; unordered_map<StringPiece, FuncInfo*>* g_func_info_map; diff --git a/testcase/deprecated_export.mk b/testcase/deprecated_export.mk new file mode 100644 index 0000000..3744f70 --- /dev/null +++ b/testcase/deprecated_export.mk @@ -0,0 +1,21 @@ +# TODO(go): not implemented + +A := 1 +B := 2 +export A B + +$(KATI_deprecate_export Message) + +export C := ok +unexport B + +ifndef KATI +$(info Makefile:9: C: export has been deprecated. Message.) +$(info Makefile:10: B: unexport has been deprecated. Message.) +endif + +test: + echo $$(A) + echo $$(B) + echo $$(C) + echo Done diff --git a/testcase/err_obsolete_export.mk b/testcase/err_obsolete_export.mk new file mode 100644 index 0000000..bf78dc3 --- /dev/null +++ b/testcase/err_obsolete_export.mk @@ -0,0 +1,7 @@ +# TODO(go): not implemented + +export A := ok + +$(KATI_obsolete_export Message) + +export B := fail $(or $(KATI),$(error B: export is obsolete. Message)) |