Genex: Fix the HEAD target used for evaluated expressions
If the expression $<TARGET_PROPERTY:prop> appears in the content of a target property, the target that prop is read from is the 'head target' of the expression. In contexts such as evaluating the content of a target property during generation, such as INCLUDE_DIRECTORIES, the 'head target' is the one on which the initial request was made. If evaluating a generator expression which is not a target property content, the target must be explicitly specified. Such contexts include add_custom_command and file(GENERATE). The content might then look like $<TARGET_PROPERTY:tgt,prop> However, as there is no HeadTarget set, any generator expressions evaluated as part of reading prop from tgt which do not specify the tgt directly report an error. Modify the logic of the TARGET_PROPERTY generator expression so that in such contexts, the 'head target' is set to the appropriate target which was first encountered.
This commit is contained in:
parent
3aa9ce441f
commit
5b222354de
|
@ -315,6 +315,7 @@ static const char* targetPropertyTransitiveWhitelist[] = {
|
||||||
|
|
||||||
std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||||
cmTarget *target,
|
cmTarget *target,
|
||||||
|
cmTarget *headTarget,
|
||||||
cmGeneratorExpressionContext *context,
|
cmGeneratorExpressionContext *context,
|
||||||
cmGeneratorExpressionDAGChecker *dagChecker,
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
const std::string &interfacePropertyName)
|
const std::string &interfacePropertyName)
|
||||||
|
@ -345,7 +346,7 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||||
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
|
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
|
||||||
context->Config,
|
context->Config,
|
||||||
context->Quiet,
|
context->Quiet,
|
||||||
context->HeadTarget,
|
headTarget,
|
||||||
target,
|
target,
|
||||||
dagChecker);
|
dagChecker);
|
||||||
if (cge->GetHadContextSensitiveCondition())
|
if (cge->GetHadContextSensitiveCondition())
|
||||||
|
@ -538,6 +539,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
|
interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmTarget *headTarget = context->HeadTarget ? context->HeadTarget : target;
|
||||||
|
|
||||||
const char **transBegin = targetPropertyTransitiveWhitelist;
|
const char **transBegin = targetPropertyTransitiveWhitelist;
|
||||||
const char **transEnd = targetPropertyTransitiveWhitelist
|
const char **transEnd = targetPropertyTransitiveWhitelist
|
||||||
+ (sizeof(targetPropertyTransitiveWhitelist) /
|
+ (sizeof(targetPropertyTransitiveWhitelist) /
|
||||||
|
@ -547,11 +550,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
{
|
{
|
||||||
const cmTarget::LinkInterface *iface = target->GetLinkInterface(
|
const cmTarget::LinkInterface *iface = target->GetLinkInterface(
|
||||||
context->Config,
|
context->Config,
|
||||||
context->HeadTarget);
|
headTarget);
|
||||||
if(iface)
|
if(iface)
|
||||||
{
|
{
|
||||||
linkedTargetsContent =
|
linkedTargetsContent =
|
||||||
getLinkedTargetsContent(iface->Libraries, target,
|
getLinkedTargetsContent(iface->Libraries, target,
|
||||||
|
headTarget,
|
||||||
context, &dagChecker,
|
context, &dagChecker,
|
||||||
interfacePropertyName);
|
interfacePropertyName);
|
||||||
}
|
}
|
||||||
|
@ -561,11 +565,12 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
{
|
{
|
||||||
const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
|
const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
|
||||||
context->Config,
|
context->Config,
|
||||||
context->HeadTarget);
|
headTarget);
|
||||||
if(impl)
|
if(impl)
|
||||||
{
|
{
|
||||||
linkedTargetsContent =
|
linkedTargetsContent =
|
||||||
getLinkedTargetsContent(impl->Libraries, target,
|
getLinkedTargetsContent(impl->Libraries, target,
|
||||||
|
headTarget,
|
||||||
context, &dagChecker,
|
context, &dagChecker,
|
||||||
interfacePropertyName);
|
interfacePropertyName);
|
||||||
}
|
}
|
||||||
|
@ -614,7 +619,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
std::string result = cge->Evaluate(context->Makefile,
|
std::string result = cge->Evaluate(context->Makefile,
|
||||||
context->Config,
|
context->Config,
|
||||||
context->Quiet,
|
context->Quiet,
|
||||||
context->HeadTarget,
|
headTarget,
|
||||||
target,
|
target,
|
||||||
&dagChecker);
|
&dagChecker);
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,11 @@ set_property(TARGET libbad APPEND PROPERTY
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bad"
|
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/bad"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_library(lib6 SHARED other.cpp)
|
||||||
|
add_library(lib7 SHARED other.cpp)
|
||||||
|
target_link_libraries(lib7 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:lib6>)
|
||||||
|
target_include_directories(lib7 PUBLIC $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:/lib7/include>)
|
||||||
|
add_custom_target(head_target_test "some_bogus_custom_tool \"$<TARGET_PROPERTY:lib7,INCLUDE_DIRECTORIES>$<TARGET_PROPERTY:lib7,INTERFACE_INCLUDE_DIRECTORIES>\"")
|
||||||
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n")
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp" "#include \"common.h\"\n")
|
||||||
add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp")
|
add_library(lib5 "${CMAKE_CURRENT_BINARY_DIR}/lib5.cpp")
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int other() {
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue