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)
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")
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})
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()