diff options
-rw-r--r-- | exec.cc | 11 | ||||
-rw-r--r-- | func.cc | 8 | ||||
-rw-r--r-- | ninja.cc | 17 | ||||
-rwxr-xr-x | runtest.rb | 22 | ||||
-rw-r--r-- | strutil.cc | 21 | ||||
-rw-r--r-- | strutil.h | 2 | ||||
-rw-r--r-- | testcase/auto_vars.mk | 2 | ||||
-rw-r--r-- | testcase/build_once.mk | 2 | ||||
-rw-r--r-- | testcase/command_vars.mk | 2 | ||||
-rw-r--r-- | testcase/escaped_backslash.mk | 4 | ||||
-rw-r--r-- | testcase/multiline_arg.mk | 2 | ||||
-rw-r--r-- | testcase/multiline_define.mk | 7 | ||||
-rw-r--r-- | testcase/ninja_normalized_path2.mk | 15 | ||||
-rw-r--r-- | testcase/nothing_to_do.mk | 2 | ||||
-rw-r--r-- | testcase/phony.mk | 2 | ||||
-rw-r--r-- | testcase/warning.mk | 9 |
16 files changed, 86 insertions, 42 deletions
@@ -98,6 +98,7 @@ class Executor { vector<Command*> commands; ce_.Eval(n, &commands); for (Command* command : commands) { + num_commands_ += 1; if (command->echo) { printf("%s\n", command->cmd.c_str()); fflush(stdout); @@ -126,10 +127,15 @@ class Executor { return output_ts; } + uint64_t Count() { + return num_commands_; + } + private: CommandEvaluator ce_; unordered_map<Symbol, double> done_; string shell_; + uint64_t num_commands_; }; } // namespace @@ -139,4 +145,9 @@ void Exec(const vector<DepNode*>& roots, Evaluator* ev) { for (DepNode* root : roots) { executor->ExecNode(root, NULL); } + if (executor->Count() == 0) { + for (DepNode* root : roots) { + printf("kati: Nothing to be done for `%s'.\n", root->output.c_str()); + } + } } @@ -622,7 +622,7 @@ void FlavorFunc(const vector<Value*>& args, Evaluator* ev, string* s) { void InfoFunc(const vector<Value*>& args, Evaluator* ev, string*) { const string&& a = args[0]->Eval(ev); if (ev->avoid_io()) { - ev->add_delayed_output_command(StringPrintf("echo '%s'", a.c_str())); + ev->add_delayed_output_command(StringPrintf("echo -e \"%s\"", EchoEscape(a).c_str())); return; } printf("%s\n", a.c_str()); @@ -633,7 +633,7 @@ void WarningFunc(const vector<Value*>& args, Evaluator* ev, string*) { const string&& a = args[0]->Eval(ev); if (ev->avoid_io()) { ev->add_delayed_output_command( - StringPrintf("echo '%s:%d: %s' 2>&1", LOCF(ev->loc()), a.c_str())); + StringPrintf("echo -e \"%s:%d: %s\" 2>&1", LOCF(ev->loc()), EchoEscape(a).c_str())); return; } printf("%s:%d: %s\n", LOCF(ev->loc()), a.c_str()); @@ -644,8 +644,8 @@ void ErrorFunc(const vector<Value*>& args, Evaluator* ev, string*) { const string&& a = args[0]->Eval(ev); if (ev->avoid_io()) { ev->add_delayed_output_command( - StringPrintf("echo '%s:%d: *** %s.' 2>&1 && false", - LOCF(ev->loc()), a.c_str())); + StringPrintf("echo -e \"%s:%d: *** %s.\" 2>&1 && false", + LOCF(ev->loc()), EchoEscape(a).c_str())); return; } ev->Error(StringPrintf("*** %s.", a.c_str())); @@ -271,6 +271,10 @@ class NinjaGenerator { prev_char = *in; } + if (prev_backslash) { + cmd_buf->resize(cmd_buf->size()-1); + } + while (true) { char c = (*cmd_buf)[cmd_buf->size()-1]; if (!isspace(c) && c != ';') @@ -410,12 +414,8 @@ class NinjaGenerator { if (g_detect_android_echo && node->output.str() == "out") return; - // Removing this will fix auto_vars.mk, build_once.mk, and - // command_vars.mk. However, this change will make - // ninja_normalized_path2.mk fail and cause a lot of warnings for - // Android build. - if (node->cmds.empty() && - node->deps.empty() && node->order_onlys.empty() && !node->is_phony) { + // This node is a leaf node + if (!node->has_rule && !node->is_phony) { return; } @@ -513,6 +513,9 @@ class NinjaGenerator { EscapeBuildTarget(node->output).c_str(), rule_name.c_str()); vector<Symbol> order_onlys; + if (node->is_phony) { + fprintf(fp_, " _kati_always_build_"); + } for (DepNode* d : node->deps) { fprintf(fp_, " %s", EscapeBuildTarget(d->output).c_str()); } @@ -596,6 +599,8 @@ class NinjaGenerator { fprintf(fp_, "pool local_pool\n"); fprintf(fp_, " depth = %d\n\n", g_num_jobs); + fprintf(fp_, "build _kati_always_build_: phony\n\n"); + EmitRegenRules(orig_args); for (DepNode* node : nodes) { @@ -93,6 +93,8 @@ def normalize_ninja_log(log, mk) log.gsub!(/^ninja: no work to do\.\n/, '') log.gsub!(/^ninja: error: (.*, needed by .*),.*/, '*** No rule to make target \\1.') + log.gsub!(/^ninja: warning: multiple rules generate (.*)\. builds involving this target will not be correct.*$/, + 'ninja: warning: multiple rules generate \\1.') if mk =~ /err_error_in_recipe.mk/ # This test expects ninja fails. Strip ninja specific error logs. log.gsub!(/^FAILED: .*\n/, '') @@ -101,7 +103,7 @@ def normalize_ninja_log(log, mk) log end -def normalize_make_log(expected) +def normalize_make_log(expected, mk, via_ninja) expected.gsub!(/^make(?:\[\d+\])?: (Entering|Leaving) directory.*\n/, '') expected.gsub!(/^make(?:\[\d+\])?: /, '') expected = move_circular_dep(expected) @@ -119,8 +121,15 @@ def normalize_make_log(expected) # GNU make 4.0 has this output. expected.gsub!(/Makefile:\d+: commands for target ".*?" failed\n/, '') # We treat some warnings as errors. - expected.gsub!(/Nothing to be done for "test"\.\n/, '') + if mk =~ /err_invalid_ifeq3.mk/ + expected.gsub!(/Nothing to be done for "test"\.\n/, '') + end expected.gsub!(/^\/bin\/sh: line 0: /, '') + # We print out some ninja warnings in some tests to match what we expect + # ninja to produce. Remove them if we're not testing ninja. + if !via_ninja + expected.gsub!(/^ninja: warning: .*\n/, '') + end expected end @@ -170,11 +179,6 @@ run_make_test = proc do |mk| end run_in_testdir(mk) do |name| - # TODO: Fix - if name =~ /eval_assign/ && ckati - next - end - File.open("Makefile", 'w') do |ofile| ofile.print(c) end @@ -195,7 +199,7 @@ run_make_test = proc do |mk| end cmd += " #{tc} 2>&1" res = `#{cmd}` - res = normalize_make_log(res) + res = normalize_make_log(res, mk, via_ninja) expected += "=== #{tc} ===\n" + res expected_files = get_output_filenames expected += "\n=== FILES ===\n#{expected_files * "\n"}\n" @@ -302,7 +306,7 @@ run_shell_test = proc do |sh| output = IO.popen(cmd, 'r:binary', &:read) - expected = normalize_make_log(expected) + expected = normalize_make_log(expected, sh, is_ninja_test) output = normalize_kati_log(output) if is_ninja_test output = normalize_ninja_log(output, sh) @@ -427,3 +427,24 @@ string ConcatDir(StringPiece b, StringPiece n) { NormalizePath(&r); return r; } + +string EchoEscape(const string str) { + const char *in = str.c_str(); + string buf; + for (; *in; in++) { + switch(*in) { + case '\\': + buf += "\\\\\\\\"; + break; + case '\n': + buf += "\\n"; + break; + case '"': + buf += "\\\""; + break; + default: + buf += *in; + } + } + return buf; +} @@ -138,4 +138,6 @@ string SortWordsInString(StringPiece s); string ConcatDir(StringPiece b, StringPiece n); +string EchoEscape(const string str); + #endif // STRUTIL_H_ diff --git a/testcase/auto_vars.mk b/testcase/auto_vars.mk index 07bc735..b571543 100644 --- a/testcase/auto_vars.mk +++ b/testcase/auto_vars.mk @@ -1,5 +1,3 @@ -# TODO(c-ninja): Fix - test1: foo bar foo echo $< echo $@ diff --git a/testcase/build_once.mk b/testcase/build_once.mk index 7dfa94e..ecb2a4e 100644 --- a/testcase/build_once.mk +++ b/testcase/build_once.mk @@ -1,5 +1,3 @@ -# TODO(c-ninja): Fix - # expect protoc compile/link only once. test: foo diff --git a/testcase/command_vars.mk b/testcase/command_vars.mk index 6676611..3d60e21 100644 --- a/testcase/command_vars.mk +++ b/testcase/command_vars.mk @@ -1,5 +1,3 @@ -# TODO(c-ninja): Fix - should emit phony rule for bar baz - test: foo foo: bar baz diff --git a/testcase/escaped_backslash.mk b/testcase/escaped_backslash.mk index 068f36c..750e297 100644 --- a/testcase/escaped_backslash.mk +++ b/testcase/escaped_backslash.mk @@ -6,3 +6,7 @@ test: echo $(two_backslash) echo \\ echo \\ foo + $(info echo $(no_comment)) + $(info echo $(two_backslash)) + $(info echo \\) + $(info echo \\ foo) diff --git a/testcase/multiline_arg.mk b/testcase/multiline_arg.mk index 5f310bd..1e64318 100644 --- a/testcase/multiline_arg.mk +++ b/testcase/multiline_arg.mk @@ -1,5 +1,3 @@ -# TODO(c-ninja): Fix - "echo \" should be "echo ". - SHELL:=/bin/bash define func diff --git a/testcase/multiline_define.mk b/testcase/multiline_define.mk index f89c1be..f5481d4 100644 --- a/testcase/multiline_define.mk +++ b/testcase/multiline_define.mk @@ -30,11 +30,10 @@ A\ B endef -$(info $(var)) -$(info $(var2)) -$(info $(var3)) - test: echo $(if $(call or1),FAIL,PASS)_or1 echo $(if $(call or2),FAIL,PASS)_or2 echo $(if $(call or3),FAIL,PASS)_or3 + $(info $(var)) + $(info $(var2)) + $(info $(var3)) diff --git a/testcase/ninja_normalized_path2.mk b/testcase/ninja_normalized_path2.mk index 4b1c140..ad53204 100644 --- a/testcase/ninja_normalized_path2.mk +++ b/testcase/ninja_normalized_path2.mk @@ -1,12 +1,15 @@ -# Unlike ninja_normalized_path.mk, this passes with the current -# implementation because we remove a/./b. See EmitNode in ninja.cc. +# Ninja only supports duplicated targets for pure dependencies. +# These will both be mapped to the same target. Two rules like +# this should cause an warning (and really should cause an warning +# in make too -- this can be very confusing, and can be racy) +ifneq ($(MAKE),kati) +$(info ninja: warning: multiple rules generate a/b.) +endif -test1: - mkdir a - -test2: a/b a/./b +test: a/b a/./b a/b: + mkdir -p $(dir $@) echo $@ a/./b: diff --git a/testcase/nothing_to_do.mk b/testcase/nothing_to_do.mk index 6958ea5..d28f05d 100644 --- a/testcase/nothing_to_do.mk +++ b/testcase/nothing_to_do.mk @@ -1,3 +1 @@ -# TODO(c): Show something like "nothing to be done" - Makefile: diff --git a/testcase/phony.mk b/testcase/phony.mk index b86d7a9..59fb911 100644 --- a/testcase/phony.mk +++ b/testcase/phony.mk @@ -1,5 +1,3 @@ -# TODO(ninja): Fix - ninja emits "no work to do" in test4 - .PHONY: foo echo PASS phony foo .PHONY: bar diff --git a/testcase/warning.mk b/testcase/warning.mk index 7e83503..27540c9 100644 --- a/testcase/warning.mk +++ b/testcase/warning.mk @@ -1,5 +1,12 @@ $(warning foo) +define baz +b +a +z +endef + test: - $(warning bar) + $(warning bar'""') + $(warning $(baz)) echo PASS |