1#!/usr/bin/env python3 2# 3# check-units.py: check the number of compilation units and identify 4# those that are rebuilt multiple times 5# 6# Copyright (C) 2025 Linaro Ltd. 7# 8# SPDX-License-Identifier: GPL-2.0-or-later 9 10from os import access, R_OK, path 11from sys import argv, exit 12import json 13from collections import Counter 14 15 16def extract_build_units(cc_path): 17 """ 18 Extract the build units and their counds from compile_commands.json file. 19 20 Returns: 21 Hash table of ["unit"] = count 22 """ 23 24 j = json.load(open(cc_path, 'r')) 25 files = [f['file'] for f in j] 26 build_units = Counter(files) 27 28 return build_units 29 30 31def analyse_units(build_units): 32 """ 33 Analyse the build units and report stats and the top 10 rebuilds 34 """ 35 36 print(f"Total source files: {len(build_units.keys())}") 37 print(f"Total build units: {sum(units.values())}") 38 39 # Create a sorted list by number of rebuilds 40 sorted_build_units = sorted(build_units.items(), 41 key=lambda item: item[1], 42 reverse=True) 43 44 print("Most rebuilt units:") 45 for unit, count in sorted_build_units[:20]: 46 print(f" {unit} built {count} times") 47 48 print("Least rebuilt units:") 49 for unit, count in sorted_build_units[-10:]: 50 print(f" {unit} built {count} times") 51 52 53if __name__ == "__main__": 54 if len(argv) != 2: 55 script_name = path.basename(argv[0]) 56 print(f"Usage: {script_name} <path_to_compile_commands.json>") 57 exit(1) 58 59 cc_path = argv[1] 60 if path.isfile(cc_path) and access(cc_path, R_OK): 61 units = extract_build_units(cc_path) 62 analyse_units(units) 63 exit(0) 64 else: 65 print(f"{cc_path} doesn't exist or isn't readable") 66 exit(1) 67