#!/usr/bin/env python3 """Generate compile_commands.json (repo root) from a dry run of the makefiles. Used by VS Code IntelliSense (C/C++ extension) and clangd. Usage: python3 gcc/gen_compile_commands.py """ import json import os import re import shlex import subprocess ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) MAKEFILES = ["gcc/makefile_boot", "gcc/makefile_appli"] COMPILERS = ("arm-none-eabi-gcc", "arm-none-eabi-g++") def dry_run(makefile): # -B forces every compile command to be printed, -n executes nothing out = subprocess.run( ["make", "-r", "-B", "-n", "-f", makefile, "build_executable"], cwd=ROOT, capture_output=True, text=True, ).stdout return re.sub(r"\\\n\s*", " ", out).splitlines() def main(): entries = [] seen = set() for makefile in MAKEFILES: for line in dry_run(makefile): line = line.strip() if not line.startswith(COMPILERS) or " -c " not in f" {line} ": continue args = shlex.split(line) source = next((a for a in args if a.endswith((".c", ".cpp", ".s"))), None) if not source or source in seen: continue seen.add(source) entries.append({ "directory": ROOT, "arguments": args, "file": os.path.join(ROOT, source), }) path = os.path.join(ROOT, "compile_commands.json") with open(path, "w") as f: json.dump(entries, f, indent=1) print(f"{len(entries)} entries written to {path}") if __name__ == "__main__": main()