CMake: Add 'collect_targets' mode to __qt_internal_walk_libs
Allow collecting all public dependency CMake targets starting from a given initial target. The new mode walks INTERFACE_LINK_LIBRARIES of a shared library or executable target, as well as the INTERFACE_LINK_LIBRARIES and LINK_LIBRARIES of a static library target. Each encountered target (checked with if(TARGET)) is added the output list. Note that the private dependencies of a non-static target (like a shared library or executable) are not walked by the new mode. Introduce a new function called __qt_internal_collect_all_target_dependencies which uses the new mode to collect the full private dependency list of a target. The final list only contains targets, so no linker flags or file paths. This list is useful to do further processing on the targets like extracting properties from them and running finalizers. Task-number: QTBUG-92933 Change-Id: I5d96cfa05722d65e2248a344a4f2b0f98a992817 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
471ff20f33
commit
8fc3fcf425
@ -56,15 +56,25 @@ function(__qt_internal_memoize_values_in_dict target dict_name dict_key values)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Walks a target's link libraries recursively, and performs some actions (poor man's polypmorphism)
|
||||
# Walks a target's public link libraries recursively, and performs some actions (poor man's
|
||||
# polypmorphism)
|
||||
#
|
||||
# Walks INTERFACE_LINK_LIBRARIES for all target types, as well as LINK_LIBRARIES for static
|
||||
# library targets.
|
||||
#
|
||||
# out_var: the name of the variable where the result will be assigned. The result is a list of
|
||||
# libraries, mostly in generator expression form.
|
||||
# rcc_objects_out_var: the name of the variable where the collected rcc object files will be
|
||||
# assigned (for the initial target and its dependencies)
|
||||
# dict_name: used for caching the results, and preventing the same target from being processed
|
||||
# twice
|
||||
# operation: a string to tell the function what additional behaviors to execute.
|
||||
# 'collect_libs' (default) operation is to collect linker file paths and flags.
|
||||
# Used for prl file generation.
|
||||
# 'promote_global' promotes walked imported targets to global scope.
|
||||
# 'collect_targets' collects all target names (discards framework or link flags)
|
||||
#
|
||||
#
|
||||
# out_var is the name of the variable where the result will be assigned. The result is a list of
|
||||
# libraries, mostly in generator expression form.
|
||||
# rcc_objects_out_var is the name of the variable where the collected rcc object files will be
|
||||
# assigned (for the initial target and its dependencies)
|
||||
# dict_name is used for caching the results, and preventing the same target from being processed
|
||||
# twice
|
||||
# operation is a string to tell the function what additional behaviors to execute.
|
||||
function(__qt_internal_walk_libs
|
||||
target out_var rcc_objects_out_var dict_name operation)
|
||||
set(collected ${ARGN})
|
||||
@ -179,7 +189,12 @@ function(__qt_internal_walk_libs
|
||||
__qt_internal_merge_libs(rcc_objects ${lib_rcc_objects_${target}})
|
||||
endif()
|
||||
elseif(NOT lib_target_type STREQUAL "OBJECT_LIBRARY")
|
||||
__qt_internal_merge_libs(libs "$<TARGET_LINKER_FILE:${lib_target}>")
|
||||
|
||||
if(operation STREQUAL "collect_targets")
|
||||
__qt_internal_merge_libs(libs ${lib_target})
|
||||
else()
|
||||
__qt_internal_merge_libs(libs "$<TARGET_LINKER_FILE:${lib_target}>")
|
||||
endif()
|
||||
|
||||
get_target_property(target_rcc_objects "${lib_target}" _qt_rcc_objects)
|
||||
if(target_rcc_objects)
|
||||
@ -220,11 +235,13 @@ function(__qt_internal_walk_libs
|
||||
message(FATAL_ERROR "The ${CMAKE_MATCH_1} target is mentioned as a dependency for \
|
||||
${target}, but not declared.")
|
||||
else()
|
||||
set(final_lib_name_to_merge "${lib_target}")
|
||||
if(lib_target MATCHES "/([^/]+).framework$")
|
||||
set(final_lib_name_to_merge "-framework ${CMAKE_MATCH_1}")
|
||||
if(NOT operation STREQUAL "collect_targets")
|
||||
set(final_lib_name_to_merge "${lib_target}")
|
||||
if(lib_target MATCHES "/([^/]+).framework$")
|
||||
set(final_lib_name_to_merge "-framework ${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
__qt_internal_merge_libs(libs "${final_lib_name_to_merge}")
|
||||
endif()
|
||||
__qt_internal_merge_libs(libs "${final_lib_name_to_merge}")
|
||||
endif()
|
||||
endforeach()
|
||||
__qt_internal_memoize_values_in_dict("${target}" "${dict_name}" "libs" "${libs}")
|
||||
@ -235,3 +252,42 @@ ${target}, but not declared.")
|
||||
set(${out_var} ${libs} PARENT_SCOPE)
|
||||
set(${rcc_objects_out_var} ${rcc_objects} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Given ${target}, collect all its private dependencies that are CMake targets.
|
||||
#
|
||||
# Discards non-CMake-target dependencies like linker flags or file paths.
|
||||
# Does nothing when given an interface library.
|
||||
#
|
||||
# To be used to extract the full list of target dependencies of a library or executable.
|
||||
function(__qt_internal_collect_all_target_dependencies target out_var)
|
||||
set(dep_targets "")
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
|
||||
if(NOT target_type STREQUAL "INTERFACE_LIBRARY")
|
||||
get_target_property(link_libs ${target} LINK_LIBRARIES)
|
||||
if(link_libs)
|
||||
foreach(lib ${link_libs})
|
||||
if(TARGET "${lib}")
|
||||
list(APPEND dep_targets "${lib}")
|
||||
|
||||
__qt_internal_walk_libs(
|
||||
"${lib}"
|
||||
lib_walked_targets
|
||||
_discarded_out_var
|
||||
"qt_private_link_library_targets"
|
||||
"collect_targets")
|
||||
|
||||
if(lib_walked_targets)
|
||||
list(APPEND dep_targets ${lib_walked_targets})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES dep_targets)
|
||||
|
||||
set(${out_var} "${dep_targets}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
Loading…
Reference in New Issue
Block a user