From 621af797622d2b501478656441128f20221564d6 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Fri, 14 Nov 2025 12:56:49 +0100 Subject: [PATCH 1/6] fix(cmakev2/project): remove temporary workaround for partition and bootloader flash dependencies With commit b719292b75ac ("refactor(build-system): Simplify flash target creation"), partition table and bootloader components are correctly adding their dependency on the flash target, so there is no need for this to be done in the build system. This removes the temporary workaround. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/project.cmake | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index eaf4d6043a..5c8e0ae1e2 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -752,16 +752,6 @@ macro(idf_project_default) TARGET dfu) endif() - # FIXME: Dependencies should be specified within the components, not in the - # build system. - if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT) - add_dependencies(flash "partition_table_bin") - endif() - - if(CONFIG_APP_BUILD_BOOTLOADER) - add_dependencies(flash "bootloader") - endif() - idf_build_generate_flasher_args() endif() From f23de1f518906513a0869c07df9482a36960a045 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 17 Nov 2025 11:37:46 +0100 Subject: [PATCH 2/6] fix(cmakev2/build): pass binary target to idf_build_generate_metadata Currently, the `idf_build_generate_metadata` function takes an executable target as an argument, and the binary name is stored in the `EXECUTABLE_BINARY` property. This approach is inconvenient because a single executable might generate multiple binary images, making it unreliable to store the binary image name in the executable property due to the N:1 relationship. To address this, pass the binary image target instead of the executable target to the `idf_build_generate_metadata` function. This change is facilitated by linking the binary target, executable target, and library interface targets with the following properties: binary:EXECUTABLE_TARGET -> executable:LIBRARY_INTERFACE -> library Signed-off-by: Frantisek Hrbata --- tools/cmakev2/build.cmake | 60 +++++++++++++++++++++---------- tools/cmakev2/project.cmake | 4 +-- tools/cmakev2/test/CMakeLists.txt | 4 +-- tools/cmakev2/utilities.cmake | 34 +++++++++++------- 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/tools/cmakev2/build.cmake b/tools/cmakev2/build.cmake index b7711a0f2f..36ebd2c369 100644 --- a/tools/cmakev2/build.cmake +++ b/tools/cmakev2/build.cmake @@ -507,7 +507,9 @@ endfunction() ``executable`` argument, and link it to the library created with the component names provided in the ``COMPONENTS`` option. If the ``COMPONENTS`` option is not set, all discovered components are added to - the library. Optinaly set the executable name and suffix. + the library. Optionally set the executable name and suffix. The executable + library target name is added to the ``LIBRARY_INTERFACE`` executable + property. #]] function(idf_build_executable executable) set(options) @@ -543,6 +545,8 @@ function(idf_build_executable executable) endif() target_link_libraries(${executable} PRIVATE ${library}) + + set_target_properties(${executable} PROPERTIES LIBRARY_INTERFACE ${library}) endfunction() #[[ @@ -647,28 +651,34 @@ endfunction() .. code-block:: cmake - idf_build_generate_metadata( + idf_build_generate_metadata( [FILE ]) - *executable[in]* + *binary[in]* - Executable target for which to generate a metadata file. + Binary target for which to generate a metadata file. *OUTPUT_FILE[in,opt]* Optional output file path for storing the metadata. If not provided, the default path ``/project_description.json`` is used. - Generate metadata for the specified ``executable`` and store it in the + Generate metadata for the specified ``binary`` and store it in the specified ``FILE``. If no ``FILE`` is provided, the default location ``/project_description.json`` will be used. #]] -function(idf_build_generate_metadata executable) +function(idf_build_generate_metadata binary) set(options) set(one_value OUTPUT_FILE) set(multi_value) cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN}) + # The EXECUTABLE_TARGET property is set by the idf_build_binary or + # the idf_sign_binary function. + get_target_property(executable "${binary}" EXECUTABLE_TARGET) + if(NOT executable) + idf_die("Binary target '${binary}' is missing 'EXECUTABLE_TARGET' property.") + endif() __get_executable_library_or_die(TARGET "${executable}" OUTPUT library) idf_build_get_property(PROJECT_NAME PROJECT_NAME) @@ -679,9 +689,13 @@ function(idf_build_generate_metadata executable) idf_build_get_property(SDKCONFIG SDKCONFIG) idf_build_get_property(SDKCONFIG_DEFAULTS SDKCONFIG_DEFAULTS) set(PROJECT_EXECUTABLE "$") - # The PROJECT_BIN executable property must be set by the idf_build_binary - # function. - get_target_property(PROJECT_BIN "${executable}" EXECUTABLE_BINARY) + # The BINARY_PATH property is set by the idf_build_binary or + # the idf_sign_binary function. + get_target_property(binary_path ${binary} BINARY_PATH) + if(NOT binary_path) + idf_die("Binary target '${binary}' is missing 'BINARY_PATH' property.") + endif() + get_filename_component(PROJECT_BIN "${binary_path}" NAME) if(NOT PROJECT_BIN) set(PROJECT_BIN "") endif() @@ -767,8 +781,9 @@ endfunction() Create a binary image for the specified ``executable`` target and save it in the file specified with the ``OUTPUT_FILE`` option. A custom target named ``TARGET`` will be created for the generated binary image. The path - of the generated binary image will be also stored in the ``BINARY_PATH`` - property of the ``TARGET``. + of the generated binary image will be stored in the ``BINARY_PATH`` + property and the executable target in the ``EXECUTABLE_TARGET`` property of + the ``TARGET``. #]] function(idf_build_binary executable) set(options) @@ -828,13 +843,13 @@ function(idf_build_binary executable) # Create a custom target to generate the binary file add_custom_target(${ARG_TARGET} DEPENDS "${ARG_OUTPUT_FILE}") - # The EXECUTABLE_BINARY property is used by idf_build_generate_metadata to - # store the name of the binary image. - set_target_properties(${executable} PROPERTIES EXECUTABLE_BINARY ${binary_name}) - # Store the path of the binary file in the BINARY_PATH property of the # custom binary target, which is used by the idf_flash_binary. set_target_properties(${ARG_TARGET} PROPERTIES BINARY_PATH ${ARG_OUTPUT_FILE}) + + # Store executable target name in the EXECUTABLE_TARGET property. This is used + # by the idf_build_generate_metadata function. + set_target_properties(${ARG_TARGET} PROPERTIES EXECUTABLE_TARGET ${executable}) endfunction() #[[ @@ -870,9 +885,10 @@ endfunction() Sign binary image specified by ``binary`` target with ``KEYFILE`` and save it in the file specified with the `OUTPUT_FILE` option. A custom target - named ``TARGET`` will be created for the signed binary image. The path of - the signed binary image will be also stored in the ``BINARY_PATH`` property - of the ``TARGET``. + named ``TARGET`` will be created for the signed binary image. The path of + the signed binary image will be stored in the ``BINARY_PATH`` property and + the executable target in the ``EXECUTABLE_TARGET`` property of the + ``TARGET``. #]] function(idf_sign_binary binary) set(options) @@ -936,6 +952,14 @@ function(idf_sign_binary binary) # Store the path of the binary file in the BINARY_PATH property of the # custom signed binary target, which is used by the idf_flash_binary. set_target_properties(${ARG_TARGET} PROPERTIES BINARY_PATH ${ARG_OUTPUT_FILE}) + + # Store executable target name in the EXECUTABLE_TARGET property. This is used + # by the idf_build_generate_metadata function. + get_target_property(executable "${binary}" EXECUTABLE_TARGET) + if(NOT executable) + idf_die("Binary target '${binary}' is missing 'EXECUTABLE_TARGET' property.") + endif() + set_target_properties(${ARG_TARGET} PROPERTIES EXECUTABLE_TARGET ${executable}) endfunction() #[[ diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index 5c8e0ae1e2..ed874af662 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -734,6 +734,7 @@ macro(idf_project_default) TARGET app-flash NAME "app" FLASH) + idf_build_generate_metadata("${executable}_binary_signed") else() idf_build_binary("${executable}" OUTPUT_FILE "${build_dir}/${executable}.bin" @@ -750,6 +751,7 @@ macro(idf_project_default) idf_create_dfu("${executable}_binary" TARGET dfu) + idf_build_generate_metadata("${executable}_binary") endif() idf_build_generate_flasher_args() @@ -769,8 +771,6 @@ macro(idf_project_default) TARGET uf2-app APP_ONLY) - idf_build_generate_metadata("${executable}") - unset(build_dir) unset(executable) endmacro() diff --git a/tools/cmakev2/test/CMakeLists.txt b/tools/cmakev2/test/CMakeLists.txt index 8332901d1b..dce1791e61 100644 --- a/tools/cmakev2/test/CMakeLists.txt +++ b/tools/cmakev2/test/CMakeLists.txt @@ -229,7 +229,7 @@ function(test_executable) NAME fatfs_example) idf_create_menuconfig(fatfs_example TARGET menuconfig-fatfs) - idf_build_generate_metadata(fatfs_example + idf_build_generate_metadata(fatfs_example_bin OUTPUT_FILE project_description_fatfs.json) idf_create_confserver(fatfs_example TARGET confserver-fatfs) @@ -246,7 +246,7 @@ function(test_executable) NAME hello_world_example) idf_create_menuconfig(hello_world_example TARGET menuconfig-hello_world) - idf_build_generate_metadata(hello_world_example + idf_build_generate_metadata(hello_world_example_bin OUTPUT_FILE project_description_hello_world.json) idf_create_confserver(hello_world_example TARGET confserver-hello_world) diff --git a/tools/cmakev2/utilities.cmake b/tools/cmakev2/utilities.cmake index 69f94a8dfb..3671598640 100644 --- a/tools/cmakev2/utilities.cmake +++ b/tools/cmakev2/utilities.cmake @@ -981,11 +981,12 @@ endfunction() Output variable to store the library interface target linked to the executable. - Search for the library interface target created with the - idf_build_library() function and linked to the executable, examine the - LINK_LIBRARIES for the executable and the LIBRARY_INTERFACES build - property, which stores all library interface targets created by the - idf_build_library() function. + Search for the library interface target in the LIBRARY_INTERFACE executable + property. If not found, search for the library interface target created with + the idf_build_library() function and linked to the executable. Examine the + LINK_LIBRARIES for the executable and the LIBRARY_INTERFACES build property, + which stores all library interface targets created by the idf_build_library() + function. #]] function(__get_executable_library_or_die) set(options) @@ -1007,15 +1008,22 @@ function(__get_executable_library_or_die) "but an 'EXECUTABLE' target type is expected.") endif() - set(library NOTFOUND) - get_target_property(targets "${ARG_TARGET}" LINK_LIBRARIES) idf_build_get_property(libraries LIBRARY_INTERFACES) - foreach(target IN LISTS targets) - if("${target}" IN_LIST libraries) - set(library "${target}") - break() - endif() - endforeach() + get_target_property(library "${ARG_TARGET}" LIBRARY_INTERFACE) + if(NOT "${library}" IN_LIST libraries) + # The library interface is not stored in the LIBRARY_INTERFACE + # executable property, so the executable was not created by the + # idf_build_executable function. Try searching for the library + # interface in the LINK_LIBRARIES property. + set(library NOTFOUND) + get_target_property(targets "${ARG_TARGET}" LINK_LIBRARIES) + foreach(target IN LISTS targets) + if("${target}" IN_LIST libraries) + set(library "${target}") + break() + endif() + endforeach() + endif() if("${library}" STREQUAL "NOTFOUND") idf_die("No library interface target linked to the '${ARG_TARGET}' executable") From 177483ec551d6c70869564f5c282cefcab17132a Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 17 Nov 2025 14:51:14 +0100 Subject: [PATCH 3/6] fix(cmakev2/build): fix the generation of the link map file The link flag for generating the map file is currently added globally to the link_options. If multiple executables are generated, the link map file is overwritten by the last created executable. Since cmakev2 supports building multiple executables, the link map file options need to be set for each executable individually. To address this, add a new MAPFILE_TARGET option to the idf_build_executable function. When set, the link map file will be generated by the linker, and a target specified in the MAPFILE_TARGET option will be created for the map file. This also splits the idf_project_default macro. Only the idf_project_init macro needs be called within the global scope, as it includes the project_include.cmake files and the cmake version of the configuration. The remaining functionality of the idf_project_default macro is implemented in a __project_default helper function to avoid polluting the global variable space. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/build.cmake | 30 +++++++++-- tools/cmakev2/project.cmake | 83 ++++++++++++++++++------------- tools/cmakev2/test/CMakeLists.txt | 6 ++- 3 files changed, 79 insertions(+), 40 deletions(-) diff --git a/tools/cmakev2/build.cmake b/tools/cmakev2/build.cmake index 36ebd2c369..11774aad7d 100644 --- a/tools/cmakev2/build.cmake +++ b/tools/cmakev2/build.cmake @@ -503,6 +503,16 @@ endfunction() Optional ``executable`` suffix. + *MAPFILE_TARGET[in,opt]* + + Name of the target for the map file. If provided, the link map file is + generated for the specified executable, and the ``MAPFILE_TARGET`` + target name is created for it. The ``MAPFILE_PATH`` property with the + link map file path is added to the ``MAPFILE_TARGET`` target. This can + be used for other targets that depend on the link map file. The link map file + is not generated on Darwin host, so the target ``MAPFILE_TARGET`` may not + be created if link map file is not generated. + Create a new executable target using the name specified in the ``executable`` argument, and link it to the library created with the component names provided in the ``COMPONENTS`` option. If the @@ -513,7 +523,7 @@ endfunction() #]] function(idf_build_executable executable) set(options) - set(one_value NAME SUFFIX) + set(one_value NAME SUFFIX MAPFILE_TARGET) set(multi_value COMPONENTS) cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN}) @@ -536,9 +546,7 @@ function(idf_build_executable executable) endif() add_executable(${executable} "${executable_src}") - if(ARG_NAME) - set_target_properties(${executable} PROPERTIES OUTPUT_NAME ${ARG_NAME}) - endif() + set_target_properties(${executable} PROPERTIES OUTPUT_NAME ${ARG_NAME}) if(ARG_SUFFIX) set_target_properties(${executable} PROPERTIES SUFFIX ${ARG_SUFFIX}) @@ -546,6 +554,20 @@ function(idf_build_executable executable) target_link_libraries(${executable} PRIVATE ${library}) + idf_build_get_property(linker_type LINKER_TYPE) + if(ARG_MAPFILE_TARGET AND "${linker_type}" STREQUAL "GNU") + set(mapfile "${CMAKE_BINARY_DIR}/${ARG_NAME}.map") + target_link_options(${executable} PRIVATE "LINKER:--Map=${mapfile}") + add_custom_command( + OUTPUT "${mapfile}" + DEPENDS ${executable} + ) + add_custom_target(${ARG_MAPFILE_TARGET} + DEPENDS "${mapfile}" + ) + set_target_properties(${ARG_MAPFILE_TARGET} PROPERTIES MAPFILE_PATH ${mapfile}) + endif() + set_target_properties(${executable} PROPERTIES LIBRARY_INTERFACE ${library}) endfunction() diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index ed874af662..4d1245b2d7 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -90,6 +90,21 @@ function(__init_project_configuration) idf_build_get_property(project_dir PROJECT_DIR) idf_build_get_property(project_name PROJECT_NAME) + # Set the LINKER_TYPE build property. Different linkers may have varying + # options, so it's important to identify the linker type to configure the + # options correctly. Currently, LINKER_TYPE is used to set the appropriate + # linker options for linking the entire archive, which differs between the + # GNU and Apple linkers when building on the host. + if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + # Compiling for the host, and the host is macOS, so the linker is Darwin LD. + # Note, when adding support for Clang and LLD based toolchain this check will + # need to be modified. + set(linker_type "Darwin") + else() + set(linker_type "GNU") + endif() + idf_build_set_property(LINKER_TYPE "${linker_type}") + list(APPEND compile_definitions "_GLIBCXX_USE_POSIX_SEMAPHORE" # These two lines enable libstd++ to use "_GLIBCXX_HAVE_POSIX_SEMAPHORE" # posix-semaphores from components/pthread "_GNU_SOURCE") @@ -407,16 +422,13 @@ function(__init_project_configuration) list(APPEND link_options "-specs=picolibc.specs") endif() - if(CMAKE_C_COMPILER_ID MATCHES "GNU") - set(mapfile "${build_dir}/${project_name}.map") + if("${linker_type}" STREQUAL "GNU") set(target_upper "${idf_target}") string(TOUPPER ${target_upper} target_upper) # Add cross-reference table to the map file list(APPEND link_options "-Wl,--cref") # Add this symbol as a hint for esp_idf_size to guess the target name list(APPEND link_options "-Wl,--defsym=IDF_TARGET_${target_upper}=0") - # Enable map file output - list(APPEND link_options "-Wl,--Map=${mapfile}") # Check if linker supports --no-warn-rwx-segments execute_process(COMMAND ${CMAKE_LINKER} "--no-warn-rwx-segments" "--version" RESULT_VARIABLE result @@ -486,21 +498,6 @@ function(__init_project_configuration) idf_build_set_property(ASM_COMPILE_OPTIONS "${asm_compile_options}" APPEND) idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND) idf_build_set_property(LINK_OPTIONS "${link_options}" APPEND) - - # Set the LINKER_TYPE build property. Different linkers may have varying - # options, so it's important to identify the linker type to configure the - # options correctly. Currently, LINKER_TYPE is used to set the appropriate - # linker options for linking the entire archive, which differs between the - # GNU and Apple linkers when building on the host. - if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") - # Compiling for the host, and the host is macOS, so the linker is Darwin LD. - # Note, when adding support for Clang and LLD based toolchain this check will - # need to be modified. - set(linker_type "Darwin") - else() - set(linker_type "GNU") - endif() - idf_build_set_property(LINKER_TYPE "${linker_type}") endfunction() #[[ @@ -694,26 +691,22 @@ function(idf_build_generate_flasher_args) INPUT "${build_dir}/flasher_args.json.in") endfunction() -#[[api -.. cmakev2:macro:: idf_project_default +#[[ +.. cmakev2:macro:: __project_default .. code-block:: cmake - idf_project_default() + __project_default() - Create a default project executable based on the main component and its - transitive dependencies. The executable name is derived from the - ``PROJECT_NAME`` variable, which by default uses the ``CMAKE_PROJECT_NAME`` - value specified in the CMake's ``project()`` call. - - Generate the binary image for the executable, signed or unsigned based on - the configuration, and add flash targets for it. + Helper function implementing the main idf_project_default macro + functionality, preventing global variable scope pollution. #]] -macro(idf_project_default) - idf_project_init() +function(__project_default) idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(executable PROJECT_NAME) - idf_build_executable("${executable}" COMPONENTS main SUFFIX ".elf") + idf_build_executable("${executable}" + COMPONENTS main + MAPFILE_TARGET "${executable}_mapfile") if(CONFIG_APP_BUILD_GENERATE_BINARIES) # Is it possible to have a configuration where @@ -770,7 +763,29 @@ macro(idf_project_default) idf_create_uf2("${executable}" TARGET uf2-app APP_ONLY) +endfunction() - unset(build_dir) - unset(executable) +#[[api +.. cmakev2:macro:: idf_project_default + + .. code-block:: cmake + + idf_project_default() + + Create a default project executable based on the main component and its + transitive dependencies. The executable name is derived from the + ``PROJECT_NAME`` variable, which by default uses the ``CMAKE_PROJECT_NAME`` + value specified in the CMake's ``project()`` call. + + Generate the binary image for the executable, signed or unsigned based on + the configuration, and add flash targets for it. +#]] +macro(idf_project_default) + idf_project_init() + # Only the idf_project_init macro needs be called within the global scope, + # as it includes the project_include.cmake files and the cmake version of + # the configuration. The remaining functionality of the idf_project_default + # macro is implemented in a __project_default helper function to avoid + # polluting the global variable space. + __project_default() endmacro() diff --git a/tools/cmakev2/test/CMakeLists.txt b/tools/cmakev2/test/CMakeLists.txt index dce1791e61..74608a7ad9 100644 --- a/tools/cmakev2/test/CMakeLists.txt +++ b/tools/cmakev2/test/CMakeLists.txt @@ -219,7 +219,8 @@ endfunction() # idf.py confserver-fatfs function(test_executable) idf_build_executable(fatfs_example - COMPONENTS fatfs_example) + COMPONENTS fatfs_example + MAPFILE_TARGET fatfs_example_mapfile) idf_build_binary(fatfs_example TARGET fatfs_example_bin OUTPUT_FILE fatfs_example.bin) @@ -236,7 +237,8 @@ function(test_executable) idf_build_executable(hello_world_example - COMPONENTS hello_world_example) + COMPONENTS hello_world_example + MAPFILE_TARGET hello_world_example_mapfile) idf_build_binary(hello_world_example TARGET hello_world_example_bin OUTPUT_FILE hello_world_example.bin) From a500965fcb31b64a5d4b64423eb2e9e3ed984df1 Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 17 Nov 2025 15:05:08 +0100 Subject: [PATCH 4/6] fix(cmakev2/build): display a warning when the MINIMAL_BUILD property is set The MINIMAL_BUILD property is not relevant in cmakev2, as only components explicitly linked through targets are included in the build by design. Display a warning when this outdated build property is set. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/build.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/cmakev2/build.cmake b/tools/cmakev2/build.cmake index 11774aad7d..fe0088ab12 100644 --- a/tools/cmakev2/build.cmake +++ b/tools/cmakev2/build.cmake @@ -37,6 +37,10 @@ function(idf_build_set_property property value) set(multi_value) cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN}) + if("${property}" STREQUAL MINIMAL_BUILD) + idf_warn("Build property 'MINIMAL_BUILD' is obsolete and will be ignored") + endif() + set(append) if(ARG_APPEND) set(append APPEND) From 3318bd4c1d69e3fb28a2874e5b4668f5c56d6b6b Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Mon, 17 Nov 2025 15:12:49 +0100 Subject: [PATCH 5/6] fix(cmakev2/project): unset global variables in idf_project_init macro The idf_project_init macro is evaluated within the global variable scope, and currently, there are a few variables still set. Let's ensure all variables are properly unset to avoid polluting the global variable namespace. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/project.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index 4d1245b2d7..dcc29f6497 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -596,6 +596,7 @@ macro(idf_project_init) idf_die("sdkconfig.cmake file not found.") endif() include("${sdkconfig_cmake}") + unset(sdkconfig_cmake) # Initialize the target architecture based on the configuration # Ensure this is done after including the sdkconfig. @@ -636,6 +637,7 @@ macro(idf_project_init) idf_component_include("${component_name}") endforeach() endif() + unset(include_all_components) idf_build_set_property(__PROJECT_INITIALIZED YES) endif() From 91add83a389f810b09a7bf57be1b81f154e9af5a Mon Sep 17 00:00:00 2001 From: Frantisek Hrbata Date: Tue, 18 Nov 2025 11:21:07 +0100 Subject: [PATCH 6/6] feat(cmakev2/size): add idf_create_size_report function The idf_create_size_report function allows for the creation of size report targets based on the generated link map file. The size report targets are created using the TARGET option name: "", "-files", and "-components". These size report targets are added to the idf_default_project with the TARGET set to "size", resulting in the creation of "size", "size-files", and "size-components" targets for the default project. Signed-off-by: Frantisek Hrbata --- tools/cmakev2/idf.cmake | 1 + tools/cmakev2/project.cmake | 5 ++ tools/cmakev2/size.cmake | 83 +++++++++++++++++++++++++++++++ tools/cmakev2/test/CMakeLists.txt | 10 ++++ 4 files changed, 99 insertions(+) create mode 100644 tools/cmakev2/size.cmake diff --git a/tools/cmakev2/idf.cmake b/tools/cmakev2/idf.cmake index 50b4368e6a..6824a9296c 100644 --- a/tools/cmakev2/idf.cmake +++ b/tools/cmakev2/idf.cmake @@ -36,6 +36,7 @@ include(compat) include(ldgen) include(dfu) include(uf2) +include(size) include(GetGitRevisionDescription) # For backward compatibility, since externalproject_add is used by # project_include.cmake in the bootloader component. The ExternalProject diff --git a/tools/cmakev2/project.cmake b/tools/cmakev2/project.cmake index dcc29f6497..f42712b516 100644 --- a/tools/cmakev2/project.cmake +++ b/tools/cmakev2/project.cmake @@ -765,6 +765,11 @@ function(__project_default) idf_create_uf2("${executable}" TARGET uf2-app APP_ONLY) + + if(TARGET "${executable}_mapfile") + idf_create_size_report("${executable}_mapfile" + TARGET size) + endif() endfunction() #[[api diff --git a/tools/cmakev2/size.cmake b/tools/cmakev2/size.cmake new file mode 100644 index 0000000000..17deff59c3 --- /dev/null +++ b/tools/cmakev2/size.cmake @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +#[[ +.. cmakev2:function:: idf_create_size_report + + .. code-block:: cmake + + idf_create_size_report( + TARGET ) + + *mapfile[in]* + + The mapfile target generated by the idf_build_executable function. + + *TARGET[in]* + + The base name for the size report targets to be created. In addition to + the default size report, which will be available under the target name + specified in the ``TARGET`` option, two more detailed targets, + "-files" and "-components", will also be created. + + Create size report targets for the specified ``mapfile`` target. The + ``TARGET`` option specifies the name of the default size report target, but + two more targets with detailed reports are also created. For example, if + ``TARGET`` is set to "size," three targets "size", "size-files", and + "size-components" will be created. +#]] +function(idf_create_size_report mapfile_target) + set(options) + set(one_value TARGET) + set(multi_value) + cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN}) + + if(NOT DEFINED ARG_TARGET) + idf_die("TARGET option is required") + endif() + + get_target_property(mapfile "${mapfile_target}" MAPFILE_PATH) + if(NOT mapfile) + idf_die("Mapfile target '${mapfile_target}' is missing 'MAPFILE_PATH' property.") + endif() + + idf_build_get_property(idf_path IDF_PATH) + idf_build_get_property(python PYTHON) + + set(idf_size ${python} -m esp_idf_size) + + add_custom_target(${ARG_TARGET} + COMMAND ${CMAKE_COMMAND} + -D "IDF_SIZE_TOOL=${idf_size}" + -D "MAP_FILE=${mapfile}" + -D "OUTPUT_JSON=${OUTPUT_JSON}" + -P "${idf_path}/tools/cmake/run_size_tool.cmake" + DEPENDS ${mapfile_target} + USES_TERMINAL + VERBATIM + ) + + add_custom_target(${ARG_TARGET}-files + COMMAND ${CMAKE_COMMAND} + -D "IDF_SIZE_TOOL=${idf_size}" + -D "IDF_SIZE_MODE=--files" + -D "MAP_FILE=${mapfile}" + -D "OUTPUT_JSON=${OUTPUT_JSON}" + -P "${idf_path}/tools/cmake/run_size_tool.cmake" + DEPENDS ${mapfile_target} + USES_TERMINAL + VERBATIM + ) + + add_custom_target(${ARG_TARGET}-components + COMMAND ${CMAKE_COMMAND} + -D "IDF_SIZE_TOOL=${idf_size}" + -D "IDF_SIZE_MODE=--archives" + -D "MAP_FILE=${mapfile}" + -D "OUTPUT_JSON=${OUTPUT_JSON}" + -P "${idf_path}/tools/cmake/run_size_tool.cmake" + DEPENDS ${mapfile_target} + USES_TERMINAL + VERBATIM + ) +endfunction() diff --git a/tools/cmakev2/test/CMakeLists.txt b/tools/cmakev2/test/CMakeLists.txt index 74608a7ad9..bc0e3fa2e5 100644 --- a/tools/cmakev2/test/CMakeLists.txt +++ b/tools/cmakev2/test/CMakeLists.txt @@ -235,6 +235,11 @@ function(test_executable) idf_create_confserver(fatfs_example TARGET confserver-fatfs) + if(TARGET fatfs_example_mapfile) + idf_create_size_report(fatfs_example_mapfile + TARGET fatfs-size) + endif() + idf_build_executable(hello_world_example COMPONENTS hello_world_example @@ -252,6 +257,11 @@ function(test_executable) OUTPUT_FILE project_description_hello_world.json) idf_create_confserver(hello_world_example TARGET confserver-hello_world) + + if(TARGET hello_world_example_mapfile) + idf_create_size_report(hello_world_example_mapfile + TARGET hello-size) + endif() endfunction() # Run tests