diff options
author | Brad King <brad.king@kitware.com> | 2019-07-21 11:58:29 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2019-07-23 10:50:31 (GMT) |
commit | ad2b3a32d1b54716d1e87ae89db8c31d614a4730 (patch) | |
tree | 7f729169299d109c9a97c585e5396b09247614a5 /Source/cmGeneratorExpressionNode.cxx | |
parent | 11fa818ecda0b50446aef891b06976973005e94b (diff) | |
download | CMake-ad2b3a32d1b54716d1e87ae89db8c31d614a4730.zip CMake-ad2b3a32d1b54716d1e87ae89db8c31d614a4730.tar.gz CMake-ad2b3a32d1b54716d1e87ae89db8c31d614a4730.tar.bz2 |
Genex: Optimize build setting TARGET_PROPERTY evaluation
For each build setting property (such as `COMPILE_DEFINITIONS` or
`INCLUDE_DIRECTORIES`), the value of `$<TARGET_PROPERTY:target,prop>`
includes the values of the corresponding `INTERFACE_*` usage requirement
property from the transitive closure of link libraries of the target.
Previously we computed this by constructing a generator expression
string like `$<TARGET_PROPERTY:lib,INTERFACE_COMPILE_DEFINITIONS>` and
recursively evaluating it with the generator expression engine. Avoid
the string construction and parsing by using the dedicated evaluation
method `cmGeneratorTarget::EvaluateInterfaceProperty`.
Issue: #18964, #18965
Diffstat (limited to 'Source/cmGeneratorExpressionNode.cxx')
-rw-r--r-- | Source/cmGeneratorExpressionNode.cxx | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 8d02b68..49d0c47 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1038,37 +1038,38 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode } } languageAndIdNode; -template <typename T> std::string getLinkedTargetsContent( - std::vector<T> const& libraries, cmGeneratorTarget const* target, - cmGeneratorTarget const* headTarget, cmGeneratorExpressionContext* context, - cmGeneratorExpressionDAGChecker* dagChecker, - const std::string& interfacePropertyName) -{ - std::string linkedTargetsContent; - std::string sep; - std::string depString; - for (T const& l : libraries) { - // 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. - if (l.Target && l.Target != target) { - std::string uniqueName = - target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target); - depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + - interfacePropertyName + ">"; - sep = ";"; - } - } - if (!depString.empty()) { - linkedTargetsContent = - cmGeneratorExpressionNode::EvaluateDependentExpression( - depString, target->GetLocalGenerator(), context, headTarget, target, - dagChecker); - } - linkedTargetsContent = - cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent); - return linkedTargetsContent; + cmGeneratorTarget const* target, std::string const& prop, + cmGeneratorExpressionContext* context, + cmGeneratorExpressionDAGChecker* dagChecker) +{ + std::string result; + if (cmLinkImplementationLibraries const* impl = + target->GetLinkImplementationLibraries(context->Config)) { + for (cmLinkImplItem const& lib : impl->Libraries) { + if (lib.Target) { + // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our + // caller's property and hand-evaluate it as if it were compiled. + // Create a context as cmCompiledGeneratorExpression::Evaluate does. + cmGeneratorExpressionContext libContext( + target->GetLocalGenerator(), context->Config, context->Quiet, target, + target, context->EvaluateForBuildsystem, lib.Backtrace, + context->Language); + std::string libResult = + lib.Target->EvaluateInterfaceProperty(prop, &libContext, dagChecker); + if (!libResult.empty()) { + if (result.empty()) { + result = std::move(libResult); + } else { + result.reserve(result.size() + 1 + libResult.size()); + result += ";"; + result += libResult; + } + } + } + } + } + return result; } static const struct TargetPropertyNode : public cmGeneratorExpressionNode @@ -1331,16 +1332,10 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } if (!interfacePropertyName.empty()) { - cmGeneratorTarget const* headTarget = target; - result = this->EvaluateDependentExpression( - result, context->LG, context, headTarget, target, &dagChecker); - std::string linkedTargetsContent; - if (cmLinkImplementationLibraries const* impl = - target->GetLinkImplementationLibraries(context->Config)) { - linkedTargetsContent = - getLinkedTargetsContent(impl->Libraries, target, target, context, - &dagChecker, interfacePropertyName); - } + result = this->EvaluateDependentExpression(result, context->LG, context, + target, target, &dagChecker); + std::string linkedTargetsContent = getLinkedTargetsContent( + target, interfacePropertyName, context, &dagChecker); if (!linkedTargetsContent.empty()) { result += (result.empty() ? "" : ";") + linkedTargetsContent; } |