#!/usr/bin/env python3 # compile_commands.json generator # Copyright (C) 2024 Intel Corporation # # This software may be distributed under the terms of the BSD license. # See README for more details. import os import sys import glob import json import argparse parser = argparse.ArgumentParser(description='Read each of the build directories that are given and generate ' 'a compile_commands.json file. If a source file is found multiple times, ' 'then the compile flags from the last build directory will be used.') parser.add_argument('-o', '--output', default='compile_commands.json', type=str, help="Output file to generate") parser.add_argument('builddirs', nargs='+', type=str, metavar="builddir", help='Build directories to search') args = parser.parse_args() files = {} for builddir in args.builddirs: for cmd_file in glob.glob('**/*.o.cmd', root_dir=builddir, recursive=True): with open(os.path.join(builddir, cmd_file), encoding='ascii') as f: base_dir, cmd = f.readline().split(':', 1) src_file = cmd.rsplit(maxsplit=1)[1] src_file = os.path.abspath(os.path.join(base_dir, src_file)) files[src_file] = { 'command': cmd.strip(), 'directory': base_dir, 'file': src_file, } flist = json.dumps(sorted(list(files.values()), key=lambda k: k['file']), indent=2, sort_keys=True) try: # Avoid writing the file if it did not change, first read original with open(args.output, 'rt', encoding='UTF-8') as f: orig = [] while data := f.read(): orig.append(data) orig = ''.join(orig) except OSError: orig = '' # And only write if something changed if orig != flist: with open(args.output, 'wt', encoding='UTF-8') as f: f.write(flist)