blob: 75f535847b602800e9bd09b809e6f1e9981cf0b3 [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:
Dan Willemsen3ce083f2017-10-11 22:17:48 -070047 explicit Executor(Evaluator* ev) : ce_(ev), num_commands_(0) {
Dan Willemsen064be222016-09-30 20:17:14 -070048 shell_ = ev->GetShell();
49 shellflag_ = ev->GetShellFlag();
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090050 }
51
Shinichiro Hamajifda79432015-07-05 03:17:34 +090052 double ExecNode(DepNode* n, DepNode* needed_by) {
53 auto found = done_.find(n->output);
54 if (found != done_.end()) {
55 if (found->second == kProcessing) {
56 WARN("Circular %s <- %s dependency dropped.",
57 needed_by ? needed_by->output.c_str() : "(null)",
58 n->output.c_str());
59 }
60 return found->second;
61 }
62 done_[n->output] = kProcessing;
63 double output_ts = GetTimestamp(n->output.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090064
Dan Willemsen3ce083f2017-10-11 22:17:48 -070065 LOG("ExecNode: %s for %s", n->output.c_str(),
Shinichiro Hamajie7992752015-06-29 18:38:35 +090066 needed_by ? needed_by->output.c_str() : "(null)");
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090067
Shinichiro Hamajifda79432015-07-05 03:17:34 +090068 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;
Sasha Smundake8f4d6d2018-07-27 10:34:04 -070078 for (auto const& d : n->order_onlys) {
79 if (Exists(d.second->output.str())) {
Shinichiro Hamajifdb56dc2015-06-18 19:54:39 +090080 continue;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090081 }
Sasha Smundake8f4d6d2018-07-27 10:34:04 -070082 double ts = ExecNode(d.second, n);
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090083 if (latest < ts)
84 latest = ts;
85 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +090086
Sasha Smundake8f4d6d2018-07-27 10:34:04 -070087 for (auto const& d : n->deps) {
88 double ts = ExecNode(d.second, n);
Shinichiro Hamajifda79432015-07-05 03:17:34 +090089 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 Hamaji776ca302015-06-06 03:52:48 +090096 }
97
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +090098 vector<Command*> commands;
99 ce_.Eval(n, &commands);
100 for (Command* command : commands) {
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700101 num_commands_ += 1;
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900102 if (command->echo) {
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900103 printf("%s\n", command->cmd.c_str());
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900104 fflush(stdout);
105 }
Shinichiro Hamaji003d06e2015-09-09 18:22:04 +0900106 if (!g_flags.is_dry_run) {
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +0900107 string out;
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700108 int result = RunCommand(shell_, shellflag_, command->cmd.c_str(),
109 RedirectStderr::STDOUT, &out);
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +0900110 printf("%s", out.c_str());
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900111 if (result != 0) {
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900112 if (command->ignore_error) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900113 fprintf(stderr, "[%s] Error %d (ignored)\n",
114 command->output.c_str(), WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900115 } else {
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700116 fprintf(stderr, "*** [%s] Error %d\n", command->output.c_str(),
117 WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900118 exit(1);
119 }
Shinichiro Hamaji5e9def32015-06-24 22:27:48 +0900120 }
121 }
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900122 delete command;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900123 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900124
125 done_[n->output] = output_ts;
126 return output_ts;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900127 }
128
Dan Willemsen3ce083f2017-10-11 22:17:48 -0700129 uint64_t Count() { return num_commands_; }
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700130
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900131 private:
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900132 CommandEvaluator ce_;
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900133 unordered_map<Symbol, double> done_;
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900134 string shell_;
Dan Willemsen064be222016-09-30 20:17:14 -0700135 string shellflag_;
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700136 uint64_t num_commands_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900137};
138
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900139} // namespace
140
Sasha Smundake8f4d6d2018-07-27 10:34:04 -0700141void Exec(const vector<NamedDepNode>& roots, Evaluator* ev) {
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900142 unique_ptr<Executor> executor(new Executor(ev));
Sasha Smundake8f4d6d2018-07-27 10:34:04 -0700143 for (auto const& root : roots) {
144 executor->ExecNode(root.second, NULL);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900145 }
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700146 if (executor->Count() == 0) {
Dan Willemsenee57a3f2018-11-05 16:18:44 -0800147 for (auto const& root : roots) {
Sasha Smundake8f4d6d2018-07-27 10:34:04 -0700148 printf("kati: Nothing to be done for `%s'.\n", root.first.c_str());
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700149 }
150 }
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900151}