53 lines
1.6 KiB
Python
Executable File
53 lines
1.6 KiB
Python
Executable File
#!/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()
|