fix(bootloader): handle extra component dirs in v1 subproject

Closes https://github.com/espressif/esp-idf/issues/18651
This commit is contained in:
Konstantin Kondrashov
2026-07-16 10:37:12 +08:00
committed by BOT
parent 1918bb2b10
commit 5bc1dfc166
16 changed files with 141 additions and 16 deletions
@@ -6,9 +6,34 @@ cmake_minimum_required(VERSION 3.22)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
idf_build_set_property(BOOTLOADER_EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/extra_bootloader_components/" APPEND)
# The bootloader always uses the "bootloader_components" folder name
# as the project-local search path for bootloader components added to the bootloader build.
#
# Use BOOTLOADER_EXTRA_COMPONENT_DIRS when bootloader components already lives somewhere else,
# for example in a shared components directory or in a component reused by several projects.
# The path may point to a directory containing multiple components.
idf_build_set_property(BOOTLOADER_EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/extra_bootloader_components" APPEND)
# The path may also point directly to a single component when adding a wrapper directory
# just for the bootloader build would be unnecessary.
idf_build_set_property(BOOTLOADER_EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/extra_component4" APPEND)
idf_build_set_property(BOOTLOADER_EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/extra_component5" APPEND)
# A shared extra directory may contain components that are not needed in this bootloader build.
# Ignore them by component name, including direct single-component paths.
set(BOOTLOADER_IGNORE_EXTRA_COMPONENT extra_component3 extra_component5)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(main)
# Check which extra bootloader components are included and which ones are ignored.
add_custom_target(check_bootloader_extra_components ALL
COMMAND ${CMAKE_COMMAND}
-DPROJECT_DESCRIPTION=${CMAKE_BINARY_DIR}/bootloader/project_description.json
-DEXPECTED_COMPONENTS=extra_component1,extra_component2,extra_component4
-DIGNORED_COMPONENTS=extra_component3,extra_component5
-P ${CMAKE_CURRENT_LIST_DIR}/check_bootloader_component.cmake
DEPENDS bootloader
VERBATIM)
@@ -5,9 +5,11 @@
(See the README.md file in the upper level for more information about bootloader examples.)
The purpose of this example is to show how to add a custom directory that contains a component to the bootloader build.
The purpose of this example is to show how to add bootloader components that are not placed in the conventional `bootloader_components` directory.
Registering extra components for the bootloader can be done thanks to the IDF property `BOOTLOADER_EXTRA_COMPONENT_DIRS`. It can either refer to a directory that contains several components, either refer to a single component.
The bootloader always uses the `bootloader_components` folder name as the project-local search path for bootloader components. Use this folder for bootloader-specific code that belongs to the project, such as hooks or overrides.
Use the `BOOTLOADER_EXTRA_COMPONENT_DIRS` property when bootloader components already live somewhere else, for example in a shared components directory or in a component reused by several projects. Each path can point either to a directory containing multiple components or directly to a single component. If the extra location contains components that are not needed in a particular bootloader build, list them by component name in `BOOTLOADER_IGNORE_EXTRA_COMPONENT`.
## Usage of this example:
@@ -33,9 +35,11 @@ User application is loaded and running.
## Organization of this example
This project contains a `main` directory that represents an application. It also has a `bootloader_components` directory that contains a component that will be compiled and linked with the bootloader. This `bootloader_components` can contain several components, each of them would be in a different directory.
This project contains a `main` directory that represents an application. It also has a `bootloader_components` directory with `my_boot_hooks`, a bootloader-specific hook component that belongs to this project.
The directory `extra_bootloader_components/extra_component/` contains a component that is meant to be included in the bootloader build. To do so, the CMake property `BOOTLOADER_EXTRA_COMPONENT_DIRS` is set from the `CMakeLists.txt` file.
The `extra_bootloader_components/` directory demonstrates an extra path that contains several components. `extra_component1` is required by `my_boot_hooks`, while `extra_component2` is included directly from `BOOTLOADER_EXTRA_COMPONENT_DIRS` without being required by another component. `extra_component3` is present in the same directory but is excluded from this bootloader build with `BOOTLOADER_IGNORE_EXTRA_COMPONENT`.
The `extra_component4/` and `extra_component5/` directories demonstrate extra paths that point directly to individual components. `extra_component4` is included directly, while `extra_component5` is excluded with `BOOTLOADER_IGNORE_EXTRA_COMPONENT`.
Below is a short explanation of files in the project folder.
@@ -49,8 +53,20 @@ Below is a short explanation of files in the project folder.
│   ├── CMakeLists.txt
│   └── hooks.c Implementation of the hooks to execute on boot
├── extra_bootloader_components
│   └── extra_component
│   ├── extra_component1
│   │   ├── CMakeLists.txt
│   │   └── extra_component1.c Implementation of the extra component
│   ├── extra_component2
│   │   ├── CMakeLists.txt
│   │   └── extra_component2.c Implementation of the 2nd extra component
│   └── extra_component3
│   ├── CMakeLists.txt
│   └── extra_component.c Implementation of the extra component
│   └── extra_component3.c Extra component excluded from this bootloader build
├── extra_component4
│   ├── CMakeLists.txt
│   └── extra_component4.c Extra component included directly
├── extra_component5
│   ├── CMakeLists.txt
│   └── extra_component5.c Extra component excluded directly
└── README.md This is the file you are currently reading
```
@@ -1,5 +1,5 @@
idf_component_register(SRCS "hooks.c"
REQUIRES extra_component)
REQUIRES extra_component1)
# We need to force GCC to integrate this static library into the
# bootloader link. Indeed, by default, as the hooks in the bootloader are weak,
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
file(READ "${PROJECT_DESCRIPTION}" project_description)
string(JSON component_count LENGTH "${project_description}" build_components)
set(build_components)
if(component_count GREATER 0)
math(EXPR last_component_index "${component_count} - 1")
foreach(component_index RANGE 0 ${last_component_index})
string(JSON component_name GET "${project_description}" build_components ${component_index})
if(NOT component_name STREQUAL "")
list(APPEND build_components "${component_name}")
endif()
endforeach()
endif()
string(REPLACE "," ";" expected_components "${EXPECTED_COMPONENTS}")
foreach(expected_component ${expected_components})
list(FIND build_components "${expected_component}" component_index)
if(component_index EQUAL -1)
message(FATAL_ERROR "${expected_component} was not included in the bootloader build")
endif()
endforeach()
string(REPLACE "," ";" ignored_components "${IGNORED_COMPONENTS}")
foreach(ignored_component ${ignored_components})
list(FIND build_components "${ignored_component}" component_index)
if(NOT component_index EQUAL -1)
message(FATAL_ERROR "${ignored_component} was included in the bootloader build")
endif()
endforeach()
@@ -1 +0,0 @@
idf_component_register(SRCS "extra_component.c")
@@ -0,0 +1 @@
idf_component_register(SRCS "extra_component1.c")
@@ -0,0 +1 @@
idf_component_register(SRCS "extra_component2.c")
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void bootloader_extra_component2_marker(void)
{
}
@@ -0,0 +1 @@
idf_component_register(SRCS "extra_component3.c")
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void bootloader_extra_component3_marker(void)
{
}
@@ -0,0 +1 @@
idf_component_register(SRCS "extra_component4.c")
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void bootloader_extra_component4_marker(void)
{
}
@@ -0,0 +1 @@
idf_component_register(SRCS "extra_component5.c")
@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
void bootloader_extra_component5_marker(void)
{
}