zephyr/scripts/footprint/fpdiff.py
Keith Packard 97f8b8b6ee scripts/footprint: Avoid fpdiff failure when data changes lots
Bounds check the array access in case the input data changes so that the
number of entries in the 'children' array is not the same. The tool output
with this change isn't terribly useful, but at least it doesn't crash.

Signed-off-by: Keith Packard <keithp@keithp.com>
2024-01-10 20:50:51 -05:00

82 lines
2.6 KiB
Python
Executable file

#!/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 increased 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, AnyNode
from anytree.search import find
import colorama
from colorama import Fore
import json
import argparse
importer = DictImporter()
def parse_args():
parser = argparse.ArgumentParser(
description="Compare footprint sizes of two builds.", allow_abbrev=False)
parser.add_argument("file1", help="First file")
parser.add_argument("file2", help="Second file")
return parser.parse_args()
def main():
colorama.init()
args = parse_args()
with open(args.file1, "r") as f:
data1 = json.load(f)
with open(args.file2, "r") as f:
data2 = json.load(f)
for idx, ch in enumerate(data1['symbols']['children']):
root1 = importer.import_(ch)
if idx >= len(data2['symbols']['children']):
root2 = AnyNode(identifier=None)
else:
root2 = importer.import_(data2['symbols']['children'][idx])
print(f"{root1.name}\n+++++++++++++++++++++")
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()