size gate: emit flash_bytes from ELF for targets without a packaged .bin (#10940)
* size gate: emit flash_bytes from ELF for targets without a packaged .bin nRF52 builds package hex/uf2/DFU zip but no raw .bin, so collect_sizes.py dropped budgeted envs like rak4631 entirely and the size-budget-gate failed closed. Emit ELF text+data as flash_bytes in the manifest and use it as the fallback flash measurement. * Factor shared size-tool invocation into run_size_tool helper
This commit is contained in:
co-authored by
GitHub
parent
8d20606203
commit
ba473bf529
+47
-14
@@ -45,6 +45,27 @@ def infer_architecture(board_cfg):
|
||||
return "stm32"
|
||||
return None
|
||||
|
||||
def run_size_tool(env, flag, purpose):
|
||||
"""Run the toolchain size tool against the built ELF and return its output.
|
||||
|
||||
Shared plumbing for compute_ram_bytes / compute_flash_bytes. Returns None
|
||||
when the ELF is missing or the tool fails; the manifest then simply omits
|
||||
the metric and downstream size reports show "n/a".
|
||||
"""
|
||||
elf = env.File(env.subst("$BUILD_DIR/${PROGNAME}.elf"))
|
||||
if not elf.exists():
|
||||
return None
|
||||
size_tool = env.subst("$SIZETOOL") or "size"
|
||||
try:
|
||||
return subprocess.check_output(
|
||||
[size_tool, flag, elf.get_abspath()],
|
||||
env=env["ENV"],
|
||||
universal_newlines=True,
|
||||
)
|
||||
except Exception as exc:
|
||||
print(f"mtjson: skipping {purpose} ({size_tool} failed: {exc})")
|
||||
return None
|
||||
|
||||
def compute_ram_bytes(env):
|
||||
"""Static RAM usage (.data + .bss) of the ELF, via the toolchain size tool.
|
||||
|
||||
@@ -54,18 +75,8 @@ def compute_ram_bytes(env):
|
||||
Returns None when the value cannot be determined; the manifest then simply
|
||||
omits ram_bytes and downstream size reports show "n/a".
|
||||
"""
|
||||
elf = env.File(env.subst("$BUILD_DIR/${PROGNAME}.elf"))
|
||||
if not elf.exists():
|
||||
return None
|
||||
size_tool = env.subst("$SIZETOOL") or "size"
|
||||
try:
|
||||
output = subprocess.check_output(
|
||||
[size_tool, "-A", elf.get_abspath()],
|
||||
env=env["ENV"],
|
||||
universal_newlines=True,
|
||||
)
|
||||
except Exception as exc:
|
||||
print(f"mtjson: skipping ram_bytes ({size_tool} failed: {exc})")
|
||||
output = run_size_tool(env, "-A", "ram_bytes")
|
||||
if output is None:
|
||||
return None
|
||||
ram = 0
|
||||
found = False
|
||||
@@ -88,6 +99,24 @@ def compute_ram_bytes(env):
|
||||
continue
|
||||
return ram if found else None
|
||||
|
||||
def compute_flash_bytes(env):
|
||||
"""Flash footprint (text + data) of the ELF via the toolchain size tool.
|
||||
|
||||
Approximates the flashed app image for targets whose packaged artifacts do
|
||||
not include a raw .bin (e.g. nRF52: hex/uf2/DFU zip only); consumed by
|
||||
bin/collect_sizes.py as a fallback flash measurement for the size report
|
||||
and the bin/ram_budgets.json budget gate. Returns None when the value
|
||||
cannot be determined; the manifest then simply omits flash_bytes.
|
||||
"""
|
||||
output = run_size_tool(env, "-B", "flash_bytes")
|
||||
if output is None:
|
||||
return None
|
||||
for line in output.splitlines():
|
||||
parts = line.split()
|
||||
if len(parts) >= 3 and parts[0].isdigit() and parts[1].isdigit():
|
||||
return int(parts[0]) + int(parts[1])
|
||||
return None
|
||||
|
||||
def manifest_gather(source, target, env):
|
||||
global manifest_ran
|
||||
if manifest_ran:
|
||||
@@ -141,9 +170,9 @@ def manifest_gather(source, target, env):
|
||||
d["part_name"] = partition_map[p]
|
||||
out.append(d)
|
||||
print(d)
|
||||
manifest_write(out, env, compute_ram_bytes(env))
|
||||
manifest_write(out, env, compute_ram_bytes(env), compute_flash_bytes(env))
|
||||
|
||||
def manifest_write(files, env, ram_bytes=None):
|
||||
def manifest_write(files, env, ram_bytes=None, flash_bytes=None):
|
||||
# Defensive: also skip manifest writing if we cannot determine architecture
|
||||
def get_project_option(name):
|
||||
try:
|
||||
@@ -184,6 +213,10 @@ def manifest_write(files, env, ram_bytes=None):
|
||||
# the CI size report and the bin/ram_budgets.json budget gate.
|
||||
if ram_bytes is not None:
|
||||
manifest["ram_bytes"] = ram_bytes
|
||||
# Flash footprint (text + data); fallback flash measurement for targets
|
||||
# whose packaged artifacts include no raw .bin (e.g. nRF52).
|
||||
if flash_bytes is not None:
|
||||
manifest["flash_bytes"] = flash_bytes
|
||||
# Get partition table (generated in esp32_pre.py) if it exists
|
||||
if env.get("custom_mtjson_part"):
|
||||
# custom_mtjson_part is a JSON string, convert it back to a dict
|
||||
|
||||
Reference in New Issue
Block a user