feat(cmakev2): Add build event callback framework for components

Introduce a callback mechanism that lets components register CMake
functions to be called at specific points in the build lifecycle.

Currently, this framework only supports registering callbacks to be
called after the executable target is created, i.e, the POST_ELF phase
of the build but before the binary target is created.
This commit is contained in:
Sudeep Mohanty
2026-02-23 16:10:15 +01:00
committed by Frantisek Hrbata
parent 08a90ffa64
commit ded543e561
2 changed files with 88 additions and 0 deletions
+29
View File
@@ -112,6 +112,32 @@ function(__dump_build_properties)
endforeach()
endfunction()
#[[
__idf_build_dispatch_build_event(<event> <target>)
*event[in]*
Build event name. Currently only ``POST_ELF`` is supported. Other build
events may be extended when required.
*target[in]*
Name of the primary CMake target at this event point. Passed as the
sole argument to every registered callback so that callbacks can
operate on the correct target without querying build properties.
For ``POST_ELF`` this is the executable target name.
Internal dispatcher called by the build system at well-defined lifecycle
points. Invokes every CMake function registered for
``event`` via ``idf_component_register_build_event_callback``.
#]]
function(__idf_build_dispatch_build_event event target)
idf_build_get_property(callbacks "__BUILD_EVENT_CALLBACKS_${event}")
foreach(cb IN LISTS callbacks)
cmake_language(CALL "${cb}" "${target}")
endforeach()
endfunction()
#[[
__get_library_interface_or_die(LIBRARY <library>
OUTPUT <variable>)
@@ -610,6 +636,9 @@ function(idf_build_executable executable)
endif()
set_target_properties(${executable} PROPERTIES LIBRARY_INTERFACE ${library})
# Dispatch POST_ELF event once the executable target exists
__idf_build_dispatch_build_event(POST_ELF "${executable}")
endfunction()
#[[
+59
View File
@@ -1058,3 +1058,62 @@ function(idf_component_include name)
idf_build_get_compile_options(compile_options)
target_compile_options("${component_real_target}" BEFORE PRIVATE "${compile_options}")
endfunction()
#[[api
.. cmakev2:function:: idf_component_register_build_event_callback
.. code-block:: cmake
idf_component_register_build_event_callback(EVENT <event> CALLBACK <function-name>)
*EVENT[in]*
Build lifecycle event at which the callback will be invoked. Currently
only ``POST_ELF`` is supported.
*CALLBACK[in]*
Name of a CMake function defined in the component's project_include.cmake file.
The build system calls this function with the primary CMake target as its argument
at the specified event point. For ``POST_ELF`` this is the executable target.
Example::
# project_include.cmake
function(my_component_post_elf_hook target)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND my_tool "$<TARGET_FILE:${target}>")
endfunction()
idf_component_register_build_event_callback(
EVENT POST_ELF
CALLBACK my_component_post_elf_hook)
#]]
function(idf_component_register_build_event_callback)
set(options)
set(one_value EVENT CALLBACK)
set(multi_value)
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
if(NOT DEFINED ARG_EVENT)
idf_die("idf_component_register_build_event_callback: EVENT option is required")
endif()
if(NOT DEFINED ARG_CALLBACK)
idf_die("idf_component_register_build_event_callback: CALLBACK option is required")
endif()
set(valid_events POST_ELF)
if(NOT "${ARG_EVENT}" IN_LIST valid_events)
idf_die("idf_component_register_build_event_callback: unknown event '${ARG_EVENT}'. "
"Valid events: ${valid_events}")
endif()
if(NOT COMMAND "${ARG_CALLBACK}")
idf_die("idf_component_register_build_event_callback: callback '${ARG_CALLBACK}' "
"is not a known CMake function. Define it before calling this function.")
endif()
idf_build_set_property("__BUILD_EVENT_CALLBACKS_${ARG_EVENT}" "${ARG_CALLBACK}" APPEND)
endfunction()