summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--appveyor.yml2
-rw-r--r--src/build.cc6
-rw-r--r--src/disk_interface.cc14
-rw-r--r--src/graph.cc28
-rw-r--r--src/graph.h6
-rw-r--r--src/line_printer.cc4
-rw-r--r--src/ninja.cc47
-rw-r--r--src/test.cc9
8 files changed, 66 insertions, 50 deletions
diff --git a/appveyor.yml b/appveyor.yml
index 4c64f29..04ed58e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -16,7 +16,7 @@ for:
build_script:
ps: "C:\\msys64\\usr\\bin\\bash -lc @\"\n
pacman -S --quiet --noconfirm --needed re2c 2>&1\n
- sed -i 's|cmd /c $ar cqs $out.tmp $in && move /Y $out.tmp $out|$ar crs $out $in|g' configure.py\n
+ sed -i 's|cmd /c `$ar cqs `$out.tmp `$in \\&\\& move /Y `$out.tmp `$out|`$ar crs `$out `$in|g' configure.py\n
./configure.py --bootstrap --platform mingw 2>&1\n
./ninja all\n
./ninja_test 2>&1\n
diff --git a/src/build.cc b/src/build.cc
index a055738..8ef88b5 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -139,7 +139,11 @@ void BuildStatus::BuildEdgeFinished(Edge* edge,
o != edge->outputs_.end(); ++o)
outputs += (*o)->path() + " ";
- printer_.PrintOnNewLine("FAILED: " + outputs + "\n");
+ if (printer_.supports_color()) {
+ printer_.PrintOnNewLine("\x1B[31m" "FAILED: " "\x1B[0m" + outputs + "\n");
+ } else {
+ printer_.PrintOnNewLine("FAILED: " + outputs + "\n");
+ }
printer_.PrintOnNewLine(edge->EvaluateCommand() + "\n");
}
diff --git a/src/disk_interface.cc b/src/disk_interface.cc
index d4c2fb0..dc297c4 100644
--- a/src/disk_interface.cc
+++ b/src/disk_interface.cc
@@ -202,19 +202,13 @@ TimeStamp RealDiskInterface::Stat(const string& path, string* err) const {
// that it doesn't exist.
if (st.st_mtime == 0)
return 1;
-#if defined(__APPLE__) && !defined(_POSIX_C_SOURCE)
+#if defined(_AIX)
+ return (int64_t)st.st_mtime * 1000000000LL + st.st_mtime_n;
+#elif defined(__APPLE__)
return ((int64_t)st.st_mtimespec.tv_sec * 1000000000LL +
st.st_mtimespec.tv_nsec);
-#elif (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700 || defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \
- defined(__BIONIC__) || (defined (__SVR4) && defined (__sun)) || defined(__FreeBSD__))
- // For glibc, see "Timestamp files" in the Notes of http://www.kernel.org/doc/man-pages/online/pages/man2/stat.2.html
- // newlib, uClibc and musl follow the kernel (or Cygwin) headers and define the right macro values above.
- // For bsd, see https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h and similar
- // For bionic, C and POSIX API is always enabled.
- // For solaris, see https://docs.oracle.com/cd/E88353_01/html/E37841/stat-2.html.
+#elif defined(st_mtime) // A macro, so we're likely on modern POSIX.
return (int64_t)st.st_mtim.tv_sec * 1000000000LL + st.st_mtim.tv_nsec;
-#elif defined(_AIX)
- return (int64_t)st.st_mtime * 1000000000LL + st.st_mtime_n;
#else
return (int64_t)st.st_mtime * 1000000000LL + st.st_mtimensec;
#endif
diff --git a/src/graph.cc b/src/graph.cc
index a90c049..376b911 100644
--- a/src/graph.cc
+++ b/src/graph.cc
@@ -323,19 +323,17 @@ bool Edge::AllInputsReady() const {
struct EdgeEnv : public Env {
enum EscapeKind { kShellEscape, kDoNotEscape };
- EdgeEnv(Edge* edge, EscapeKind escape)
+ EdgeEnv(const Edge* const edge, const EscapeKind escape)
: edge_(edge), escape_in_out_(escape), recursive_(false) {}
virtual string LookupVariable(const string& var);
/// Given a span of Nodes, construct a list of paths suitable for a command
/// line.
- string MakePathList(vector<Node*>::iterator begin,
- vector<Node*>::iterator end,
- char sep);
+ std::string MakePathList(const Node* const* span, size_t size, char sep) const;
private:
vector<string> lookups_;
- Edge* edge_;
+ const Edge* const edge_;
EscapeKind escape_in_out_;
bool recursive_;
};
@@ -344,14 +342,11 @@ string EdgeEnv::LookupVariable(const string& var) {
if (var == "in" || var == "in_newline") {
int explicit_deps_count = edge_->inputs_.size() - edge_->implicit_deps_ -
edge_->order_only_deps_;
- return MakePathList(edge_->inputs_.begin(),
- edge_->inputs_.begin() + explicit_deps_count,
+ return MakePathList(&edge_->inputs_[0], explicit_deps_count,
var == "in" ? ' ' : '\n');
} else if (var == "out") {
int explicit_outs_count = edge_->outputs_.size() - edge_->implicit_outs_;
- return MakePathList(edge_->outputs_.begin(),
- edge_->outputs_.begin() + explicit_outs_count,
- ' ');
+ return MakePathList(&edge_->outputs_[0], explicit_outs_count, ' ');
}
if (recursive_) {
@@ -376,11 +371,10 @@ string EdgeEnv::LookupVariable(const string& var) {
return edge_->env_->LookupWithFallback(var, eval, this);
}
-string EdgeEnv::MakePathList(vector<Node*>::iterator begin,
- vector<Node*>::iterator end,
- char sep) {
+std::string EdgeEnv::MakePathList(const Node* const* const span,
+ const size_t size, const char sep) const {
string result;
- for (vector<Node*>::iterator i = begin; i != end; ++i) {
+ for (const Node* const* i = span; i != span + size; ++i) {
if (!result.empty())
result.push_back(sep);
const string& path = (*i)->PathDecanonicalized();
@@ -397,7 +391,7 @@ string EdgeEnv::MakePathList(vector<Node*>::iterator begin,
return result;
}
-string Edge::EvaluateCommand(bool incl_rsp_file) {
+std::string Edge::EvaluateCommand(const bool incl_rsp_file) const {
string command = GetBinding("command");
if (incl_rsp_file) {
string rspfile_content = GetBinding("rspfile_content");
@@ -407,7 +401,7 @@ string Edge::EvaluateCommand(bool incl_rsp_file) {
return command;
}
-string Edge::GetBinding(const string& key) {
+std::string Edge::GetBinding(const std::string& key) const {
EdgeEnv env(this, EdgeEnv::kShellEscape);
return env.LookupVariable(key);
}
@@ -426,7 +420,7 @@ string Edge::GetUnescapedDyndep() {
return env.LookupVariable("dyndep");
}
-string Edge::GetUnescapedRspfile() {
+std::string Edge::GetUnescapedRspfile() const {
EdgeEnv env(this, EdgeEnv::kDoNotEscape);
return env.LookupVariable("rspfile");
}
diff --git a/src/graph.h b/src/graph.h
index 75edbc5..6122837 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -155,10 +155,10 @@ struct Edge {
/// Expand all variables in a command and return it as a string.
/// If incl_rsp_file is enabled, the string will also contain the
/// full contents of a response file (if applicable)
- string EvaluateCommand(bool incl_rsp_file = false);
+ std::string EvaluateCommand(bool incl_rsp_file = false) const;
/// Returns the shell-escaped value of |key|.
- string GetBinding(const string& key);
+ std::string GetBinding(const string& key) const;
bool GetBindingBool(const string& key);
/// Like GetBinding("depfile"), but without shell escaping.
@@ -166,7 +166,7 @@ struct Edge {
/// Like GetBinding("dyndep"), but without shell escaping.
string GetUnescapedDyndep();
/// Like GetBinding("rspfile"), but without shell escaping.
- string GetUnescapedRspfile();
+ std::string GetUnescapedRspfile() const;
void Dump(const char* prefix="") const;
diff --git a/src/line_printer.cc b/src/line_printer.cc
index 55469d9..c93173e 100644
--- a/src/line_printer.cc
+++ b/src/line_printer.cc
@@ -58,7 +58,9 @@ LinePrinter::LinePrinter() : have_blank_line_(true), console_locked_(false) {
if (supports_color_) {
DWORD mode;
if (GetConsoleMode(console_, &mode)) {
- SetConsoleMode(console_, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+ if (!SetConsoleMode(console_, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING)) {
+ supports_color_ = false;
+ }
}
}
#endif
diff --git a/src/ninja.cc b/src/ninja.cc
index a093cd1..c24f09d 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -732,7 +732,8 @@ enum EvaluateCommandMode {
ECM_NORMAL,
ECM_EXPAND_RSPFILE
};
-string EvaluateCommandWithRspfile(Edge* edge, EvaluateCommandMode mode) {
+std::string EvaluateCommandWithRspfile(const Edge* edge,
+ const EvaluateCommandMode mode) {
string command = edge->EvaluateCommand();
if (mode == ECM_NORMAL)
return command;
@@ -756,6 +757,19 @@ string EvaluateCommandWithRspfile(Edge* edge, EvaluateCommandMode mode) {
return command;
}
+void printCompdb(const char* const directory, const Edge* const edge,
+ const EvaluateCommandMode eval_mode) {
+ printf("\n {\n \"directory\": \"");
+ EncodeJSONString(directory);
+ printf("\",\n \"command\": \"");
+ EncodeJSONString(EvaluateCommandWithRspfile(edge, eval_mode).c_str());
+ printf("\",\n \"file\": \"");
+ EncodeJSONString(edge->inputs_[0]->path().c_str());
+ printf("\",\n \"output\": \"");
+ EncodeJSONString(edge->outputs_[0]->path().c_str());
+ printf("\"\n }");
+}
+
int NinjaMain::ToolCompilationDatabase(const Options* options, int argc,
char* argv[]) {
// The compdb tool uses getopt, and expects argv[0] to contain the name of
@@ -804,22 +818,21 @@ int NinjaMain::ToolCompilationDatabase(const Options* options, int argc,
e != state_.edges_.end(); ++e) {
if ((*e)->inputs_.empty())
continue;
- for (int i = 0; i != argc; ++i) {
- if ((*e)->rule_->name() == argv[i]) {
- if (!first)
- putchar(',');
-
- printf("\n {\n \"directory\": \"");
- EncodeJSONString(&cwd[0]);
- printf("\",\n \"command\": \"");
- EncodeJSONString(EvaluateCommandWithRspfile(*e, eval_mode).c_str());
- printf("\",\n \"file\": \"");
- EncodeJSONString((*e)->inputs_[0]->path().c_str());
- printf("\",\n \"output\": \"");
- EncodeJSONString((*e)->outputs_[0]->path().c_str());
- printf("\"\n }");
-
- first = false;
+ if (argc == 0) {
+ if (!first) {
+ putchar(',');
+ }
+ printCompdb(&cwd[0], *e, eval_mode);
+ first = false;
+ } else {
+ for (int i = 0; i != argc; ++i) {
+ if ((*e)->rule_->name() == argv[i]) {
+ if (!first) {
+ putchar(',');
+ }
+ printCompdb(&cwd[0], *e, eval_mode);
+ first = false;
+ }
}
}
}
diff --git a/src/test.cc b/src/test.cc
index a9816bc..8ba2297 100644
--- a/src/test.cc
+++ b/src/test.cc
@@ -33,6 +33,15 @@
#include "manifest_parser.h"
#include "util.h"
+#ifdef _AIX
+extern "C" {
+ // GCC "helpfully" strips the definition of mkdtemp out on AIX.
+ // The function is still present, so if we define it ourselves
+ // it will work perfectly fine.
+ extern char* mkdtemp(char* name_template);
+}
+#endif
+
namespace {
#ifdef _WIN32