scripts: introduce footprint diffing
Very simple script to diff between two ram or rom reports generated by
size_report. When you call call the ram_report or rom_report targets you
end up with a json file in the build directory that can be used as input
for this script.
The output shows which symbols insreased and which decreased in size and
also tracked added/remove symbols as well.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
diff --git a/scripts/footprint/fpdiff.py b/scripts/footprint/fpdiff.py
new file mode 100755
index 0000000..3c4172b
--- /dev/null
+++ b/scripts/footprint/fpdiff.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 Intel Corporation
+#
+# SPDX-License-Identifier: Apache-2.0
+
+# A script to diff between two ram or rom reports generated by
+# size_report. When you call call the ram_report or rom_report targets you
+# end up with a json file in the build directory that can be used as input
+# for this script.
+
+# The output shows which symbols insreased and which decreased in size and
+# also tracked added/remove symbols as well.
+
+# Example:
+# ./scripts/footprint/fpdiff.py ram1.json ram2.json
+
+from anytree.importer import DictImporter
+from anytree import PreOrderIter
+from anytree.search import find
+
+from colorama import Fore
+import json
+import argparse
+
+importer = DictImporter()
+
+def parse_args():
+ parser = argparse.ArgumentParser(
+ description="Compare footprint sizes of two builds.")
+ parser.add_argument("file1", help="First file")
+ parser.add_argument("file2", help="Second file")
+
+ return parser.parse_args()
+
+def main():
+ args = parse_args()
+
+ with open(args.file1, "r") as f:
+ data = json.load(f)
+ root1 = importer.import_(data['symbols'])
+
+ with open(args.file2, "r") as f:
+ data = json.load(f)
+ root2 = importer.import_(data['symbols'])
+
+ for node in PreOrderIter(root1):
+ # pylint: disable=undefined-loop-variable
+ n = find(root2, lambda node2: node2.identifier == node.identifier)
+ if n:
+ if n.size != node.size:
+ diff = n.size - node.size
+ if diff == 0:
+ continue
+ if not n.children or not n.parent:
+ if diff < 0:
+ print(f"{n.identifier} -> {Fore.GREEN}{diff}{Fore.RESET}")
+ else:
+ print(f"{n.identifier} -> {Fore.RED}+{diff}{Fore.RESET}")
+
+ else:
+ if not node.children:
+ print(f"{node.identifier} ({Fore.GREEN}-{node.size}{Fore.RESET}) disappeared.")
+
+ for node in PreOrderIter(root2):
+ n = find(root1, lambda node2: node2.identifier == node.identifier)
+ if not n:
+ if not node.children and node.size != 0:
+ print(f"{node.identifier} ({Fore.RED}+{node.size}{Fore.RESET}) is new.")
+
+
+if __name__ == "__main__":
+ main()