diff --git a/esphome/build_gen/espidf.py b/esphome/build_gen/espidf.py index 7f0cd6fee8..7689fc93b0 100644 --- a/esphome/build_gen/espidf.py +++ b/esphome/build_gen/espidf.py @@ -90,11 +90,10 @@ def get_project_cmakelists( """ idf_target = variant_to_idf_target(get_esp32_variant()) - # esp_idf_size 2.x (bundled with IDF >=6.0) made NG the default and - # removed the --ng flag; on 1.x (IDF 5.5) --ng is required to get - # --format=json2 because the legacy mode doesn't support it. 1.x json2 - # also lacks total_size, which is why espidf/size_summary.py carries an - # ELF fallback; both go away together when 1.x support is dropped. + # esp_idf_size 2.x (IDF >=6.0) made NG the default and removed --ng; + # 1.x (IDF 5.5) needs --ng for --format=json2. 1.x json2 also lacks + # total_size, hence the ELF fallback in espidf/size_summary.py; both + # go away together when 1.x support is dropped. size_ng_flag = "--ng" if idf_version() < cv.Version(6, 0, 0) else "" # Project-wide compile options: -D defines and -W warning flags (skip @@ -214,9 +213,8 @@ include($ENV{{IDF_PATH}}/tools/cmake/project.cmake) project({CORE.name}) # Emit per-memory-type JSON size data for ESPHome to read post-build. -# json2 only summarizes memory regions; the raw format also dumps every -# symbol (multi-MB, ~2s on a large map) and this command runs inside the -# link edge, so everything downstream of the ELF would wait on it. +# json2 stays small; raw dumps every symbol (~2s on a large map) and +# this command runs inside the link edge, blocking everything downstream. add_custom_command( TARGET ${{CMAKE_PROJECT_NAME}}.elf POST_BUILD COMMAND ${{PYTHON}} -m esp_idf_size {size_ng_flag} --format=json2 diff --git a/esphome/espidf/size_summary.py b/esphome/espidf/size_summary.py index e52e1f04c6..d8303d37dd 100644 --- a/esphome/espidf/size_summary.py +++ b/esphome/espidf/size_summary.py @@ -20,10 +20,8 @@ subtype is ``factory`` or ``ota_0``; see Structured size data is produced at link time by a CMake POST_BUILD custom command (see ``build_gen/espidf.py``) which writes -``esp_idf_size.json`` (``--format=json2``: a per-memory-type summary, -``{"version": ..., "layout": [{"name", "total", "used", ...}]}``) next -to the ELF. We read that file here rather than re-running -``esp_idf_size`` from Python. +``esp_idf_size.json`` (``--format=json2``, a per-memory-type summary) +next to the ELF; we read that rather than re-running ``esp_idf_size``. """ from __future__ import annotations @@ -78,13 +76,9 @@ def _find_app_partition_size(partitions_csv: Path) -> int: def _image_size_from_elf(elf: Path) -> int: """Sum the loadable PROGBITS section sizes from an ELF32 file. - This is the rule ``esp_idf_size.ng.memorymap._get_image_size`` uses for - its image size figure, so the result is byte-identical to the tool's. - esptool's ``ELFFile`` is deliberately not reused: its section filter - differs (counts INIT/FINI arrays, skips lma==0 sections) and would - report a different number. Reads only the header and section table, - not the multi-MB debug payload. Raises ``ValueError`` for anything - that is not a well-formed 32-bit little-endian ELF. + Matches ``esp_idf_size.ng.memorymap._get_image_size`` byte for byte; + esptool's ``ELFFile`` filters sections differently and would not. + Raises ``ValueError`` for anything but a well-formed ELF32 LE file. """ with elf.open("rb") as f: header = f.read(52) # ELF32 header diff --git a/esphome/espidf/toolchain.py b/esphome/espidf/toolchain.py index ec84b9d84e..f695bdb7ab 100644 --- a/esphome/espidf/toolchain.py +++ b/esphome/espidf/toolchain.py @@ -580,10 +580,10 @@ def get_ota_firmware_path() -> Path: def get_built_elf_path() -> Path: - """Get the path to the ELF that idf.py writes directly, ``/.elf``. + """Path to the ELF idf.py writes directly, ``/.elf``. - Unlike ``get_elf_path``, this file exists as soon as the build finishes, - before ``create_elf_copy`` produces the ``firmware.elf`` copy. + Exists as soon as the build finishes, unlike the ``firmware.elf`` + copy that ``create_elf_copy`` makes later. """ build_dir = CORE.relative_build_path("build") return build_dir / f"{CORE.name}.elf"