@ -15,17 +15,52 @@
function ( target_link_dependencies TARGET )
# T h e l i b r a r y w e ' r e l i n k i n g m a y n o t h a v e b e e n d e f i n e d y e t ,
# s o w e r e c o r d i t f o r n o w a n d r e s o l v e i t l a t e r .
set_property ( TARGET ${ TARGET } APPEND PROPERTY LINKED_DEPENDENCIES ${ ARGN } )
# C M a k e < 3 . 1 9 l i m i t s w h i c h p r o p e r t y n a m e s a r e a l l o w e d o n I N T E R F A C E t a r g e t s ,
# s o w e p r e f i x t h e n a m e w i t h " I N T E R F A C E _ " :
# h t t p s : / / c m a k e . o r g / c m a k e / h e l p / v 3 . 1 8 / m a n u a l / c m a k e - b u i l d s y s t e m . 7 . h t m l # i n t e r f a c e - l i b r a r i e s
set_property ( TARGET ${ TARGET } APPEND PROPERTY INTERFACE_LINKED_DEPENDENCIES ${ ARGN } )
set_property ( GLOBAL APPEND PROPERTY TARGETS_WITH_LINKED_DEPENDENCIES "${TARGET}" )
endfunction ( )
# A c t u a l l y r e s o l v e s t h e l i n k e d d e p e n d e n c i e s .
function ( resolve_target_link_dependencies )
# T r a n s i t i v e l y c o l l e c t s d e p e n d e n c i e s i n t o p o l o g i c a l o r d e r u s i n g d e p t h - f i r s t s e a r c h .
function ( _collect_linked_dependencies INITIAL_TARGET )
set ( MODES PUBLIC PRIVATE INTERFACE )
get_property ( TARGETS GLOBAL PROPERTY TARGETS_WITH_LINKED_DEPENDENCIES )
foreach ( TARGET ${ TARGETS } )
list ( APPEND STACK "${INITIAL_TARGET}" )
while ( NOT STACK STREQUAL "" )
list ( POP_BACK STACK TARGET )
if ( ${ TARGET } MATCHES "^\\$" )
set ( FINALIZING ON )
string ( SUBSTRING "${TARGET}" 1 -1 TARGET )
else ( )
set ( FINALIZING OFF )
endif ( )
get_target_property ( LINKED_DEPENDENCIES ${ TARGET } INTERFACE_LINKED_DEPENDENCIES )
if ( LINKED_DEPENDENCIES STREQUAL "LINKED_DEPENDENCIES-NOTFOUND" )
# N o t a ` t a r g e t _ l i n k _ d e p e n d e n c i e s ` t a r g e t , n o t h i n g t o d o .
continue ( )
endif ( )
if ( NOT FINALIZING )
get_target_property ( LINKED_DEPENDENCIES_COLLECTED ${ TARGET } INTERFACE_LINKED_DEPENDENCIES_COLLECTED )
if ( NOT LINKED_DEPENDENCIES_COLLECTED STREQUAL "LINKED_DEPENDENCIES_COLLECTED-NOTFOUND" )
# A l r e a d y p r o c e s s e d .
continue ( )
endif ( )
list ( APPEND STACK "$${TARGET}" )
get_target_property ( LINKED_DEPENDENCIES_COLLECTING ${ TARGET } INTERFACE_LINKED_DEPENDENCIES_COLLECTING )
if ( NOT LINKED_DEPENDENCIES_COLLECTING STREQUAL "LINKED_DEPENDENCIES_COLLECTING-NOTFOUND" )
# A c y c l e .
message ( FATAL_ERROR "Dependency cycle for ${TARGET}: ${STACK}" )
endif ( )
set_property ( TARGET "${TARGET}" PROPERTY INTERFACE_LINKED_DEPENDENCIES_COLLECTING ON )
endif ( )
get_target_property ( TARGET_TYPE ${ TARGET } TYPE )
get_target_property ( LINKED_DEPENDENCIES ${ TARGET } LINKED_DEPENDENCIES )
get_target_property ( LINKED_DEPENDENCIES ${ TARGET } INTERFACE_ LINKED_DEPENDENCIES)
set ( MODE PUBLIC )
foreach ( ARG ${ LINKED_DEPENDENCIES } )
if ( ARG IN_LIST MODES )
@ -34,6 +69,11 @@ function(resolve_target_link_dependencies)
endif ( )
set ( LIBRARY "${ARG}" )
if ( TARGET ${ LIBRARY } )
if ( NOT FINALIZING )
list ( APPEND STACK ${ LIBRARY } )
continue ( )
endif ( )
# W h e n l i n k i n g t w o O B J E C T l i b r a r i e s t o g e t h e r , r e c o r d t h e i n p u t l i b r a r y o b j e c t s i n
# a c u s t o m t a r g e t p r o p e r t y " L I N K E D _ O B J E C T S " t o g e t h e r w i t h a n y o t h e r e x i s t i n g o n e s
# f r o m t h e i n p u t l i b r a r y ' s L I N K E D _ O B J E C T S p r o p e r t y .
@ -45,16 +85,45 @@ function(resolve_target_link_dependencies)
if ( TARGET_TYPE STREQUAL "INTERFACE_LIBRARY" )
message ( FATAL_ERROR "OBJECT to INTERFACE library linking is not supported." )
endif ( )
# A l l t r a n s i t i v e d e p e n d e n c i e s o f t h i s o b j e c t l i b r a r y :
get_target_property ( LIBRARY_LINKED_OBJECTS ${ LIBRARY } LINKED_OBJECTS )
if ( LIBRARY_LINKED_OBJECTS STREQUAL "LIBRARY_LINKED_OBJECTS-NOTFOUND" )
set ( LIBRARY_LINKED_OBJECTS )
endif ( )
# t a r g e t _ s o u r c e s d e d u p l i c a t e s t h e l i s t b u t w e a l s o d o i t h e r e f o r e a s e o f d e b u g g i n g .
get_target_property ( TARGET_LINKED_OBJECTS ${ TARGET } LINKED_OBJECTS )
if ( TARGET_LINKED_OBJECTS STREQUAL "TARGET_LINKED_OBJECTS-NOTFOUND" )
set ( TARGET_LINKED_OBJECTS )
endif ( )
list ( APPEND TARGET_LINKED_OBJECTS ${ LIBRARY_LINKED_OBJECTS } $< TARGET_OBJECTS:${LIBRARY} > )
list ( REMOVE_DUPLICATES TARGET_LINKED_OBJECTS )
if ( TARGET_TYPE STREQUAL "OBJECT_LIBRARY" )
set_property ( TARGET ${ TARGET } APPEND PROPERTY LINKED_OBJECTS $< TARGET_OBJECTS:${LIBRARY} > )
elseif ( NOT LIBRARY_LINKED_OBJECTS STREQUAL "LIBRARY_LINKED_OBJECTS-NOTFOUND" )
target_sources ( ${ TARGET } PRIVATE ${ LIBRARY_LINKED_OBJECTS } )
set_property ( TARGET ${ TARGET } PROPERTY LINKED_OBJECTS "${TARGET_LINKED_OBJECTS}" )
else ( )
target_sources ( ${ TARGET } PRIVATE ${ TARGET _LINKED_OBJECTS} )
endif ( )
endif ( )
endif ( )
target_link_libraries ( ${ TARGET } ${ MODE } "${LIBRARY}" )
if ( FINALIZING )
target_link_libraries ( ${ TARGET } ${ MODE } "${LIBRARY}" )
endif ( )
endforeach ( )
if ( FINALIZING )
set_property ( TARGET "${TARGET}" PROPERTY INTERFACE_LINKED_DEPENDENCIES_COLLECTED ON )
endif ( )
endwhile ( )
endfunction ( )
# A c t u a l l y r e s o l v e s t h e l i n k e d d e p e n d e n c i e s .
function ( resolve_target_link_dependencies )
set ( MODES PUBLIC PRIVATE INTERFACE )
get_property ( TARGETS GLOBAL PROPERTY TARGETS_WITH_LINKED_DEPENDENCIES )
foreach ( TARGET ${ TARGETS } )
_collect_linked_dependencies ( "${TARGET}" "" )
endforeach ( )
set_property ( GLOBAL PROPERTY TARGETS_WITH_LINKED_DEPENDENCIES )
endfunction ( )