41 map<string, EvalString>::const_iterator i =
bindings_.find(key);
49 return var ==
"command" ||
51 var ==
"description" ||
57 var ==
"rspfile_content";
73 Node* most_recent_input = NULL;
74 for (vector<Node*>::iterator i = edge->
inputs_.begin();
75 i != edge->
inputs_.end(); ++i) {
77 if (
Edge* in_edge = (*i)->in_edge()) {
83 EXPLAIN(
"%s has no in-edge and is missing", (*i)->path().c_str());
84 (*i)->set_dirty(!(*i)->exists());
89 if (
Edge* in_edge = (*i)->in_edge()) {
90 if (!in_edge->outputs_ready_)
98 EXPLAIN(
"%s is dirty", (*i)->path().c_str());
101 if (!most_recent_input || (*i)->
mtime() > most_recent_input->
mtime()) {
102 most_recent_input = *i;
113 for (vector<Node*>::iterator i = edge->
outputs_.begin();
126 for (vector<Node*>::iterator i = edge->
outputs_.begin();
145 Node* most_recent_input,
147 const string& command,
159 EXPLAIN(
"output %s doesn't exist", output->
path().c_str());
164 if (most_recent_input && output->
mtime() < most_recent_input->
mtime()) {
171 bool used_restat =
false;
178 if (output_mtime < most_recent_input->mtime()) {
179 EXPLAIN(
"%soutput %s older than most recent input %s "
181 used_restat ?
"restat of " :
"", output->
path().c_str(),
182 most_recent_input->
path().c_str(),
183 output_mtime, most_recent_input->
mtime());
189 if (deps_mtime && output->
mtime() > deps_mtime) {
190 EXPLAIN(
"stored deps info out of date for for %s (%d vs %d)",
191 output->
path().c_str(), deps_mtime, output->
mtime());
199 if (entry || (entry =
build_log()->LookupByOutput(output->
path()))) {
201 EXPLAIN(
"command line changed for %s", output->
path().c_str());
206 EXPLAIN(
"command line not found in log for %s", output->
path().c_str());
215 for (vector<Node*>::const_iterator i =
inputs_.begin();
217 if ((*i)->in_edge() && !(*i)->in_edge()->outputs_ready())
231 vector<Node*>::iterator end,
238 if (var ==
"in" || var ==
"in_newline") {
243 var ==
"in" ?
' ' :
'\n');
244 }
else if (var ==
"out") {
256 vector<Node*>::iterator end,
259 for (vector<Node*>::iterator i = begin; i != end; ++i) {
261 result.push_back(sep);
262 const string& path = (*i)->path();
263 if (path.find(
" ") != string::npos) {
277 string rspfile_content =
GetBinding(
"rspfile_content");
278 if (!rspfile_content.empty())
279 command +=
";rspfile=" + rspfile_content;
294 printf(
"%s[ ", prefix);
295 for (vector<Node*>::const_iterator i =
inputs_.begin();
296 i !=
inputs_.end() && *i != NULL; ++i) {
297 printf(
"%s ", (*i)->path().c_str());
299 printf(
"--%s-> ",
rule_->
name().c_str());
300 for (vector<Node*>::const_iterator i =
outputs_.begin();
301 i !=
outputs_.end() && *i != NULL; ++i) {
302 printf(
"%s ", (*i)->path().c_str());
306 printf(
"(in pool '%s')",
pool_->
name().c_str());
309 printf(
"(null pool?)");
311 printf(
"] 0x%p\n",
this);
319 printf(
"%s <%s 0x%p> mtime: %d%s, (:%s), ",
320 prefix,
path().c_str(),
this,
322 dirty() ?
" dirty" :
" clean");
326 printf(
"no in-edge\n");
328 printf(
" out edges:\n");
329 for (vector<Edge*>::const_iterator e =
out_edges().begin();
330 e !=
out_edges().end() && *e != NULL; ++e) {
337 if (!deps_type.empty()) {
348 if (!depfile.empty()) {
352 EXPLAIN(
"depfile '%s' is missing", depfile.c_str());
367 *err =
"loading '" + path +
"': " + *err;
376 if (!depfile.
Parse(&content, &depfile_err)) {
377 *err = path +
": " + depfile_err;
384 if (opath != depfile.
out_) {
385 *err =
"expected depfile '" + path +
"' to mention '" +
391 vector<Node*>::iterator implicit_dep =
395 for (vector<StringPiece>::iterator i = depfile.
ins_.begin();
396 i != depfile.
ins_.end(); ++i, ++implicit_dep) {
401 *implicit_dep = node;
415 *deps_mtime = deps->
mtime;
417 vector<Node*>::iterator implicit_dep =
419 for (
int i = 0; i < deps->
node_count; ++i, ++implicit_dep) {
420 *implicit_dep = deps->
nodes[i];
441 phony_edge->
outputs_.push_back(node);