diff options
-rw-r--r-- | doc/manual.asciidoc | 6 | ||||
-rw-r--r-- | src/ninja.cc | 45 |
2 files changed, 51 insertions, 0 deletions
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc index 1e5b70b..ea26b8d 100644 --- a/doc/manual.asciidoc +++ b/doc/manual.asciidoc @@ -283,6 +283,12 @@ Files created but not referenced in the graph are not removed. This tool takes in account the +-v+ and the +-n+ options (note that +-n+ implies +-v+). +`compdb`:: given a list of rules, each of which is expected to be a +C family language compiler rule whose first input is the name of the +source file, prints on standard output a compilation database in the +http://clang.llvm.org/docs/JSONCompilationDatabase.html[JSON format] expected +by the Clang tooling interface. +_Available since Ninja 1.2._ Writing your own Ninja files diff --git a/src/ninja.cc b/src/ninja.cc index 2b250b7..c6a3500 100644 --- a/src/ninja.cc +++ b/src/ninja.cc @@ -485,6 +485,49 @@ int ToolClean(Globals* globals, int argc, char* argv[]) { } } +void EncodeJSONString(const char *str) { + while (*str) { + if (*str == '"' || *str == '\\') + putchar('\\'); + putchar(*str); + str++; + } +} + +int ToolCompilationDatabase(Globals* globals, int argc, char* argv[]) { + bool first = true; + char cwd[PATH_MAX]; + + if (!getcwd(cwd, PATH_MAX)) { + Error("cannot determine working directory: %s", strerror(errno)); + return 1; + } + + putchar('['); + for (vector<Edge*>::iterator e = globals->state->edges_.begin(); + e != globals->state->edges_.end(); ++e) { + for (int i = 0; i != argc; ++i) { + if ((*e)->rule_->name() == argv[i]) { + if (!first) + putchar(','); + + printf("\n {\n \"directory\": \""); + EncodeJSONString(cwd); + printf("\",\n \"command\": \""); + EncodeJSONString((*e)->EvaluateCommand().c_str()); + printf("\",\n \"file\": \""); + EncodeJSONString((*e)->inputs_[0]->path().c_str()); + printf("\"\n }"); + + first = false; + } + } + } + + puts("\n]"); + return 0; +} + int ToolUrtle(Globals* globals, int argc, char** argv) { // RLE encoded. const char* urtle = @@ -533,6 +576,8 @@ int ChooseTool(const string& tool_name, const Tool** tool_out) { Tool::RUN_AFTER_LOAD, ToolQuery }, { "targets", "list targets by their rule or depth in the DAG", Tool::RUN_AFTER_LOAD, ToolTargets }, + { "compdb", "dump JSON compilation database to stdout", + Tool::RUN_AFTER_LOAD, ToolCompilationDatabase }, { "urtle", NULL, Tool::RUN_AFTER_FLAGS, ToolUrtle }, { NULL, NULL, Tool::RUN_AFTER_FLAGS, NULL } |