Skip to content

Instantly share code, notes, and snippets.

@fsimonis
Created November 19, 2024 10:03
Show Gist options
  • Save fsimonis/f8da437c7f22e6a923a194003f7115e9 to your computer and use it in GitHub Desktop.
Save fsimonis/f8da437c7f22e6a923a194003f7115e9 to your computer and use it in GitHub Desktop.
Tool to expand CMake unity builds for clangd support

deunify

This tool exands the compile_commands.json of unity build files generated by CMake to enable clangd support.

Without this, clangd doesn't know what to do with the compilation units.

Default file is compile_commands.json in the current working directory. Outputs to console by default. Use -i to update in-place.

To use:

deunify -i build/compile_commands.json
deunify -i # update file in the same directory
#!python3
import json
import argparse
def traverse(entry):
with open(entry["file"]) as f:
for line in f:
if line.startswith('#include "/'):
file = line.removeprefix('#include "').removesuffix(
'\n').removesuffix('"')
output = file + ".o"
command = entry["command"].replace(
entry["file"], file).replace(entry["output"], output)
yield {
"directory": entry["directory"],
"command": command,
"file": file,
"output": file + ".o"
}
def deunify(cc):
return cc + [newentry for entry in cc for newentry in traverse(entry)]
def main():
p = argparse.ArgumentParser()
p.add_argument("file", nargs="?", default="compile_commands.json")
p.add_argument("-i", "--inplace", action="store_true", help="Overwrite input file")
args = p.parse_args()
with open(args.file) as f:
cc = json.load(f)
res = deunify(cc)
if args.inplace:
with open(args.file, "w") as f:
json.dump(res, f, indent=2)
else:
print(json.dumps(res, indent=2))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment