From 12be3997623eacb7cc33778e5e1a13c6a898ae87 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 1 Mar 2018 17:02:08 +1100 Subject: [PATCH] cmake: Add link-time dependencies for linker script files Requires some hackery around limitations in CMake's LINK_DEPENDS --- .../bootloader/subproject/CMakeLists.txt | 5 ++-- components/esp32/CMakeLists.txt | 16 ++++++------- tools/cmake/components.cmake | 18 ++++++++++++++ tools/cmake/utilities.cmake | 24 +++++++++++++++++++ 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt index 9d99e6e0c7..5ac887a404 100644 --- a/components/bootloader/subproject/CMakeLists.txt +++ b/components/bootloader/subproject/CMakeLists.txt @@ -14,8 +14,7 @@ set(MAIN_SRCS main/bootloader_start.c) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(bootloader) -target_link_libraries(bootloader.elf "-L ${CMAKE_CURRENT_SOURCE_DIR}/main") -target_link_libraries(bootloader.elf "-T esp32.bootloader.ld") -target_link_libraries(bootloader.elf "-T esp32.bootloader.rom.ld") +target_linker_script(bootloader.elf "main/esp32.bootloader.ld") +target_linker_script(bootloader.elf "main/esp32.bootloader.rom.ld") target_link_libraries(bootloader.elf "${BOOTLOADER_LINKER_ARGS}") target_link_libraries(bootloader.elf gcc) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 77d4fd0b40..1172dda7fb 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -24,24 +24,24 @@ else() if(NOT CONFIG_NO_BLOBS) target_link_libraries(esp32 coexist core espnow net80211 phy pp rtc smartconfig wpa2 wpa wps) endif() - target_link_libraries(esp32 "-L ${CMAKE_CURRENT_SOURCE_DIR}/ld") - target_link_libraries(esp32 "-T ${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld") - target_link_libraries(esp32 "-T esp32.common.ld") - target_link_libraries(esp32 "-T esp32.rom.ld") - target_link_libraries(esp32 "-T esp32.peripherals.ld") + target_linker_script(esp32 "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld") + + target_linker_script(esp32 "ld/esp32.common.ld") + target_linker_script(esp32 "ld/esp32.rom.ld") + target_linker_script(esp32 "ld/esp32.peripherals.ld") if(CONFIG_SPIRAM_CACHE_WORKAROUND) add_compile_options(-mfix-esp32-psram-cache-issue) else() - target_link_libraries(esp32 "-T esp32.rom.spiram_incompatible_fns.ld") + target_linker_script(esp32 "ld/esp32.rom.spiram_incompatible_fns.ld") endif() if(CONFIG_NEWLIB_NANO_FORMAT) - target_link_libraries(esp32 "-T esp32.rom.nanofmt.ld") + target_linker_script(esp32 "ld/esp32.rom.nanofmt.ld") endif() if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH) - target_link_libraries(esp32 "-T esp32.rom.spiflash.ld") + target_linker_script(esp32 "ld/esp32.rom.spiflash.ld") endif() target_link_libraries(esp32 "${CMAKE_CURRENT_SOURCE_DIR}/libhal.a") diff --git a/tools/cmake/components.cmake b/tools/cmake/components.cmake index 8c65187035..4334ffee7d 100644 --- a/tools/cmake/components.cmake +++ b/tools/cmake/components.cmake @@ -161,6 +161,24 @@ function(components_finish_registration) endif() endforeach() + # Add each component library's link-time dependencies (which are otherwise ignored) to the executable + # LINK_DEPENDS in order to trigger a re-link when needed (on Ninja/Makefile generators at least). + # (maybe this should probably be something CMake does, but it doesn't do it...) + foreach(component ${COMPONENTS}) + if(TARGET ${component}) + get_target_property(imported ${component} IMPORTED) + get_target_property(type ${component} TYPE) + if(NOT imported) + if(${type} STREQUAL STATIC_LIBRARY OR ${type} STREQUAL EXECUTABLE) + get_target_property(link_depends "${component}" LINK_DEPENDS) + if(link_depends) + set_property(TARGET ${CMAKE_PROJECT_NAME}.elf APPEND PROPERTY LINK_DEPENDS "${link_depends}") + endif() + endif() + endif() + endif() + endforeach() + # Embedded binary & text files spaces2list(COMPONENT_EMBED_FILES) foreach(embed_src ${COMPONENT_EMBED_FILES}) diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 0415e64978..ec6323d90f 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -145,3 +145,27 @@ function(file_append_line file line) endif() file(APPEND "${file}" "${line}${line_ending}") endfunction() + +# Add a linker script to the target, including a link-time dependency +# +# Automatically adds a -L search path for the containing directory (if found), +# and then adds -T with the filename only. This allows INCLUDE directives to be +# used to include other linker scripts in the same directory. +function(target_linker_script target scriptfile) + get_filename_component(abs_script "${scriptfile}" ABSOLUTE) + + get_filename_component(search_dir "${abs_script}" DIRECTORY) + get_filename_component(scriptname "${abs_script}" NAME) + + get_target_property(link_libraries "${target}" LINK_LIBRARIES) + list(FIND "${link_libraries}" "-L ${search_dir}" found_search_dir) + if(found_search_dir EQUAL "-1") # not already added as a search path + target_link_libraries("${target}" "-L ${search_dir}") + endif() + + target_link_libraries("${target}" "-T ${scriptname}") + + # Note: In ESP-IDF, most targets are libraries and libary LINK_DEPENDS don't propagate to + # executable(s) the library is linked to. This is done manually in components.cmake. + set_property(TARGET "${target}" APPEND PROPERTY LINK_DEPENDS "${abs_script}") +endfunction() -- 2.40.0