Skip to content

Make WiFi mesh library (libmesh.a) optional for ESP32-C3/S3 (IDFGH-16881) #17950

@jonsmirl

Description

@jonsmirl

Is your feature request related to a problem?

Feature Request: Make WiFi mesh library (libmesh.a) optional for ESP32-C3/S3

Problem Description

When building a WiFi application for ESP32-C3 with CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n and no mesh functionality needed, the entire libmesh.a library (~230 KB) is still linked into the final binary. This significantly impacts flash usage on memory-constrained devices.

Environment

  • ESP-IDF version: v5.4
  • Target: ESP32-C3
  • Application: Matter smart home device (needs WiFi STA mode only)

Analysis

Current Behavior

The mesh library is unconditionally included in the blob list for all targets except ESP32-C2:

# From components/esp_wifi/CMakeLists.txt lines 67-72
if(CONFIG_IDF_TARGET_ESP32C2)
    set(blobs core espnow net80211 pp smartconfig)
else()
    set(blobs core espnow mesh net80211 pp smartconfig wapi)
endif()

Root Cause - Symbol Dependency Chain

Even with SoftAP disabled, the mesh library gets pulled in through this dependency chain in the closed-source blobs:

wifi_netif.c (ESP-IDF source)
    ↓ needs esp_wifi_internal_tx()
libnet80211.a(ieee80211_output.o)
    ↓ needs hostap_query_mac_in_list()
libnet80211.a(ieee80211_hostap.o)
    ↓ needs is_esp_mesh_assoc()
libnet80211.a(ieee80211_mesh_quick.o)
    ↓ needs mesh_sta_auth_expire_time()
libmesh.a(mesh_parent.o)
    ↓ pulls in entire mesh library via transitive dependencies

The key issue is that ieee80211_output.o unconditionally calls hostap_query_mac_in_list(), which pulls in ieee80211_hostap.o, which then references mesh functions.

Evidence from Map File

/home/user/esp-idf/components/esp_wifi/lib/esp32c3/libnet80211.a(ieee80211_output.o)
                              esp-idf/esp_wifi/libesp_wifi.a(wifi_netif.c.obj) (esp_wifi_internal_tx)
/home/user/esp-idf/components/esp_wifi/lib/esp32c3/libnet80211.a(ieee80211_hostap.o)
                              .../libnet80211.a(ieee80211_output.o) (hostap_query_mac_in_list)
/home/user/esp-idf/components/esp_wifi/lib/esp32c3/libnet80211.a(ieee80211_mesh_quick.o)
                              .../libnet80211.a(ieee80211_hostap.o) (is_esp_mesh_assoc)
/home/user/esp-idf/components/esp_wifi/lib/esp32c3/libmesh.a(mesh_parent.o)
                              .../libnet80211.a(ieee80211_proto.o) (mesh_sta_auth_expire_time)

Flash Impact

Component Size
libmesh.a total 229.55 KB
mesh_parent.o 72.10 KB
mesh_quick.o 36.39 KB
mesh_schedule.o 34.90 KB
mesh.o 28.15 KB
Other mesh objects ~58 KB

This represents ~15% of a typical 1.9MB OTA partition.

Requested Solution

  1. Short-term: Add a Kconfig option (e.g., CONFIG_ESP_WIFI_MESH_SUPPORT) that, when disabled:

    • Removes mesh from the blob list in CMakeLists.txt
    • Provides weak stub implementations for the mesh symbols referenced by libnet80211.a
  2. Long-term: Refactor the WiFi blob architecture to:

    • Make hostap_query_mac_in_list() call in ieee80211_output.o conditional or use weak symbol
    • Make mesh symbol references in ieee80211_hostap.o use weak symbols
    • Allow true dead-code elimination for mesh functionality

Proposed Implementation

Example stub implementations that could be provided when mesh is disabled:

// Weak stubs for mesh functions when CONFIG_ESP_WIFI_MESH_SUPPORT=n
__attribute__((weak)) bool is_esp_mesh_assoc(void) { return false; }
__attribute__((weak)) uint32_t mesh_sta_auth_expire_time(void) { return 0; }
// ... other required stubs

Workarounds Attempted (None Successful)

  • CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n - Does not prevent hostap.o linkage
  • # CONFIG_WIFI_MESH_ENABLED is not set - No effect, option doesn't exist for WiFi mesh
  • Linker --wrap - Not feasible due to multiple interdependent symbols

Impact

This issue affects all ESP32-C3, ESP32-S3, and ESP32 users who:

  • Need WiFi STA mode only
  • Don't use ESP-MESH networking
  • Are constrained on flash space (common for OTA-capable devices)

Thank you for considering this enhancement.

Describe the solution you'd like.

No response

Describe alternatives you've considered.

No response

Additional context.

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions