mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-07 22:59:56 -05:00
GenEx: Evaluate LINK_LIBRARIES target properties transitively
The `LINK_LIBRARIES` and `INTERFACE_LINK_LIBRARIES` target properties establish the graph of link dependencies used to propagate usage requirements transitively. Therefore the `$<TARGET_PROPERTY:...>` generator expression should evaluate them transitively as it does for other transitive properties. Add policy CMP0189 for compatibility. Fixes: #26709 Issue: #12435
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
cmake_policy(SET CMP0189 NEW)
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt")
|
||||
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
|
||||
${in_LINK_LIBRARIES}
|
||||
")
|
||||
add_custom_target(check-CMP0189-NEW ALL VERBATIM
|
||||
COMMAND ${CMAKE_COMMAND} -Dconfig=$<CONFIG> -Dout=${out} -P${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
|
||||
COMMAND check-args
|
||||
"$<TARGET_PROPERTY:iface1,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface1,INTERFACE_LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface2,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface2,INTERFACE_LINK_LIBRARIES>" "iface1"
|
||||
"$<TARGET_PROPERTY:static1,LINK_LIBRARIES>" "iface2;iface1"
|
||||
"$<TARGET_PROPERTY:static1,INTERFACE_LINK_LIBRARIES>" "iface2;iface1"
|
||||
"$<TARGET_PROPERTY:CustomTransitiveProperties,LINK_LIBRARIES>" "static1;object1;iface2;iface1;iface2"
|
||||
"$<TARGET_PROPERTY:CustomTransitiveProperties,INTERFACE_LINK_LIBRARIES>" ""
|
||||
COMMAND check-args
|
||||
"$<TARGET_PROPERTY:iface10,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface10,INTERFACE_LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface11,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface11,INTERFACE_LINK_LIBRARIES>" "iface10"
|
||||
"$<TARGET_PROPERTY:static10,LINK_LIBRARIES>" "iface11;iface10"
|
||||
# _/ \__
|
||||
# / \
|
||||
# "static10[iface11];iface11[iface10]"
|
||||
"$<TARGET_PROPERTY:static10,INTERFACE_LINK_LIBRARIES>" "iface11;iface10"
|
||||
"$<TARGET_PROPERTY:static11,LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
|
||||
# __/ __/ \__ \__________
|
||||
# / / \ \
|
||||
# "static11[static10;iface11];static10[iface11;iface11[iface10]]"
|
||||
"$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>" "static10;iface11;iface11;iface10"
|
||||
"$<TARGET_PROPERTY:main10,LINK_LIBRARIES>" "static11;static10;static10;iface11;iface11;iface10"
|
||||
# _______/ _______/ | | \______ \______________
|
||||
# / / | | \ \
|
||||
# "main10[static11;static10];static11[static10;iface11;static10[iface11;iface11[iface10]]]"
|
||||
"$<TARGET_PROPERTY:main10,INTERFACE_LINK_LIBRARIES>" ""
|
||||
COMMAND check-args
|
||||
"$<TARGET_PROPERTY:iface20,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface20,INTERFACE_LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface21,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface21,INTERFACE_LINK_LIBRARIES>" "iface20"
|
||||
"$<TARGET_PROPERTY:static20,LINK_LIBRARIES>" "iface21;iface20"
|
||||
# _/ \__
|
||||
# / \
|
||||
# "static20[iface21];iface21[iface20]"
|
||||
"$<TARGET_PROPERTY:static20,INTERFACE_LINK_LIBRARIES>" "iface21;iface20"
|
||||
"$<TARGET_PROPERTY:static21,LINK_LIBRARIES>" "static20;iface21;iface21;iface20"
|
||||
# __/ __/ \__ \__________
|
||||
# / / \ \
|
||||
# "static21[static20;iface21];static20[iface21;iface21[iface20]]"
|
||||
"$<TARGET_PROPERTY:static21,INTERFACE_LINK_LIBRARIES>" "static20;iface21;iface21;iface20"
|
||||
"$<TARGET_PROPERTY:main20,LINK_LIBRARIES>" "static21;static20;static20;iface21;iface21;iface20"
|
||||
# _______/ _______/ | | \______ \______________
|
||||
# / / | | \ \
|
||||
# "main20[static21;static20];static21[static20;iface21;static20[iface21;iface21[iface20]]]"
|
||||
"$<TARGET_PROPERTY:main20,INTERFACE_LINK_LIBRARIES>" ""
|
||||
)
|
||||
@@ -0,0 +1,32 @@
|
||||
set(expect [[
|
||||
# file\(GENERATE\) produced:
|
||||
iface1 LINK_LIBRARIES: ''
|
||||
iface1 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface2 LINK_LIBRARIES: ''
|
||||
iface2 INTERFACE_LINK_LIBRARIES: 'iface1'
|
||||
static1 LINK_LIBRARIES: 'iface2;iface1'
|
||||
static1 INTERFACE_LINK_LIBRARIES: 'iface2;iface1'
|
||||
main LINK_LIBRARIES: 'static1;object1;iface2;iface1;iface2'
|
||||
main INTERFACE_LINK_LIBRARIES: ''
|
||||
iface10 LINK_LIBRARIES: ''
|
||||
iface10 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface11 LINK_LIBRARIES: ''
|
||||
iface11 INTERFACE_LINK_LIBRARIES: 'iface10'
|
||||
static10 LINK_LIBRARIES: 'iface11;iface10'
|
||||
static10 INTERFACE_LINK_LIBRARIES: 'iface11;iface10'
|
||||
static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10'
|
||||
main10 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface20 LINK_LIBRARIES: ''
|
||||
iface20 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface21 LINK_LIBRARIES: ''
|
||||
iface21 INTERFACE_LINK_LIBRARIES: 'iface20'
|
||||
static20 LINK_LIBRARIES: 'iface21;iface20'
|
||||
static20 INTERFACE_LINK_LIBRARIES: 'iface21;iface20'
|
||||
static21 LINK_LIBRARIES: 'static20;iface21;iface21;iface20'
|
||||
static21 INTERFACE_LINK_LIBRARIES: 'static20;iface21;iface21;iface20'
|
||||
main20 LINK_LIBRARIES: 'static21;static20;static20;iface21;iface21;iface20'
|
||||
main20 INTERFACE_LINK_LIBRARIES: ''
|
||||
]])
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../check-common.cmake)
|
||||
@@ -102,6 +102,17 @@ target_link_libraries(static11 PRIVATE static10 iface11)
|
||||
add_executable(main10 main10.c)
|
||||
target_link_libraries(main10 PRIVATE static11 static10)
|
||||
|
||||
# Test CMP0189 OLD and NEW behavior.
|
||||
add_library(iface20 INTERFACE)
|
||||
add_library(iface21 INTERFACE)
|
||||
target_link_libraries(iface21 INTERFACE iface20)
|
||||
add_library(static20 STATIC static20.c)
|
||||
target_link_libraries(static20 PRIVATE iface21)
|
||||
add_library(static21 STATIC static21.c)
|
||||
target_link_libraries(static21 PRIVATE static20 iface21)
|
||||
add_executable(main20 main20.c)
|
||||
target_link_libraries(main20 PRIVATE static21 static20)
|
||||
|
||||
# Test TRANSITIVE_*_PROPERTY evaluation outside of usage requirements.
|
||||
add_executable(check-args check-args.c)
|
||||
set(out "${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt")
|
||||
@@ -158,6 +169,16 @@ static11 LINK_LIBRARIES: '$<TARGET_PROPERTY:static11,LINK_LIBRARIES>'
|
||||
static11 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static11,INTERFACE_LINK_LIBRARIES>'
|
||||
main10 LINK_LIBRARIES: '$<TARGET_PROPERTY:main10,LINK_LIBRARIES>'
|
||||
main10 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:main10,INTERFACE_LINK_LIBRARIES>'
|
||||
iface20 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface20,LINK_LIBRARIES>'
|
||||
iface20 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface20,INTERFACE_LINK_LIBRARIES>'
|
||||
iface21 LINK_LIBRARIES: '$<TARGET_PROPERTY:iface21,LINK_LIBRARIES>'
|
||||
iface21 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:iface21,INTERFACE_LINK_LIBRARIES>'
|
||||
static20 LINK_LIBRARIES: '$<TARGET_PROPERTY:static20,LINK_LIBRARIES>'
|
||||
static20 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static20,INTERFACE_LINK_LIBRARIES>'
|
||||
static21 LINK_LIBRARIES: '$<TARGET_PROPERTY:static21,LINK_LIBRARIES>'
|
||||
static21 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:static21,INTERFACE_LINK_LIBRARIES>'
|
||||
main20 LINK_LIBRARIES: '$<TARGET_PROPERTY:main20,LINK_LIBRARIES>'
|
||||
main20 INTERFACE_LINK_LIBRARIES: '$<TARGET_PROPERTY:main20,INTERFACE_LINK_LIBRARIES>'
|
||||
]====])
|
||||
file(GENERATE OUTPUT "${out}" CONTENT "# file(GENERATE) produced:
|
||||
${in_CUSTOM}
|
||||
@@ -210,4 +231,17 @@ add_custom_target(check ALL VERBATIM
|
||||
# / / | | \ \
|
||||
# "main10[static11;static10];static11[static10;iface11;static10[iface11;iface11[iface10]]]"
|
||||
"$<TARGET_PROPERTY:main10,INTERFACE_LINK_LIBRARIES>" ""
|
||||
COMMAND check-args
|
||||
"$<TARGET_PROPERTY:iface20,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface20,INTERFACE_LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface21,LINK_LIBRARIES>" ""
|
||||
"$<TARGET_PROPERTY:iface21,INTERFACE_LINK_LIBRARIES>" "iface20"
|
||||
"$<TARGET_PROPERTY:static20,LINK_LIBRARIES>" "iface21"
|
||||
"$<TARGET_PROPERTY:static20,INTERFACE_LINK_LIBRARIES>" "$<LINK_ONLY:iface21$<ANGLE-R>"
|
||||
"$<TARGET_PROPERTY:static21,LINK_LIBRARIES>" "static20;iface21"
|
||||
"$<TARGET_PROPERTY:static21,INTERFACE_LINK_LIBRARIES>" "$<LINK_ONLY:static20$<ANGLE-R>;$<LINK_ONLY:iface21$<ANGLE-R>"
|
||||
"$<TARGET_PROPERTY:main20,LINK_LIBRARIES>" "static21;static20"
|
||||
"$<TARGET_PROPERTY:main20,INTERFACE_LINK_LIBRARIES>" ""
|
||||
)
|
||||
|
||||
add_subdirectory(CMP0189)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
|
||||
string(REGEX REPLACE "\n+$" "" expect "${expect}")
|
||||
|
||||
file(READ "${out}" actual)
|
||||
string(REGEX REPLACE "\r\n" "\n" actual "${actual}")
|
||||
string(REGEX REPLACE "\n+$" "" actual "${actual}")
|
||||
|
||||
if(NOT actual MATCHES "^${expect}$")
|
||||
string(REPLACE "\n" "\n expect> " expect " expect> ${expect}")
|
||||
string(REPLACE "\n" "\n actual> " actual " actual> ${actual}")
|
||||
message(FATAL_ERROR "Expected file(GENERATE) output:\n${expect}\ndoes not match actual output:\n${actual}")
|
||||
endif()
|
||||
@@ -51,16 +51,15 @@ static11 LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
static11 INTERFACE_LINK_LIBRARIES: 'static10;iface11;iface11;iface10'
|
||||
main10 LINK_LIBRARIES: 'static11;static10;static10;iface11;iface11;iface10'
|
||||
main10 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface20 LINK_LIBRARIES: ''
|
||||
iface20 INTERFACE_LINK_LIBRARIES: ''
|
||||
iface21 LINK_LIBRARIES: ''
|
||||
iface21 INTERFACE_LINK_LIBRARIES: 'iface20'
|
||||
static20 LINK_LIBRARIES: 'iface21'
|
||||
static20 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:iface21>'
|
||||
static21 LINK_LIBRARIES: 'static20;iface21'
|
||||
static21 INTERFACE_LINK_LIBRARIES: '\$<LINK_ONLY:static20>;\$<LINK_ONLY:iface21>'
|
||||
main20 LINK_LIBRARIES: 'static21;static20'
|
||||
main20 INTERFACE_LINK_LIBRARIES: ''
|
||||
]])
|
||||
string(REGEX REPLACE "\r\n" "\n" expect "${expect}")
|
||||
string(REGEX REPLACE "\n+$" "" expect "${expect}")
|
||||
|
||||
file(READ "${out}" actual)
|
||||
string(REGEX REPLACE "\r\n" "\n" actual "${actual}")
|
||||
string(REGEX REPLACE "\n+$" "" actual "${actual}")
|
||||
|
||||
if(NOT actual MATCHES "^${expect}$")
|
||||
string(REPLACE "\n" "\n expect> " expect " expect> ${expect}")
|
||||
string(REPLACE "\n" "\n actual> " actual " actual> ${actual}")
|
||||
message(FATAL_ERROR "Expected file(GENERATE) output:\n${expect}\ndoes not match actual output:\n${actual}")
|
||||
endif()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
extern int static20(void);
|
||||
extern int static21(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return static20() + static21();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
int static20(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
int static21(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user