Files

132 lines
3.8 KiB
Python

#!/bin/env python3
'''
Quick and dirty script to analyze the contents of the binary.
Shows total size of a crate's added code, count of the number of sections,
and the name of the crate. Names with non-rust names are lumped into
esp-idf, as that's most likely what they are in this project.
Unfortunately, since much of the actual functionality is carried out by the
esp-idf, including newly added functionality (such as bluetooth) often mostly
just grows the amount of esp-idf that is included.
'''
import subprocess
import os.path
import os.getcwd
# Shorten names to crates instead of the whole function
mangle_name = True
program_name = os.path.split(os.getcwd())[1]
print(program_name)
targets = ("./target/xtensa-esp32-espidf/release/", "./target/xtensa-esp32-espidf/debug/")
def find_file():
for t in targets:
if os.path.isfile(t + program_name):
#return t
analyze_file(t + program_name)
def analyze_file(f):
results = subprocess.run(["nm", "-S", "--demangle=rust", "--size-sort", f], capture_output=True).stdout
lines = results.splitlines()
data = {}
for line in lines:
cols = line.split()
# Cols are: 0: position, 1: size, 2: ? 3: name
if len(cols) < 4:
pass # this shouldn't happen if we sort by size; but nm lists things without a size otherwise.
else:
raw_name = cols[3].decode("utf-8")
raw_size = cols[1]
if mangle_name:
if len(raw_name):
while "<" == raw_name[0] or "&" == raw_name[0]:
raw_name = raw_name[1:]
parts = raw_name.split(':')
if len(parts[0]) == len(raw_name):
# Assume if it has no crate delimiters that it is part of esp-idf
name = "esp-idf"
else:
name = parts[0]
else:
name = "(blank)"
else:
name = raw_name
size = int(raw_size, 16)
if name in data:
(count, total) = data[name]
count += 1
total += size
data[name] = (count, total)
else:
data[name] = (1, size)
print(" total | ct | crate")
sorted_data = []
for item in data.items():
(name, (count, size)) = item
sorted_data.append((size, count, name))
sorted_data.sort(key=lambda tup: tup[0])
for i in sorted_data:
(size, count, name) = i
print(f'{size:8,}', f'{count:4}', name)
i = 0
for tup in data.values():
i += tup[1]
print("\n","Total size: ", f'{i:,}', "Actual binary size may differ due to included data and the chunks nm didn't identify")
def main():
find_file()
if __name__ == "__main__":
main()
'''
For comparison; the 'Hello, World' app generated by 'cargo generate esp-rs/esp-idf-template cargo'
Hello, World (release) analysis
total | ct | crate
9 1 panic_abort
11 1 esp_idf_sys
84 1 hello_world
223 1 memchr
315 12 log
654 2 adler
724 8 esp_idf_svc
2,757 24 object
8,104 6 miniz_oxide
15,044 181 alloc
15,765 42 rustc_demangle
19,581 37 addr2line
26,343 200 std
33,966 291 core
34,980 104 gimli
159,412 1778 esp-idf
Total size: 317,972
Hello, World (debug) analysis
total | ct | crate
9 1 panic_abort
11 1 esp_idf_sys
84 1 hello_world
267 2 memchr
356 13 log
817 8 esp_idf_svc
1,012 5 adler
3,571 45 object
9,796 13 miniz_oxide
13,331 45 rustc_demangle
20,043 45 addr2line
28,044 281 std
35,175 629 alloc
38,761 210 gimli
60,658 863 core
186,909 2286 esp-idf
Total size: 398,844
'''