mirror of
https://github.com/esphome/esphome.git
synced 2026-08-23 06:36:23 +00:00
Merge branch 'esp8266-native-library-backend' into esp8266-native-build-spec
This commit is contained in:
+5
-1
@@ -855,7 +855,11 @@ def compile_program(args: ArgsProtocol, config: ConfigType) -> int:
|
||||
toolchain.create_factory_bin()
|
||||
toolchain.create_ota_bin()
|
||||
toolchain.create_elf_copy()
|
||||
toolchain.get_idedata()
|
||||
try:
|
||||
toolchain.get_idedata()
|
||||
except EsphomeError as err:
|
||||
# The firmware already built; idedata is a bonus artifact here
|
||||
_LOGGER.warning("Could not generate idedata: %s", err)
|
||||
else:
|
||||
from esphome.platformio import toolchain
|
||||
|
||||
|
||||
@@ -297,17 +297,8 @@ def idedata_from_build(compile_commands: Path, launcher: str | None = None) -> d
|
||||
"""
|
||||
entries = json.loads(Path(compile_commands).read_text(encoding="utf-8"))
|
||||
|
||||
# ninja-generated compile DBs repeat one identical multi-KB command per
|
||||
# source file; parse each distinct (directory, command) once.
|
||||
parsed: dict[tuple[str, str], tuple[str, list[str], list[str], list[str]]] = {}
|
||||
|
||||
def _parse(entry: dict) -> tuple[str, list[str], list[str], list[str]]:
|
||||
key = (entry["directory"], entry["command"])
|
||||
if key not in parsed:
|
||||
parsed[key] = parse_entry(entry, launcher)
|
||||
return parsed[key]
|
||||
|
||||
cxx_path, defines, _, cxx_flags = _parse(_pick_entry(entries))
|
||||
representative = _pick_entry(entries)
|
||||
cxx_path, defines, rep_includes, cxx_flags = parse_entry(representative, launcher)
|
||||
if _is_launcher(cxx_path):
|
||||
# Checked before the toolchain probe (which would fail opaquely on
|
||||
# a launcher) so the unusable compile DB is named, and never
|
||||
@@ -317,11 +308,16 @@ def idedata_from_build(compile_commands: Path, launcher: str | None = None) -> d
|
||||
"compiler; the compile database is unusable"
|
||||
)
|
||||
|
||||
build_includes: dict[str, None] = {}
|
||||
# Seed with the representative's includes so it is not parsed twice
|
||||
# (per-file -c/-o arguments make every command distinct, so memoizing
|
||||
# whole commands would never hit)
|
||||
build_includes: dict[str, None] = dict.fromkeys(
|
||||
rep_includes if _is_esphome_src(representative["file"]) else ()
|
||||
)
|
||||
for entry in entries:
|
||||
if not _is_esphome_src(entry["file"]):
|
||||
if entry is representative or not _is_esphome_src(entry["file"]):
|
||||
continue
|
||||
for inc in _parse(entry)[2]:
|
||||
for inc in parse_entry(entry, launcher)[2]:
|
||||
build_includes.setdefault(inc, None)
|
||||
|
||||
return {
|
||||
|
||||
@@ -7130,3 +7130,35 @@ def test_warn_source_tree_mismatch_falls_back_when_stat_fails(
|
||||
|
||||
# Same tree, so the path comparison still finds them equal and stays silent
|
||||
assert not caplog.text
|
||||
|
||||
|
||||
def test_compile_program_espidf_idedata_failure_does_not_fail_build(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""A post-compile idedata error is a warning: the firmware already built."""
|
||||
from esphome.const import (
|
||||
KEY_CORE,
|
||||
KEY_TARGET_FRAMEWORK,
|
||||
KEY_TARGET_PLATFORM,
|
||||
Toolchain,
|
||||
)
|
||||
from esphome.core import CORE, EsphomeError
|
||||
|
||||
CORE.toolchain = Toolchain.ESP_IDF
|
||||
CORE.data[KEY_CORE] = {
|
||||
KEY_TARGET_PLATFORM: "esp32",
|
||||
KEY_TARGET_FRAMEWORK: "esp-idf",
|
||||
}
|
||||
with (
|
||||
patch("esphome.espidf.toolchain.run_compile", return_value=0),
|
||||
patch("esphome.espidf.toolchain.create_factory_bin"),
|
||||
patch("esphome.espidf.toolchain.create_ota_bin"),
|
||||
patch("esphome.espidf.toolchain.create_elf_copy"),
|
||||
patch(
|
||||
"esphome.espidf.toolchain.get_idedata",
|
||||
side_effect=EsphomeError("compile database is unusable"),
|
||||
),
|
||||
patch("esphome.__main__._check_and_emit_build_info"),
|
||||
):
|
||||
assert compile_program(MagicMock(), {}) == 0
|
||||
assert "Could not generate idedata" in caplog.text
|
||||
|
||||
@@ -575,3 +575,15 @@ def test_split_flag_entry_non_string_is_clean() -> None:
|
||||
split_flag_entry({"esp32": ["-DX"]}, "lib x")
|
||||
with pytest.raises(EsphomeError, match="Malformed build flag 5"):
|
||||
split_flag_entry(5, "lib x")
|
||||
|
||||
|
||||
def test_source_kind_map_shape() -> None:
|
||||
"""The kind values the native compile rules key on, and the deliberate
|
||||
AS/ASPP merge (.s and .S both map to asm)."""
|
||||
from esphome.platformio.library import SOURCE_KIND_FOR_SUFFIX
|
||||
|
||||
assert set(SOURCE_KIND_FOR_SUFFIX.values()) == {"c", "cxx", "asm"}
|
||||
assert SOURCE_KIND_FOR_SUFFIX[".s"] == "asm"
|
||||
assert SOURCE_KIND_FOR_SUFFIX[".S"] == "asm"
|
||||
assert SOURCE_KIND_FOR_SUFFIX[".c"] == "c"
|
||||
assert SOURCE_KIND_FOR_SUFFIX[".cpp"] == "cxx"
|
||||
|
||||
Reference in New Issue
Block a user