poky/scripts/tiny/ksize.py
Tom Zanussi 1cae998af9 scripts: python3 fixes and new tool ksum
'ksum.py' generates a combined summary of vmlinux and module sizes for
a built kernel, as a quick tool for comparing the overall effects of
systemic tinification changes.  Execute from the base directory of the
kernel build you want to summarize.  Setting the 'verbose' flag will
display the sizes for each file included in the summary.

(From OE-Core rev: 016b19c2589582d7ec3c8cac9cfa75a1edc716fe)

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Alejandro Hernandez <alejandro.hernandez@linux.intel.com>
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2017-01-16 18:05:14 +00:00

171 lines
5.6 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Copyright (c) 2011, Intel Corporation.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Display details of the kernel build size, broken up by built-in.o. Sort
# the objects by size. Run from the top level kernel build directory.
#
# Author: Darren Hart <dvhart@linux.intel.com>
#
import sys
import getopt
import os
from subprocess import *
def usage():
prog = os.path.basename(sys.argv[0])
print('Usage: %s [OPTION]...' % prog)
print(' -d, display an additional level of drivers detail')
print(' -h, --help display this help and exit')
print('')
print('Run %s from the top-level Linux kernel build directory.' % prog)
class Sizes:
def __init__(self, glob):
self.title = glob
p = Popen("size -t " + str(glob), shell=True, stdout=PIPE, stderr=PIPE)
output = p.communicate()[0].splitlines()
if len(output) > 2:
sizes = output[-1].split()[0:4]
self.text = int(sizes[0])
self.data = int(sizes[1])
self.bss = int(sizes[2])
self.total = int(sizes[3])
else:
self.text = self.data = self.bss = self.total = 0
def show(self, indent=""):
print("%-32s %10d | %10d %10d %10d" % \
(indent+self.title, self.total, self.text, self.data, self.bss))
class Report:
def create(filename, title, subglob=None):
r = Report(filename, title)
path = os.path.dirname(filename)
p = Popen("ls " + str(path) + "/*.o | grep -v built-in.o",
shell=True, stdout=PIPE, stderr=PIPE)
glob = ' '.join(p.communicate()[0].splitlines())
oreport = Report(glob, str(path) + "/*.o")
oreport.sizes.title = str(path) + "/*.o"
r.parts.append(oreport)
if subglob:
p = Popen("ls " + subglob, shell=True, stdout=PIPE, stderr=PIPE)
for f in p.communicate()[0].splitlines():
path = os.path.dirname(f)
r.parts.append(Report.create(f, path, str(path) + "/*/built-in.o"))
r.parts.sort(reverse=True)
for b in r.parts:
r.totals["total"] += b.sizes.total
r.totals["text"] += b.sizes.text
r.totals["data"] += b.sizes.data
r.totals["bss"] += b.sizes.bss
r.deltas["total"] = r.sizes.total - r.totals["total"]
r.deltas["text"] = r.sizes.text - r.totals["text"]
r.deltas["data"] = r.sizes.data - r.totals["data"]
r.deltas["bss"] = r.sizes.bss - r.totals["bss"]
return r
create = staticmethod(create)
def __init__(self, glob, title):
self.glob = glob
self.title = title
self.sizes = Sizes(glob)
self.parts = []
self.totals = {"total":0, "text":0, "data":0, "bss":0}
self.deltas = {"total":0, "text":0, "data":0, "bss":0}
def show(self, indent=""):
rule = str.ljust(indent, 80, '-')
print("%-32s %10s | %10s %10s %10s" % \
(indent+self.title, "total", "text", "data", "bss"))
print(rule)
self.sizes.show(indent)
print(rule)
for p in self.parts:
if p.sizes.total > 0:
p.sizes.show(indent)
print(rule)
print("%-32s %10d | %10d %10d %10d" % \
(indent+"sum", self.totals["total"], self.totals["text"],
self.totals["data"], self.totals["bss"]))
print("%-32s %10d | %10d %10d %10d" % \
(indent+"delta", self.deltas["total"], self.deltas["text"],
self.deltas["data"], self.deltas["bss"]))
print("\n")
def __lt__(this, that):
if that is None:
return 1
if not isinstance(that, Report):
raise TypeError
return this.sizes.total < that.sizes.total
def __cmp__(this, that):
if that is None:
return 1
if not isinstance(that, Report):
raise TypeError
if this.sizes.total < that.sizes.total:
return -1
if this.sizes.total > that.sizes.total:
return 1
return 0
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "dh", ["help"])
except getopt.GetoptError as err:
print('%s' % str(err))
usage()
sys.exit(2)
driver_detail = False
for o, a in opts:
if o == '-d':
driver_detail = True
elif o in ('-h', '--help'):
usage()
sys.exit(0)
else:
assert False, "unhandled option"
glob = "arch/*/built-in.o */built-in.o"
vmlinux = Report.create("vmlinux", "Linux Kernel", glob)
vmlinux.show()
for b in vmlinux.parts:
if b.totals["total"] > 0 and len(b.parts) > 1:
b.show()
if b.title == "drivers" and driver_detail:
for d in b.parts:
if d.totals["total"] > 0 and len(d.parts) > 1:
d.show(" ")
if __name__ == "__main__":
main()