Merge branch 'esp8266-native-ninja-emission' into esp8266-arduino-toolchain

This commit is contained in:
J. Nick Koston
2026-08-23 10:48:54 -05:00
7 changed files with 80 additions and 20 deletions
+9 -4
View File
@@ -178,6 +178,8 @@ def parse_entry(
# token0 is the compiler path; the rest of the command already uses forward
# slashes on Windows, so normalize it too for a consistent idedata file.
cxx_path = tokens[0].replace("\\", "/")
# Enforced here so no caller can record ccache as the compiler
reject_launcher_compiler(cxx_path)
defines: list[str] = []
includes: list[str] = []
cxx_flags: list[str] = []
@@ -337,13 +339,12 @@ def idedata_from_build(compile_commands: Path, launcher: str | None = None) -> d
project-wide superset (as PlatformIO's idedata provides).
"""
entries = json.loads(Path(compile_commands).read_text(encoding="utf-8"))
if not isinstance(entries, list):
if not isinstance(entries, list) or not all(isinstance(e, dict) for e in entries):
# A TypeError here would escape IDEDATA_BEST_EFFORT_ERRORS
raise EsphomeError(f"{compile_commands} is not a compile-command list")
representative = _pick_entry(entries)
cxx_path, defines, rep_includes, cxx_flags = parse_entry(representative, launcher)
reject_launcher_compiler(cxx_path)
# Seed with the representative's includes so it is not parsed twice
has_esphome_tu = _is_esphome_src(representative["file"])
@@ -357,12 +358,16 @@ def idedata_from_build(compile_commands: Path, launcher: str | None = None) -> d
# per shape instead of once per TU. Response-file commands never
# dedupe: per-object .rsp names strip to one shape while the files
# may hold different include sets.
# Keyed on directory too: relative -I paths resolve against it, so
# identical commands in different dirs mean different include sets
command = entry["command"]
directory = entry.get("directory", "")
if "@" in command:
return f"unique:{entry.get('output') or command}"
return command.replace(entry.get("file", ""), "").replace(
return f"unique:{directory}|{entry.get('output') or command}"
stripped = command.replace(entry.get("file", ""), "").replace(
entry.get("output", ""), ""
)
return f"{directory}|{stripped}"
seen_shapes = {_shape(representative)}
for entry in entries:
+4 -1
View File
@@ -5,7 +5,10 @@ from __future__ import annotations
def format_bar(used: int, total: int) -> str:
"""Match PlatformIO's ``_format_availale_bytes`` (sic, pioupload.py) exactly."""
pct_raw = used / total if total else 0
if total <= 0:
# A "from 0 bytes" bar is meaningless; make every caller handle it
raise ValueError(f"non-positive size total {total}")
pct_raw = used / total
blocks = 10
filled = min(int(round(blocks * pct_raw)), blocks)
progress = "=" * filled
+14 -4
View File
@@ -79,8 +79,9 @@ def print_summary(size_json: Path, partitions_csv: Path | None) -> None:
try:
_print_summary(size_json, partitions_csv)
except Exception as e: # noqa: BLE001 # pylint: disable=broad-exception-caught
# Backstop for nested shapes the named guards below miss
# Backstop for shapes the named guards below miss
_LOGGER.warning("Skipping size summary: %s", e)
_LOGGER.debug("Size summary failure detail", exc_info=True)
def _print_summary(size_json: Path, partitions_csv: Path | None) -> None:
@@ -99,12 +100,21 @@ def _print_summary(size_json: Path, partitions_csv: Path | None) -> None:
_LOGGER.warning("Skipping size summary: unexpected shape in %s", size_json)
return
memory_types = data.get("memory_types", {})
memory_types = data.get("memory_types")
if not isinstance(memory_types, dict):
memory_types = {}
ram_region = memory_types.get("DRAM") or memory_types.get("DIRAM") or {}
if not isinstance(ram_region, dict):
ram_region = {}
ram_used = ram_region.get("used")
ram_total = ram_region.get("size")
if ram_total and ram_used is not None:
print_size_line("RAM", ram_used, ram_total)
# Numeric checks isolate a malformed RAM region from the Flash line below
if (
isinstance(ram_used, (int, float))
and isinstance(ram_total, (int, float))
and ram_total > 0
):
print_size_line("RAM", int(ram_used), int(ram_total))
else:
_LOGGER.warning(
"Skipping RAM summary: no usable DRAM/DIRAM region in %s", size_json