Ninja generator, compilation database issues

"Jelic, Nikola" <[email protected]> Fri, 30 Aug 2024 08:38:17 +0000
Newsgroups gmane.comp.programming.tools.scons.user
Message-ID <GVAP278MB0151A380EFDE488FB3B7B5BA9C972@GVAP278MB0151.CHEP278.PROD.OUTLOOK.COM>
Greetings,

We are using SCons' Ninja generator to upgrade the existing project. We are also using the compilation database extension in SCons, but we have reached some interesting limitations when we try to use Ninja generator.
In short, if "compile_commands.json" is requested to be anywhere except the root of the project (which is not our case), we face one or all of these issues:

  *
Duplicate Ninja targets
  *
A hanging task for generating the compilation database on a different location

I have a small WIP patch that resolves some of these issues, but I wanted to start a discussion and see what the best approach would be.

The points I have so far:

  *
Compilation database can be generated from SCons or from Ninja independently, as it is an open format
  *
Ninja doesn't have to invoke SCons to generate the compilation database
  *
The location and the name of the compilation database file should be completely independent of the project structure

Kind regards,

Nikola Jelić

_______________________________________________
Scons-users mailing list
[email protected]
https://pairlist4.pair.net/mailman/listinfo/scons-users
0002-Generated-ninja-file-doesn-t-have-the-duplicated-com.patch (application/octet-stream, 3.2 KB)
From 378bde67d87117f552bc73205ae2cfa74ee32a49 Mon Sep 17 00:00:00 2001
From: Nikola Jelic <[email protected]>
Date: Wed, 10 Jul 2024 10:46:56 +0200
Subject: [PATCH 2/2] Generated ninja file doesn't have the duplicated
 compiledb entries anymore

Signed-off-by: Nikola Jelic <[email protected]>
---
 SCons/Tool/ninja/NinjaState.py | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/SCons/Tool/ninja/NinjaState.py b/SCons/Tool/ninja/NinjaState.py
index 5e7c28919..9cec999ee 100644
--- a/SCons/Tool/ninja/NinjaState.py
+++ b/SCons/Tool/ninja/NinjaState.py
@@ -474,6 +474,7 @@ class NinjaState:
 
         template_builders = []
         scons_compiledb = False
+        scons_compiledb_path = "compile_commands.json"
 
         if SCons.Script._Get_Default_Targets == SCons.Script._Set_Default_Targets_Has_Not_Been_Called:
             all_targets = set()
@@ -483,6 +484,11 @@ class NinjaState:
         for build in [self.builds[key] for key in sorted(self.builds.keys())]:
             if "compile_commands.json" in build["outputs"]:
                 scons_compiledb = True
+            else:
+                candidate = [i for i in build["outputs"] if i.endswith("compile_commands.json")]
+                if len(candidate) != 0:
+                    scons_compiledb_path = candidate[0]
+                    continue
 
             # this is for the no command line targets, no SCons default case. We want this default
             # to just be all real files in the build.
@@ -622,26 +628,27 @@ class NinjaState:
             # update this build to reflect that complete list.
             ninja_sorted_build(
                 ninja,
-                outputs="compile_commands.json",
+                outputs=scons_compiledb_path,
                 rule="CMD",
                 pool="console",
                 implicit=[str(self.ninja_file)],
                 variables={
-                    "cmd": "{} -f {} -t compdb {}CC CXX > compile_commands.json".format(
+                    "cmd": "{} -f {} -t compdb {}CC CXX > {}".format(
                         # NINJA_COMPDB_EXPAND - should only be true for ninja
                         # This was added to ninja's compdb tool in version 1.9.0 (merged April 2018)
                         # https://github.com/ninja-build/ninja/pull/1223
                         # TODO: add check in generate to check version and enable this by default if it's available.
                         self.ninja_bin_path, str(self.ninja_file),
-                        '-x ' if self.env.get('NINJA_COMPDB_EXPAND', True) else ''
+                        '-x ' if self.env.get('NINJA_COMPDB_EXPAND', True) else '',
+                        scons_compiledb_path
                     )
                 },
             )
-
-            ninja_sorted_build(
-                ninja,
-                outputs="compiledb", rule="phony", implicit=["compile_commands.json"],
-            )
+            if scons_compiledb_path == "compile_commands.json":
+                ninja_sorted_build(
+                    ninja,
+                    outputs="compiledb", rule="phony", implicit=[scons_compiledb_path],
+                )
 
         ninja_sorted_build(
             ninja,
-- 
2.43.0.windows.1