summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmisc/output_test.py5
-rw-r--r--src/build_log.cc12
-rw-r--r--src/build_log.h3
-rw-r--r--src/build_log_test.cc2
-rw-r--r--src/deps_log.cc14
-rw-r--r--src/deps_log.h3
-rw-r--r--src/load_status.h24
-rw-r--r--src/ninja.cc34
8 files changed, 71 insertions, 26 deletions
diff --git a/misc/output_test.py b/misc/output_test.py
index 966417d..3fd9c32 100755
--- a/misc/output_test.py
+++ b/misc/output_test.py
@@ -102,5 +102,10 @@ red
\x1b[31mred\x1b[0m
''')
+ def test_pr_1685(self):
+ # Running those tools without .ninja_deps and .ninja_log shouldn't fail.
+ self.assertEqual(run('', flags='-t recompact'), '')
+ self.assertEqual(run('', flags='-t restat'), '')
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/build_log.cc b/src/build_log.cc
index 0b06cc5..e2a9344 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -242,14 +242,14 @@ struct LineReader {
char* line_end_;
};
-bool BuildLog::Load(const string& path, string* err) {
+LoadStatus BuildLog::Load(const string& path, string* err) {
METRIC_RECORD(".ninja_log load");
FILE* file = fopen(path.c_str(), "r");
if (!file) {
if (errno == ENOENT)
- return true;
+ return LOAD_NOT_FOUND;
*err = strerror(errno);
- return false;
+ return LOAD_ERROR;
}
int log_version = 0;
@@ -270,7 +270,7 @@ bool BuildLog::Load(const string& path, string* err) {
unlink(path.c_str());
// Don't report this as a failure. An empty build log will cause
// us to rebuild the outputs anyway.
- return true;
+ return LOAD_SUCCESS;
}
}
@@ -340,7 +340,7 @@ bool BuildLog::Load(const string& path, string* err) {
fclose(file);
if (!line_start) {
- return true; // file was empty
+ return LOAD_SUCCESS; // file was empty
}
// Decide whether it's time to rebuild the log:
@@ -355,7 +355,7 @@ bool BuildLog::Load(const string& path, string* err) {
needs_recompaction_ = true;
}
- return true;
+ return LOAD_SUCCESS;
}
BuildLog::LogEntry* BuildLog::LookupByOutput(const string& path) {
diff --git a/src/build_log.h b/src/build_log.h
index d52dd3b..ed59d79 100644
--- a/src/build_log.h
+++ b/src/build_log.h
@@ -20,6 +20,7 @@
using namespace std;
#include "hash_map.h"
+#include "load_status.h"
#include "timestamp.h"
#include "util.h" // uint64_t
@@ -50,7 +51,7 @@ struct BuildLog {
void Close();
/// Load the on-disk log.
- bool Load(const string& path, string* err);
+ LoadStatus Load(const string& path, string* err);
struct LogEntry {
string output;
diff --git a/src/build_log_test.cc b/src/build_log_test.cc
index eee8290..48ece23 100644
--- a/src/build_log_test.cc
+++ b/src/build_log_test.cc
@@ -151,7 +151,7 @@ TEST_F(BuildLogTest, Truncate) {
BuildLog log3;
err.clear();
- ASSERT_TRUE(log3.Load(kTestFilename, &err) || !err.empty());
+ ASSERT_TRUE(log3.Load(kTestFilename, &err) == LOAD_SUCCESS || !err.empty());
}
}
diff --git a/src/deps_log.cc b/src/deps_log.cc
index 4aaffeb..cf55194 100644
--- a/src/deps_log.cc
+++ b/src/deps_log.cc
@@ -167,15 +167,15 @@ void DepsLog::Close() {
file_ = NULL;
}
-bool DepsLog::Load(const string& path, State* state, string* err) {
+LoadStatus DepsLog::Load(const string& path, State* state, string* err) {
METRIC_RECORD(".ninja_deps load");
char buf[kMaxRecordSize + 1];
FILE* f = fopen(path.c_str(), "rb");
if (!f) {
if (errno == ENOENT)
- return true;
+ return LOAD_NOT_FOUND;
*err = strerror(errno);
- return false;
+ return LOAD_ERROR;
}
bool valid_header = true;
@@ -196,7 +196,7 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
unlink(path.c_str());
// Don't report this as a failure. An empty deps log will cause
// us to rebuild the outputs anyway.
- return true;
+ return LOAD_SUCCESS;
}
long offset;
@@ -284,12 +284,12 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
fclose(f);
if (!Truncate(path, offset, err))
- return false;
+ return LOAD_ERROR;
// The truncate succeeded; we'll just report the load error as a
// warning because the build can proceed.
*err += "; recovering";
- return true;
+ return LOAD_SUCCESS;
}
fclose(f);
@@ -302,7 +302,7 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
needs_recompaction_ = true;
}
- return true;
+ return LOAD_SUCCESS;
}
DepsLog::Deps* DepsLog::GetDeps(Node* node) {
diff --git a/src/deps_log.h b/src/deps_log.h
index 3812a28..e7974a1 100644
--- a/src/deps_log.h
+++ b/src/deps_log.h
@@ -21,6 +21,7 @@ using namespace std;
#include <stdio.h>
+#include "load_status.h"
#include "timestamp.h"
struct Node;
@@ -84,7 +85,7 @@ struct DepsLog {
int node_count;
Node** nodes;
};
- bool Load(const string& path, State* state, string* err);
+ LoadStatus Load(const string& path, State* state, string* err);
Deps* GetDeps(Node* node);
/// Rewrite the known log entries, throwing away old data.
diff --git a/src/load_status.h b/src/load_status.h
new file mode 100644
index 0000000..0b16b1a
--- /dev/null
+++ b/src/load_status.h
@@ -0,0 +1,24 @@
+// Copyright 2019 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef NINJA_LOAD_STATUS_H_
+#define NINJA_LOAD_STATUS_H_
+
+enum LoadStatus {
+ LOAD_ERROR,
+ LOAD_SUCCESS,
+ LOAD_NOT_FOUND,
+};
+
+#endif // NINJA_LOAD_STATUS_H_
diff --git a/src/ninja.cc b/src/ninja.cc
index 8b76ded..7fcb4f7 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -17,6 +17,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <cstdlib>
#ifdef _WIN32
#include "getopt.h"
@@ -130,11 +131,11 @@ struct NinjaMain : public BuildLogUser {
int ToolRules(const Options* options, int argc, char* argv[]);
/// Open the build log.
- /// @return false on error.
+ /// @return LOAD_ERROR on error.
bool OpenBuildLog(bool recompact_only = false);
/// Open the deps log: load it, then open for writing.
- /// @return false on error.
+ /// @return LOAD_ERROR on error.
bool OpenDepsLog(bool recompact_only = false);
/// Ensure the build directory exists, creating it if necessary.
@@ -846,8 +847,8 @@ int NinjaMain::ToolRecompact(const Options* options, int argc, char* argv[]) {
if (!EnsureBuildDirExists())
return 1;
- if (!OpenBuildLog(/*recompact_only=*/true) ||
- !OpenDepsLog(/*recompact_only=*/true))
+ if (OpenBuildLog(/*recompact_only=*/true) == LOAD_ERROR ||
+ OpenDepsLog(/*recompact_only=*/true) == LOAD_ERROR)
return 1;
return 0;
@@ -862,12 +863,17 @@ int NinjaMain::ToolRestat(const Options* options, int argc, char* argv[]) {
log_path = build_dir_ + "/" + log_path;
string err;
- if (!build_log_.Load(log_path, &err)) {
+ const LoadStatus status = build_log_.Load(log_path, &err);
+ if (status == LOAD_ERROR) {
Error("loading build log %s: %s", log_path.c_str(), err.c_str());
return EXIT_FAILURE;
}
+ if (status == LOAD_NOT_FOUND) {
+ // Nothing to restat, ignore this
+ return EXIT_SUCCESS;
+ }
if (!err.empty()) {
- // Hack: Load() can return a warning via err by returning true.
+ // Hack: Load() can return a warning via err by returning LOAD_SUCCESS.
Warning("%s", err.c_str());
err.clear();
}
@@ -1068,17 +1074,21 @@ bool NinjaMain::OpenBuildLog(bool recompact_only) {
log_path = build_dir_ + "/" + log_path;
string err;
- if (!build_log_.Load(log_path, &err)) {
+ const LoadStatus status = build_log_.Load(log_path, &err);
+ if (status == LOAD_ERROR) {
Error("loading build log %s: %s", log_path.c_str(), err.c_str());
return false;
}
if (!err.empty()) {
- // Hack: Load() can return a warning via err by returning true.
+ // Hack: Load() can return a warning via err by returning LOAD_SUCCESS.
Warning("%s", err.c_str());
err.clear();
}
if (recompact_only) {
+ if (status == LOAD_NOT_FOUND) {
+ return true;
+ }
bool success = build_log_.Recompact(log_path, *this, &err);
if (!success)
Error("failed recompaction: %s", err.c_str());
@@ -1103,17 +1113,21 @@ bool NinjaMain::OpenDepsLog(bool recompact_only) {
path = build_dir_ + "/" + path;
string err;
- if (!deps_log_.Load(path, &state_, &err)) {
+ const LoadStatus status = deps_log_.Load(path, &state_, &err);
+ if (status == LOAD_ERROR) {
Error("loading deps log %s: %s", path.c_str(), err.c_str());
return false;
}
if (!err.empty()) {
- // Hack: Load() can return a warning via err by returning true.
+ // Hack: Load() can return a warning via err by returning LOAD_SUCCESS.
Warning("%s", err.c_str());
err.clear();
}
if (recompact_only) {
+ if (status == LOAD_NOT_FOUND) {
+ return true;
+ }
bool success = deps_log_.Recompact(path, &err);
if (!success)
Error("failed recompaction: %s", err.c_str());