master
py 71 lines 2.02 KB
Raw
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
10 from os import access, R_OK, path
11 from sys import exit
12 import json
13 import argparse
14 from pathlib import Path
15 from collections import Counter
16
17
18 def extract_build_units(cc_path):
19 """
20 Extract the build units and their counds from compile_commands.json file.
21
22 Returns:
23 Hash table of ["unit"] = count
24 """
25
26 j = json.load(open(cc_path, 'r'))
27 files = [f['file'] for f in j]
28 build_units = Counter(files)
29
30 return build_units
31
32
33 def analyse_units(build_units, top_n):
34 """
35 Analyse the build units and report stats and the top 10 rebuilds
36 """
37
38 print(f"Total source files: {len(build_units.keys())}")
39 print(f"Total build units: {sum(units.values())}")
40
41 # Create a sorted list by number of rebuilds
42 sorted_build_units = sorted(build_units.items(),
43 key=lambda item: item[1],
44 reverse=True)
45
46 print("Most rebuilt units:")
47 for unit, count in sorted_build_units[:top_n]:
48 print(f" {unit} built {count} times")
49
50 print("Least rebuilt units:")
51 for unit, count in sorted_build_units[-10:]:
52 print(f" {unit} built {count} times")
53
54
55 if __name__ == "__main__":
56 parser = argparse.ArgumentParser(
57 description="analyse number of build units in compile_commands.json")
58 parser.add_argument("cc_path", type=Path, default=None,
59 help="Path to compile_commands.json")
60 parser.add_argument("-n", type=int, default=20,
61 help="Dump the top <n> entries")
62
63 args = parser.parse_args()
64
65 if path.isfile(args.cc_path) and access(args.cc_path, R_OK):
66 units = extract_build_units(args.cc_path)
67 analyse_units(units, args.n)
68 exit(0)
69 else:
70 print(f"{args.cc_path} doesn't exist or isn't readable")
71 exit(1)