CMake: Simplify target_link_libraries "object" linking shim

This uses generator expressions instead, so that it's no longer
dependent on all linked component libraries existing first.
This commit is contained in:
Sam Edwards 2018-10-10 20:14:47 -06:00
parent e89621b88d
commit a0d9a931e0

View File

@ -34,31 +34,35 @@ function(target_link_libraries target)
set(compile_definitions "$<TARGET_PROPERTY:${library},INTERFACE_COMPILE_DEFINITIONS>") set(compile_definitions "$<TARGET_PROPERTY:${library},INTERFACE_COMPILE_DEFINITIONS>")
set_property(TARGET "${target}" APPEND PROPERTY COMPILE_DEFINITIONS "${compile_definitions}") set_property(TARGET "${target}" APPEND PROPERTY COMPILE_DEFINITIONS "${compile_definitions}")
# Libraries are only linked transitively if they aren't components. # Build up some generator expressions for determining whether `library`
# Unfortunately, it seems like INTERFACE_LINK_LIBRARIES can't have # is a component library or not.
# generator expressions on an object library(?) so we resort to taking if(library MATCHES ".*::.*")
# care of this at configuration time. # "::" messes up CMake's genex parser; fortunately, a library whose
if(TARGET "${library}") # name contains that is either an interface library or alias, and
get_target_property(target_type "${library}" TYPE) # definitely not a component
if(NOT target_type STREQUAL "INTERFACE_LIBRARY") set(is_component 0)
get_target_property(is_component "${library}" IS_COMPONENT) set(name_of_component "")
else() set(name_of_non_component "${library}")
set(is_component OFF)
endif()
else() else()
# This is a safe assumption, since we define all component libraries set(is_component "$<TARGET_PROPERTY:${library},IS_COMPONENT>")
# before the metalib they appear in:
set(is_component OFF) # CMake complains if we lookup IS_COMPONENT on an INTERFACE library :(
set(is_object "$<STREQUAL:$<TARGET_PROPERTY:${library},TYPE>,OBJECT_LIBRARY>")
set(is_component "$<BOOL:$<${is_object}:${is_component}>>")
set(name_of_component "$<${is_component}:${library}>")
set(name_of_non_component "$<$<NOT:${is_component}>:${library}>")
endif() endif()
if(is_component) # Libraries are only linked transitively if they aren't components.
# Also build with the same BUILDING_ macros, because these will all end set_property(TARGET "${target}" APPEND PROPERTY
# up in the same library. INTERFACE_LINK_LIBRARIES "${name_of_non_component}")
set(compile_definitions "$<TARGET_PROPERTY:${library},COMPILE_DEFINITIONS>")
set_property(TARGET "${target}" APPEND PROPERTY COMPILE_DEFINITIONS "${compile_definitions}") # Also build with the same BUILDING_ macros, because these will all end
else() # up in the same library.
set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${library}") set(compile_definitions "$<TARGET_PROPERTY:${library},COMPILE_DEFINITIONS>")
endif() set_property(TARGET "${target}" APPEND PROPERTY
COMPILE_DEFINITIONS "$<${is_component}:${compile_definitions}>")
else() else()
# This is a file path to an out-of-tree library - this needs to be # This is a file path to an out-of-tree library - this needs to be
# recorded so that the metalib can link them. (They aren't needed at # recorded so that the metalib can link them. (They aren't needed at
@ -66,7 +70,8 @@ function(target_link_libraries target)
# transitively.) # transitively.)
set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${library}") set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${library}")
endif() endif()
endforeach()
endforeach(library)
endfunction(target_link_libraries) endfunction(target_link_libraries)