Skip to content

Commit

Permalink
feat: generate compile_commands.json with ninja
Browse files Browse the repository at this point in the history
  • Loading branch information
legendecas committed Mar 8, 2024
1 parent 7875642 commit c78f680
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 0 deletions.
4 changes: 4 additions & 0 deletions data/ninja/build.ninja
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rule cc
command = cc $in $out

build my.out: cc my.in
31 changes: 31 additions & 0 deletions pylib/gyp/generator/ninja.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import os.path
import re
import signal
import shutil
import subprocess
import sys
import gyp
Expand Down Expand Up @@ -2210,6 +2211,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name
options = params["options"]
flavor = gyp.common.GetFlavor(params)
generator_flags = params.get("generator_flags", {})
generate_compile_commands = generator_flags.get("compile_commands", False)

# build_dir: relative path from source root to our output files.
# e.g. "out/Debug"
Expand Down Expand Up @@ -2878,6 +2880,35 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, config_name

master_ninja_file.close()

if generate_compile_commands:
compile_db = GenerateCompileDBWithNinja(toplevel_build)
compile_db_file = OpenOutput(
os.path.join(toplevel_build, "compile_commands.json")
)
compile_db_file.write(json.dumps(compile_db, indent=2))
compile_db_file.close()


def GenerateCompileDBWithNinja(path, targets=["all"]):
"""Generates a compile database using ninja.
Args:
path: The build directory to generate a compile database for.
targets: Additional targets to pass to ninja.
Returns:
List of the contents of the compile database.
"""
ninja_path = shutil.which("ninja")
if ninja_path is None:
raise Exception("ninja not found in PATH")
json_compile_db = subprocess.check_output(
[ninja_path, "-C", path]
+ targets
+ ["-t", "compdb", "cc", "cxx", "objc", "objcxx"]
)
return json.loads(json_compile_db)


def PerformBuild(data, configurations, params):
options = params["options"]
Expand Down
11 changes: 11 additions & 0 deletions pylib/gyp/generator/ninja_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

""" Unit tests for the ninja.py file. """

import os
import sys
import unittest

Expand Down Expand Up @@ -50,6 +51,16 @@ def test_BinaryNamesLinux(self):
writer.ComputeOutputFileName(spec, "static_library").endswith(".a")
)

def test_GenerateCompileDBWithNinja(self):
this_dir = os.path.abspath(os.path.dirname(__file__))
build_dir = os.path.normpath(os.path.join(this_dir, "../../../data/ninja"))
compile_db = ninja.GenerateCompileDBWithNinja(build_dir)
self.assertEqual(len(compile_db), 1)
self.assertEqual(compile_db[0]["directory"], build_dir)
self.assertEqual(compile_db[0]["command"], "cc my.in my.out")
self.assertEqual(compile_db[0]["file"], "my.in")
self.assertEqual(compile_db[0]["output"], "my.out")


if __name__ == "__main__":
unittest.main()

0 comments on commit c78f680

Please sign in to comment.