Shinichiro Hamaji | 1d545aa | 2015-06-23 15:29:13 +0900 | [diff] [blame] | 1 | // Copyright 2015 Google Inc. All rights reserved |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
Fumitoshi Ukai | 744bb2b | 2015-06-25 00:10:52 +0900 | [diff] [blame] | 15 | // +build ignore |
| 16 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 17 | #include "exec.h" |
| 18 | |
| 19 | #include <stdio.h> |
| 20 | #include <stdlib.h> |
| 21 | |
| 22 | #include <memory> |
| 23 | #include <unordered_map> |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 24 | #include <utility> |
| 25 | #include <vector> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 26 | |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 27 | #include "command.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 28 | #include "dep.h" |
| 29 | #include "eval.h" |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 30 | #include "expr.h" |
Shinichiro Hamaji | fdb56dc | 2015-06-18 19:54:39 +0900 | [diff] [blame] | 31 | #include "fileutil.h" |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 32 | #include "flags.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 33 | #include "log.h" |
| 34 | #include "string_piece.h" |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 35 | #include "strutil.h" |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 36 | #include "symtab.h" |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 37 | #include "var.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 38 | |
| 39 | namespace { |
| 40 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 41 | const double kNotExist = -2.0; |
| 42 | const double kProcessing = -1.0; |
| 43 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 44 | class Executor { |
| 45 | public: |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 46 | explicit Executor(Evaluator* ev) |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 47 | : ce_(ev) { |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 48 | shell_ = ev->EvalVar(kShellSym); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 49 | } |
| 50 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 51 | double ExecNode(DepNode* n, DepNode* needed_by) { |
| 52 | auto found = done_.find(n->output); |
| 53 | if (found != done_.end()) { |
| 54 | if (found->second == kProcessing) { |
| 55 | WARN("Circular %s <- %s dependency dropped.", |
| 56 | needed_by ? needed_by->output.c_str() : "(null)", |
| 57 | n->output.c_str()); |
| 58 | } |
| 59 | return found->second; |
| 60 | } |
| 61 | done_[n->output] = kProcessing; |
| 62 | double output_ts = GetTimestamp(n->output.c_str()); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 63 | |
| 64 | LOG("ExecNode: %s for %s", |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 65 | n->output.c_str(), |
| 66 | needed_by ? needed_by->output.c_str() : "(null)"); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 67 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 68 | if (!n->has_rule && output_ts == kNotExist && !n->is_phony) { |
| 69 | if (needed_by) { |
| 70 | ERROR("*** No rule to make target '%s', needed by '%s'.", |
| 71 | n->output.c_str(), needed_by->output.c_str()); |
| 72 | } else { |
| 73 | ERROR("*** No rule to make target '%s'.", n->output.c_str()); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | double latest = kProcessing; |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 78 | for (DepNode* d : n->order_onlys) { |
| 79 | if (Exists(d->output.str())) { |
Shinichiro Hamaji | fdb56dc | 2015-06-18 19:54:39 +0900 | [diff] [blame] | 80 | continue; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 81 | } |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 82 | double ts = ExecNode(d, n); |
| 83 | if (latest < ts) |
| 84 | latest = ts; |
| 85 | } |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 86 | |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 87 | for (DepNode* d : n->deps) { |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 88 | double ts = ExecNode(d, n); |
| 89 | if (latest < ts) |
| 90 | latest = ts; |
| 91 | } |
| 92 | |
| 93 | if (output_ts >= latest && !n->is_phony) { |
| 94 | done_[n->output] = output_ts; |
| 95 | return output_ts; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 96 | } |
| 97 | |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 98 | vector<Command*> commands; |
| 99 | ce_.Eval(n, &commands); |
| 100 | for (Command* command : commands) { |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 101 | num_commands_ += 1; |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 102 | if (command->echo) { |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 103 | printf("%s\n", command->cmd.c_str()); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 104 | fflush(stdout); |
| 105 | } |
Shinichiro Hamaji | 003d06e | 2015-09-09 18:22:04 +0900 | [diff] [blame] | 106 | if (!g_flags.is_dry_run) { |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 107 | string out; |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 108 | int result = RunCommand(shell_, command->cmd.c_str(), |
Shinichiro Hamaji | c9b0aca | 2015-07-31 16:47:56 +0900 | [diff] [blame] | 109 | RedirectStderr::STDOUT, |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 110 | &out); |
| 111 | printf("%s", out.c_str()); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 112 | if (result != 0) { |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 113 | if (command->ignore_error) { |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 114 | fprintf(stderr, "[%s] Error %d (ignored)\n", |
| 115 | command->output.c_str(), WEXITSTATUS(result)); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 116 | } else { |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 117 | fprintf(stderr, "*** [%s] Error %d\n", |
| 118 | command->output.c_str(), WEXITSTATUS(result)); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 119 | exit(1); |
| 120 | } |
Shinichiro Hamaji | 5e9def3 | 2015-06-24 22:27:48 +0900 | [diff] [blame] | 121 | } |
| 122 | } |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 123 | delete command; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 124 | } |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 125 | |
| 126 | done_[n->output] = output_ts; |
| 127 | return output_ts; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 128 | } |
| 129 | |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 130 | uint64_t Count() { |
| 131 | return num_commands_; |
| 132 | } |
| 133 | |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 134 | private: |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 135 | CommandEvaluator ce_; |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 136 | unordered_map<Symbol, double> done_; |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 137 | string shell_; |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 138 | uint64_t num_commands_; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 139 | }; |
| 140 | |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 141 | } // namespace |
| 142 | |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 143 | void Exec(const vector<DepNode*>& roots, Evaluator* ev) { |
| 144 | unique_ptr<Executor> executor(new Executor(ev)); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 145 | for (DepNode* root : roots) { |
| 146 | executor->ExecNode(root, NULL); |
| 147 | } |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 148 | if (executor->Count() == 0) { |
| 149 | for (DepNode* root : roots) { |
| 150 | printf("kati: Nothing to be done for `%s'.\n", root->output.c_str()); |
| 151 | } |
| 152 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 153 | } |