Apply review cleanups to the native ESP8266 toolchain

This commit is contained in:
J. Nick Koston
2026-08-19 23:13:30 -05:00
parent 8811224c0e
commit 3fe9cac1fc
12 changed files with 164 additions and 100 deletions
+2 -2
View File
@@ -93,9 +93,9 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
lib.include_dirs.append(path.resolve())
lib.sources = sorted(
Path(f).resolve()
path.resolve()
for f in collect_filtered_files(read_path / src_dir, src_filter)
if Path(f).suffix in SRC_FILE_EXTENSIONS
if (path := Path(f)).suffix in SRC_FILE_EXTENSIONS
)
return lib
+7 -8
View File
@@ -4,7 +4,6 @@ from __future__ import annotations
import logging
from pathlib import Path
import re
import subprocess
from esphome.arduino8266 import framework
@@ -43,7 +42,7 @@ def run_compile(config: ConfigType, verbose: bool) -> int:
from esphome.build_gen import arduino8266 as build_gen
paths = framework.check_and_install(CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION])
build_gen.write_project(paths)
ninja_changed = build_gen.write_project(paths)
build_dir = get_build_dir()
env = framework.get_build_env(paths["toolchain_path"])
@@ -58,7 +57,10 @@ def run_compile(config: ConfigType, verbose: bool) -> int:
if rc != 0:
return rc
_write_compile_commands(paths["ninja_path"], build_dir, env)
# The compile database is a pure function of build.ninja; skip its
# regeneration (a ninja spawn plus MBs of text) on unchanged builds.
if ninja_changed or not (build_dir / "compile_commands.json").is_file():
_write_compile_commands(paths["ninja_path"], build_dir, env)
_print_size_summary(build_dir, paths["toolchain_path"])
get_idedata()
return 0
@@ -86,16 +88,13 @@ def _write_compile_commands(
def _parse_app_size(build_dir: Path) -> int | None:
"""Read the app flash budget (irom0_0_seg length) from the linker script."""
from esphome.build_gen.arduino8266 import get_flash_ld_path
from esphome.components.esp8266.build_surgery import segment_length
appsize_re = re.compile(r"irom0_0_seg\s*:.+len\s*=\s*(0x[\da-f]+)", re.IGNORECASE)
try:
ld_text = get_flash_ld_path(build_dir).read_text(encoding="utf-8")
except OSError:
return None
for line in ld_text.splitlines():
if match := appsize_re.search(line):
return int(match.group(1), 16)
return None
return segment_length(ld_text, "irom0_0_seg")
def _print_size_summary(build_dir: Path, toolchain_path: Path) -> None:
+7 -3
View File
@@ -373,8 +373,12 @@ def _common_parent(paths: list[Path]) -> Path:
return Path(os.path.commonpath([str(p.parent) for p in paths]))
def write_project(paths: dict[str, Path]) -> None:
"""Write the ninja build for the current configuration."""
def write_project(paths: dict[str, Path]) -> bool:
"""Write the ninja build for the current configuration.
Returns True when ``build.ninja`` changed, so the caller can skip work
derived purely from it (the compile database) on unchanged builds.
"""
from esphome.arduino8266.component import resolve_libraries
from esphome.arduino8266.framework import ccache_path
@@ -551,7 +555,7 @@ def write_project(paths: dict[str, Path]) -> None:
lines.append("default firmware.factory.bin firmware.ota.bin")
lines.append("")
write_file_if_changed(build_dir / "build.ninja", "\n".join(lines))
return write_file_if_changed(build_dir / "build.ninja", "\n".join(lines))
def get_flash_ld_path(build_dir: Path) -> Path:
+19 -1
View File
@@ -361,12 +361,30 @@ BOARDS = {
},
}
"""
ESP8266_BOARD_BUILD generate with:
git clone https://github.com/platformio/platform-espressif8266
python3 - <<'EOF'
import json, glob, os
for f in sorted(glob.glob("platform-espressif8266/boards/*.json")):
b = json.load(open(f))["build"]
extra = b["extra_flags"]
extra = extra.split() if isinstance(extra, str) else extra
defines = [
e[2:] for e in extra if e not in ("-DESP8266", "-DARDUINO_ARCH_ESP8266")
]
entries = ", ".join(f'"{d}"' for d in defines) + ("," if len(defines) == 1 else "")
board = os.path.splitext(os.path.basename(f))[0]
print(f' "{board}": {{"variant": "{b["variant"]}", "defines": ({entries})}},')
EOF
"""
# Per-board Arduino core build metadata for the native (PlatformIO-free)
# toolchain: the variant directory (supplies pins_arduino.h) and the
# board-identity defines the PlatformIO builder passes via build.extra_flags.
# -DESP8266 and -DARDUINO_ARCH_ESP8266 are shared by every board and added by
# the generator; only the per-board defines are listed here.
# Generated from platform-espressif8266 boards/*.json (see BOARDS note above).
ESP8266_BOARD_BUILD = {
"agruminolemon": {
"variant": "agruminolemonv4",
@@ -57,3 +57,12 @@ def apply_testing_memory_patches(content: str) -> str:
content = _patch_segment_size(content, "iram1_0_seg", TESTING_IRAM_SIZE)
content = _patch_segment_size(content, "dram0_0_seg", TESTING_DRAM_SIZE)
return _patch_segment_size(content, "irom0_0_seg", TESTING_FLASH_SIZE)
def segment_length(content: str, segment_name: str) -> int | None:
"""Read a memory segment's length from linker script content."""
match = re.search(
rf"{segment_name}\s*:.+len\s*=\s*(0x[\da-fA-F]+)",
content,
)
return int(match.group(1), 16) if match else None