mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
Genex: Fix TARGET_PROPERTY lookup scope in transitive usage requirements
When `$<TARGET_PROPERTY:tgt,prop>` is used in an `INTERFACE_*` target property for usage requirements, it may be evaluated in the context of a dependent target in another directory. Look up the `tgt` name in the directory of the target whose property holds the expression so that imported targets isolated to that directory are visible. Fixes: #24163
This commit is contained in:
@@ -1401,6 +1401,13 @@ In the following, the phrase "the ``tgt`` filename" means the name of the
|
|||||||
Note that ``tgt`` is not added as a dependency of the target this
|
Note that ``tgt`` is not added as a dependency of the target this
|
||||||
expression is evaluated on.
|
expression is evaluated on.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.26
|
||||||
|
When encountered during evaluation of :ref:`Target Usage Requirements`,
|
||||||
|
typically in an ``INTERFACE_*`` target property, lookup of the ``tgt``
|
||||||
|
name occurs in the directory of the target specifying the requirement,
|
||||||
|
rather than the directory of the consuming target for which the
|
||||||
|
expression is being evaluated.
|
||||||
|
|
||||||
.. genex:: $<TARGET_PROPERTY:prop>
|
.. genex:: $<TARGET_PROPERTY:prop>
|
||||||
|
|
||||||
Value of the property ``prop`` on the target for which the expression
|
Value of the property ``prop`` on the target for which the expression
|
||||||
|
|||||||
@@ -1970,7 +1970,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||||||
}
|
}
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
target = context->LG->FindGeneratorTargetToUse(targetName);
|
cmLocalGenerator const* lg = context->CurrentTarget
|
||||||
|
? context->CurrentTarget->GetLocalGenerator()
|
||||||
|
: context->LG;
|
||||||
|
target = lg->FindGeneratorTargetToUse(targetName);
|
||||||
|
|
||||||
if (!target) {
|
if (!target) {
|
||||||
std::ostringstream e;
|
std::ostringstream e;
|
||||||
|
|||||||
@@ -13,3 +13,10 @@ run_cmake(LinkImplementationCycle5)
|
|||||||
run_cmake(LinkImplementationCycle6)
|
run_cmake(LinkImplementationCycle6)
|
||||||
run_cmake(LOCATION)
|
run_cmake(LOCATION)
|
||||||
run_cmake(SOURCES)
|
run_cmake(SOURCES)
|
||||||
|
|
||||||
|
block()
|
||||||
|
run_cmake(Scope)
|
||||||
|
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Scope-build)
|
||||||
|
set(RunCMake_TEST_NO_CLEAN 1)
|
||||||
|
run_cmake_command(Scope-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||||
|
endblock()
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.*iface scope1: 'SCOPED_A_1;SCOPED_B_1'
|
||||||
|
.*iface scope2: 'SCOPED_A_2'
|
||||||
|
.*iface scope2 in scope1: 'SCOPED_A_2'
|
||||||
|
.*custom scope1: 'SCOPED_A_1;SCOPED_B_1'
|
||||||
|
.*custom scope2: 'SCOPED_A_2'
|
||||||
|
.*custom scope2 in scope1: 'SCOPED_A_1'
|
||||||
12
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope.c
Normal file
12
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef SCOPED_A_1
|
||||||
|
# error "SCOPED_A_1 not defined"
|
||||||
|
#endif
|
||||||
|
#ifndef SCOPED_B_1
|
||||||
|
# error "SCOPED_B_1 not defined"
|
||||||
|
#endif
|
||||||
|
#ifndef SCOPED_A_2
|
||||||
|
# error "SCOPED_A_2 not defined"
|
||||||
|
#endif
|
||||||
|
void Scope(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
19
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope.cmake
Normal file
19
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope.cmake
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
enable_language(C)
|
||||||
|
|
||||||
|
add_subdirectory(Scope1)
|
||||||
|
add_subdirectory(Scope2)
|
||||||
|
|
||||||
|
add_library(Scope Scope.c)
|
||||||
|
target_link_libraries(Scope PRIVATE
|
||||||
|
scope1_iface
|
||||||
|
scope2_iface
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(Custom ALL VERBATIM
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "iface scope1: '$<TARGET_PROPERTY:scope1_iface,INTERFACE_COMPILE_DEFINITIONS>'"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "iface scope2: '$<TARGET_PROPERTY:scope2_iface,INTERFACE_COMPILE_DEFINITIONS>'"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "iface scope2 in scope1: '$<TARGET_GENEX_EVAL:scope1_iface,$<TARGET_PROPERTY:scope2_iface,INTERFACE_COMPILE_DEFINITIONS>>'"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "custom scope1: '$<TARGET_GENEX_EVAL:scope1_iface,$<TARGET_PROPERTY:scope1_iface,CUSTOM_PROP>>'"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "custom scope2: '$<TARGET_GENEX_EVAL:scope2_iface,$<TARGET_PROPERTY:scope2_iface,CUSTOM_PROP>>'"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "custom scope2 in scope1: '$<TARGET_GENEX_EVAL:scope1_iface,$<TARGET_PROPERTY:scope2_iface,CUSTOM_PROP>>'"
|
||||||
|
)
|
||||||
15
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope1/CMakeLists.txt
Normal file
15
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope1/CMakeLists.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
add_library(scopedA INTERFACE IMPORTED)
|
||||||
|
set_property(TARGET scopedA PROPERTY INTERFACE_COMPILE_DEFINITIONS "SCOPED_A_1")
|
||||||
|
|
||||||
|
add_library(scopedB INTERFACE IMPORTED)
|
||||||
|
set_property(TARGET scopedB PROPERTY INTERFACE_COMPILE_DEFINITIONS "SCOPED_B_1")
|
||||||
|
|
||||||
|
add_library(scope1_iface INTERFACE)
|
||||||
|
set_property(TARGET scope1_iface PROPERTY INTERFACE_COMPILE_DEFINITIONS
|
||||||
|
"$<TARGET_PROPERTY:scopedA,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
"$<TARGET_PROPERTY:scopedB,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
)
|
||||||
|
set_property(TARGET scope1_iface PROPERTY CUSTOM_PROP
|
||||||
|
"$<TARGET_PROPERTY:scopedA,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
"$<TARGET_PROPERTY:scopedB,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
)
|
||||||
10
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope2/CMakeLists.txt
Normal file
10
Tests/RunCMake/GenEx-TARGET_PROPERTY/Scope2/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
add_library(scopedA INTERFACE IMPORTED)
|
||||||
|
set_property(TARGET scopedA PROPERTY INTERFACE_COMPILE_DEFINITIONS "SCOPED_A_2")
|
||||||
|
|
||||||
|
add_library(scope2_iface INTERFACE)
|
||||||
|
set_property(TARGET scope2_iface PROPERTY INTERFACE_COMPILE_DEFINITIONS
|
||||||
|
"$<TARGET_PROPERTY:scopedA,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
)
|
||||||
|
set_property(TARGET scope2_iface PROPERTY CUSTOM_PROP
|
||||||
|
"$<TARGET_PROPERTY:scopedA,INTERFACE_COMPILE_DEFINITIONS>"
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user