Merge branch 'esp8266-native-converter-hardening' into esp8266-native-library-converter

This commit is contained in:
J. Nick Koston
2026-08-23 12:55:57 -05:00
2 changed files with 21 additions and 47 deletions
+6 -14
View File
@@ -30,10 +30,7 @@ def apply_extra_script(
pio_platform: str,
) -> None:
"""Run a library's ``extraScript`` and fold its captured env vars into
``component.data["build"]["flags"]``.
``board_mcu`` is a callable so its lookup runs only when a script will.
"""
``build.flags``; ``board_mcu`` is a callable so it resolves lazily."""
extra_script = component.data.get("build", {}).get("extraScript")
if not extra_script:
return
@@ -177,12 +174,10 @@ def run_extra_script(
board_mcu: str,
pio_platform: str,
) -> ExtraScriptResult:
"""Execute ``script_path`` with a fake SCons env and return captured vars.
"""Execute ``script_path`` with a fake SCons env, ``library_dir`` as CWD.
Runs with ``library_dir`` as CWD so relative lookups resolve against
the library tree. A crashed script warns and returns an empty result,
never a partial capture.
"""
A crashed script warns and returns an empty result, never a partial
capture."""
env = _FakeSConsEnv(
board_mcu=board_mcu,
pio_env=f"esphome_{board_mcu}",
@@ -248,11 +243,8 @@ def run_extra_script(
def captured_as_build_flags(
result: ExtraScriptResult, *, library_dir: Path
) -> list[str]:
"""Translate captured env vars into -L/-l/-D/raw build flags.
``LIBPATH`` entries are made relative to ``library_dir`` so the
generated build files stay portable.
"""
"""Translate captured env vars into -L/-l/-D/raw build flags; path
entries anchor to ``library_dir`` so the build files stay portable."""
flags: list[str] = []
def _strs(bucket: list, kind: str) -> list[str]:
+15 -33
View File
@@ -55,12 +55,9 @@ DEFAULT_BUILD_SRC_FILTER = (
DEFAULT_BUILD_SRC_DIRS = "src"
DEFAULT_BUILD_INCLUDE_DIR = "include"
DEFAULT_BUILD_FLAGS = []
# Suffix -> compiler kind (PlatformIO's CSUFFIXES/CXXSUFFIXES/ASSUFFIXES).
# "asm" merges SCons's AS and ASPP sets: all compile as assembler-with-cpp.
# The kind values drive the ESP8266 native ninja rules (later in this
# chain); existing backends consume only the keys. Note .C/.C++ join the
# suffix set here per CXXSUFFIXES; SCons demotes .C to C on
# case-insensitive filesystems, we always treat it as C++.
# Suffix -> compiler kind (PlatformIO's CSUFFIXES/CXXSUFFIXES/ASSUFFIXES);
# "asm" merges SCons's AS and ASPP sets. Per CXXSUFFIXES .C/.C++ are C++
# here, even where SCons demotes .C on case-insensitive filesystems.
SOURCE_KIND_FOR_SUFFIX: dict[str, str] = {
".c": "c",
".cpp": "cxx",
@@ -252,11 +249,8 @@ class InvalidLibrary(Exception):
class IncompatiblePlatform(InvalidLibrary):
"""The manifest's platform filter rejected the target platform.
A distinct type so callers can treat the routine cross-platform skip
differently from other manifest problems without matching message text.
"""
"""The routine cross-platform skip, typed so callers need not match
message text."""
class ConvertedLibrary:
@@ -635,9 +629,8 @@ def split_flag_entry(entry: Any, owner: str) -> list[str]:
def lex_build_flags(entries: str | list[str], owner: str) -> list[str]:
"""Shell-lex ``build.flags`` entries the way PlatformIO's ParseFlags
does; bare -I/-L/-l/-D tokens re-glue to their argument."""
# Join per entry, as SCons's ParseFlags lexes each string independently:
# a dangling -I ending one entry must warn, not absorb the next entry's
# first token.
# Lex per entry as ParseFlags does: a dangling -I must warn, not absorb
# the next entry's first token
return [
token
for entry in ensure_list(entries)
@@ -650,13 +643,9 @@ BARE_ARG_FLAGS = frozenset({"-I", "-L", "-l", "-D"})
def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]:
"""Join a bare ``-I``/``-L``/``-l``/``-D`` with its following token,
the way PlatformIO's ParseFlags lexes them.
A trailing or empty argument (``-D ""``) is warned and dropped: the
bare flag would make gcc eat the next flag as its argument (or add
the CWD for ``-L``); always a typo.
"""
"""Join a bare ``-I``/``-L``/``-l``/``-D`` with its following token, as
PlatformIO's ParseFlags does. A trailing or empty argument is warned and
dropped: the bare flag would make gcc eat the next flag."""
out: list[str] = []
it = iter(tokens)
for tok in it:
@@ -676,11 +665,8 @@ def join_flag_args(tokens: Iterable[str], owner: str) -> list[str]:
def warn_properties_depends(name: str, data: object) -> None:
"""Warn when a manifest declares dependencies only as ``depends=``.
The dependency walk reads the JSON ``dependencies`` key; the raw
``library.properties`` spelling would otherwise drop silently.
"""
"""Warn for ``depends=``-only manifests; the walk reads only the JSON
``dependencies`` key, so they would otherwise drop silently."""
if isinstance(data, dict) and not data.get("dependencies") and data.get("depends"):
# INFO: common and unactionable for transitive libraries; a WARNING
# on every build would train users to ignore the stream
@@ -711,13 +697,9 @@ def dependency_is_usable(
def _valid_dependency_entry(entry: dict, manifest_name: str) -> bool:
"""Whether a normalized entry carries a usable name and version.
The name must be a non-empty string (every consumer indexes or joins
it); a present version must be a string (a container would raise from
``set.add()``, an int fails opaquely inside the registry resolution).
Invalid entries warn naming the manifest.
"""
"""Whether a normalized entry carries a usable name (non-empty string)
and version (string, if present); invalid entries warn naming the
manifest."""
name = entry.get("name")
if (
isinstance(name, str)