132 lines
3.8 KiB
Python
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
|
|
'''
|