diff --git a/tools/cmakev2/build.cmake b/tools/cmakev2/build.cmake index 36ebd2c3693..11774aad7df 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 ed874af6623..4d1245b2d7c 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 dce1791e61f..74608a7ad95 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)