diff options
| author | Shinichiro Hamaji <hamaji@google.com> | 2015-10-01 14:36:04 +0900 |
|---|---|---|
| committer | Shinichiro Hamaji <hamaji@google.com> | 2015-10-01 14:36:04 +0900 |
| commit | 7bd2e93a0036cf5eda8fc299cbdeda3ba9a14950 (patch) | |
| tree | 1cfb0e7e89ad923a7e418a09c9158441df69907e | |
| parent | 77af4e409d964a8a892e01ed97025e9aee7a24db (diff) | |
| parent | a62b02a1251a0f6c452a25fce03258f12472507f (diff) | |
| download | platform_build_kati-7bd2e93a0036cf5eda8fc299cbdeda3ba9a14950.tar.gz platform_build_kati-7bd2e93a0036cf5eda8fc299cbdeda3ba9a14950.tar.bz2 platform_build_kati-7bd2e93a0036cf5eda8fc299cbdeda3ba9a14950.zip | |
Merge remote-tracking branch 'aosp/upstream'
| -rw-r--r-- | dep.cc | 17 | ||||
| -rw-r--r-- | dep.h | 1 | ||||
| -rw-r--r-- | main.cc | 9 | ||||
| -rw-r--r-- | ninja.cc | 140 | ||||
| -rw-r--r-- | ninja.h | 12 | ||||
| -rw-r--r-- | rule.cc | 3 | ||||
| -rw-r--r-- | rule.h | 1 | ||||
| -rw-r--r-- | testcase/default_rule.mk | 5 |
8 files changed, 85 insertions, 103 deletions
@@ -104,6 +104,7 @@ DepNode::DepNode(Symbol o, bool p) : output(o), has_rule(false), is_phony(p), + is_default_target(false), rule_vars(NULL), output_pattern(Symbol::IsUninitialized()) { g_dep_node_pool->push_back(this); @@ -135,14 +136,15 @@ class DepBuilder { ~DepBuilder() { } - void Build(vector<Symbol> targets, - vector<DepNode*>* nodes) { - if (targets.empty()) { - if (!first_rule_) { - ERROR("*** No targets."); - } - CHECK(!first_rule_->outputs.empty()); + void Build(vector<Symbol> targets, vector<DepNode*>* nodes) { + if (!first_rule_) { + ERROR("*** No targets."); + } + CHECK(!first_rule_->outputs.empty()); + + first_rule_->is_default_target = true; + if (targets.empty()) { targets.push_back(first_rule_->outputs[0]); } if (g_flags.gen_all_phony_targets) { @@ -505,6 +507,7 @@ class DepBuilder { n->has_rule = true; n->cmds = rule->cmds; + n->is_default_target = rule->is_default_target; if (cur_rule_vars_->empty()) { n->rule_vars = NULL; } else { @@ -39,6 +39,7 @@ struct DepNode { vector<DepNode*> parents; bool has_rule; bool is_phony; + bool is_default_target; vector<Symbol> actual_inputs; Vars* rule_vars; Symbol output_pattern; @@ -133,10 +133,7 @@ static int Run(const vector<Symbol>& targets, if (g_flags.generate_ninja && (g_flags.regen || g_flags.dump_kati_stamp)) { ScopedTimeReporter tr("regen check time"); - if (!NeedsRegen(g_flags.ninja_suffix, g_flags.ninja_dir, - g_flags.regen_ignoring_kati_binary, - g_flags.dump_kati_stamp, - start_time, orig_args)) { + if (!NeedsRegen(start_time, orig_args)) { printf("No need to regenerate ninja file\n"); return 0; } @@ -197,9 +194,7 @@ static int Run(const vector<Symbol>& targets, if (g_flags.generate_ninja) { ScopedTimeReporter tr("generate ninja time"); - GenerateNinja(g_flags.ninja_suffix, g_flags.ninja_dir, - nodes, ev, !targets.empty(), - orig_args, start_time); + GenerateNinja(nodes, ev, orig_args, start_time); return 0; } @@ -168,21 +168,13 @@ bool GetDepfileFromCommand(string* cmd, string* out) { class NinjaGenerator { public: - NinjaGenerator(const char* ninja_suffix, const char* ninja_dir, Evaluator* ev, - double start_time) - : ce_(ev), ev_(ev), fp_(NULL), rule_id_(0), start_time_(start_time) { + NinjaGenerator(Evaluator* ev, double start_time) + : ce_(ev), ev_(ev), fp_(NULL), rule_id_(0), start_time_(start_time), + default_target_(NULL) { ev_->set_avoid_io(true); shell_ = ev->EvalVar(kShellSym); if (g_flags.goma_dir) gomacc_ = StringPrintf("%s/gomacc ", g_flags.goma_dir); - if (ninja_suffix) { - ninja_suffix_ = ninja_suffix; - } - if (ninja_dir) { - ninja_dir_ = ninja_dir; - } else { - ninja_dir_ = "."; - } GetExecutablePath(&kati_binary_); } @@ -192,24 +184,19 @@ class NinjaGenerator { } void Generate(const vector<DepNode*>& nodes, - bool build_all_targets, const string& orig_args) { unlink(GetStampFilename().c_str()); - GenerateNinja(nodes, build_all_targets, orig_args); + GenerateNinja(nodes, orig_args); GenerateShell(); GenerateStamp(orig_args); } - static string GetStampFilename(const char* ninja_dir, - const char* ninja_suffix) { - return StringPrintf("%s/.kati_stamp%s", - ninja_dir ? ninja_dir : ".", - ninja_suffix ? ninja_suffix : ""); + static string GetStampFilename() { + return GetFilename(".kati_stamp%s"); } - static string GetStampTempFilename(const char* ninja_dir, - const char* ninja_suffix) { - return StringPrintf("%s.tmp", GetStampFilename(ninja_dir, ninja_suffix).c_str()); + static string GetStampTempFilename() { + return GetFilename(".kati_stamp%s.tmp"); } private: @@ -452,9 +439,7 @@ class NinjaGenerator { } } - EmitBuild(node, rule_name); - if (use_local_pool) - fprintf(fp_, " pool = local_pool\n"); + EmitBuild(node, rule_name, use_local_pool); for (DepNode* d : node->deps) { EmitNode(d); @@ -513,9 +498,10 @@ class NinjaGenerator { s->swap(r); } - void EmitBuild(DepNode* node, const string& rule_name) { + void EmitBuild(DepNode* node, const string& rule_name, bool use_local_pool) { + string target = EscapeBuildTarget(node->output); fprintf(fp_, "build %s: %s", - EscapeBuildTarget(node->output).c_str(), + target.c_str(), rule_name.c_str()); vector<Symbol> order_onlys; if (node->is_phony) { @@ -531,6 +517,11 @@ class NinjaGenerator { } } fprintf(fp_, "\n"); + if (use_local_pool) + fprintf(fp_, " pool = local_pool\n"); + if (node->is_default_target) { + default_target_ = node; + } } void EmitRegenRules(const string& orig_args) { @@ -552,25 +543,21 @@ class NinjaGenerator { } string GetNinjaFilename() const { - return StringPrintf("%s/build%s.ninja", - ninja_dir_.c_str(), ninja_suffix_.c_str()); + return GetFilename("build%s.ninja"); } string GetShellScriptFilename() const { - return StringPrintf("%s/ninja%s.sh", - ninja_dir_.c_str(), ninja_suffix_.c_str()); + return GetFilename("ninja%s.sh"); } - string GetStampFilename() const { - return GetStampFilename(ninja_dir_.c_str(), ninja_suffix_.c_str()); - } - - string GetStampTempFilename() const { - return GetStampTempFilename(ninja_dir_.c_str(), ninja_suffix_.c_str()); + static string GetFilename(const char* fmt) { + string r = g_flags.ninja_dir ? g_flags.ninja_dir : "."; + r += '/'; + r += StringPrintf(fmt, g_flags.ninja_suffix ? g_flags.ninja_suffix : ""); + return r; } void GenerateNinja(const vector<DepNode*>& nodes, - bool build_all_targets, const string& orig_args) { fp_ = fopen(GetNinjaFilename().c_str(), "wb"); if (fp_ == NULL) @@ -587,8 +574,8 @@ class NinjaGenerator { fprintf(fp_, "\n"); } - if (ninja_dir_ != ".") { - fprintf(fp_, "builddir = %s\n\n", ninja_dir_.c_str()); + if (g_flags.ninja_dir) { + fprintf(fp_, "builddir = %s\n\n", g_flags.ninja_dir); } fprintf(fp_, "pool local_pool\n"); @@ -607,11 +594,20 @@ class NinjaGenerator { used_envs_.emplace(e.str(), val.as_string()); } - if (!build_all_targets) { - CHECK(!nodes.empty()); - fprintf(fp_, "\ndefault %s\n", - EscapeBuildTarget(nodes.front()->output).c_str()); + string default_targets; + if (g_flags.targets.empty() || + g_flags.gen_all_targets || g_flags.gen_all_phony_targets) { + CHECK(default_target_); + default_targets = EscapeBuildTarget(default_target_->output); + } else { + for (Symbol s : g_flags.targets) { + if (!default_targets.empty()) + default_targets += ' '; + default_targets += EscapeBuildTarget(s); + } } + fprintf(fp_, "\n"); + fprintf(fp_, "default %s\n", default_targets.c_str()); fclose(fp_); } @@ -624,8 +620,6 @@ class NinjaGenerator { fprintf(fp, "#!/bin/sh\n"); fprintf(fp, "# Generated by kati %s\n", kGitVersion); fprintf(fp, "\n"); - if (ninja_dir_ == ".") - fprintf(fp, "cd $(dirname \"$0\")\n"); for (const auto& p : ev_->exports()) { if (p.second) { @@ -736,23 +730,19 @@ class NinjaGenerator { unordered_set<Symbol> done_; int rule_id_; string gomacc_; - string ninja_suffix_; - string ninja_dir_; string shell_; map<string, string> used_envs_; string kati_binary_; double start_time_; + DepNode* default_target_; }; -void GenerateNinja(const char* ninja_suffix, - const char* ninja_dir, - const vector<DepNode*>& nodes, +void GenerateNinja(const vector<DepNode*>& nodes, Evaluator* ev, - bool build_all_targets, const string& orig_args, double start_time) { - NinjaGenerator ng(ninja_suffix, ninja_dir, ev, start_time); - ng.Generate(nodes, build_all_targets, orig_args); + NinjaGenerator ng(ev, start_time); + ng.Generate(nodes, orig_args); } static bool ShouldIgnoreDirty(StringPiece s) { @@ -760,15 +750,10 @@ static bool ShouldIgnoreDirty(StringPiece s) { Pattern(g_flags.ignore_dirty_pattern).Match(s)); } -bool NeedsRegen(const char* ninja_suffix, - const char* ninja_dir, - bool ignore_kati_binary, - bool dump_kati_stamp, - double start_time, - const string& orig_args) { +bool NeedsRegen(double start_time, const string& orig_args) { bool retval = false; #define RETURN_TRUE do { \ - if (dump_kati_stamp) \ + if (g_flags.dump_kati_stamp) \ retval = true; \ else \ return true; \ @@ -790,8 +775,7 @@ bool NeedsRegen(const char* ninja_suffix, } \ }) - const string& stamp_filename = - NinjaGenerator::GetStampFilename(ninja_dir, ninja_suffix); + const string& stamp_filename = NinjaGenerator::GetStampFilename(); FILE* fp = fopen(stamp_filename.c_str(), "rb+"); if (!fp) RETURN_TRUE; @@ -803,7 +787,7 @@ bool NeedsRegen(const char* ninja_suffix, fprintf(stderr, "incomplete kati_stamp, regenerating...\n"); RETURN_TRUE; } - if (dump_kati_stamp) + if (g_flags.dump_kati_stamp) printf("Generated time: %f\n", gen_time); string s, s2; @@ -812,7 +796,7 @@ bool NeedsRegen(const char* ninja_suffix, LOAD_STRING(fp, &s); double ts = GetTimestamp(s); if (gen_time < ts) { - if (ignore_kati_binary) { + if (g_flags.regen_ignoring_kati_binary) { string kati_binary; GetExecutablePath(&kati_binary); if (s == kati_binary) { @@ -821,16 +805,16 @@ bool NeedsRegen(const char* ninja_suffix, } } if (ShouldIgnoreDirty(s)) { - if (dump_kati_stamp) + if (g_flags.dump_kati_stamp) printf("file %s: ignored (%f)\n", s.c_str(), ts); continue; } - if (dump_kati_stamp) + if (g_flags.dump_kati_stamp) printf("file %s: dirty (%f)\n", s.c_str(), ts); else fprintf(stderr, "%s was modified, regenerating...\n", s.c_str()); RETURN_TRUE; - } else if (dump_kati_stamp) { + } else if (g_flags.dump_kati_stamp) { printf("file %s: clean (%f)\n", s.c_str(), ts); } } @@ -839,14 +823,14 @@ bool NeedsRegen(const char* ninja_suffix, for (int i = 0; i < num_undefineds; i++) { LOAD_STRING(fp, &s); if (getenv(s.c_str())) { - if (dump_kati_stamp) { + if (g_flags.dump_kati_stamp) { printf("env %s: dirty (unset => %s)\n", s.c_str(), getenv(s.c_str())); } else { fprintf(stderr, "Environment variable %s was set, regenerating...\n", s.c_str()); } RETURN_TRUE; - } else if (dump_kati_stamp) { + } else if (g_flags.dump_kati_stamp) { printf("env %s: clean (unset)\n", s.c_str()); } } @@ -857,7 +841,7 @@ bool NeedsRegen(const char* ninja_suffix, StringPiece val(getenv(s.c_str())); LOAD_STRING(fp, &s2); if (val != s2) { - if (dump_kati_stamp) { + if (g_flags.dump_kati_stamp) { printf("env %s: dirty (%s => %.*s)\n", s.c_str(), s2.c_str(), SPF(val)); } else { @@ -866,7 +850,7 @@ bool NeedsRegen(const char* ninja_suffix, s.c_str(), s2.c_str(), SPF(val)); } RETURN_TRUE; - } else if (dump_kati_stamp) { + } else if (g_flags.dump_kati_stamp) { printf("env %s: clean (%.*s)\n", s.c_str(), SPF(val)); } } @@ -902,19 +886,19 @@ bool NeedsRegen(const char* ninja_suffix, } if (needs_regen) { if (ShouldIgnoreDirty(pat)) { - if (dump_kati_stamp) { + if (g_flags.dump_kati_stamp) { printf("wildcard %s: ignored\n", pat.c_str()); } continue; } - if (dump_kati_stamp) { + if (g_flags.dump_kati_stamp) { printf("wildcard %s: dirty\n", pat.c_str()); } else { fprintf(stderr, "wildcard(%s) was changed, regenerating...\n", pat.c_str()); } RETURN_TRUE; - } else if (dump_kati_stamp) { + } else if (g_flags.dump_kati_stamp) { printf("wildcard %s: clean\n", pat.c_str()); } } @@ -950,7 +934,7 @@ bool NeedsRegen(const char* ninja_suffix, } if (!should_run_command) { - if (dump_kati_stamp) + if (g_flags.dump_kati_stamp) printf("shell %s: clean (no rerun)\n", cmd.c_str()); continue; } @@ -959,7 +943,7 @@ bool NeedsRegen(const char* ninja_suffix, FindCommand fc; if (fc.Parse(cmd) && !fc.chdir.empty() && ShouldIgnoreDirty(fc.chdir)) { - if (dump_kati_stamp) + if (g_flags.dump_kati_stamp) printf("shell %s: ignored\n", cmd.c_str()); continue; } @@ -970,7 +954,7 @@ bool NeedsRegen(const char* ninja_suffix, RunCommand("/bin/sh", cmd, RedirectStderr::DEV_NULL, &result); FormatForCommandSubstitution(&result); if (expected != result) { - if (dump_kati_stamp) { + if (g_flags.dump_kati_stamp) { printf("shell %s: dirty\n", cmd.c_str()); } else { fprintf(stderr, "$(shell %s) was changed, regenerating...\n", @@ -981,7 +965,7 @@ bool NeedsRegen(const char* ninja_suffix, #endif } RETURN_TRUE; - } else if (dump_kati_stamp) { + } else if (g_flags.dump_kati_stamp) { printf("shell %s: clean (rerun)\n", cmd.c_str()); } } @@ -27,20 +27,12 @@ using namespace std; struct DepNode; class Evaluator; -void GenerateNinja(const char* ninja_suffix, - const char* ninja_dir, - const vector<DepNode*>& nodes, +void GenerateNinja(const vector<DepNode*>& nodes, Evaluator* ev, - bool build_all_targets, const string& orig_args, double start_time); -bool NeedsRegen(const char* ninja_suffix, - const char* ninja_dir, - bool ignore_kati_binary, - bool dump_kati_stamp, - double start_time, - const string& orig_args); +bool NeedsRegen(double start_time, const string& orig_args); // Exposed only for test. bool GetDepfileFromCommand(string* cmd, string* out); @@ -50,7 +50,8 @@ bool IsPatternRule(StringPiece s) { Rule::Rule() : is_double_colon(false), is_suffix_rule(false), - cmd_lineno(0) { + cmd_lineno(0), + is_default_target(false) { } void ParseRule(Loc& loc, StringPiece line, char term, @@ -44,6 +44,7 @@ class Rule { vector<Value*> cmds; Loc loc; int cmd_lineno; + bool is_default_target; private: void Error(const string& msg) { diff --git a/testcase/default_rule.mk b/testcase/default_rule.mk new file mode 100644 index 0000000..e123358 --- /dev/null +++ b/testcase/default_rule.mk @@ -0,0 +1,5 @@ +abc: + echo PASS + +def: + echo FAIL |
