blob: fa534d528f43ee41a64ad0492b2cb155a465642e [file] [log] [blame]
Shinichiro Hamaji1d545aa2015-06-23 15:29:13 +09001// 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 Ukai744bb2b2015-06-25 00:10:52 +090015// +build ignore
16
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090017#include "exec.h"
18
19#include <stdio.h>
20#include <stdlib.h>
Dan Willemsene6ede252017-09-29 16:49:02 -070021#include <sys/wait.h>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090022
23#include <memory>
24#include <unordered_map>
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090025#include <utility>
26#include <vector>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090027
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +090028#include "command.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090029#include "dep.h"
30#include "eval.h"
Shinichiro Hamaji645cca72015-09-24 17:04:21 +090031#include "expr.h"
Shinichiro Hamajifdb56dc2015-06-18 19:54:39 +090032#include "fileutil.h"
Shinichiro Hamaji08808d32015-06-26 08:02:45 +090033#include "flags.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090034#include "log.h"
35#include "string_piece.h"
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090036#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090037#include "symtab.h"
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090038#include "var.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090039
40namespace {
41
Shinichiro Hamajifda79432015-07-05 03:17:34 +090042const double kNotExist = -2.0;
43const double kProcessing = -1.0;
44
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090045class Executor {
46 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +090047 explicit Executor(Evaluator* ev)
Shinichiro Hamajid07e2972016-04-28 16:47:16 +090048 : ce_(ev),
49 num_commands_(0) {
Dan Willemsen064be222016-09-30 20:17:14 -070050 shell_ = ev->GetShell();
51 shellflag_ = ev->GetShellFlag();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090052 }
53
Shinichiro Hamajifda79432015-07-05 03:17:34 +090054 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 Hamaji776ca302015-06-06 03:52:48 +090066
67 LOG("ExecNode: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +090068 n->output.c_str(),
69 needed_by ? needed_by->output.c_str() : "(null)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090070
Shinichiro Hamajifda79432015-07-05 03:17:34 +090071 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 Hamaji183dbb92015-07-06 17:21:39 +090081 for (DepNode* d : n->order_onlys) {
82 if (Exists(d->output.str())) {
Shinichiro Hamajifdb56dc2015-06-18 19:54:39 +090083 continue;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090084 }
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090085 double ts = ExecNode(d, n);
86 if (latest < ts)
87 latest = ts;
88 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +090089
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090090 for (DepNode* d : n->deps) {
Shinichiro Hamajifda79432015-07-05 03:17:34 +090091 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 Hamaji776ca302015-06-06 03:52:48 +090099 }
100
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900101 vector<Command*> commands;
102 ce_.Eval(n, &commands);
103 for (Command* command : commands) {
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700104 num_commands_ += 1;
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900105 if (command->echo) {
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900106 printf("%s\n", command->cmd.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900107 fflush(stdout);
108 }
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900109 if (!g_flags.is_dry_run) {
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +0900110 string out;
Dan Willemsen064be222016-09-30 20:17:14 -0700111 int result = RunCommand(shell_, shellflag_,
112 command->cmd.c_str(),
Shinichiro Hamajic9b0aca2015-07-31 16:47:56 +0900113 RedirectStderr::STDOUT,
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +0900114 &out);
115 printf("%s", out.c_str());
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900116 if (result != 0) {
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900117 if (command->ignore_error) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900118 fprintf(stderr, "[%s] Error %d (ignored)\n",
119 command->output.c_str(), WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900120 } else {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900121 fprintf(stderr, "*** [%s] Error %d\n",
122 command->output.c_str(), WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900123 exit(1);
124 }
Shinichiro Hamaji5e9def32015-06-24 22:27:48 +0900125 }
126 }
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900127 delete command;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900128 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900129
130 done_[n->output] = output_ts;
131 return output_ts;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900132 }
133
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700134 uint64_t Count() {
135 return num_commands_;
136 }
137
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900138 private:
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900139 CommandEvaluator ce_;
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900140 unordered_map<Symbol, double> done_;
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900141 string shell_;
Dan Willemsen064be222016-09-30 20:17:14 -0700142 string shellflag_;
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700143 uint64_t num_commands_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900144};
145
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900146} // namespace
147
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900148void Exec(const vector<DepNode*>& roots, Evaluator* ev) {
149 unique_ptr<Executor> executor(new Executor(ev));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900150 for (DepNode* root : roots) {
151 executor->ExecNode(root, NULL);
152 }
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700153 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 Hamaji776ca302015-06-06 03:52:48 +0900158}