cmake: use new signature form of target_link_library to link components

!4452 used setting LINK_LIBRARIES and INTERFACE_LINK_LIBRARIES to link
components built under ESP-IDF build system. However, LINK_LIBRARIES does
not produce behavior same as linking PRIVATE. This MR uses the new
signature for target_link_libraries directly instead. This also moves
setting dependencies during component registration rather than after all
components have been processed.

The consequence is that internally, components have to use the new
signature form as well. This does not affect linking the components to
external targets, such as with idf_as_lib example. This only affects
linking additional libraries to ESP-IDF libraries outside component processing (after
idf_build_process), which is not even possible for CMake<v3.13 as
target_link_libraries is not valid for targets not created in current
directory. See https://cmake.org/cmake/help/v3.13/policy/CMP0079.html#policy:CMP0079
pull/3627/head
Renz Christian Bagaporo 2019-06-04 19:05:33 +08:00
rodzic 6365658d3f
commit 3882e48e8a
21 zmienionych plików z 84 dodań i 103 usunięć

Wyświetl plik

@ -79,30 +79,4 @@ foreach(component_target ${build_component_targets})
add_subdirectory(${dir} ${_name})
endif()
set(__idf_component_context 0)
endforeach()
# Establish dependencies between components
idf_build_get_property(build_components BUILD_COMPONENTS)
foreach(build_component ${build_components})
__component_get_target(component_target ${build_component})
__component_get_property(component_lib ${component_target} COMPONENT_LIB)
__component_get_property(reqs ${component_target} __REQUIRES)
foreach(req ${reqs})
__component_get_property(req_lib ${req} COMPONENT_LIB)
if(TARGET ${req_lib})
set_property(TARGET ${component_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${req_lib})
endif()
endforeach()
get_property(type TARGET ${component_lib} PROPERTY TYPE)
if(type STREQUAL STATIC_LIBRARY)
__component_get_property(reqs ${component_target} __REQUIRES)
__component_get_property(priv_reqs ${component_target} __PRIV_REQUIRES)
foreach(req ${reqs} ${priv_reqs})
__component_get_property(req_lib ${req} COMPONENT_LIB)
if(TARGET ${req_lib})
set_property(TARGET ${component_lib} APPEND PROPERTY LINK_LIBRARIES ${req_lib})
endif()
endforeach()
endif()
endforeach()
endforeach()

Wyświetl plik

@ -31,4 +31,4 @@ register_component()
# disable --coverage for this component, as it is used as transport
# for gcov
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
target_link_libraries(${COMPONENT_LIB} gcov ${LIBC} ${LIBM} gcc)
target_link_libraries(${COMPONENT_LIB} PUBLIC gcov ${LIBC} ${LIBM} gcc)

Wyświetl plik

@ -8,7 +8,7 @@ register_component()
# esp_app_desc structure is added as an undefined symbol because otherwise the
# linker will ignore this structure as it has no other files depending on it.
target_link_libraries(${COMPONENT_LIB} "-u esp_app_desc")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
idf_build_get_property(project_ver PROJECT_VER)

Wyświetl plik

@ -7,4 +7,4 @@ idf_build_get_property(target IDF_TARGET)
set(scripts "${target}.bootloader.ld"
"${target}.bootloader.rom.ld")
target_linker_script(${COMPONENT_LIB} "${scripts}")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")

Wyświetl plik

@ -295,6 +295,6 @@ if(CONFIG_BT_ENABLED)
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable)
endif()
target_link_libraries(${COMPONENT_LIB} "-L${CMAKE_CURRENT_LIST_DIR}/lib")
target_link_libraries(${COMPONENT_LIB} btdm_app)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L${CMAKE_CURRENT_LIST_DIR}/lib")
target_link_libraries(${COMPONENT_LIB} PUBLIC btdm_app)
endif()

Wyświetl plik

@ -2,9 +2,9 @@ set(COMPONENT_SRCS "cxx_exception_stubs.cpp"
"cxx_guards.cpp")
register_component()
target_link_libraries(${COMPONENT_LIB} stdc++ gcc)
target_link_libraries(${COMPONENT_LIB} "-u __cxa_guard_dummy")
target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy")
if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS)
target_link_libraries(${COMPONENT_LIB} "-u __cxx_fatal_exception")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxx_fatal_exception")
endif()

Wyświetl plik

@ -4,7 +4,7 @@ if(BOOTLOADER_BUILD)
# For bootloader, all we need from esp32 is headers
set(COMPONENT_ADD_INCLUDEDIRS include)
register_component()
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.peripherals.ld")
else()
# Regular app build
@ -46,29 +46,29 @@ else()
register_component()
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld")
# Rely on user code to define app_main
target_link_libraries(${COMPONENT_LIB} "-u app_main")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u app_main")
if(CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY)
# This has to be linked before esp32.project.ld
target_linker_script(${COMPONENT_LIB} "ld/esp32.extram.bss.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld")
endif()
# Process the template file through the linker script generation mechanism, and use the output for linking the
# final binary
target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in"
target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in"
PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld")
target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld")
target_link_libraries(${COMPONENT_LIB} gcc)
target_link_libraries(${COMPONENT_LIB} "-u call_user_start_cpu0")
target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.peripherals.ld")
target_link_libraries(${COMPONENT_LIB} PUBLIC gcc)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u call_user_start_cpu0")
#ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the
#linker will ignore panic_highint_hdl.S as it has no other files depending on any
#symbols in it.
target_link_libraries(${COMPONENT_LIB} "-u ld_include_panic_highint_hdl")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u ld_include_panic_highint_hdl")
idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER)
get_filename_component(config_dir ${sdkconfig_header} DIRECTORY)
@ -96,6 +96,6 @@ else()
# To handle some corner cases, the same flag is set in project_include.cmake
target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
# also, make sure we link with this option so correct toolchain libs are pulled in
target_link_libraries(${COMPONENT_LIB} -mfix-esp32-psram-cache-issue)
target_link_libraries(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
endif()
endif()

Wyświetl plik

@ -9,7 +9,7 @@ if(BOOTLOADER_BUILD)
"esp32/ld/esp32.rom.newlib-funcs.ld"
"esp32/ld/esp32.rom.libgcc.ld"
)
target_linker_script(${COMPONENT_LIB} "${scripts}")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")
else()
# Regular app build
set(COMPONENT_SRCS "esp_rom.c")
@ -23,21 +23,21 @@ else()
"esp32/ld/esp32.rom.syscalls.ld"
"esp32/ld/esp32.rom.newlib-data.ld"
)
target_linker_script(${COMPONENT_LIB} "${scripts}")
target_linker_script(${COMPONENT_LIB} INTERFACE "${scripts}")
if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND)
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "esp32/ld/esp32.rom.newlib-funcs.ld")
endif()
if(CONFIG_NEWLIB_NANO_FORMAT)
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-nano.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "esp32/ld/esp32.rom.newlib-nano.ld")
endif()
if(NOT GCC_NOT_5_2_0)
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-locale.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "esp32/ld/esp32.rom.newlib-locale.ld")
endif()
if(NOT CONFIG_SPI_FLASH_ROM_DRIVER_PATCH)
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.spiflash.ld")
target_linker_script(${COMPONENT_LIB} INTERFACE "esp32/ld/esp32.rom.spiflash.ld")
endif()
endif()

Wyświetl plik

@ -16,14 +16,14 @@ if(NOT CONFIG_ESP32_NO_BLOBS)
endif()
register_component()
target_link_libraries(${COMPONENT_LIB} "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}")
target_link_libraries(${COMPONENT_LIB} PUBLIC "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}")
if(NOT CONFIG_ESP32_NO_BLOBS)
set(blobs coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps)
foreach(blob ${blobs})
add_library(${blob} STATIC IMPORTED)
set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a)
target_link_libraries(${COMPONENT_LIB} ${blob})
target_link_libraries(${COMPONENT_LIB} PUBLIC ${blob})
foreach(_blob ${blobs})
if(NOT _blob STREQUAL ${blob})

Wyświetl plik

@ -25,7 +25,7 @@ set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
register_component()
target_link_libraries(${COMPONENT_LIB} "-Wl,--undefined=uxTopUsedPriority")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--undefined=uxTopUsedPriority")
set_source_files_properties(
tasks.c

Wyświetl plik

@ -32,7 +32,7 @@ if(CONFIG_HEAP_TRACING)
heap_caps_realloc_default)
foreach(wrap ${WRAP_FUNCTIONS})
target_link_libraries(${COMPONENT_LIB} "-Wl,--wrap=${wrap}")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
endforeach()
endif()

Wyświetl plik

@ -94,4 +94,4 @@ foreach(target ${mbedtls_targets})
endforeach()
# Link mbedtls libraries to component library
target_link_libraries(${COMPONENT_LIB} ${mbedtls_targets})
target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets})

Wyświetl plik

@ -42,8 +42,8 @@ list(APPEND COMPONENT_ADD_LDFRAGMENTS newlib.lf)
register_component()
if (LIB_PATH)
target_link_libraries(${COMPONENT_LIB} "-L ${LIB_PATH}")
if(LIB_PATH)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-L ${LIB_PATH}")
endif()
if(GCC_NOT_5_2_0)
@ -51,13 +51,13 @@ if(GCC_NOT_5_2_0)
add_library(extra INTERFACE)
idf_component_get_property(newlib newlib COMPONENT_LIB)
target_link_libraries(extra INTERFACE ${LIBC} ${LIBM} gcc "$<TARGET_FILE:${newlib}>")
target_link_libraries(${COMPONENT_LIB} extra)
target_link_libraries(${COMPONENT_LIB} PUBLIC extra)
else()
target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM} gcc)
target_link_libraries(${COMPONENT_LIB} PUBLIC ${LIBC} ${LIBM} gcc)
endif()
set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin)
if(EXTRA_LINK_FLAGS)
target_link_libraries(${COMPONENT_LIB} "${EXTRA_LINK_FLAGS}")
target_link_libraries(${COMPONENT_LIB} INTERFACE "${EXTRA_LINK_FLAGS}")
endif()

Wyświetl plik

@ -61,7 +61,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
add_dependencies(${COMPONENT_LIB} ${app_name}_artifacts)
target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld)
target_linker_script(${COMPONENT_LIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld)
target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.bin BINARY)
endif()
endfunction()

Wyświetl plik

@ -6,4 +6,4 @@ register_component()
# Some newlib syscalls are implemented in vfs.c, make sure these are always
# seen by the linker
target_link_libraries(${COMPONENT_LIB} "-u vfs_include_syscalls_impl")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u vfs_include_syscalls_impl")

Wyświetl plik

@ -7,4 +7,4 @@ set(COMPONENT_PRIV_REQUIRES soc)
register_component()
target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a")
target_link_libraries(${COMPONENT_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a")

Wyświetl plik

@ -23,4 +23,4 @@ endfunction()
add_subdirectory(lib/tinyxml2)
# Link tinyxml2 to main component
target_link_libraries(${COMPONENT_LIB} tinyxml2)
target_link_libraries(${COMPONENT_LIB} PUBLIC tinyxml2)

Wyświetl plik

@ -436,29 +436,8 @@ endmacro()
# generating additional binary files, generating files related to flashing, etc.)
function(idf_build_executable elf)
# Propagate link dependencies from component library targets to the executable
idf_build_get_property(build_components BUILD_COMPONENTS)
foreach(build_component ${build_components})
get_target_property(type ${build_component} TYPE)
if(type STREQUAL "INTERFACE_LIBRARY")
get_target_property(iface_link_depends ${build_component} INTERFACE_LINK_DEPENDS)
else()
get_target_property(link_depends ${build_component} LINK_DEPENDS)
get_target_property(iface_link_depends ${build_component} INTERFACE_LINK_DEPENDS)
endif()
if(iface_link_depends)
list(APPEND _link_depends ${iface_link_depends})
endif()
if(link_depends)
list(APPEND _link_depends ${link_depends})
endif()
endforeach()
idf_build_get_property(link_depends LINK_DEPENDS)
if(link_depends)
list(APPEND _link_depends ${link_depends})
endif()
set_property(TARGET ${elf} APPEND PROPERTY LINK_DEPENDS "${_link_depends}")
idf_build_get_property(link_depends __LINK_DEPENDS)
set_property(TARGET ${elf} APPEND PROPERTY LINK_DEPENDS "${link_depends}")
# Set the EXECUTABLE_NAME and EXECUTABLE properties since there are generator expression
# from components that depend on it

Wyświetl plik

@ -288,6 +288,39 @@ macro(__component_check_target)
endif()
endmacro()
# __component_set_dependencies, __component_set_all_dependencies
#
# Links public and private requirements for the currently processed component
macro(__component_set_dependencies reqs type)
foreach(req ${reqs})
if(req IN_LIST build_component_targets)
__component_get_property(req_lib ${req} COMPONENT_LIB)
target_link_libraries(${component_lib} ${type} ${req_lib})
endif()
endforeach()
endmacro()
macro(__component_set_all_dependencies)
__component_get_property(type ${component_target} COMPONENT_TYPE)
idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS)
if(NOT type STREQUAL CONFIG_ONLY)
__component_get_property(reqs ${component_target} __REQUIRES)
__component_set_dependencies("${reqs}" PUBLIC)
__component_get_property(priv_reqs ${component_target} __PRIV_REQUIRES)
__component_set_dependencies("${priv_reqs}" PRIVATE)
else()
__component_get_property(reqs ${component_target} __REQUIRES)
foreach(req ${reqs})
if(req IN_LIST build_component_targets)
__component_get_property(req_lib ${req} COMPONENT_LIB)
target_link_libraries(${component_lib} INTERFACE ${req_lib})
endif()
endforeach()
endif()
endmacro()
# idf_component_get_property
#
# @brief Retrieve the value of the specified component property
@ -331,6 +364,7 @@ function(idf_component_set_property component property val)
endif()
endfunction()
# idf_component_register
#
# @brief Register a component to the build, creating component library targets etc.
@ -431,6 +465,9 @@ function(idf_component_register)
__ldgen_add_fragment_files("${__LDFRAGMENTS}")
endif()
# Set dependencies
__component_set_all_dependencies()
# Add the component to built components
idf_build_set_property(__BUILD_COMPONENTS ${component_lib} APPEND)
idf_build_set_property(BUILD_COMPONENTS ${component_alias} APPEND)

Wyświetl plik

@ -75,5 +75,5 @@ function(__ldgen_process_template template output)
get_filename_component(_name ${output} NAME)
add_custom_target(__ldgen_output_${_name} DEPENDS ${output})
add_dependencies(__idf_build_target __ldgen_output_${_name})
idf_build_set_property(LINK_DEPENDS ${output} APPEND)
idf_build_set_property(__LINK_DEPENDS ${output} APPEND)
endfunction()

Wyświetl plik

@ -130,7 +130,7 @@ endfunction()
# 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 scriptfiles)
function(target_linker_script target deptype scriptfiles)
cmake_parse_arguments(_ "" "PROCESS" "" ${ARGN})
foreach(scriptfile ${scriptfiles})
get_filename_component(abs_script "${scriptfile}" ABSOLUTE)
@ -145,12 +145,7 @@ function(target_linker_script target scriptfiles)
get_filename_component(search_dir "${abs_script}" DIRECTORY)
get_filename_component(scriptname "${abs_script}" NAME)
get_target_property(type ${target} TYPE)
if(type STREQUAL "INTERFACE_LIBRARY")
set(is_interface "INTERFACE")
endif()
if(is_interface)
if(deptype STREQUAL INTERFACE OR deptype STREQUAL PUBLIC)
get_target_property(link_libraries "${target}" INTERFACE_LINK_LIBRARIES)
else()
get_target_property(link_libraries "${target}" LINK_LIBRARIES)
@ -158,10 +153,10 @@ function(target_linker_script target scriptfiles)
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}" "${is_interface}" "-L ${search_dir}")
target_link_libraries("${target}" "${deptype}" "-L ${search_dir}")
endif()
target_link_libraries("${target}" "${is_interface}" "-T ${scriptname}")
target_link_libraries("${target}" "${deptype}" "-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. Attach manually to executable once it is known.
@ -169,11 +164,7 @@ function(target_linker_script target scriptfiles)
# Property INTERFACE_LINK_DEPENDS is available in CMake 3.13 which should propagate link
# dependencies.
if(NOT __PROCESS)
if(is_interface)
set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LINK_DEPENDS ${abs_script})
else()
set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS ${abs_script})
endif()
idf_build_set_property(__LINK_DEPENDS ${abs_script} APPEND)
endif()
endforeach()
endfunction()