Skip to content

Commit 42d03ac

Browse files
authored
Another attempt to fix ClangD-tidy (#6131)
This restores the original approach in #6046 as it appears `--notool_deps` isn't sufficient in some situations. It still isn't clear to me why it seemed to work initially, but I can easily reproduce the issue now even with that flag. I've tried to address the feedback in the original PR on the Python code.
1 parent d85781a commit 42d03ac

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

scripts/create_compdb.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
"""
2525

2626
import argparse
27+
import json
2728
import subprocess
2829
import sys
30+
from typing import Any, Dict
2931

3032
import scripts_utils
3133

@@ -72,6 +74,60 @@ def _build_generated_files(
7274
)
7375

7476

77+
def _get_config_for_entry(entry: Dict[str, Any]) -> str:
78+
"""Returns the configuration for a compile command entry."""
79+
arguments = entry.get("arguments")
80+
81+
# Only handle files where the object file argument is easily found as
82+
# the last argument, which matches the expected structure from Bazel.
83+
if not arguments or len(arguments) < 2 or arguments[-2] != "-o":
84+
return "unknown"
85+
obj_file = arguments[-1]
86+
87+
# The configuration is the name of the subdirectory of `bazel-out`.
88+
if not obj_file.startswith("bazel-out/"):
89+
return "unknown"
90+
return str(obj_file.split("/")[1])
91+
92+
93+
def _filter_compilation_database(file_path: str) -> None:
94+
"""Filters out duplicate exec-config entries from the database."""
95+
print("Filtering out duplicate exec-configuration entries...")
96+
try:
97+
with open(file_path, "r") as f:
98+
commands = json.load(f)
99+
except FileNotFoundError:
100+
print(f"Error: The file '{file_path}' was not found.")
101+
sys.exit(1)
102+
except json.JSONDecodeError:
103+
print(f"Error: The file '{file_path}' is not a valid JSON file.")
104+
sys.exit(1)
105+
106+
# We want to skip compiles that were in the "exec" configuration for tools.
107+
# Because we generate compile commands for every bazel cc_* target in the
108+
# main configuration, even if only used by tools, their sources should be
109+
# covered and the exec configuration would simply be a duplicate.
110+
#
111+
# Detecting this based on the `-exec-` string in the configuration name of
112+
# the directory is a bit of a hack, but even using the `--notool_deps`
113+
# argument, Bazel seems to sometimes include this configuration in the query
114+
# that produces the compilation database.
115+
filtered_commands = [
116+
entry
117+
for entry in commands
118+
if "-exec-" not in _get_config_for_entry(entry)
119+
]
120+
121+
with open(file_path, "w") as f:
122+
# Use indent=4 for a human-readable, pretty-printed output file
123+
json.dump(filtered_commands, f, indent=4)
124+
print(
125+
"Filtered out "
126+
f"{len(commands) - len(filtered_commands)} "
127+
"duplicate entries..."
128+
)
129+
130+
75131
def main() -> None:
76132
parser = argparse.ArgumentParser(
77133
description=__doc__,
@@ -108,6 +164,8 @@ def main() -> None:
108164
]
109165
)
110166

167+
_filter_compilation_database("compile_commands.json")
168+
111169

112170
if __name__ == "__main__":
113171
main()

0 commit comments

Comments
 (0)