--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/build/buildutils/armsize.py Fri Oct 29 11:49:32 2010 +0300
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# This utility is used to find out the size in disk of files
+# written to ROM images (or compiled). Script finds out Symbian
+# build enviornment binary file paths based on iby-file(s) or
+# mmp-files, and prints out file sizes.
+#
+# Run the script with option --help to see the parameters
+
+import os.path, fnmatch, re, subprocess, glob
+from optparse import OptionParser
+from itertools import chain
+
+RE_MMP_TARGET = re.compile(r"\s*TARGET\s+(\S+)", re.IGNORECASE)
+RE_DEFINE = re.compile(r"^define\s*(\S+)\s+(\S+)\s*$", re.IGNORECASE)
+RE_IBYTARGET = re.compile(r"^(?:file|data)=(\S+)\s+\S+\s*$", re.IGNORECASE)
+
+# Base defines used in IBY files
+BASE_DEFINES = [("ABI_DIR", r"\epoc32\release\armv5"),
+ ("BUILD_DIR", r"urel"),
+ ("DATAZ_", r"\epoc32\data\z"),
+ ("RESOURCE_FILES_DIR", r"resource"),
+ ("ZRESOURCE", r"DATAZ_\resource"),
+ ("ZSYSTEM", r"DATAZ_\system"),
+ ("ZPRIVATE", r"DATAZ_\private")]
+
+def flatten(listOfLists):
+ return list(chain(*listOfLists))
+
+def cppFile(source, cppDefines = None, include = None):
+ ''' Preprocess source with epoc32/include, and return preprocessed lines '''
+ includePaths = [r"/epoc32/include"]
+
+ if cppDefines:
+ cppDefines = " ".join(["-D%s" % d for d in cppDefines])
+ else:
+ cppDefines = ""
+ if include:
+ path, filename = os.path.split(include)
+ includePaths.append(path)
+
+ include = "-include " + include
+
+ else:
+ include = ""
+
+ drive, tail = os.path.splitdrive(source)
+ command = r'cpp %s %s %s "%s"' % (" ".join(["-I %s" % i for i in includePaths]),
+ cppDefines, include, source)
+ process = subprocess.Popen(command,
+ shell = True,
+ cwd = "%s\\" % drive,
+ stdout = subprocess.PIPE)
+ for line in process.stdout.readlines():
+ yield line
+
+def replaceDefines(line, defines):
+ ''' Replace the macro definitions recursively '''
+ oldLine = None
+ while oldLine != line:
+ oldLine = line
+ for search, replace in defines:
+ line = line.replace(search, replace)
+ return line
+
+def parseIby(lines):
+ ''' Parse IBY file lines, using defines '''
+ defines = BASE_DEFINES[:]
+ for l in lines:
+ defineMatch = RE_DEFINE.match(l)
+ if defineMatch:
+ search, replace = defineMatch.groups()
+ defines.append((search, replace))
+ else:
+ yield replaceDefines(l, defines)
+
+def getIbySources(ibyfile, cppDefines = None, include = None):
+ ''' Get IBY file source files'''
+ drive, tail = os.path.splitdrive(ibyfile)
+ for l in parseIby(cppFile(ibyfile, cppDefines, include)):
+ match = RE_IBYTARGET.match(l)
+ if match:
+ yield drive + match.group(1)
+
+def findFiles(root, pattern):
+ ''' Find files recursively '''
+ for path, dirs, files in os.walk(root):
+ for f in fnmatch.filter(files, pattern):
+ yield os.path.join(path, f)
+
+def getMmpTarget(mmpfile):
+ ''' Get the target binary name from mmp-file '''
+ for l in open(mmpfile, "r").readlines():
+ match = RE_MMP_TARGET.search(l)
+ if match:
+ return match.group(1)
+ return None
+
+def getMmpTargets(mmpRoot):
+ ''' Get the target binary paths of all mmp-files found under root '''
+ drive, tail = os.path.splitdrive(mmpRoot)
+
+ totalSize = 0
+ for mmp in findFiles(mmpRoot, "*.mmp"):
+ target = getMmpTarget(mmp)
+ if not target:
+ continue
+ binPath = drive + "/epoc32/release/armv5/urel/" + target
+ if os.path.exists(binPath):
+ yield binPath
+
+def getSizes(binaries):
+ ''' Get the sizes of given files, return list of tuples (size|None, file) '''
+ for binPath in binaries:
+ if not os.path.exists(binPath):
+ yield None, binPath
+ else:
+ yield os.path.getsize(binPath), binPath
+
+def printSizes(sizes):
+ ''' Print file sizes and a total '''
+ totalSize = 0
+ for size, binPath in sizes:
+ if size:
+ totalSize = totalSize + size
+
+ print "%s\t%s" % (size, binPath)
+
+ print "%d\tTotal" % totalSize
+
+def main():
+ parser = OptionParser()
+ parser.add_option(
+ "--mmproot", dest = "mmproot",
+ help = "root for searching mmp-files (whose target is used for filenames)")
+ parser.add_option(
+ "--ibyfile", dest = "ibyfile",
+ help = "ibyfile(s) which are processed to find out target file paths")
+ parser.add_option(
+ "--sortname", dest = "sortname", action = "store_true", default = False,
+ help = "sort files by name")
+ parser.add_option(
+ "--sortsize", dest = "sortsize", action = "store_true", default = False,
+ help = "sort files by size")
+ parser.add_option(
+ "--cppdefines", dest = "cppdefines",
+ help = "cpp defines for iby, e.g. --cppdefines __JAVA,__JAVA_MIDP20")
+ parser.add_option(
+ "--include", dest = "include",
+ help = "Include file for iby cpp, e.g. --include /epoc32/include/config/ncp52/bldpublic.hrh")
+ (options, args) = parser.parse_args()
+
+ if options.mmproot:
+ binaries = getMmpTargets(options.mmproot)
+
+ elif options.ibyfile:
+ cppdefines = options.cppdefines and options.cppdefines.split(",")
+
+ ibys = glob.glob(options.ibyfile)
+ binaries = flatten([getIbySources(iby, cppdefines, options.include)
+ for iby in ibys])
+
+ sizes = getSizes(binaries)
+
+ if options.sortsize:
+ sizes = sorted(sizes)
+ if options.sortname:
+ sizes = sorted(sizes, cmp=lambda x,y: cmp(x[1], y[1]))
+
+ printSizes(sizes)
+
+if __name__ == "__main__":
+ main()