[esp32] Exclude the WiFi and Bluetooth stacks from builds that do not use them

This commit is contained in:
J. Nick Koston
2026-08-21 13:51:41 -05:00
parent 00cffa09a2
commit a2a7a6add6
10 changed files with 70 additions and 1 deletions
+6
View File
@@ -212,11 +212,13 @@ COMPILER_OPTIMIZATIONS = {
# builds that need them. # builds that need them.
DEFAULT_EXCLUDED_IDF_COMPONENTS = ( DEFAULT_EXCLUDED_IDF_COMPONENTS = (
"app_trace", # CPU trace/SystemView support - unused by ESPHome "app_trace", # CPU trace/SystemView support - unused by ESPHome
"bt", # Bluetooth stack - re-included by esp32_ble; its REQUIRES pulls the WiFi stack back
"cmock", # Unit testing mock framework - ESPHome doesn't use IDF's testing "cmock", # Unit testing mock framework - ESPHome doesn't use IDF's testing
"console", # Console REPL - unused by ESPHome; espressif/mdns pulls it back when configured "console", # Console REPL - unused by ESPHome; espressif/mdns pulls it back when configured
"driver", # Legacy driver shim - only needed by esp32_touch, esp32_can for legacy headers "driver", # Legacy driver shim - only needed by esp32_touch, esp32_can for legacy headers
"esp-tls", # TLS wrapper - re-included by http_request, mqtt, web_server_idf "esp-tls", # TLS wrapper - re-included by http_request, mqtt, web_server_idf
"esp_adc", # ADC driver - only needed by adc component "esp_adc", # ADC driver - only needed by adc component
"esp_coex", # WiFi/BT coexistence - re-included by esp32_ble_tracker, zigbee; esp_wifi/bt pull it back
"esp_driver_cam", # Camera driver - the esp32-camera managed component pulls it back "esp_driver_cam", # Camera driver - the esp32-camera managed component pulls it back
"esp_driver_dac", # DAC driver - only needed by esp32_dac component "esp_driver_dac", # DAC driver - only needed by esp32_dac component
"esp_driver_gptimer", # General purpose timer - re-included by ac_dimmer, opentherm, Arduino BLE libs "esp_driver_gptimer", # General purpose timer - re-included by ac_dimmer, opentherm, Arduino BLE libs
@@ -239,8 +241,11 @@ DEFAULT_EXCLUDED_IDF_COMPONENTS = (
"esp_https_server", # HTTPS server - ESPHome has its own web server "esp_https_server", # HTTPS server - ESPHome has its own web server
"esp_lcd", # LCD controller drivers - only needed by display component "esp_lcd", # LCD controller drivers - only needed by display component
"esp_local_ctrl", # Local control over HTTPS/BLE - ESPHome has native API "esp_local_ctrl", # Local control over HTTPS/BLE - ESPHome has native API
"esp_phy", # RF PHY - esp_wifi/bt/ieee802154 pull it back when they are in the build
"esp_wifi", # WiFi stack - re-included by wifi, espnow; bt pulls it back for BLE builds
"espcoredump", # Core dump support - ESPHome has its own debug component "espcoredump", # Core dump support - ESPHome has its own debug component
"fatfs", # FAT filesystem - ESPHome doesn't use filesystem storage "fatfs", # FAT filesystem - ESPHome doesn't use filesystem storage
"ieee802154", # 802.15.4 radio - IDF openthread and the Zigbee libs pull it back
"json", # cJSON library - ESPHome uses ArduinoJson instead "json", # cJSON library - ESPHome uses ArduinoJson instead
"mqtt", # ESP-IDF MQTT library - ESPHome has its own MQTT implementation "mqtt", # ESP-IDF MQTT library - ESPHome has its own MQTT implementation
"openthread", # Thread protocol - only needed by openthread component "openthread", # Thread protocol - only needed by openthread component
@@ -255,6 +260,7 @@ DEFAULT_EXCLUDED_IDF_COMPONENTS = (
"unity", # Unit testing framework - ESPHome doesn't use IDF's testing "unity", # Unit testing framework - ESPHome doesn't use IDF's testing
"wear_levelling", # Flash wear levelling for fatfs - unused since fatfs unused "wear_levelling", # Flash wear levelling for fatfs - unused since fatfs unused
"wifi_provisioning", # WiFi provisioning - ESPHome uses its own improv implementation "wifi_provisioning", # WiFi provisioning - ESPHome uses its own improv implementation
"wpa_supplicant", # WPA supplicant - esp_wifi pulls it back when the WiFi stack is in the build
) )
# Additional IDF managed components to exclude for Arduino framework builds # Additional IDF managed components to exclude for Arduino framework builds
+2
View File
@@ -19,6 +19,7 @@ from esphome.components.esp32 import (
add_idf_sdkconfig_option, add_idf_sdkconfig_option,
const, const,
get_esp32_variant, get_esp32_variant,
include_builtin_idf_component,
request_bluetooth, request_bluetooth,
) )
from esphome.components.esp32.const import VARIANT_ESP32C2 from esphome.components.esp32.const import VARIANT_ESP32C2
@@ -520,6 +521,7 @@ FINAL_VALIDATE_SCHEMA = final_validation
async def to_code(config: ConfigType) -> None: async def to_code(config: ConfigType) -> None:
include_builtin_idf_component("bt")
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
cg.add(var.set_enable_on_boot(config[CONF_ENABLE_ON_BOOT])) cg.add(var.set_enable_on_boot(config[CONF_ENABLE_ON_BOOT]))
cg.add(var.set_io_capability(config[CONF_IO_CAPABILITY])) cg.add(var.set_io_capability(config[CONF_IO_CAPABILITY]))
@@ -11,6 +11,7 @@ from esphome.components.const import CONF_ON_SCAN_END, CONF_SCAN_PARAMETERS, CON
from esphome.components.esp32 import ( from esphome.components.esp32 import (
add_idf_sdkconfig_option, add_idf_sdkconfig_option,
idf_version, idf_version,
include_builtin_idf_component,
request_bluetooth, request_bluetooth,
request_software_coexistence, request_software_coexistence,
) )
@@ -355,6 +356,7 @@ async def to_code(config: ConfigType) -> None:
if config.get(CONF_SOFTWARE_COEXISTENCE): if config.get(CONF_SOFTWARE_COEXISTENCE):
cg.add_define("USE_ESP32_BLE_SOFTWARE_COEXISTENCE") cg.add_define("USE_ESP32_BLE_SOFTWARE_COEXISTENCE")
include_builtin_idf_component("esp_coex")
# This needs to be run as a job with very low priority so that all components have # This needs to be run as a job with very low priority so that all components have
+5
View File
@@ -155,6 +155,11 @@ async def to_code(config: ConfigType) -> None:
cg.add_define("USE_ESPNOW") cg.add_define("USE_ESPNOW")
cg.add_define("USE_ESPNOW_MAX_PAYLOAD_SIZE", config[CONF_MAX_PAYLOAD_SIZE]) cg.add_define("USE_ESPNOW_MAX_PAYLOAD_SIZE", config[CONF_MAX_PAYLOAD_SIZE])
if CORE.is_esp32:
from esphome.components.esp32 import include_builtin_idf_component
include_builtin_idf_component("esp_wifi")
if CONF_WIFI in CORE.config: if CONF_WIFI in CORE.config:
# Track the Wi-Fi channel via connect events instead of polling every loop # Track the Wi-Fi channel via connect events instead of polling every loop
wifi.request_wifi_connect_state_listener() wifi.request_wifi_connect_state_listener()
+8 -1
View File
@@ -1,5 +1,5 @@
import esphome.codegen as cg import esphome.codegen as cg
from esphome.components.esp32 import add_idf_component from esphome.components.esp32 import add_idf_component, add_idf_sdkconfig_option
from esphome.config_helpers import filter_source_files_from_platform, get_logger_level from esphome.config_helpers import filter_source_files_from_platform, get_logger_level
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.const import ( from esphome.const import (
@@ -209,6 +209,13 @@ async def to_code(config):
if CORE.is_esp32: if CORE.is_esp32:
add_idf_component(name="espressif/mdns", ref="1.11.3") add_idf_component(name="espressif/mdns", ref="1.11.3")
# The mdns console CLI is never used by ESPHome
add_idf_sdkconfig_option("CONFIG_MDNS_ENABLE_CONSOLE_CLI", False)
if "wifi" not in CORE.config:
# Without WiFi the predefined STA/AP interface handlers are dead
# code; disabling them lets mdns build without the WiFi stack.
add_idf_sdkconfig_option("CONFIG_MDNS_PREDEF_NETIF_STA", False)
add_idf_sdkconfig_option("CONFIG_MDNS_PREDEF_NETIF_AP", False)
cg.add_define("USE_MDNS") cg.add_define("USE_MDNS")
+4
View File
@@ -10,6 +10,7 @@ from esphome.components.esp32 import (
add_idf_sdkconfig_option, add_idf_sdkconfig_option,
const, const,
get_esp32_variant, get_esp32_variant,
include_builtin_idf_component,
only_on_variant, only_on_variant,
request_wifi, request_wifi,
) )
@@ -647,6 +648,9 @@ async def to_code(config):
# drops SoftAP support / the LWIP DHCP server when AP mode is unused. # drops SoftAP support / the LWIP DHCP server when AP mode is unused.
if CORE.is_esp32: if CORE.is_esp32:
request_wifi(ap=CONF_AP in config) request_wifi(ap=CONF_AP in config)
include_builtin_idf_component("esp_wifi")
# wifi_component.cpp includes esp_eap_client.h/esp_wpa2.h
include_builtin_idf_component("wpa_supplicant")
# Disable Enterprise WiFi support if no EAP is configured # Disable Enterprise WiFi support if no EAP is configured
if CORE.is_esp32: if CORE.is_esp32:
@@ -9,6 +9,7 @@ from esphome.components.esp32 import (
add_idf_component, add_idf_component,
add_idf_sdkconfig_option, add_idf_sdkconfig_option,
add_partition, add_partition,
include_builtin_idf_component,
require_vfs_select, require_vfs_select,
) )
import esphome.config_validation as cv import esphome.config_validation as cv
@@ -288,6 +289,10 @@ async def esp32_to_code(config: ConfigType) -> "MockObj":
ref="2.0.4", ref="2.0.4",
) )
if CONF_WIFI in CORE.config:
# zigbee_esp32.cpp uses esp_coexist.h when WiFi is present
include_builtin_idf_component("esp_coex")
# add sdkconfigs later so they can overwrite esp32 defaults # add sdkconfigs later so they can overwrite esp32 defaults
CORE.add_job(_zigbee_add_sdkconfigs, config) CORE.add_job(_zigbee_add_sdkconfigs, config)
@@ -0,0 +1,11 @@
esphome:
name: test
esp32:
board: esp32dev
framework:
type: esp-idf
espnow:
channel: 1
auto_add_peer: true
@@ -0,0 +1,13 @@
esphome:
name: test
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ssid: MySSID
password: password1
esp32_ble_tracker:
+14
View File
@@ -268,6 +268,20 @@ def test_esp32_configuration_errors(
("esp-tls", "esp_http_client"), ("esp-tls", "esp_http_client"),
id="nextion", id="nextion",
), ),
pytest.param(
# esp_wifi from wifi, bt from esp32_ble, esp_coex from
# esp32_ble_tracker's software coexistence (defaults on with wifi).
# wpa_supplicant/esp_phy stay excluded; IDF requirement expansion
# pulls them back via esp_wifi.
"exclusion_reincludes_wifi_ble.yaml",
("esp_wifi", "bt", "esp_coex"),
id="wifi_ble",
),
pytest.param(
"exclusion_reincludes_espnow.yaml",
("esp_wifi",),
id="espnow",
),
], ],
) )
def test_default_exclusions_reincluded_by_owning_components( def test_default_exclusions_reincluded_by_owning_components(