From c91597454d4a75d7674ce2f92dd4c0a172f5a80d Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 9 Mar 2026 12:07:49 +0100 Subject: [PATCH] feat(cmakev2/idf): add PROJECT_COMPONENTS_SOURCE build property Add the PROJECT_COMPONENTS_SOURCE build property to control how project components are categorised during component discovery. By default it is set to "project_components" (priority 3 - highest), preserving the existing behaviour. Setting it to "idf_components" (priority 0) before calling idf_project_init() makes the project's built-in components overridable by user-supplied components through EXTRA_COMPONENT_DIRS (priority 2). This is needed for sub-projects like the bootloader, whose built-in components (e.g. main) are provided by ESP-IDF and should be overridable by user-supplied components placed in bootloader_components/. The cmakev1 build system allowed this override because it used a last-one-wins strategy, but cmakev2 uses strict priority-based component resolution where project_components always win. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/idf.cmake | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/cmakev2/idf.cmake b/tools/cmakev2/idf.cmake index 691c4c85edc..4287d8d4c9e 100644 --- a/tools/cmakev2/idf.cmake +++ b/tools/cmakev2/idf.cmake @@ -362,12 +362,34 @@ endfunction() EXTRA_COMPONENT_EXCLUDE_DIRS List of paths to exclude from searching the component directories. + The ``PROJECT_COMPONENTS_SOURCE`` build property controls how the + project's own components are categorised -- i.e. those discovered + under ``CMAKE_CURRENT_SOURCE_DIR/main``, + ``CMAKE_CURRENT_SOURCE_DIR/components``, or the paths listed in + ``COMPONENT_DIRS``. It defaults to ``project_components`` + (priority 3 -- highest). Setting it to ``idf_components`` + (priority 0) makes them overridable by components supplied through + ``EXTRA_COMPONENT_DIRS`` (priority 2). This is useful for + sub-projects whose built-in components are provided by ESP-IDF and + should be overridable by user-supplied components. + Each component is initialized for every component directory found. #]] function(__init_components) idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(prefix PREFIX) + idf_build_get_property(project_components_source PROJECT_COMPONENTS_SOURCE) + if(NOT project_components_source) + set(project_components_source "project_components") + endif() + + set(valid_sources "project_components" "idf_components") + if(NOT project_components_source IN_LIST valid_sources) + idf_die("Invalid PROJECT_COMPONENTS_SOURCE '${project_components_source}'." + " Must be one of: ${valid_sources}") + endif() + __get_component_paths(PATHS "${idf_path}/components" OUTPUT idf_components) if(COMPONENT_DIRS) @@ -404,7 +426,7 @@ function(__init_components) foreach(path IN LISTS project_components) __init_component(DIRECTORY "${path}" PREFIX "${prefix}" - SOURCE "project_components") + SOURCE "${project_components_source}") endforeach() foreach(path IN LISTS project_extra_components)