Ninja: 'ninja -t compdb' should dump every rule

Created on 29 Jan 2018  ·  4Comments  ·  Source: ninja-build/ninja

I'm trying to use the compdb generation functionality of ninja, but it seems to just output [\n] every time. There's no documentation for this option, so it seems like there should be no other requirements than to run the command with a valid -C option?

Using ninja version 1.8.2 in case that matters.

feature

Most helpful comment

I'm also confused by this tool. I don't have problems passing rule names like cc cxx if they exist, but my problem with it was that I figured with no arguments, it should dump every rule it knows about, and only fallback to filtering when you give it arguments to do so.

I'm not sure if it's the project I work on or CMake, but when run using CMake in this project, the rule names are incredibly baroque and plentiful, so typing them all out is a non-starter for me. Instead, I use this patch to the package on my Ubuntu computer,

--- ninja-build-1.7.2.orig/src/ninja.cc
+++ ninja-build-1.7.2/src/ninja.cc
@@ -638,20 +638,36 @@ int NinjaMain::ToolCompilationDatabase(c
        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((*e)->EvaluateCommand().c_str());
-        printf("\",\n    \"file\": \"");
-        EncodeJSONString((*e)->inputs_[0]->path().c_str());
-        printf("\"\n  }");
+    if (argc == 0) {
+      if (!first)
+        putchar(',');

-        first = false;
+      printf("\n  {\n    \"directory\": \"");
+      EncodeJSONString(&cwd[0]);
+      printf("\",\n    \"command\": \"");
+      EncodeJSONString((*e)->EvaluateCommand().c_str());
+      printf("\",\n    \"file\": \"");
+      EncodeJSONString((*e)->inputs_[0]->path().c_str());
+      printf("\"\n  }");
+
+      first = false;
+    } else {
+      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((*e)->EvaluateCommand().c_str());
+          printf("\",\n    \"file\": \"");
+          EncodeJSONString((*e)->inputs_[0]->path().c_str());
+          printf("\"\n  }");
+
+          first = false;
+        }
       }
     }
   }

I never bothered cleaning it and posting to the list, because CMake provides it's own way to generate compile commands, but the above might help you in your situation.

All 4 comments

I'm also confused by this tool. I don't have problems passing rule names like cc cxx if they exist, but my problem with it was that I figured with no arguments, it should dump every rule it knows about, and only fallback to filtering when you give it arguments to do so.

I'm not sure if it's the project I work on or CMake, but when run using CMake in this project, the rule names are incredibly baroque and plentiful, so typing them all out is a non-starter for me. Instead, I use this patch to the package on my Ubuntu computer,

--- ninja-build-1.7.2.orig/src/ninja.cc
+++ ninja-build-1.7.2/src/ninja.cc
@@ -638,20 +638,36 @@ int NinjaMain::ToolCompilationDatabase(c
        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((*e)->EvaluateCommand().c_str());
-        printf("\",\n    \"file\": \"");
-        EncodeJSONString((*e)->inputs_[0]->path().c_str());
-        printf("\"\n  }");
+    if (argc == 0) {
+      if (!first)
+        putchar(',');

-        first = false;
+      printf("\n  {\n    \"directory\": \"");
+      EncodeJSONString(&cwd[0]);
+      printf("\",\n    \"command\": \"");
+      EncodeJSONString((*e)->EvaluateCommand().c_str());
+      printf("\",\n    \"file\": \"");
+      EncodeJSONString((*e)->inputs_[0]->path().c_str());
+      printf("\"\n  }");
+
+      first = false;
+    } else {
+      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((*e)->EvaluateCommand().c_str());
+          printf("\",\n    \"file\": \"");
+          EncodeJSONString((*e)->inputs_[0]->path().c_str());
+          printf("\"\n  }");
+
+          first = false;
+        }
       }
     }
   }

I never bothered cleaning it and posting to the list, because CMake provides it's own way to generate compile commands, but the above might help you in your situation.

I figured with no arguments, it should dump every rule it knows about, and only fallback to filtering when you give it arguments to do so.

That sounds reasonable to me.

As mentioned on https://github.com/ninja-build/ninja/issues/1024#issuecomment-178885017 , I think this would be a good change.

yes please.....

Was this page helpful?
0 / 5 - 0 ratings