blob: afba609d9eadcef89dc7acc5cef5a6354eef143d [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>
21
22#include <memory>
23#include <unordered_map>
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090024#include <utility>
25#include <vector>
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090026
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +090027#include "command.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090028#include "dep.h"
29#include "eval.h"
Shinichiro Hamaji645cca72015-09-24 17:04:21 +090030#include "expr.h"
Shinichiro Hamajifdb56dc2015-06-18 19:54:39 +090031#include "fileutil.h"
Shinichiro Hamaji08808d32015-06-26 08:02:45 +090032#include "flags.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090033#include "log.h"
34#include "string_piece.h"
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090035#include "strutil.h"
Shinichiro Hamajie7992752015-06-29 18:38:35 +090036#include "symtab.h"
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +090037#include "var.h"
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090038
39namespace {
40
Shinichiro Hamajifda79432015-07-05 03:17:34 +090041const double kNotExist = -2.0;
42const double kProcessing = -1.0;
43
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090044class Executor {
45 public:
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +090046 explicit Executor(Evaluator* ev)
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +090047 : ce_(ev) {
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +090048 shell_ = ev->EvalVar(kShellSym);
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090049 }
50
Shinichiro Hamajifda79432015-07-05 03:17:34 +090051 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 Hamaji776ca302015-06-06 03:52:48 +090063
64 LOG("ExecNode: %s for %s",
Shinichiro Hamajie7992752015-06-29 18:38:35 +090065 n->output.c_str(),
66 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;
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090078 for (DepNode* d : n->order_onlys) {
79 if (Exists(d->output.str())) {
Shinichiro Hamajifdb56dc2015-06-18 19:54:39 +090080 continue;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +090081 }
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090082 double ts = ExecNode(d, n);
83 if (latest < ts)
84 latest = ts;
85 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +090086
Shinichiro Hamaji183dbb92015-07-06 17:21:39 +090087 for (DepNode* d : n->deps) {
Shinichiro Hamajifda79432015-07-05 03:17:34 +090088 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 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;
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900108 int result = RunCommand(shell_, command->cmd.c_str(),
Shinichiro Hamajic9b0aca2015-07-31 16:47:56 +0900109 RedirectStderr::STDOUT,
Shinichiro Hamaji94d6f2a2015-07-05 05:32:25 +0900110 &out);
111 printf("%s", out.c_str());
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900112 if (result != 0) {
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900113 if (command->ignore_error) {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900114 fprintf(stderr, "[%s] Error %d (ignored)\n",
115 command->output.c_str(), WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900116 } else {
Shinichiro Hamajie7992752015-06-29 18:38:35 +0900117 fprintf(stderr, "*** [%s] Error %d\n",
118 command->output.c_str(), WEXITSTATUS(result));
Shinichiro Hamaji08808d32015-06-26 08:02:45 +0900119 exit(1);
120 }
Shinichiro Hamaji5e9def32015-06-24 22:27:48 +0900121 }
122 }
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900123 delete command;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900124 }
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900125
126 done_[n->output] = output_ts;
127 return output_ts;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900128 }
129
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700130 uint64_t Count() {
131 return num_commands_;
132 }
133
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900134 private:
Shinichiro Hamaji5f86e1a2015-06-29 14:25:39 +0900135 CommandEvaluator ce_;
Shinichiro Hamajifda79432015-07-05 03:17:34 +0900136 unordered_map<Symbol, double> done_;
Shinichiro Hamajifb415ad2015-08-14 17:19:34 +0900137 string shell_;
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700138 uint64_t num_commands_;
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900139};
140
Shinichiro Hamaji7154e8d2015-06-18 18:28:26 +0900141} // namespace
142
Shinichiro Hamajiffc52c32015-06-23 16:51:07 +0900143void Exec(const vector<DepNode*>& roots, Evaluator* ev) {
144 unique_ptr<Executor> executor(new Executor(ev));
Shinichiro Hamaji776ca302015-06-06 03:52:48 +0900145 for (DepNode* root : roots) {
146 executor->ExecNode(root, NULL);
147 }
Dan Willemsenfcd7a982015-08-21 16:58:21 -0700148 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 Hamaji776ca302015-06-06 03:52:48 +0900153}