diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 93d881e09..df52368bb 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -399,6 +399,59 @@ static const char* targetPropertyTransitiveWhitelist[] = { , "INTERFACE_COMPILE_DEFINITIONS" }; +std::string getLinkedTargetsContent(const std::vector &libraries, + cmTarget *target, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string &interfacePropertyName) +{ + cmGeneratorExpression ge(context->Backtrace); + + std::string sep; + std::string depString; + for (std::vector::const_iterator + it = libraries.begin(); + it != libraries.end(); ++it) + { + if (*it == target->GetName()) + { + // Broken code can have a target in its own link interface. + // Don't follow such link interface entries so as not to create a + // self-referencing loop. + continue; + } + if (context->Makefile->FindTargetToUse(it->c_str())) + { + depString += + sep + "$"; + sep = ";"; + } + } + cmsys::auto_ptr cge = ge.Parse(depString); + std::string linkedTargetsContent = cge->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + dagChecker); + if (cge->GetHadContextSensitiveCondition()) + { + context->HadContextSensitiveCondition = true; + } + return linkedTargetsContent; +} + +//---------------------------------------------------------------------------- +struct TransitiveWhitelistCompare +{ + explicit TransitiveWhitelistCompare(const std::string &needle) + : Needle(needle) {} + bool operator() (const char *item) + { return strcmp(item, this->Needle.c_str()) == 0; } +private: + std::string Needle; +}; + //---------------------------------------------------------------------------- static const struct TargetPropertyNode : public cmGeneratorExpressionNode { @@ -571,49 +624,36 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; } - if (interfacePropertyName == "INTERFACE_INCLUDE_DIRECTORIES" - || interfacePropertyName == "INTERFACE_COMPILE_DEFINITIONS") + const char **transBegin = targetPropertyTransitiveWhitelist; + const char **transEnd = targetPropertyTransitiveWhitelist + + (sizeof(targetPropertyTransitiveWhitelist) / + sizeof(*targetPropertyTransitiveWhitelist)); + if (std::find_if(transBegin, transEnd, + TransitiveWhitelistCompare(propertyName)) != transEnd) { const cmTarget::LinkInterface *iface = target->GetLinkInterface( context->Config, context->HeadTarget); if(iface) { - cmGeneratorExpression ge(context->Backtrace); - - std::string sep; - std::string depString; - for (std::vector::const_iterator - it = iface->Libraries.begin(); - it != iface->Libraries.end(); ++it) - { - if (*it == target->GetName()) - { - // Broken code can have a target in its own link interface. - // Don't follow such link interface entries so as not to create a - // self-referencing loop. - continue; - } - if (context->Makefile->FindTargetToUse(it->c_str())) - { - depString += - sep + "$"; - sep = ";"; - } - } - cmsys::auto_ptr cge = - ge.Parse(depString); - linkedTargetsContent = cge->Evaluate(context->Makefile, - context->Config, - context->Quiet, - context->HeadTarget, - target, - &dagChecker); - if (cge->GetHadContextSensitiveCondition()) - { - context->HadContextSensitiveCondition = true; - } + linkedTargetsContent = + getLinkedTargetsContent(iface->Libraries, target, + context, &dagChecker, + interfacePropertyName); + } + } + else if (std::find_if(transBegin, transEnd, + TransitiveWhitelistCompare(interfacePropertyName)) != transEnd) + { + const cmTarget::LinkImplementation *impl = target->GetLinkImplementation( + context->Config, + context->HeadTarget); + if(impl) + { + linkedTargetsContent = + getLinkedTargetsContent(impl->Libraries, target, + context, &dagChecker, + interfacePropertyName); } }