From e99c493bc7a7d06cd0de91c3ac670315800e760b Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 28 Feb 2013 00:28:23 -0800 Subject: Add compdb tool This tool helps convert Ninja build files to a compilation database of the form used by Clang tooling. --- doc/manual.asciidoc | 6 ++++++ src/ninja.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) 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::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 } -- cgit v0.12