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