esp32/tools: Update metrics_esp32 script for ESP-IDF >=v5.4.x.

The output of 'idf.py size' has changed, plus some other cleanups around
build dir name, etc.  Can now run on v5.2.2 and v5.4.1, probably other
versions.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
Angus Gratton
2025-04-24 17:52:43 +10:00
committed by Damien George
parent ce7f65f967
commit 584fa8800b

View File

@@ -32,6 +32,7 @@
# column of the table is really D/IRAM. # column of the table is really D/IRAM.
import os import os
import re import re
import shutil
import sys import sys
import subprocess import subprocess
from dataclasses import dataclass from dataclasses import dataclass
@@ -47,6 +48,13 @@ BUILDS = (
) )
def rmtree(path):
try:
shutil.rmtree(path)
except FileNotFoundError:
pass
@dataclass @dataclass
class BuildSizes: class BuildSizes:
idf_ver: str idf_ver: str
@@ -99,7 +107,7 @@ class BuildSizes:
def build_dir(self): def build_dir(self):
if self.variant: if self.variant:
return f"build-{self.board}_{self.variant}" return f"build-{self.board}-{self.variant}"
else: else:
return f"build-{self.board}" return f"build-{self.board}"
@@ -124,12 +132,23 @@ class BuildSizes:
def make_size(self): def make_size(self):
try: try:
size_out = self.run_make("size") size_out = self.run_make("size")
# "Used static DRAM:" or "Used stat D/IRAM:" try:
RE_DRAM = r"Used stat(?:ic)? D.*: *(\d+) bytes" # pre IDF v5.4 size output
RE_IRAM = r"Used static IRAM: *(\d+) bytes" # "Used static DRAM:" or "Used stat D/IRAM:"
RE_DRAM = r"Used stat(?:ic)? D.*: *(\d+) bytes"
RE_IRAM = r"Used static IRAM: *(\d+) bytes"
self.dram_size = re.search(RE_DRAM, size_out).group(1)
self.iram_size = re.search(RE_IRAM, size_out).group(1)
except AttributeError:
# IDF v5.4 size output is much nicer formatted
# Note the pipes in these expressions are not the ASCII/RE |
RE_DRAM = r"│ *DI?RAM *│ *(\d+)"
RE_IRAM = r"│ *IRAM *│ *(\d+)"
self.dram_size = re.search(RE_DRAM, size_out).group(1)
self.iram_size = re.search(RE_IRAM, size_out).group(1)
# This line is the same on before/after versions
RE_BIN = r"Total image size: *(\d+) bytes" RE_BIN = r"Total image size: *(\d+) bytes"
self.dram_size = re.search(RE_DRAM, size_out).group(1)
self.iram_size = re.search(RE_IRAM, size_out).group(1)
self.bin_size = re.search(RE_BIN, size_out).group(1) self.bin_size = re.search(RE_BIN, size_out).group(1)
except subprocess.CalledProcessError: except subprocess.CalledProcessError:
self.bin_size = "build failed" self.bin_size = "build failed"
@@ -139,13 +158,26 @@ def main(do_clean):
if "IDF_PATH" not in os.environ: if "IDF_PATH" not in os.environ:
raise RuntimeError("IDF_PATH must be set") raise RuntimeError("IDF_PATH must be set")
if not os.path.exists("Makefile"):
raise RuntimeError(
"This script must be run from the ports/esp32 directory, i.e. as ./tools/metrics_esp32.py"
)
if "IDF_PYTHON_ENV_PATH" in os.environ:
raise RuntimeError(
"Run this script without any existing ESP-IDF environment active/exported."
)
sizes = [] sizes = []
for idf_ver in IDF_VERS: for idf_ver in IDF_VERS:
switch_ver(idf_ver) switch_ver(idf_ver)
rmtree("managed_components")
for board, variant in BUILDS: for board, variant in BUILDS:
print(f"Building '{board}'/'{variant}'...", file=sys.stderr) print(f"Building '{board}'/'{variant}'...", file=sys.stderr)
result = BuildSizes(idf_ver, board, variant) result = BuildSizes(idf_ver, board, variant)
result.run_make("clean") # Rather than running the 'clean' target, delete the build directory to avoid
# environment version mismatches, etc.
rmtree(result.build_dir())
result.make_size() result.make_size()
result.print_summary() result.print_summary()
sizes.append(result) sizes.append(result)