summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build.cc2
-rw-r--r--src/build_log.cc19
-rw-r--r--src/build_log.h3
-rw-r--r--src/build_log_test.cc20
-rw-r--r--src/build_test.cc2
-rw-r--r--src/clean.cc12
-rw-r--r--src/clean.h1
7 files changed, 52 insertions, 7 deletions
diff --git a/src/build.cc b/src/build.cc
index 9877db8..19775e7 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -728,6 +728,7 @@ bool Builder::Build(string* err) {
}
bool Builder::StartEdge(Edge* edge, string* err) {
+ METRIC_RECORD("StartEdge");
if (edge->is_phony())
return true;
@@ -758,6 +759,7 @@ bool Builder::StartEdge(Edge* edge, string* err) {
}
void Builder::FinishEdge(Edge* edge, bool success, const string& output) {
+ METRIC_RECORD("FinishEdge");
TimeStamp restat_mtime = 0;
if (success) {
diff --git a/src/build_log.cc b/src/build_log.cc
index a633892..235951f 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -91,6 +91,15 @@ uint64_t BuildLog::LogEntry::HashCommand(StringPiece command) {
return MurmurHash64A(command.str_, command.len_);
}
+BuildLog::LogEntry::LogEntry(const string& output)
+ : output(output) {}
+
+BuildLog::LogEntry::LogEntry(const string& output, uint64_t command_hash,
+ int start_time, int end_time, TimeStamp restat_mtime)
+ : output(output), command_hash(command_hash),
+ start_time(start_time), end_time(end_time), restat_mtime(restat_mtime)
+{}
+
BuildLog::BuildLog()
: log_file_(NULL), needs_recompaction_(false) {}
@@ -130,6 +139,7 @@ bool BuildLog::OpenForWrite(const string& path, string* err) {
void BuildLog::RecordCommand(Edge* edge, int start_time, int end_time,
TimeStamp restat_mtime) {
string command = edge->EvaluateCommand(true);
+ uint64_t command_hash = LogEntry::HashCommand(command);
for (vector<Node*>::iterator out = edge->outputs_.begin();
out != edge->outputs_.end(); ++out) {
const string& path = (*out)->path();
@@ -138,11 +148,10 @@ void BuildLog::RecordCommand(Edge* edge, int start_time, int end_time,
if (i != entries_.end()) {
log_entry = i->second;
} else {
- log_entry = new LogEntry;
- log_entry->output = path;
+ log_entry = new LogEntry(path);
entries_.insert(Entries::value_type(log_entry->output, log_entry));
}
- log_entry->command_hash = LogEntry::HashCommand(command);
+ log_entry->command_hash = command_hash;
log_entry->start_time = start_time;
log_entry->end_time = end_time;
log_entry->restat_mtime = restat_mtime;
@@ -287,8 +296,7 @@ bool BuildLog::Load(const string& path, string* err) {
if (i != entries_.end()) {
entry = i->second;
} else {
- entry = new LogEntry;
- entry->output = output;
+ entry = new LogEntry(output);
entries_.insert(Entries::value_type(entry->output, entry));
++unique_entry_count;
}
@@ -341,6 +349,7 @@ void BuildLog::WriteEntry(FILE* f, const LogEntry& entry) {
}
bool BuildLog::Recompact(const string& path, string* err) {
+ METRIC_RECORD(".ninja_log recompact");
printf("Recompacting log...\n");
string temp_path = path + ".recompact";
diff --git a/src/build_log.h b/src/build_log.h
index 4141ff3..5a3b516 100644
--- a/src/build_log.h
+++ b/src/build_log.h
@@ -60,6 +60,9 @@ struct BuildLog {
start_time == o.start_time && end_time == o.end_time &&
restat_mtime == o.restat_mtime;
}
+
+ explicit LogEntry(const string& output);
+ LogEntry(const string& output, uint64_t command_hash, int start_time, int end_time, TimeStamp restat_mtime);
};
/// Lookup a previously-run command by its output path.
diff --git a/src/build_log_test.cc b/src/build_log_test.cc
index a6c2a86..5275f25 100644
--- a/src/build_log_test.cc
+++ b/src/build_log_test.cc
@@ -245,3 +245,23 @@ TEST_F(BuildLogTest, VeryLongInputLine) {
ASSERT_EQ(789, e->restat_mtime);
ASSERT_NO_FATAL_FAILURE(AssertHash("command2", e->command_hash));
}
+
+TEST_F(BuildLogTest, MultiTargetEdge) {
+ AssertParse(&state_,
+"build out out.d: cat\n");
+
+ BuildLog log;
+ log.RecordCommand(state_.edges_[0], 21, 22);
+
+ ASSERT_EQ(2u, log.entries().size());
+ BuildLog::LogEntry* e1 = log.LookupByOutput("out");
+ ASSERT_TRUE(e1);
+ BuildLog::LogEntry* e2 = log.LookupByOutput("out.d");
+ ASSERT_TRUE(e2);
+ ASSERT_EQ("out", e1->output);
+ ASSERT_EQ("out.d", e2->output);
+ ASSERT_EQ(21, e1->start_time);
+ ASSERT_EQ(21, e2->start_time);
+ ASSERT_EQ(22, e2->end_time);
+ ASSERT_EQ(22, e2->end_time);
+}
diff --git a/src/build_test.cc b/src/build_test.cc
index 859e758..c208463 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -943,7 +943,7 @@ TEST_F(BuildDryRun, AllCommandsShown) {
}
// Test that RSP files are created when & where appropriate and deleted after
-// succesful execution.
+// successful execution.
TEST_F(BuildTest, RspFileSuccess)
{
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
diff --git a/src/clean.cc b/src/clean.cc
index 3fe23ec..c9d4cbd 100644
--- a/src/clean.cc
+++ b/src/clean.cc
@@ -29,6 +29,7 @@ Cleaner::Cleaner(State* state, const BuildConfig& config)
: state_(state),
config_(config),
removed_(),
+ cleaned_(),
cleaned_files_count_(0),
disk_interface_(new RealDiskInterface),
status_(0) {
@@ -40,6 +41,7 @@ Cleaner::Cleaner(State* state,
: state_(state),
config_(config),
removed_(),
+ cleaned_(),
cleaned_files_count_(0),
disk_interface_(disk_interface),
status_(0) {
@@ -134,9 +136,16 @@ void Cleaner::DoCleanTarget(Node* target) {
}
for (vector<Node*>::iterator n = e->inputs_.begin(); n != e->inputs_.end();
++n) {
- DoCleanTarget(*n);
+ Node* next = *n;
+ // call DoCleanTarget recursively if this node has not been visited
+ if (cleaned_.count(next) == 0) {
+ DoCleanTarget(next);
+ }
}
}
+
+ // mark this target to be cleaned already
+ cleaned_.insert(target);
}
int Cleaner::CleanTarget(Node* target) {
@@ -249,4 +258,5 @@ void Cleaner::Reset() {
status_ = 0;
cleaned_files_count_ = 0;
removed_.clear();
+ cleaned_.clear();
}
diff --git a/src/clean.h b/src/clean.h
index 5938dff..8359901 100644
--- a/src/clean.h
+++ b/src/clean.h
@@ -95,6 +95,7 @@ class Cleaner {
State* state_;
const BuildConfig& config_;
set<string> removed_;
+ set<Node*> cleaned_;
int cleaned_files_count_;
DiskInterface* disk_interface_;
int status_;