35 lines
1.4 KiB
Python
Executable File
35 lines
1.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Runs only in the build image, during configure/lsp, never server startup."""
|
|
import json
|
|
import pathlib
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
def header_roots(config):
|
|
roots = set()
|
|
for driver in config["query_drivers"]:
|
|
for language in ("c", "c++"):
|
|
result = subprocess.run([driver, "-E", "-v", "-x", language, "-"], input="",
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True)
|
|
listing = False
|
|
for line in result.stderr.splitlines():
|
|
if line == "#include <...> search starts here:":
|
|
listing = True
|
|
elif line == "End of search list.":
|
|
listing = False
|
|
elif listing:
|
|
roots.add(pathlib.Path(line.strip()).resolve())
|
|
version = subprocess.check_output([config["executable"], "--version"], text=True)
|
|
major = re.search(r"version (\d+)", version).group(1)
|
|
builtin = pathlib.Path(f"/usr/lib/llvm-{major}/lib/clang/{major}/include")
|
|
roots.add(builtin)
|
|
roots.update(pathlib.Path(root) for root in config["header_roots"])
|
|
for root in roots:
|
|
if not root.is_dir() or root == pathlib.Path("/"):
|
|
raise ValueError(f"missing or invalid header directory: {root}")
|
|
return sorted(str(root) for root in roots if not any(parent in roots for parent in root.parents))
|
|
|
|
if __name__ == "__main__":
|
|
print(json.dumps(header_roots(json.loads(sys.argv[1]))))
|