blob: d4f3892156da5d1572045d8f0a8224a60a09f221 [file] [log] [blame]
Brad Bishop6e60e8b2018-02-01 10:27:11 -05001#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# Copyright (c) 2016, Intel Corporation.
6# All rights reserved.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License version 2 as
10# published by the Free Software Foundation.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# DESCRIPTION 'ksum.py' generates a combined summary of vmlinux and
22# module sizes for a built kernel, as a quick tool for comparing the
23# overall effects of systemic tinification changes. Execute from the
24# base directory of the kernel build you want to summarize. Setting
25# the 'verbose' flag will display the sizes for each file included in
26# the summary.
27#
28# AUTHORS
29# Tom Zanussi <tom.zanussi (at] linux.intel.com>
30#
31
32__version__ = "0.1.0"
33
34# Python Standard Library modules
35import os
36import sys
37import getopt
38from subprocess import *
39
40def usage():
41 prog = os.path.basename(sys.argv[0])
42 print('Usage: %s [OPTION]...' % prog)
43 print(' -v, display sizes for each file')
44 print(' -h, --help display this help and exit')
45 print('')
46 print('Run %s from the top-level Linux kernel build directory.' % prog)
47
48verbose = False
49
50n_ko_files = 0
51ko_file_list = []
52
53ko_text = 0
54ko_data = 0
55ko_bss = 0
56ko_total = 0
57
58vmlinux_file = ""
59vmlinux_level = 0
60
61vmlinux_text = 0
62vmlinux_data = 0
63vmlinux_bss = 0
64vmlinux_total = 0
65
66def is_vmlinux_file(filename):
67 global vmlinux_level
68 if filename == ("vmlinux") and vmlinux_level == 0:
69 vmlinux_level += 1
70 return True
71 return False
72
73def is_ko_file(filename):
74 if filename.endswith(".ko"):
75 return True
76 return False
77
78def collect_object_files():
79 print "Collecting object files recursively from %s..." % os.getcwd()
80 for dirpath, dirs, files in os.walk(os.getcwd()):
81 for filename in files:
82 if is_ko_file(filename):
83 ko_file_list.append(os.path.join(dirpath, filename))
84 elif is_vmlinux_file(filename):
85 global vmlinux_file
86 vmlinux_file = os.path.join(dirpath, filename)
87 print "Collecting object files [DONE]"
88
89def add_ko_file(filename):
90 p = Popen("size -t " + filename, shell=True, stdout=PIPE, stderr=PIPE)
91 output = p.communicate()[0].splitlines()
92 if len(output) > 2:
93 sizes = output[-1].split()[0:4]
94 if verbose:
95 print " %10d %10d %10d %10d\t" % \
96 (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])),
97 print "%s" % filename[len(os.getcwd()) + 1:]
98 global n_ko_files, ko_text, ko_data, ko_bss, ko_total
99 ko_text += int(sizes[0])
100 ko_data += int(sizes[1])
101 ko_bss += int(sizes[2])
102 ko_total += int(sizes[3])
103 n_ko_files += 1
104
105def get_vmlinux_totals():
106 p = Popen("size -t " + vmlinux_file, shell=True, stdout=PIPE, stderr=PIPE)
107 output = p.communicate()[0].splitlines()
108 if len(output) > 2:
109 sizes = output[-1].split()[0:4]
110 if verbose:
111 print " %10d %10d %10d %10d\t" % \
112 (int(sizes[0]), int(sizes[1]), int(sizes[2]), int(sizes[3])),
113 print "%s" % vmlinux_file[len(os.getcwd()) + 1:]
114 global vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total
115 vmlinux_text += int(sizes[0])
116 vmlinux_data += int(sizes[1])
117 vmlinux_bss += int(sizes[2])
118 vmlinux_total += int(sizes[3])
119
120def sum_ko_files():
121 for ko_file in ko_file_list:
122 add_ko_file(ko_file)
123
124def main():
125 try:
126 opts, args = getopt.getopt(sys.argv[1:], "vh", ["help"])
127 except getopt.GetoptError as err:
128 print('%s' % str(err))
129 usage()
130 sys.exit(2)
131
132 for o, a in opts:
133 if o == '-v':
134 global verbose
135 verbose = True
136 elif o in ('-h', '--help'):
137 usage()
138 sys.exit(0)
139 else:
140 assert False, "unhandled option"
141
142 collect_object_files()
143 sum_ko_files()
144 get_vmlinux_totals()
145
146 print "\nTotals:"
147 print "\nvmlinux:"
148 print " text\tdata\t\tbss\t\ttotal"
149 print " %-10d\t%-10d\t%-10d\t%-10d" % \
150 (vmlinux_text, vmlinux_data, vmlinux_bss, vmlinux_total)
151 print "\nmodules (%d):" % n_ko_files
152 print " text\tdata\t\tbss\t\ttotal"
153 print " %-10d\t%-10d\t%-10d\t%-10d" % \
154 (ko_text, ko_data, ko_bss, ko_total)
155 print "\nvmlinux + modules:"
156 print " text\tdata\t\tbss\t\ttotal"
157 print " %-10d\t%-10d\t%-10d\t%-10d" % \
158 (vmlinux_text + ko_text, vmlinux_data + ko_data, \
159 vmlinux_bss + ko_bss, vmlinux_total + ko_total)
160
161if __name__ == "__main__":
162 try:
163 ret = main()
164 except Exception:
165 ret = 1
166 import traceback
167 traceback.print_exc(5)
168 sys.exit(ret)