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> |
Dan Willemsen | e6ede25 | 2017-09-29 16:49:02 -0700 | [diff] [blame] | 21 | #include <sys/wait.h> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 22 | |
| 23 | #include <memory> |
| 24 | #include <unordered_map> |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 25 | #include <utility> |
| 26 | #include <vector> |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 27 | |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 28 | #include "command.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 29 | #include "dep.h" |
| 30 | #include "eval.h" |
Shinichiro Hamaji | 645cca7 | 2015-09-24 17:04:21 +0900 | [diff] [blame] | 31 | #include "expr.h" |
Shinichiro Hamaji | fdb56dc | 2015-06-18 19:54:39 +0900 | [diff] [blame] | 32 | #include "fileutil.h" |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 33 | #include "flags.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 34 | #include "log.h" |
| 35 | #include "string_piece.h" |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 36 | #include "strutil.h" |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 37 | #include "symtab.h" |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 38 | #include "var.h" |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 39 | |
| 40 | namespace { |
| 41 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 42 | const double kNotExist = -2.0; |
| 43 | const double kProcessing = -1.0; |
| 44 | |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 45 | class Executor { |
| 46 | public: |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 47 | explicit Executor(Evaluator* ev) |
Shinichiro Hamaji | d07e297 | 2016-04-28 16:47:16 +0900 | [diff] [blame] | 48 | : ce_(ev), |
| 49 | num_commands_(0) { |
Dan Willemsen | 064be22 | 2016-09-30 20:17:14 -0700 | [diff] [blame] | 50 | shell_ = ev->GetShell(); |
| 51 | shellflag_ = ev->GetShellFlag(); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 52 | } |
| 53 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 54 | double ExecNode(DepNode* n, DepNode* needed_by) { |
| 55 | auto found = done_.find(n->output); |
| 56 | if (found != done_.end()) { |
| 57 | if (found->second == kProcessing) { |
| 58 | WARN("Circular %s <- %s dependency dropped.", |
| 59 | needed_by ? needed_by->output.c_str() : "(null)", |
| 60 | n->output.c_str()); |
| 61 | } |
| 62 | return found->second; |
| 63 | } |
| 64 | done_[n->output] = kProcessing; |
| 65 | double output_ts = GetTimestamp(n->output.c_str()); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 66 | |
| 67 | LOG("ExecNode: %s for %s", |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 68 | n->output.c_str(), |
| 69 | needed_by ? needed_by->output.c_str() : "(null)"); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 70 | |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 71 | if (!n->has_rule && output_ts == kNotExist && !n->is_phony) { |
| 72 | if (needed_by) { |
| 73 | ERROR("*** No rule to make target '%s', needed by '%s'.", |
| 74 | n->output.c_str(), needed_by->output.c_str()); |
| 75 | } else { |
| 76 | ERROR("*** No rule to make target '%s'.", n->output.c_str()); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | double latest = kProcessing; |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 81 | for (DepNode* d : n->order_onlys) { |
| 82 | if (Exists(d->output.str())) { |
Shinichiro Hamaji | fdb56dc | 2015-06-18 19:54:39 +0900 | [diff] [blame] | 83 | continue; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 84 | } |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 85 | double ts = ExecNode(d, n); |
| 86 | if (latest < ts) |
| 87 | latest = ts; |
| 88 | } |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 89 | |
Shinichiro Hamaji | 183dbb9 | 2015-07-06 17:21:39 +0900 | [diff] [blame] | 90 | for (DepNode* d : n->deps) { |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 91 | double ts = ExecNode(d, n); |
| 92 | if (latest < ts) |
| 93 | latest = ts; |
| 94 | } |
| 95 | |
| 96 | if (output_ts >= latest && !n->is_phony) { |
| 97 | done_[n->output] = output_ts; |
| 98 | return output_ts; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 99 | } |
| 100 | |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 101 | vector<Command*> commands; |
| 102 | ce_.Eval(n, &commands); |
| 103 | for (Command* command : commands) { |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 104 | num_commands_ += 1; |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 105 | if (command->echo) { |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 106 | printf("%s\n", command->cmd.c_str()); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 107 | fflush(stdout); |
| 108 | } |
Shinichiro Hamaji | 003d06e | 2015-09-09 18:22:04 +0900 | [diff] [blame] | 109 | if (!g_flags.is_dry_run) { |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 110 | string out; |
Dan Willemsen | 064be22 | 2016-09-30 20:17:14 -0700 | [diff] [blame] | 111 | int result = RunCommand(shell_, shellflag_, |
| 112 | command->cmd.c_str(), |
Shinichiro Hamaji | c9b0aca | 2015-07-31 16:47:56 +0900 | [diff] [blame] | 113 | RedirectStderr::STDOUT, |
Shinichiro Hamaji | 94d6f2a | 2015-07-05 05:32:25 +0900 | [diff] [blame] | 114 | &out); |
| 115 | printf("%s", out.c_str()); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 116 | if (result != 0) { |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 117 | if (command->ignore_error) { |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 118 | fprintf(stderr, "[%s] Error %d (ignored)\n", |
| 119 | command->output.c_str(), WEXITSTATUS(result)); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 120 | } else { |
Shinichiro Hamaji | e799275 | 2015-06-29 18:38:35 +0900 | [diff] [blame] | 121 | fprintf(stderr, "*** [%s] Error %d\n", |
| 122 | command->output.c_str(), WEXITSTATUS(result)); |
Shinichiro Hamaji | 08808d3 | 2015-06-26 08:02:45 +0900 | [diff] [blame] | 123 | exit(1); |
| 124 | } |
Shinichiro Hamaji | 5e9def3 | 2015-06-24 22:27:48 +0900 | [diff] [blame] | 125 | } |
| 126 | } |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 127 | delete command; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 128 | } |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 129 | |
| 130 | done_[n->output] = output_ts; |
| 131 | return output_ts; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 132 | } |
| 133 | |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 134 | uint64_t Count() { |
| 135 | return num_commands_; |
| 136 | } |
| 137 | |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 138 | private: |
Shinichiro Hamaji | 5f86e1a | 2015-06-29 14:25:39 +0900 | [diff] [blame] | 139 | CommandEvaluator ce_; |
Shinichiro Hamaji | fda7943 | 2015-07-05 03:17:34 +0900 | [diff] [blame] | 140 | unordered_map<Symbol, double> done_; |
Shinichiro Hamaji | fb415ad | 2015-08-14 17:19:34 +0900 | [diff] [blame] | 141 | string shell_; |
Dan Willemsen | 064be22 | 2016-09-30 20:17:14 -0700 | [diff] [blame] | 142 | string shellflag_; |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 143 | uint64_t num_commands_; |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 144 | }; |
| 145 | |
Shinichiro Hamaji | 7154e8d | 2015-06-18 18:28:26 +0900 | [diff] [blame] | 146 | } // namespace |
| 147 | |
Shinichiro Hamaji | ffc52c3 | 2015-06-23 16:51:07 +0900 | [diff] [blame] | 148 | void Exec(const vector<DepNode*>& roots, Evaluator* ev) { |
| 149 | unique_ptr<Executor> executor(new Executor(ev)); |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 150 | for (DepNode* root : roots) { |
| 151 | executor->ExecNode(root, NULL); |
| 152 | } |
Dan Willemsen | fcd7a98 | 2015-08-21 16:58:21 -0700 | [diff] [blame] | 153 | if (executor->Count() == 0) { |
| 154 | for (DepNode* root : roots) { |
| 155 | printf("kati: Nothing to be done for `%s'.\n", root->output.c_str()); |
| 156 | } |
| 157 | } |
Shinichiro Hamaji | 776ca30 | 2015-06-06 03:52:48 +0900 | [diff] [blame] | 158 | } |