[esp32] Exclude esp_http_server and nvs_sec_provider from IDF builds by default (#18748)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
J. Nick Koston
2026-08-25 06:16:32 +00:00
committed by GitHub
co-authored by Jesse Hills
parent c6d423159c
commit 3f615f87cf
7 changed files with 85 additions and 1 deletions
+16
View File
@@ -238,6 +238,7 @@ DEFAULT_EXCLUDED_IDF_COMPONENTS = (
"esp_gdbstub", # GDB stub panic handler - unused by ESPHome; bt pulls it back
"esp_hid", # HID host/device support - ESPHome doesn't implement HID functionality
"esp_http_client", # HTTP client - only needed by http_request component
"esp_http_server", # HTTP server - re-included by web_server_idf, esp32_camera_web_server
"esp_https_ota", # ESP-IDF HTTPS OTA - ESPHome has its own OTA implementation
"esp_https_server", # HTTPS server - ESPHome has its own web server
"esp_lcd", # LCD controller drivers - only needed by display component
@@ -246,6 +247,7 @@ DEFAULT_EXCLUDED_IDF_COMPONENTS = (
"fatfs", # FAT filesystem - ESPHome doesn't use filesystem storage
"json", # cJSON library - ESPHome uses ArduinoJson instead
"mqtt", # ESP-IDF MQTT library - ESPHome has its own MQTT implementation
"nvs_sec_provider", # NVS encryption key provider - re-included when CONFIG_NVS_ENCRYPTION is set
"openthread", # Thread protocol - only needed by openthread component
"perfmon", # Xtensa performance monitor - ESPHome has its own debug component
"protobuf-c", # Protobuf runtime - only used by provisioning components (also excluded)
@@ -649,6 +651,16 @@ class RawSdkconfigValue:
SdkconfigValueType = bool | int | HexInt | str | RawSdkconfigValue
def is_idf_sdkconfig_option_enabled(name: str) -> bool:
"""Return True when a bool sdkconfig option resolves to ``y``.
Handles both the ``True`` a component sets and the raw ``y`` a user sets
in ``sdkconfig_options``.
"""
value = CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS].get(name)
return value is not None and _format_sdkconfig_val(value) == "y"
def set_idf_sdkconfig_default(name: str, value: SdkconfigValueType) -> None:
"""Set an sdkconfig option unless it is already set.
@@ -2191,6 +2203,10 @@ def register_exclude_components_cmake_arg() -> None:
@coroutine_with_priority(CoroPriority.FINAL)
async def _write_exclude_components() -> None:
"""Write EXCLUDE_COMPONENTS cmake arg after all components have registered exclusions."""
# NVS encryption needs nvs_sec_provider however it was enabled: the
# nvs_encryption option, raw sdkconfig_options or another component.
if is_idf_sdkconfig_option_enabled("CONFIG_NVS_ENCRYPTION"):
include_builtin_idf_component("nvs_sec_provider")
register_exclude_components_cmake_arg()
@@ -1,4 +1,5 @@
import esphome.codegen as cg
from esphome.components.esp32 import include_builtin_idf_component
import esphome.config_validation as cv
from esphome.const import CONF_ID, CONF_MODE, CONF_PORT
from esphome.types import ConfigType
@@ -35,6 +36,7 @@ CONFIG_SCHEMA = cv.All(
cv.Required(CONF_MODE): cv.enum(MODES, upper=True),
},
).extend(cv.COMPONENT_SCHEMA),
cv.only_on_esp32,
_consume_camera_web_server_sockets,
)
@@ -44,3 +46,5 @@ async def to_code(config: ConfigType) -> None:
cg.add(server.set_port(config[CONF_PORT]))
cg.add(server.set_mode(config[CONF_MODE]))
await cg.register_component(server, config)
# esp_http_server is excluded from IDF builds by default to save compile time
include_builtin_idf_component("esp_http_server")
@@ -20,6 +20,7 @@ async def to_code(config: ConfigType) -> None:
# Re-enable esp-tls (excluded by default to save compile time);
# web_server_idf.cpp includes <esp_tls_crypto.h> for digest auth
include_builtin_idf_component("esp-tls")
include_builtin_idf_component("esp_http_server")
# multipart.cpp is fully #ifdef'd on USE_WEBSERVER_OTA (set by the
@@ -0,0 +1,15 @@
esphome:
name: test
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ssid: "test_ssid"
password: "test_password"
esp32_camera_web_server:
port: 8080
mode: stream
@@ -0,0 +1,11 @@
esphome:
name: test
esp32:
board: esp32dev
framework:
type: esp-idf
sdkconfig_options:
CONFIG_NVS_ENCRYPTION: y
CONFIG_NVS_SEC_KEY_PROTECT_USING_HMAC: y
CONFIG_NVS_SEC_HMAC_EFUSE_KEY_ID: "0"
@@ -0,0 +1,9 @@
esphome:
name: test
esp32:
board: esp32dev
framework:
type: esp-idf
sdkconfig_options:
CONFIG_NVS_ENCRYPTION: n
+29 -1
View File
@@ -261,9 +261,24 @@ def test_esp32_configuration_errors(
),
pytest.param(
"exclusion_reincludes_web_server.yaml",
("esp-tls",),
("esp-tls", "esp_http_server"),
id="web_server_idf",
),
pytest.param(
"nvs_encryption_s3.yaml",
("nvs_sec_provider",),
id="nvs_encryption",
),
pytest.param(
"exclusion_reincludes_nvs_sdkconfig.yaml",
("nvs_sec_provider",),
id="nvs_encryption_raw_sdkconfig",
),
pytest.param(
"exclusion_reincludes_camera_web_server.yaml",
("esp_http_server",),
id="esp32_camera_web_server",
),
pytest.param(
"exclusion_reincludes_nextion.yaml",
("esp-tls", "esp_http_client"),
@@ -291,6 +306,19 @@ def test_default_exclusions_reincluded_by_owning_components(
# Components no part of this config touches stay excluded.
assert "unity" in excluded
assert "fatfs" in excluded
# The HTTP server only comes back for configs that run one.
assert ("esp_http_server" in excluded) == ("esp_http_server" not in reincluded)
def test_nvs_sec_provider_stays_excluded_when_encryption_is_off(
generate_main: Callable[[str | Path], str],
component_config_path: Callable[[str], Path],
) -> None:
"""An explicit CONFIG_NVS_ENCRYPTION=n keeps nvs_sec_provider excluded."""
from esphome.components.esp32.const import KEY_EXCLUDE_COMPONENTS
generate_main(component_config_path("exclusion_stays_nvs_sdkconfig_off.yaml"))
assert "nvs_sec_provider" in CORE.data[KEY_ESP32][KEY_EXCLUDE_COMPONENTS]
_BUNDLE_OPTIONS = (