summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/manual.asciidoc6
-rw-r--r--src/ninja.cc45
2 files changed, 51 insertions, 0 deletions
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc
index 119ccfd..c23a3e3 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 cc43325..b24ac33 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -486,6 +486,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 =
@@ -534,6 +577,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 }