[core] Skip copying entity automation and filter sources when unused

This commit is contained in:
J. Nick Koston
2026-08-21 14:13:04 -05:00
parent 00cffa09a2
commit 4e250a654c
8 changed files with 65 additions and 2 deletions
@@ -560,6 +560,11 @@ _CALLBACK_AUTOMATIONS = (
async def _build_binary_sensor_automations(var, config):
await automation.build_callback_automations(var, config, _CALLBACK_AUTOMATIONS)
if CONF_ON_CLICK in config or CONF_ON_DOUBLE_CLICK in config:
cg.add_define("USE_BINARY_SENSOR_CLICK_TRIGGER")
if CONF_ON_MULTI_CLICK in config:
cg.add_define("USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER")
for conf in config.get(CONF_ON_CLICK, []):
trigger = cg.new_Pvariable(
conf[CONF_TRIGGER_ID], var, conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH]
@@ -673,3 +678,19 @@ async def to_code(config):
async def binary_sensor_invalidate_state_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
return cg.new_Pvariable(action_id, template_arg, paren)
def FILTER_SOURCE_FILES() -> list[str]:
"""automation.cpp only implements the click/double_click/multi_click
triggers and filter.cpp is fully #ifdef'd on USE_BINARY_SENSOR_FILTER;
skip copying them when unused so they are not opened and parsed."""
defines = {define.name for define in CORE.defines}
files: list[str] = []
if not defines & {
"USE_BINARY_SENSOR_CLICK_TRIGGER",
"USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER",
}:
files.append("automation.cpp")
if "USE_BINARY_SENSOR_FILTER" not in defines:
files.append("filter.cpp")
return files
@@ -1,8 +1,13 @@
#include "esphome/core/defines.h"
#if defined(USE_BINARY_SENSOR_CLICK_TRIGGER) || defined(USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER)
#include "automation.h"
#include "esphome/core/log.h"
namespace esphome::binary_sensor {
#ifdef USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER
static const char *const TAG = "binary_sensor.automation";
// MultiClickTrigger timeout IDs.
@@ -120,6 +125,9 @@ void MultiClickTriggerBase::trigger_() {
this->trigger();
}
#endif // USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER
#ifdef USE_BINARY_SENSOR_CLICK_TRIGGER
bool match_interval(uint32_t min_length, uint32_t max_length, uint32_t length) {
if (max_length == 0) {
return length >= min_length;
@@ -127,4 +135,8 @@ bool match_interval(uint32_t min_length, uint32_t max_length, uint32_t length) {
return length >= min_length && length <= max_length;
}
}
#endif // USE_BINARY_SENSOR_CLICK_TRIGGER
} // namespace esphome::binary_sensor
#endif // USE_BINARY_SENSOR_CLICK_TRIGGER || USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER
+9
View File
@@ -3450,3 +3450,12 @@ def process_stacktrace(config, line, backtrace_state):
_decode_pc(config, addr.group())
return backtrace_state
def FILTER_SOURCE_FILES() -> list[str]:
"""gpio.cpp only implements ESP32InternalGPIOPin (and its ISR helpers),
which is instantiated solely by the pin schema codegen; skip copying it
when the config uses no internal GPIO pins."""
if not any(define.name == "USE_ESP32_INTERNAL_GPIO" for define in CORE.defines):
return ["gpio.cpp"]
return []
+3 -2
View File
@@ -1,4 +1,5 @@
#ifdef USE_ESP32
#include "esphome/core/defines.h"
#if defined(USE_ESP32) && defined(USE_ESP32_INTERNAL_GPIO)
#include "gpio.h"
#include "esphome/core/log.h"
@@ -204,4 +205,4 @@ void IRAM_ATTR ISRInternalGPIOPin::pin_mode(gpio::Flags flags) {
} // namespace esphome
#endif // USE_ESP32
#endif // USE_ESP32 && USE_ESP32_INTERNAL_GPIO
+1
View File
@@ -257,6 +257,7 @@ ESP32_PIN_SCHEMA = cv.All(
@pins.PIN_SCHEMA_REGISTRY.register(PLATFORM_ESP32, ESP32_PIN_SCHEMA)
async def esp32_pin_to_code(config):
cg.add_define("USE_ESP32_INTERNAL_GPIO")
var = cg.new_Pvariable(config[CONF_ID])
num = config[CONF_NUMBER]
cg.add(var.set_pin(getattr(gpio_num_t, f"GPIO_NUM_{num}")))
+8
View File
@@ -1303,3 +1303,11 @@ def _lstsq(a, b):
@coroutine_with_priority(CoroPriority.CORE)
async def to_code(config):
cg.add_global(sensor_ns.using)
def FILTER_SOURCE_FILES() -> list[str]:
"""filter.cpp is fully #ifdef'd on USE_SENSOR_FILTER; skip copying it
when no sensor uses filters so it is not opened and parsed."""
if not any(define.name == "USE_SENSOR_FILTER" for define in CORE.defines):
return ["filter.cpp"]
return []
@@ -256,3 +256,11 @@ async def text_sensor_state_to_code(config, condition_id, template_arg, args):
templ = await cg.templatable(config[CONF_STATE], args, cg.std_string)
cg.add(var.set_state(templ))
return var
def FILTER_SOURCE_FILES() -> list[str]:
"""filter.cpp is fully #ifdef'd on USE_TEXT_SENSOR_FILTER; skip copying it
when no text sensor uses filters so it is not opened and parsed."""
if not any(define.name == "USE_TEXT_SENSOR_FILTER" for define in CORE.defines):
return ["filter.cpp"]
return []
+3
View File
@@ -43,7 +43,9 @@
#define USE_ALARM_CONTROL_PANEL
#define USE_AREAS
#define USE_BINARY_SENSOR
#define USE_BINARY_SENSOR_CLICK_TRIGGER
#define USE_BINARY_SENSOR_FILTER
#define USE_BINARY_SENSOR_MULTI_CLICK_TRIGGER
#define USE_BLE_DEVICE_IRK
#define USE_BUTTON
#define USE_CAMERA
@@ -281,6 +283,7 @@
// ESP32-specific feature flags
#ifdef USE_ESP32
#define USE_ESP32_CRASH_HANDLER
#define USE_ESP32_INTERNAL_GPIO
#define USE_MQTT_IDF_ENQUEUE
#define USE_ESPHOME_TASK_LOG_BUFFER
#define ESPHOME_TASK_LOG_BUFFER_SIZE 768