mirror of https://github.com/ArduPilot/ardupilot
122 lines
4.6 KiB
Python
Executable File
122 lines
4.6 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
'''
|
|
This script intend to provide a pretty size diff between two binaries.
|
|
|
|
AP_FLAKE8_CLEAN
|
|
'''
|
|
|
|
import os
|
|
from argparse import ArgumentParser
|
|
from tabulate import tabulate
|
|
|
|
parser = ArgumentParser(description="Print binary size difference with master.")
|
|
parser.add_argument("-m", "--master", dest='master', type=str, help="Master Binaries Path", required=True)
|
|
parser.add_argument("-s", "--second", dest='second', type=str, help="Second Binaries Path", required=True)
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
def sizes_for_file(filepath):
|
|
"""Get binary size information with size."""
|
|
print("Get binary size of %s" % filepath)
|
|
cmd = "size %s" % (filepath,)
|
|
stuff = os.popen(cmd).read()
|
|
lines = stuff.splitlines()[1:]
|
|
size_list = []
|
|
for line in lines:
|
|
row = line.strip().split()
|
|
size_list.append(dict(
|
|
text=int(row[0]),
|
|
data=int(row[1]),
|
|
bss=int(row[2]),
|
|
total=int(row[3]),
|
|
))
|
|
|
|
# Get the size of .crash_log to remove it from .bss reporting
|
|
cmd = "size -A %s" % (filepath,)
|
|
output = os.popen(cmd).read()
|
|
lines = output.splitlines()[1:]
|
|
for line in lines:
|
|
if ".crash_log" in line:
|
|
row = line.strip().split()
|
|
size_list[0]["crash_log"] = int(row[1])
|
|
break
|
|
|
|
# check if crash_log wasn't found and set to 0B if not found
|
|
# FIX ME : so it doesn't report Flash_Free 0B for non-ARM boards
|
|
if size_list[0].get("crash_log") is None:
|
|
size_list[0]["crash_log"] = 0
|
|
|
|
return size_list
|
|
|
|
|
|
def print_table(summary_data_list_second, summary_data_list_master):
|
|
"""Print the binaries size diff on a table."""
|
|
print_data = []
|
|
print("")
|
|
# print(summary_data_list_second)
|
|
# print(summary_data_list_master)
|
|
for name in summary_data_list_second[0]:
|
|
for master_name in summary_data_list_master[0]:
|
|
if name == master_name:
|
|
col_data = [name]
|
|
for key in ["text", "data", "bss", "total"]:
|
|
bvalue = summary_data_list_second[0][name].get(key)
|
|
mvalue = summary_data_list_master[0][name].get(key)
|
|
|
|
# BSS: remove the portion occupied by crash_log as the command `size binary.elf`
|
|
# reports BSS with crash_log included
|
|
if key == "bss":
|
|
mvalue = (summary_data_list_master[0][name].get("bss") -
|
|
summary_data_list_master[0][name].get("crash_log"))
|
|
bvalue = (summary_data_list_second[0][name].get("bss") -
|
|
summary_data_list_second[0][name].get("crash_log"))
|
|
|
|
# Total Flash Cost = Data + Text
|
|
if key == "total":
|
|
mvalue = (summary_data_list_master[0][name].get("text") +
|
|
summary_data_list_master[0][name].get("data"))
|
|
bvalue = (summary_data_list_second[0][name].get("text") +
|
|
summary_data_list_second[0][name].get("data"))
|
|
diff = (bvalue - mvalue) * 100.0 / mvalue
|
|
signum = "+" if diff > 0.0 else ""
|
|
print_diff = str(bvalue - mvalue)
|
|
print_diff += " (" + signum + "%0.4f%%" % diff + ")"
|
|
col_data.append(print_diff)
|
|
|
|
# Append free flash space which is equivalent to crash_log's size
|
|
col_data.append(str(summary_data_list_second[0][name].get("crash_log")))
|
|
print_data.append(col_data)
|
|
print(tabulate(print_data, headers=["Binary Name", "Text [B]", "Data [B]", "BSS (B)",
|
|
"Total Flash Change [B] (%)", "Flash Free After PR (B)"]))
|
|
|
|
|
|
def extract_binaries_size(path):
|
|
"""Search and extract binary size for each binary in the given path."""
|
|
print("Extracting binaries size on %s" % path)
|
|
binaries_list = []
|
|
for file in os.listdir(args.master):
|
|
fileNoExt = os.path.splitext(file)[0]
|
|
binaries_list.append(fileNoExt)
|
|
binaries_list = list(dict.fromkeys(binaries_list))
|
|
if len(binaries_list) == 0:
|
|
print("Failed to get binaries")
|
|
|
|
size_dict = None
|
|
for binaries in binaries_list:
|
|
binary_path = os.path.join(path, binaries)
|
|
parsed = sizes_for_file(binary_path)
|
|
if size_dict is None:
|
|
size_dict = [{binaries.lower(): parsed[0]}]
|
|
else:
|
|
size_dict[0].update({binaries.lower(): parsed[0]})
|
|
print("Success !")
|
|
return size_dict
|
|
|
|
|
|
master_dict = extract_binaries_size(args.master)
|
|
second_dict = extract_binaries_size(args.second)
|
|
|
|
print_table(second_dict, master_dict)
|