[espidf] Suggest installing missing system libraries when the tools install fails (#17619)

This commit is contained in:
Jonathan Swoboda
2026-07-21 08:18:15 +12:00
committed by Jesse Hills
parent e08bdf8cca
commit 7afe7750cd
2 changed files with 37 additions and 0 deletions
+9
View File
@@ -1,5 +1,6 @@
"""ESP-IDF framework tools for ESPHome."""
from ctypes.util import find_library
import json
import logging
import os
@@ -668,6 +669,14 @@ def _check_esphome_idf_framework_install(
env=env,
stream_output=True,
):
if platform.system() == "Linux" and find_library("usb-1.0") is None:
_LOGGER.error(
"libusb-1.0.so.0 was not found on this system and the ESP-IDF "
"tools need it (openocd fails its install check without it). "
"Install the libusb 1.0 package, e.g. libusb-1.0-0 "
"(Debian/Ubuntu), libusb1 (Fedora) or libusb (Alpine/Arch), "
"then run the build again."
)
raise RuntimeError(f"ESP-IDF {version} framework installation failure")
_write_stamp(env_stamp_file, stamp_info)
+28
View File
@@ -478,6 +478,34 @@ def test_check_esp_idf_install_python_stamp_mismatch_rebuilds_venv(
espidf_mocks.venv.assert_called_once()
@pytest.mark.parametrize(
("lib", "expect_hint"),
[
(None, True),
("libusb-1.0.so.0", False),
],
)
def test_check_esp_idf_install_failure_libusb_hint(
espidf_mocks: SimpleNamespace,
caplog: pytest.LogCaptureFixture,
lib: str | None,
expect_hint: bool,
) -> None:
"""A failed tools install only shows the libusb hint when libusb-1.0 is
actually missing."""
espidf_mocks.run_ok.return_value = False
# Fake Linux so the gate is exercised on all CI hosts; faking Linux is safe
# everywhere (unlike faking Windows, which pulls in winreg on other hosts)
with (
patch("esphome.espidf.framework.find_library", return_value=lib),
patch("esphome.espidf.framework.platform.system", return_value="Linux"),
caplog.at_level(logging.ERROR, logger="esphome.espidf.framework"),
pytest.raises(RuntimeError, match="framework installation failure"),
):
check_esp_idf_install(_IDF_VERSION, force=True)
assert ("libusb-1.0.so.0 was not found" in caplog.text) == expect_hint
def test_check_esp_idf_install_unparseable_version(
espidf_mocks: SimpleNamespace,
) -> None: