Просмотр исходного кода

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.
Chandler Carruth 7 месяцев назад
Родитель
Сommit
42d03ac390
1 измененных файлов с 58 добавлено и 0 удалено
  1. 58 0
      scripts/create_compdb.py

+ 58 - 0
scripts/create_compdb.py

@@ -24,8 +24,10 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 """
 
 import argparse
+import json
 import subprocess
 import sys
+from typing import Any, Dict
 
 import scripts_utils
 
@@ -72,6 +74,60 @@ def _build_generated_files(
     )
 
 
+def _get_config_for_entry(entry: Dict[str, Any]) -> str:
+    """Returns the configuration for a compile command entry."""
+    arguments = entry.get("arguments")
+
+    # Only handle files where the object file argument is easily found as
+    # the last argument, which matches the expected structure from Bazel.
+    if not arguments or len(arguments) < 2 or arguments[-2] != "-o":
+        return "unknown"
+    obj_file = arguments[-1]
+
+    # The configuration is the name of the subdirectory of `bazel-out`.
+    if not obj_file.startswith("bazel-out/"):
+        return "unknown"
+    return str(obj_file.split("/")[1])
+
+
+def _filter_compilation_database(file_path: str) -> None:
+    """Filters out duplicate exec-config entries from the database."""
+    print("Filtering out duplicate exec-configuration entries...")
+    try:
+        with open(file_path, "r") as f:
+            commands = json.load(f)
+    except FileNotFoundError:
+        print(f"Error: The file '{file_path}' was not found.")
+        sys.exit(1)
+    except json.JSONDecodeError:
+        print(f"Error: The file '{file_path}' is not a valid JSON file.")
+        sys.exit(1)
+
+    # We want to skip compiles that were in the "exec" configuration for tools.
+    # Because we generate compile commands for every bazel cc_* target in the
+    # main configuration, even if only used by tools, their sources should be
+    # covered and the exec configuration would simply be a duplicate.
+    #
+    # Detecting this based on the `-exec-` string in the configuration name of
+    # the directory is a bit of a hack, but even using the `--notool_deps`
+    # argument, Bazel seems to sometimes include this configuration in the query
+    # that produces the compilation database.
+    filtered_commands = [
+        entry
+        for entry in commands
+        if "-exec-" not in _get_config_for_entry(entry)
+    ]
+
+    with open(file_path, "w") as f:
+        # Use indent=4 for a human-readable, pretty-printed output file
+        json.dump(filtered_commands, f, indent=4)
+    print(
+        "Filtered out "
+        f"{len(commands) - len(filtered_commands)} "
+        "duplicate entries..."
+    )
+
+
 def main() -> None:
     parser = argparse.ArgumentParser(
         description=__doc__,
@@ -108,6 +164,8 @@ def main() -> None:
         ]
     )
 
+    _filter_compilation_database("compile_commands.json")
+
 
 if __name__ == "__main__":
     main()