From ded543e561fbc478646c648d77121eeaf5bc4f04 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 23 Feb 2026 16:10:15 +0100 Subject: [PATCH] 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. --- tools/cmakev2/build.cmake | 29 +++++++++++++++++ tools/cmakev2/component.cmake | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/tools/cmakev2/build.cmake b/tools/cmakev2/build.cmake index 8084e9095b..ae15ca22a7 100644 --- a/tools/cmakev2/build.cmake +++ b/tools/cmakev2/build.cmake @@ -112,6 +112,32 @@ function(__dump_build_properties) endforeach() endfunction() +#[[ + __idf_build_dispatch_build_event( ) + + *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 OUTPUT ) @@ -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() #[[ diff --git a/tools/cmakev2/component.cmake b/tools/cmakev2/component.cmake index c8bd118c4f..a0262a9ac8 100644 --- a/tools/cmakev2/component.cmake +++ b/tools/cmakev2/component.cmake @@ -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 CALLBACK ) + + *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 "$") + 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()