diff options
-rw-r--r-- | appveyor.yml | 2 | ||||
-rw-r--r-- | src/build.cc | 6 | ||||
-rw-r--r-- | src/disk_interface.cc | 14 | ||||
-rw-r--r-- | src/graph.cc | 28 | ||||
-rw-r--r-- | src/graph.h | 6 | ||||
-rw-r--r-- | src/line_printer.cc | 4 | ||||
-rw-r--r-- | src/ninja.cc | 47 | ||||
-rw-r--r-- | src/test.cc | 9 |
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 |