Genex: Fix value lifetimes in nested TARGET_PROPERTY evaluation
For special properties like `INCLUDE_DIRECTORIES`, the pointer returned by `cmTarget::GetProperty` is only valid until the next time the same special property is queried on *any* target. When evaluating a nested `TARGET_PROPERTY` generator expression we may look up such a property more than once on different targets. Fix `TargetPropertyNode::Evaluate` to store the lookup result in locally owned memory earlier. Fixes: #19286
This commit is contained in:
parent
01b6a2c4ee
commit
5a1af142f1
@ -1215,7 +1215,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
break;
|
||||
}
|
||||
|
||||
const char* prop = target->GetProperty(propertyName);
|
||||
std::string prop;
|
||||
bool haveProp = false;
|
||||
if (const char* p = target->GetProperty(propertyName)) {
|
||||
prop = p;
|
||||
haveProp = true;
|
||||
}
|
||||
|
||||
if (dagCheckerParent) {
|
||||
if (dagCheckerParent->EvaluatingGenexExpression() ||
|
||||
@ -1235,7 +1240,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
#undef TRANSITIVE_PROPERTY_COMPARE
|
||||
|
||||
if (!prop) {
|
||||
if (!haveProp) {
|
||||
return std::string();
|
||||
}
|
||||
} else {
|
||||
@ -1291,7 +1296,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
if (!haveProp) {
|
||||
if (target->IsImported() ||
|
||||
target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
|
||||
return linkedTargetsContent;
|
||||
|
@ -53,6 +53,7 @@ run_cmake_with_options(TARGET_FILE_BASE_NAME -DCMAKE_BUILD_TYPE:STRING=Debug)
|
||||
run_cmake_with_options(TARGET_FILE_BASE_NAME-imported-target -DCMAKE_BUILD_TYPE:STRING=Debug)
|
||||
run_cmake(TARGET_FILE_BASE_NAME-non-valid-target)
|
||||
run_cmake(TARGET_LINKER_FILE_BASE_NAME-non-valid-target)
|
||||
run_cmake(TARGET_PROPERTY-INCLUDE_DIRECTORIES)
|
||||
run_cmake(TARGET_PROPERTY-LOCATION)
|
||||
run_cmake(TARGET_PROPERTY-SOURCES)
|
||||
run_cmake(LINK_ONLY-not-linking)
|
||||
|
@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
enable_language(C)
|
||||
|
||||
add_library(foo1 STATIC empty.c)
|
||||
target_include_directories(foo1 PUBLIC include)
|
||||
target_link_libraries(foo1 PRIVATE foo2 foo3 foo4)
|
||||
|
||||
add_library(foo2 STATIC empty.c)
|
||||
target_include_directories(foo2 PUBLIC $<TARGET_PROPERTY:foo1,INCLUDE_DIRECTORIES>)
|
||||
|
||||
add_library(foo3 STATIC empty.c)
|
||||
target_include_directories(foo3 PUBLIC $<TARGET_PROPERTY:foo2,INCLUDE_DIRECTORIES>)
|
||||
|
||||
add_library(foo4 STATIC empty.c)
|
||||
target_include_directories(foo4 PUBLIC $<TARGET_PROPERTY:foo3,INCLUDE_DIRECTORIES>)
|
||||
|
||||
# Evaluate a genex that looks up INCLUDE_DIRECTORIES on multiple targets.
|
||||
file(GENERATE OUTPUT out.txt CONTENT "$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>")
|
Loading…
Reference in New Issue
Block a user