xref: /openbmc/openbmc/poky/scripts/tiny/ksize.py (revision c182c62d)
1eb8dc403SDave Cobbley#!/usr/bin/env python3
2eb8dc403SDave Cobbley#
3eb8dc403SDave Cobbley# Copyright (c) 2011, Intel Corporation.
4eb8dc403SDave Cobbley#
5c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-or-later
6eb8dc403SDave Cobbley#
7*c182c62dSAndrew Geissler# Display details of the kernel build size, broken up by built-in.[o,a]. Sort
8eb8dc403SDave Cobbley# the objects by size. Run from the top level kernel build directory.
9eb8dc403SDave Cobbley#
10eb8dc403SDave Cobbley# Author: Darren Hart <dvhart@linux.intel.com>
11eb8dc403SDave Cobbley#
12eb8dc403SDave Cobbley
13eb8dc403SDave Cobbleyimport sys
14eb8dc403SDave Cobbleyimport getopt
15eb8dc403SDave Cobbleyimport os
16eb8dc403SDave Cobbleyfrom subprocess import *
17eb8dc403SDave Cobbley
18eb8dc403SDave Cobbleydef usage():
19eb8dc403SDave Cobbley    prog = os.path.basename(sys.argv[0])
20eb8dc403SDave Cobbley    print('Usage: %s [OPTION]...' % prog)
21eb8dc403SDave Cobbley    print('  -d,                 display an additional level of drivers detail')
22eb8dc403SDave Cobbley    print('  -h, --help          display this help and exit')
23eb8dc403SDave Cobbley    print('')
24eb8dc403SDave Cobbley    print('Run %s from the top-level Linux kernel build directory.' % prog)
25eb8dc403SDave Cobbley
26eb8dc403SDave Cobbley
27eb8dc403SDave Cobbleyclass Sizes:
28eb8dc403SDave Cobbley    def __init__(self, glob):
29eb8dc403SDave Cobbley        self.title = glob
3082c905dcSAndrew Geissler        p = Popen("size -t " + str(glob), shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
31eb8dc403SDave Cobbley        output = p.communicate()[0].splitlines()
32eb8dc403SDave Cobbley        if len(output) > 2:
33eb8dc403SDave Cobbley            sizes = output[-1].split()[0:4]
34eb8dc403SDave Cobbley            self.text = int(sizes[0])
35eb8dc403SDave Cobbley            self.data = int(sizes[1])
36eb8dc403SDave Cobbley            self.bss = int(sizes[2])
37eb8dc403SDave Cobbley            self.total = int(sizes[3])
38eb8dc403SDave Cobbley        else:
39eb8dc403SDave Cobbley            self.text = self.data = self.bss = self.total = 0
40eb8dc403SDave Cobbley
41eb8dc403SDave Cobbley    def show(self, indent=""):
42eb8dc403SDave Cobbley        print("%-32s %10d | %10d %10d %10d" % \
43eb8dc403SDave Cobbley              (indent+self.title, self.total, self.text, self.data, self.bss))
44eb8dc403SDave Cobbley
45eb8dc403SDave Cobbley
46eb8dc403SDave Cobbleyclass Report:
47eb8dc403SDave Cobbley    def create(filename, title, subglob=None):
48eb8dc403SDave Cobbley        r = Report(filename, title)
49eb8dc403SDave Cobbley        path = os.path.dirname(filename)
50eb8dc403SDave Cobbley
51eb8dc403SDave Cobbley        p = Popen("ls " + str(path) + "/*.o | grep -v built-in.o",
5282c905dcSAndrew Geissler                  shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
53eb8dc403SDave Cobbley        glob = ' '.join(p.communicate()[0].splitlines())
54eb8dc403SDave Cobbley        oreport = Report(glob, str(path) + "/*.o")
55eb8dc403SDave Cobbley        oreport.sizes.title = str(path) + "/*.o"
56eb8dc403SDave Cobbley        r.parts.append(oreport)
57eb8dc403SDave Cobbley
58eb8dc403SDave Cobbley        if subglob:
5982c905dcSAndrew Geissler            p = Popen("ls " + subglob, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
60eb8dc403SDave Cobbley            for f in p.communicate()[0].splitlines():
61eb8dc403SDave Cobbley                path = os.path.dirname(f)
62*c182c62dSAndrew Geissler                r.parts.append(Report.create(f, path, str(path) + "/*/built-in.[o,a]"))
63eb8dc403SDave Cobbley            r.parts.sort(reverse=True)
64eb8dc403SDave Cobbley
65eb8dc403SDave Cobbley        for b in r.parts:
66eb8dc403SDave Cobbley            r.totals["total"] += b.sizes.total
67eb8dc403SDave Cobbley            r.totals["text"] += b.sizes.text
68eb8dc403SDave Cobbley            r.totals["data"] += b.sizes.data
69eb8dc403SDave Cobbley            r.totals["bss"] += b.sizes.bss
70eb8dc403SDave Cobbley
71eb8dc403SDave Cobbley        r.deltas["total"] = r.sizes.total - r.totals["total"]
72eb8dc403SDave Cobbley        r.deltas["text"] = r.sizes.text - r.totals["text"]
73eb8dc403SDave Cobbley        r.deltas["data"] = r.sizes.data - r.totals["data"]
74eb8dc403SDave Cobbley        r.deltas["bss"] = r.sizes.bss - r.totals["bss"]
75eb8dc403SDave Cobbley        return r
76eb8dc403SDave Cobbley    create = staticmethod(create)
77eb8dc403SDave Cobbley
78eb8dc403SDave Cobbley    def __init__(self, glob, title):
79eb8dc403SDave Cobbley        self.glob = glob
80eb8dc403SDave Cobbley        self.title = title
81eb8dc403SDave Cobbley        self.sizes = Sizes(glob)
82eb8dc403SDave Cobbley        self.parts = []
83eb8dc403SDave Cobbley        self.totals = {"total":0, "text":0, "data":0, "bss":0}
84eb8dc403SDave Cobbley        self.deltas = {"total":0, "text":0, "data":0, "bss":0}
85eb8dc403SDave Cobbley
86eb8dc403SDave Cobbley    def show(self, indent=""):
87eb8dc403SDave Cobbley        rule = str.ljust(indent, 80, '-')
88eb8dc403SDave Cobbley        print("%-32s %10s | %10s %10s %10s" % \
89eb8dc403SDave Cobbley              (indent+self.title, "total", "text", "data", "bss"))
90eb8dc403SDave Cobbley        print(rule)
91eb8dc403SDave Cobbley        self.sizes.show(indent)
92eb8dc403SDave Cobbley        print(rule)
93eb8dc403SDave Cobbley        for p in self.parts:
94eb8dc403SDave Cobbley            if p.sizes.total > 0:
95eb8dc403SDave Cobbley                p.sizes.show(indent)
96eb8dc403SDave Cobbley        print(rule)
97eb8dc403SDave Cobbley        print("%-32s %10d | %10d %10d %10d" % \
98eb8dc403SDave Cobbley              (indent+"sum", self.totals["total"], self.totals["text"],
99eb8dc403SDave Cobbley               self.totals["data"], self.totals["bss"]))
100eb8dc403SDave Cobbley        print("%-32s %10d | %10d %10d %10d" % \
101eb8dc403SDave Cobbley              (indent+"delta", self.deltas["total"], self.deltas["text"],
102eb8dc403SDave Cobbley               self.deltas["data"], self.deltas["bss"]))
103eb8dc403SDave Cobbley        print("\n")
104eb8dc403SDave Cobbley
105eb8dc403SDave Cobbley    def __lt__(this, that):
106eb8dc403SDave Cobbley        if that is None:
107eb8dc403SDave Cobbley            return 1
108eb8dc403SDave Cobbley        if not isinstance(that, Report):
109eb8dc403SDave Cobbley            raise TypeError
110eb8dc403SDave Cobbley        return this.sizes.total < that.sizes.total
111eb8dc403SDave Cobbley
112eb8dc403SDave Cobbley    def __cmp__(this, that):
113eb8dc403SDave Cobbley        if that is None:
114eb8dc403SDave Cobbley            return 1
115eb8dc403SDave Cobbley        if not isinstance(that, Report):
116eb8dc403SDave Cobbley            raise TypeError
117eb8dc403SDave Cobbley        if this.sizes.total < that.sizes.total:
118eb8dc403SDave Cobbley            return -1
119eb8dc403SDave Cobbley        if this.sizes.total > that.sizes.total:
120eb8dc403SDave Cobbley            return 1
121eb8dc403SDave Cobbley        return 0
122eb8dc403SDave Cobbley
123eb8dc403SDave Cobbley
124eb8dc403SDave Cobbleydef main():
125eb8dc403SDave Cobbley    try:
126eb8dc403SDave Cobbley        opts, args = getopt.getopt(sys.argv[1:], "dh", ["help"])
127eb8dc403SDave Cobbley    except getopt.GetoptError as err:
128eb8dc403SDave Cobbley        print('%s' % str(err))
129eb8dc403SDave Cobbley        usage()
130eb8dc403SDave Cobbley        sys.exit(2)
131eb8dc403SDave Cobbley
132eb8dc403SDave Cobbley    driver_detail = False
133eb8dc403SDave Cobbley    for o, a in opts:
134eb8dc403SDave Cobbley        if o == '-d':
135eb8dc403SDave Cobbley            driver_detail = True
136eb8dc403SDave Cobbley        elif o in ('-h', '--help'):
137eb8dc403SDave Cobbley            usage()
138eb8dc403SDave Cobbley            sys.exit(0)
139eb8dc403SDave Cobbley        else:
140eb8dc403SDave Cobbley            assert False, "unhandled option"
141eb8dc403SDave Cobbley
142*c182c62dSAndrew Geissler    glob = "arch/*/built-in.[o,a] */built-in.[o,a]"
143eb8dc403SDave Cobbley    vmlinux = Report.create("vmlinux",  "Linux Kernel", glob)
144eb8dc403SDave Cobbley
145eb8dc403SDave Cobbley    vmlinux.show()
146eb8dc403SDave Cobbley    for b in vmlinux.parts:
147eb8dc403SDave Cobbley        if b.totals["total"] > 0 and len(b.parts) > 1:
148eb8dc403SDave Cobbley            b.show()
149eb8dc403SDave Cobbley        if b.title == "drivers" and driver_detail:
150eb8dc403SDave Cobbley            for d in b.parts:
151eb8dc403SDave Cobbley                if d.totals["total"] > 0 and len(d.parts) > 1:
152eb8dc403SDave Cobbley                    d.show("    ")
153eb8dc403SDave Cobbley
154eb8dc403SDave Cobbley
155eb8dc403SDave Cobbleyif __name__ == "__main__":
156eb8dc403SDave Cobbley    main()
157