From 5b4a9b5e35594eafea7e0981a9fab9cd266debb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C3=ABl=20Carr=C3=A9?= Date: Mon, 31 May 2010 00:46:04 +0000 Subject: [PATCH] Add a tool to compare the binsizes of plugins and codecs of 2 build dirs Doesn't handle IRAM (yet) Synopsys: ./cmp-plugins-size build1 build2 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26428 a1c6a512-1295-4272-9138-f99709370657 --- utils/analysis/cmp-plugins-size.py | 159 +++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 utils/analysis/cmp-plugins-size.py diff --git a/utils/analysis/cmp-plugins-size.py b/utils/analysis/cmp-plugins-size.py new file mode 100755 index 0000000000..27ffb0fcae --- /dev/null +++ b/utils/analysis/cmp-plugins-size.py @@ -0,0 +1,159 @@ +#!/usr/bin/python +# -*- coding: utf8 -*- +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# +# Copyright © 2010 Rafaël Carré +# +# 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# + +# TODO: iram + +import sys +import os +import re +import stat +import fnmatch + + +def percent_diff(old, new): + if old == 0: + return '?' + diff = 100.0*(new-old)/old + return format(diff, '+2.2f') + '%' + + +def find_map(dir): + dirs = [] + for file in os.listdir(dir): + path = os.path.join(dir, file) + if stat.S_ISDIR(os.stat(path).st_mode) != 0: + dirs += find_map(path) + elif fnmatch.fnmatch(file, '*.map'): + dirs += [path] + return dirs + + +def rb_version(dir): + info = os.path.join(dir, 'rockbox-info.txt') + if not os.path.lexists(info): + return 'unknown' + info = open(info).read() + s = re.search('^Version: .*', info, re.MULTILINE) + if not s: + return 'unknown' + return re.sub('^Version: ', '', info[s.start():s.end()]) + + +def map_info(map): + file = os.path.basename(map) + name = file.rsplit('.map', 1)[0] + + # ignore ape-pre map, used to fill IRAM + if name == 'ape-pre': + return None + + # ignore overlays + ovlmap = os.path.join(os.path.dirname(map), name, file) + if os.path.lexists(ovlmap): + return None + + f = open(map).read() # read map content + + s = re.search('^PLUGIN_RAM *0x(\d|[abcdef])*', f, re.MULTILINE) + plugin_start = re.sub('^PLUGIN_RAM *0x0*', '', f[s.start():s.end()]) + + s = re.search('^\.pluginend *0x(\d|[abcdef])*', f, re.MULTILINE) + plugin_end = re.sub('^\.pluginend *0x0*', '', f[s.start():s.end()]) + + size = int(plugin_end, 16) - int(plugin_start, 16) + return (name, size) + + +def get_new(oldinfo, newinfo, name): + i = 0 + while i < len(oldinfo) and i < len(newinfo): + if newinfo[i][0] == name: + return newinfo[i] + i += 1 + return None + + +def compare(olddir, newdir, oldver, newer): + oldinfo = [] + for map in find_map(olddir): + info = map_info(map) + if info: + oldinfo += [info] + + newinfo = [] + for map in find_map(newdir): + info = map_info(map) + if info: + newinfo += [info] + + oldinfo.sort() + newinfo.sort() + + diff = [] + longest_name = 0 + for (name, old_size) in oldinfo: + new = get_new(oldinfo, newinfo, name) + if not new: + continue + (name, new_size) = new + if len(name) > longest_name: + longest_name = len(name) + diff += [(name, new_size - old_size, old_size)] + + spacelen = (longest_name + 3) + + print(' ' * spacelen + oldver + '\t\t' + newver + '\n') + + for (name, diff, old_size) in diff: + space = ' ' * (longest_name - len(name) + 3) + new_size = old_size + diff + pdiff = percent_diff(old_size, new_size) + diff = str(diff) + if diff[0] != '-': + diff = '+' + diff + + print(name + space + str(old_size) + '\t' + diff + \ + '\t=\t' + str(new_size) + '\t-->\t' + pdiff) + + + + +### main + + +if len(sys.argv) != 3: + print('Usage: ' + sys.argv[0] + ' build-old build-new') + sys.exit(1) + +oldver = rb_version(sys.argv[1]) +newver = rb_version(sys.argv[2]) + +oldplugindir = sys.argv[1] + '/apps/plugins' +newplugindir = sys.argv[2] + '/apps/plugins' +oldcodecsdir = sys.argv[1] + '/apps/codecs' +newcodecsdir = sys.argv[2] + '/apps/codecs' + +if os.path.lexists(oldplugindir) and os.path.lexists(newplugindir): + compare(oldplugindir, newplugindir, oldver, newver) + +print('\n\n\n') + +if os.path.lexists(oldcodecsdir) and os.path.lexists(newcodecsdir): + compare(oldcodecsdir, newcodecsdir, oldver, newver)