summaryrefslogtreecommitdiff
path: root/ninja/src/ninja.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ninja/src/ninja.cc')
-rw-r--r--ninja/src/ninja.cc28
1 files changed, 21 insertions, 7 deletions
diff --git a/ninja/src/ninja.cc b/ninja/src/ninja.cc
index 0586bdca907..03ca83b544c 100644
--- a/ninja/src/ninja.cc
+++ b/ninja/src/ninja.cc
@@ -32,8 +32,8 @@
#include "build_log.h"
#include "deps_log.h"
#include "clean.h"
+#include "debug_flags.h"
#include "disk_interface.h"
-#include "explain.h"
#include "graph.h"
#include "graphviz.h"
#include "manifest_parser.h"
@@ -68,7 +68,7 @@ struct Options {
/// The Ninja main() loads up a series of data structures; various tools need
/// to poke into these, so store them as fields on an object.
-struct NinjaMain {
+struct NinjaMain : public BuildLogUser {
NinjaMain(const char* ninja_command, const BuildConfig& config) :
ninja_command_(ninja_command), config_(config) {}
@@ -137,6 +137,18 @@ struct NinjaMain {
/// Dump the output requested by '-d stats'.
void DumpMetrics();
+
+ virtual bool IsPathDead(StringPiece s) const {
+ Node* n = state_.LookupNode(s);
+ // Just checking n isn't enough: If an old output is both in the build log
+ // and in the deps log, it will have a Node object in state_. (It will also
+ // have an in edge if one of its inputs is another output that's in the deps
+ // log, but having a deps edge product an output thats input to another deps
+ // edge is rare, and the first recompaction will delete all old outputs from
+ // the deps log, and then a second recompaction will clear the build log,
+ // which seems good enough for this corner case.)
+ return !n || !n->in_edge();
+ }
};
/// Subtools, accessible via "-t foo".
@@ -444,9 +456,7 @@ int NinjaMain::ToolDeps(int argc, char** argv) {
if (argc == 0) {
for (vector<Node*>::const_iterator ni = deps_log_.nodes().begin();
ni != deps_log_.nodes().end(); ++ni) {
- // Only query for targets with an incoming edge and deps
- Edge* e = (*ni)->in_edge();
- if (e && !e->GetBinding("deps").empty())
+ if (deps_log_.IsDepsEntryLiveFor(*ni))
nodes.push_back(*ni);
}
} else {
@@ -747,6 +757,7 @@ bool DebugEnable(const string& name) {
printf("debugging modes:\n"
" stats print operation counts/timing info\n"
" explain explain what caused a command to execute\n"
+" keeprsp don't delete @response files on success\n"
"multiple modes can be enabled via -d FOO -d BAR\n");
return false;
} else if (name == "stats") {
@@ -755,6 +766,9 @@ bool DebugEnable(const string& name) {
} else if (name == "explain") {
g_explaining = true;
return true;
+ } else if (name == "keeprsp") {
+ g_keep_rsp = true;
+ return true;
} else {
const char* suggestion =
SpellcheckString(name.c_str(), "stats", "explain", NULL);
@@ -785,14 +799,14 @@ bool NinjaMain::OpenBuildLog(bool recompact_only) {
}
if (recompact_only) {
- bool success = build_log_.Recompact(log_path, &err);
+ bool success = build_log_.Recompact(log_path, *this, &err);
if (!success)
Error("failed recompaction: %s", err.c_str());
return success;
}
if (!config_.dry_run) {
- if (!build_log_.OpenForWrite(log_path, &err)) {
+ if (!build_log_.OpenForWrite(log_path, *this, &err)) {
Error("opening build log: %s", err.c_str());
return false;
}