Skip to content

Commit

Permalink
feat: generate compile_commands.json with ninja (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
legendecas authored Apr 1, 2024
1 parent 4b95b2c commit 7b20b46
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/python_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
- uses: seanmiddleditch/gha-setup-ninja@v4
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
Expand Down
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
12 changes: 12 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. """

from pathlib import Path
import sys
import unittest

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

def test_GenerateCompileDBWithNinja(self):
build_dir = (
Path(__file__).resolve().parent.parent.parent.parent / "data" / "ninja"
)
compile_db = ninja.GenerateCompileDBWithNinja(build_dir)
assert len(compile_db) == 1
assert compile_db[0]["directory"] == str(build_dir)
assert compile_db[0]["command"] == "cc my.in my.out"
assert compile_db[0]["file"] == "my.in"
assert compile_db[0]["output"] == "my.out"


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

0 comments on commit 7b20b46

Please sign in to comment.