summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorExpressionNode.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2019-07-21 11:58:29 (GMT)
committerBrad King <brad.king@kitware.com>2019-07-23 10:50:31 (GMT)
commitad2b3a32d1b54716d1e87ae89db8c31d614a4730 (patch)
tree7f729169299d109c9a97c585e5396b09247614a5 /Source/cmGeneratorExpressionNode.cxx
parent11fa818ecda0b50446aef891b06976973005e94b (diff)
downloadCMake-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.cxx75
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;
}