[api] Make api a buildable cpp unit test target

Three fixes so 'script/cpp_unit_test.py api' actually compiles instead
of crashing in build setup:

1. script/build_helpers.py: when adding transitive component
   dependencies to the post-validation config, use {} (dict) instead
   of [] (list) for non-MULTI_CONF components. socket's
   FILTER_SOURCE_FILES (and any other code that subscripts
   CORE.config[component] with a string key) was crashing because
   socket got config = [] from setdefault.

2. esphome/components/api/api_pb2_service.cpp + the codegen in
   script/api_protobuf/api_protobuf.py: wrap the generated
   APIConnection::read_message_ definition in #ifdef USE_API. The
   class itself is only declared inside #ifdef USE_API in
   api_connection.h, so without the guard the .cpp fails to compile
   in any build that pulls in the api source files without setting
   USE_API (e.g. cpp unit tests of api dependencies).
This commit is contained in:
J. Nick Koston
2026-04-25 04:41:17 -05:00
parent 68ffd3b221
commit 45525c8a82
4 changed files with 17 additions and 11 deletions
+7 -2
View File
@@ -324,8 +324,13 @@ def compile_and_get_binary(
domain_list.append({CONF_PLATFORM: component})
# Skip "core" — it's a pseudo-component handled by the build
# system, not a real loadable component (get_component returns None)
elif get_component(component_name) is not None:
config.setdefault(component_name, [])
elif (component := get_component(component_name)) is not None:
# MULTI_CONF components store their config as a list of dicts,
# everything else stores a single dict. Using the wrong shape
# breaks code paths that subscript CORE.config[component] with
# a string key (e.g. socket.FILTER_SOURCE_FILES).
default = [] if component.multi_conf else {}
config.setdefault(component_name, default)
# Register platforms from the extra config (benchmark.yaml) so
# USE_SENSOR, USE_LIGHT, etc. defines are emitted without needing