This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  d9156c387c60bc15523a27bba83809ec9fa2a8bf (commit)
       via  8df10447a18d6479160189509a248a465d6e967c (commit)
       via  52ea0c4676e2e9893312a9f73609603129cd6886 (commit)
       via  838278f4babe248eeb302f98651662ef8d94c7e6 (commit)
       via  3b113cc131a2c477a29960676cccb697994353ec (commit)
       via  1d3841b6003d4f1a45e79f6b9e6d6357514905f1 (commit)
       via  b5460f99315f8e6a6bdc985ebc0ca18dd8a294a8 (commit)
       via  ad2b3a32d1b54716d1e87ae89db8c31d614a4730 (commit)
       via  11fa818ecda0b50446aef891b06976973005e94b (commit)
       via  0239bf8ac88bb8ae9d8945be506cee2c9adb08f5 (commit)
       via  7caebeb0e4babc41e5c84b4ce0ea70adcfdea4a1 (commit)
       via  b2785a0fbdcfa703f3ad3aaa2949ec7db55a27d9 (commit)
      from  467e6ac728cefa484f9e9369a7da4d05b04ec403 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d9156c387c60bc15523a27bba83809ec9fa2a8bf
commit d9156c387c60bc15523a27bba83809ec9fa2a8bf
Merge: 8df1044 838278f
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Fri Jul 26 07:37:55 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Fri Jul 26 07:37:55 2019 -0400

    Merge branch 'release-3.15'


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8df10447a18d6479160189509a248a465d6e967c
commit 8df10447a18d6479160189509a248a465d6e967c
Merge: 52ea0c4 3b113cc
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Fri Jul 26 11:37:10 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Fri Jul 26 07:37:19 2019 -0400

    Merge topic 'doc-relnotes-3.15'
    
    3b113cc131 Help: Add 3.15.1 release notes
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Merge-request: !3608


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=52ea0c4676e2e9893312a9f73609603129cd6886
commit 52ea0c4676e2e9893312a9f73609603129cd6886
Merge: 467e6ac 1d3841b
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Fri Jul 26 11:29:53 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Fri Jul 26 07:33:27 2019 -0400

    Merge topic 'optimize-usage-requirements'
    
    1d3841b600 Genex: Memoize usage requirement TARGET_PROPERTY existence
    b5460f9931 cmLinkItem: Expose HadHeadSensitiveCondition in 
cmLinkInterfaceLibraries
    ad2b3a32d1 Genex: Optimize build setting TARGET_PROPERTY evaluation
    11fa818ecd Genex: Optimize usage requirement TARGET_PROPERTY recursion
    0239bf8ac8 Genex: In TARGET_PROPERTY check for usage reqs in link libs 
earlier
    7caebeb0e4 Genex: Re-order TARGET_PROPERTY logic to de-duplicate checks
    b2785a0fbd Genex: Move TARGET_PROPERTY linked targets evaluation to end
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Acked-by: Cristian Adam <cristian.a...@gmail.com>
    Merge-request: !3589


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1d3841b6003d4f1a45e79f6b9e6d6357514905f1
commit 1d3841b6003d4f1a45e79f6b9e6d6357514905f1
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Tue Jul 23 10:01:13 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Tue Jul 23 10:44:19 2019 -0400

    Genex: Memoize usage requirement TARGET_PROPERTY existence
    
    For each usage requirement (such as `INTERFACE_COMPILE_DEFINITIONS` or
    `INTERFACE_INCLUDE_DIRECTORIES`), the value of the generator expression
    `$<TARGET_PROPERTY:target,prop>` includes the values of the same
    property from the transitive closure of link libraries of the target.
    
    In cases that a target's transitive closure of dependencies does not
    depend on the target being linked (the "head" target), we can memoize
    whether or not a usage requirement property exists at all for that
    target.  When a usage requirement does not exist for a target, we
    can skip evaluating it for every consuming target.
    
    Fixes: #18964, #18965

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index b22d8b6..7c41045 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1143,12 +1143,59 @@ bool cmGeneratorTarget::GetPropertyAsBool(const 
std::string& prop) const
   return this->Target->GetPropertyAsBool(prop);
 }
 
+bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
+  std::string const& prop, cmGeneratorExpressionContext* context) const
+{
+  std::string const key = prop + '@' + context->Config;
+  auto i = this->MaybeInterfacePropertyExists.find(key);
+  if (i == this->MaybeInterfacePropertyExists.end()) {
+    // Insert an entry now in case there is a cycle.
+    i = this->MaybeInterfacePropertyExists.emplace(key, false).first;
+    bool& maybeInterfaceProp = i->second;
+
+    // If this target itself has a non-empty property value, we are done.
+    const char* p = this->GetProperty(prop);
+    maybeInterfaceProp = p && *p;
+
+    // Otherwise, recurse to interface dependencies.
+    if (!maybeInterfaceProp) {
+      cmGeneratorTarget const* headTarget =
+        context->HeadTarget ? context->HeadTarget : this;
+      if (cmLinkInterfaceLibraries const* iface =
+            this->GetLinkInterfaceLibraries(context->Config, headTarget,
+                                            true)) {
+        if (iface->HadHeadSensitiveCondition) {
+          // With a different head target we may get to a library with
+          // this interface property.
+          maybeInterfaceProp = true;
+        } else {
+          // The transitive interface libraries do not depend on the
+          // head target, so we can follow them.
+          for (cmLinkItem const& lib : iface->Libraries) {
+            if (lib.Target &&
+                lib.Target->MaybeHaveInterfaceProperty(prop, context)) {
+              maybeInterfaceProp = true;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  return i->second;
+}
+
 std::string cmGeneratorTarget::EvaluateInterfaceProperty(
   std::string const& prop, cmGeneratorExpressionContext* context,
   cmGeneratorExpressionDAGChecker* dagCheckerParent) const
 {
   std::string result;
 
+  // If the property does not appear transitively at all, we are done.
+  if (!this->MaybeHaveInterfaceProperty(prop, context)) {
+    return result;
+  }
+
   // Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled.  This is
   // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
   // but sufficient for transitive interface properties.
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index b875c40..3874738 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -14,6 +14,7 @@
 #include <set>
 #include <stddef.h>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -856,6 +857,10 @@ private:
   mutable std::vector<AllConfigSource> AllConfigSources;
   void ComputeAllConfigSources() const;
 
+  mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
+  bool MaybeHaveInterfaceProperty(std::string const& prop,
+                                  cmGeneratorExpressionContext* context) const;
+
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b5460f99315f8e6a6bdc985ebc0ca18dd8a294a8
commit b5460f99315f8e6a6bdc985ebc0ca18dd8a294a8
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Tue Jul 23 09:52:33 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Tue Jul 23 10:06:35 2019 -0400

    cmLinkItem: Expose HadHeadSensitiveCondition in cmLinkInterfaceLibraries
    
    Clients may be able to avoid repeating work if they know the transitive
    link interface libraries do not depend on what is linking them.

diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 5b635b5..6450c62 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -58,6 +58,9 @@ struct cmLinkInterfaceLibraries
 {
   // Libraries listed in the interface.
   std::vector<cmLinkItem> Libraries;
+
+  // Whether the list depends on a genex referencing the head target.
+  bool HadHeadSensitiveCondition = false;
 };
 
 struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -84,7 +87,6 @@ struct cmOptionalLinkInterface : public cmLinkInterface
   bool LibrariesDone = false;
   bool AllDone = false;
   bool Exists = false;
-  bool HadHeadSensitiveCondition = false;
   const char* ExplicitLibraries = nullptr;
 };
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ad2b3a32d1b54716d1e87ae89db8c31d614a4730
commit ad2b3a32d1b54716d1e87ae89db8c31d614a4730
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Sun Jul 21 07:58:29 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Tue Jul 23 06:50:31 2019 -0400

    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

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;
       }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 21da2fd..b22d8b6 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1227,23 +1227,17 @@ void AddInterfaceEntries(cmGeneratorTarget const* 
headTarget,
         headTarget->GetLinkImplementationLibraries(config)) {
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target) {
-        std::string uniqueName =
-          headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
-            lib.Target);
-        std::string genex =
-          "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">";
-        cmGeneratorExpression ge(lib.Backtrace);
-        std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
-        cge->SetEvaluateForBuildsystem(true);
-
         EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+        // 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 context(
+          headTarget->GetLocalGenerator(), config, false, headTarget,
+          headTarget, true, lib.Backtrace, lang);
         cmSystemTools::ExpandListArgument(
-          cge->Evaluate(headTarget->GetLocalGenerator(), config, false,
-                        headTarget, dagChecker, lang),
+          lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker),
           ee.Values);
-        if (cge->GetHadContextSensitiveCondition()) {
-          ee.ContextDependent = true;
-        }
+        ee.ContextDependent = context.HadContextSensitiveCondition;
         entries.emplace_back(std::move(ee));
       }
     }

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=11fa818ecda0b50446aef891b06976973005e94b
commit 11fa818ecda0b50446aef891b06976973005e94b
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Sun Jul 21 07:57:08 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Tue Jul 23 06:46:34 2019 -0400

    Genex: Optimize usage requirement TARGET_PROPERTY recursion
    
    In large projects the generation process spends a lot of time evaluating
    usage requirements through transitive interface properties on targets.
    This can be seen in a contrived example with deep dependencies:
    
        set(prev "")
        foreach(i RANGE 1 500)
          add_library(a${i} a.c)
          target_compile_definitions(a${i} PUBLIC A${i})
          target_link_libraries(a${i} PUBLIC ${prev})
          set(prev a${i})
        endforeach()
    
    For each usage requirement (such as `INTERFACE_COMPILE_DEFINITIONS` or
    `INTERFACE_INCLUDE_DIRECTORIES`), the value of the generator expression
    `$<TARGET_PROPERTY:target,prop>` includes the values of the same
    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 creating and using a dedicated
    evaluation method `cmGeneratorTarget::EvaluateInterfaceProperty` that
    looks up the properties directly.
    
    Issue: #18964, #18965

diff --git a/Source/cmGeneratorExpressionNode.cxx 
b/Source/cmGeneratorExpressionNode.cxx
index b268ea2..8d02b68 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1243,6 +1243,11 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
       }
     }
 
+    if (isInterfaceProperty) {
+      return target->EvaluateInterfaceProperty(propertyName, context,
+                                               dagCheckerParent);
+    }
+
     cmGeneratorExpressionDAGChecker dagChecker(
       context->Backtrace, target, propertyName, content, dagCheckerParent);
 
@@ -1254,10 +1259,8 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
         // No error. We just skip cyclic references.
         return std::string();
       case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
-        if (isInterfaceProperty) {
-          // No error. We're not going to find anything new here.
-          return std::string();
-        }
+        // We handle transitive properties above.  For non-transitive
+        // properties we accept repeats anyway.
       case cmGeneratorExpressionDAGChecker::DAG:
         break;
     }
@@ -1328,27 +1331,15 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
     }
 
     if (!interfacePropertyName.empty()) {
-      cmGeneratorTarget const* headTarget =
-        context->HeadTarget && isInterfaceProperty ? context->HeadTarget
-                                                   : target;
+      cmGeneratorTarget const* headTarget = target;
       result = this->EvaluateDependentExpression(
         result, context->LG, context, headTarget, target, &dagChecker);
       std::string linkedTargetsContent;
-      if (isInterfaceProperty) {
-        if (cmLinkInterfaceLibraries const* iface =
-              target->GetLinkInterfaceLibraries(context->Config, headTarget,
-                                                true)) {
-          linkedTargetsContent = getLinkedTargetsContent(
-            iface->Libraries, target, headTarget, context, &dagChecker,
-            interfacePropertyName);
-        }
-      } else {
-        if (cmLinkImplementationLibraries const* impl =
-              target->GetLinkImplementationLibraries(context->Config)) {
-          linkedTargetsContent =
-            getLinkedTargetsContent(impl->Libraries, target, target, context,
-                                    &dagChecker, interfacePropertyName);
-        }
+      if (cmLinkImplementationLibraries const* impl =
+            target->GetLinkImplementationLibraries(context->Config)) {
+        linkedTargetsContent =
+          getLinkedTargetsContent(impl->Libraries, target, target, context,
+                                  &dagChecker, interfacePropertyName);
       }
       if (!linkedTargetsContent.empty()) {
         result += (result.empty() ? "" : ";") + linkedTargetsContent;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6e6c917..21da2fd 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -22,7 +22,9 @@
 #include "cmCustomCommandGenerator.h"
 #include "cmCustomCommandLines.h"
 #include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
+#include "cmGeneratorExpressionNode.h"
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
@@ -1141,6 +1143,79 @@ bool cmGeneratorTarget::GetPropertyAsBool(const 
std::string& prop) const
   return this->Target->GetPropertyAsBool(prop);
 }
 
+std::string cmGeneratorTarget::EvaluateInterfaceProperty(
+  std::string const& prop, cmGeneratorExpressionContext* context,
+  cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+{
+  std::string result;
+
+  // Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled.  This is
+  // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
+  // but sufficient for transitive interface properties.
+  cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, this, prop,
+                                             nullptr, dagCheckerParent);
+  switch (dagChecker.Check()) {
+    case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+      dagChecker.ReportError(
+        context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
+      return result;
+    case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+      // No error. We just skip cyclic references.
+      return result;
+    case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+      // No error. We have already seen this transitive property.
+      return result;
+    case cmGeneratorExpressionDAGChecker::DAG:
+      break;
+  }
+
+  cmGeneratorTarget const* headTarget =
+    context->HeadTarget ? context->HeadTarget : this;
+
+  if (const char* p = this->GetProperty(prop)) {
+    result = cmGeneratorExpressionNode::EvaluateDependentExpression(
+      p, context->LG, context, headTarget, this, &dagChecker);
+  }
+
+  if (cmLinkInterfaceLibraries const* iface =
+        this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) {
+    for (cmLinkItem const& lib : iface->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 (lib.Target && lib.Target != this) {
+        // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
+        // above property and hand-evaluate it as if it were compiled.
+        // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+        cmGeneratorExpressionContext libContext(
+          context->LG, context->Config, context->Quiet, headTarget, this,
+          context->EvaluateForBuildsystem, context->Backtrace,
+          context->Language);
+        std::string libResult = cmGeneratorExpression::StripEmptyListElements(
+          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;
+          }
+        }
+        context->HadContextSensitiveCondition =
+          context->HadContextSensitiveCondition ||
+          libContext.HadContextSensitiveCondition;
+        context->HadHeadSensitiveCondition =
+          context->HadHeadSensitiveCondition ||
+          libContext.HadHeadSensitiveCondition;
+      }
+    }
+  }
+
+  return result;
+}
+
 namespace {
 void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
                          std::string const& config, std::string const& prop,
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e86535d..b875c40 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -25,6 +25,9 @@ class cmMakefile;
 class cmSourceFile;
 class cmTarget;
 
+struct cmGeneratorExpressionContext;
+struct cmGeneratorExpressionDAGChecker;
+
 class cmGeneratorTarget
 {
 public:
@@ -674,6 +677,10 @@ public:
 
   class TargetPropertyEntry;
 
+  std::string EvaluateInterfaceProperty(
+    std::string const& prop, cmGeneratorExpressionContext* context,
+    cmGeneratorExpressionDAGChecker* dagCheckerParent) const;
+
   bool HaveInstallTreeRPATH(const std::string& config) const;
 
   bool GetBuildRPATH(const std::string& config, std::string& rpath) const;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0239bf8ac88bb8ae9d8945be506cee2c9adb08f5
commit 0239bf8ac88bb8ae9d8945be506cee2c9adb08f5
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Sat Jul 20 19:29:13 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Sun Jul 21 08:17:04 2019 -0400

    Genex: In TARGET_PROPERTY check for usage reqs in link libs earlier

diff --git a/Source/cmGeneratorExpressionNode.cxx 
b/Source/cmGeneratorExpressionNode.cxx
index b027cd4..b268ea2 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1219,6 +1219,30 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
     }
 #undef POPULATE_INTERFACE_PROPERTY_NAME
 
+    bool evaluatingLinkLibraries = false;
+
+    if (dagCheckerParent) {
+      if (dagCheckerParent->EvaluatingGenexExpression() ||
+          dagCheckerParent->EvaluatingPICExpression()) {
+        // No check required.
+      } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
+        evaluatingLinkLibraries = true;
+        if (!interfacePropertyName.empty()) {
+          reportError(
+            context, content->GetOriginalExpression(),
+            "$<TARGET_PROPERTY:...> expression in link libraries "
+            "evaluation depends on target property which is transitive "
+            "over the link libraries, creating a recursion.");
+          return std::string();
+        }
+      } else {
+#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
+        assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
+          ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
+#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
+      }
+    }
+
     cmGeneratorExpressionDAGChecker dagChecker(
       context->Backtrace, target, propertyName, content, dagCheckerParent);
 
@@ -1243,31 +1267,8 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
     if (const char* p = target->GetProperty(propertyName)) {
       result = p;
       haveProp = true;
-    }
-
-    if (dagCheckerParent) {
-      if (dagCheckerParent->EvaluatingGenexExpression() ||
-          dagCheckerParent->EvaluatingPICExpression()) {
-        // No check required.
-      } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
-        if (!interfacePropertyName.empty()) {
-          reportError(
-            context, content->GetOriginalExpression(),
-            "$<TARGET_PROPERTY:...> expression in link libraries "
-            "evaluation depends on target property which is transitive "
-            "over the link libraries, creating a recursion.");
-          return std::string();
-        }
-
-        if (!haveProp) {
-          return std::string();
-        }
-      } else {
-#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
-        assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
-          ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
-#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
-      }
+    } else if (evaluatingLinkLibraries) {
+      return std::string();
     }
 
     if (!haveProp && !target->IsImported() &&

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7caebeb0e4babc41e5c84b4ce0ea70adcfdea4a1
commit 7caebeb0e4babc41e5c84b4ce0ea70adcfdea4a1
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Sat Jul 20 17:30:31 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Sun Jul 21 08:14:27 2019 -0400

    Genex: Re-order TARGET_PROPERTY logic to de-duplicate checks
    
    Check for usage requirement properties early enough to avoid duplicate
    checks in other conditions.

diff --git a/Source/cmGeneratorExpressionNode.cxx 
b/Source/cmGeneratorExpressionNode.cxx
index 1973e99..b027cd4 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1038,14 +1038,6 @@ static const struct CompileLanguageAndIdNode : public 
cmGeneratorExpressionNode
   }
 } languageAndIdNode;
 
-#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY
-
-static const char* targetPropertyTransitiveWhitelist[] = {
-  nullptr CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
-};
-
-#undef TRANSITIVE_PROPERTY_NAME
-
 template <typename T>
 std::string getLinkedTargetsContent(
   std::vector<T> const& libraries, cmGeneratorTarget const* target,
@@ -1205,6 +1197,28 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
       return target->GetLinkerLanguage(context->Config);
     }
 
+    std::string interfacePropertyName;
+    bool isInterfaceProperty = false;
+
+#define POPULATE_INTERFACE_PROPERTY_NAME(prop)                                \
+  if (propertyName == #prop) {                                                \
+    interfacePropertyName = "INTERFACE_" #prop;                               \
+  } else if (propertyName == "INTERFACE_" #prop) {                            \
+    interfacePropertyName = "INTERFACE_" #prop;                               \
+    isInterfaceProperty = true;                                               \
+  } else
+
+    CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
+    // Note that the above macro terminates with an else
+    /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) {
+      cmPolicies::PolicyStatus polSt =
+        context->LG->GetPolicyStatus(cmPolicies::CMP0043);
+      if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
+        interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
+      }
+    }
+#undef POPULATE_INTERFACE_PROPERTY_NAME
+
     cmGeneratorExpressionDAGChecker dagChecker(
       context->Backtrace, target, propertyName, content, dagCheckerParent);
 
@@ -1216,12 +1230,9 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
         // No error. We just skip cyclic references.
         return std::string();
       case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
-        for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist);
-             ++i) {
-          if (targetPropertyTransitiveWhitelist[i] == propertyName) {
-            // No error. We're not going to find anything new here.
-            return std::string();
-          }
+        if (isInterfaceProperty) {
+          // No error. We're not going to find anything new here.
+          return std::string();
         }
       case cmGeneratorExpressionDAGChecker::DAG:
         break;
@@ -1239,10 +1250,7 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
           dagCheckerParent->EvaluatingPICExpression()) {
         // No check required.
       } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
-#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY)                                 \
-  (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
-        if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(
-              TRANSITIVE_PROPERTY_COMPARE) false) { // NOLINT(*)
+        if (!interfacePropertyName.empty()) {
           reportError(
             context, content->GetOriginalExpression(),
             "$<TARGET_PROPERTY:...> expression in link libraries "
@@ -1250,42 +1258,18 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
             "over the link libraries, creating a recursion.");
           return std::string();
         }
-#undef TRANSITIVE_PROPERTY_COMPARE
 
         if (!haveProp) {
           return std::string();
         }
       } else {
 #define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
-
         assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
           ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
 #undef ASSERT_TRANSITIVE_PROPERTY_METHOD
       }
     }
 
-    std::string interfacePropertyName;
-    bool isInterfaceProperty = false;
-
-#define POPULATE_INTERFACE_PROPERTY_NAME(prop)                                \
-  if (propertyName == #prop) {                                                \
-    interfacePropertyName = "INTERFACE_" #prop;                               \
-  } else if (propertyName == "INTERFACE_" #prop) {                            \
-    interfacePropertyName = "INTERFACE_" #prop;                               \
-    isInterfaceProperty = true;                                               \
-  } else
-
-    CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME)
-    // Note that the above macro terminates with an else
-    /* else */ if (cmHasLiteralPrefix(propertyName, "COMPILE_DEFINITIONS_")) {
-      cmPolicies::PolicyStatus polSt =
-        context->LG->GetPolicyStatus(cmPolicies::CMP0043);
-      if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
-        interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS";
-      }
-    }
-#undef POPULATE_INTERFACE_PROPERTY_NAME
-
     if (!haveProp && !target->IsImported() &&
         target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       if (target->IsLinkInterfaceDependentBoolProperty(propertyName,

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b2785a0fbdcfa703f3ad3aaa2949ec7db55a27d9
commit b2785a0fbdcfa703f3ad3aaa2949ec7db55a27d9
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Sat Jul 20 16:09:03 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Sun Jul 21 07:47:27 2019 -0400

    Genex: Move TARGET_PROPERTY linked targets evaluation to end

diff --git a/Source/cmGeneratorExpressionNode.cxx 
b/Source/cmGeneratorExpressionNode.cxx
index d828dac..1973e99 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1227,10 +1227,10 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
         break;
     }
 
-    std::string prop;
+    std::string result;
     bool haveProp = false;
     if (const char* p = target->GetProperty(propertyName)) {
-      prop = p;
+      result = p;
       haveProp = true;
     }
 
@@ -1264,8 +1264,6 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
       }
     }
 
-    std::string linkedTargetsContent;
-
     std::string interfacePropertyName;
     bool isInterfaceProperty = false;
 
@@ -1287,32 +1285,9 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
       }
     }
 #undef POPULATE_INTERFACE_PROPERTY_NAME
-    cmGeneratorTarget const* headTarget =
-      context->HeadTarget && isInterfaceProperty ? context->HeadTarget
-                                                 : target;
-
-    if (isInterfaceProperty) {
-      if (cmLinkInterfaceLibraries const* iface =
-            target->GetLinkInterfaceLibraries(context->Config, headTarget,
-                                              true)) {
-        linkedTargetsContent =
-          getLinkedTargetsContent(iface->Libraries, target, headTarget,
-                                  context, &dagChecker, interfacePropertyName);
-      }
-    } else if (!interfacePropertyName.empty()) {
-      if (cmLinkImplementationLibraries const* impl =
-            target->GetLinkImplementationLibraries(context->Config)) {
-        linkedTargetsContent =
-          getLinkedTargetsContent(impl->Libraries, target, target, context,
-                                  &dagChecker, interfacePropertyName);
-      }
-    }
 
-    if (!haveProp) {
-      if (target->IsImported() ||
-          target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-        return linkedTargetsContent;
-      }
+    if (!haveProp && !target->IsImported() &&
+        target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
                                                        context->Config)) {
         context->HadContextSensitiveCondition = true;
@@ -1345,8 +1320,6 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
                                                              context->Config);
         return propContent ? propContent : "";
       }
-
-      return linkedTargetsContent;
     }
 
     if (!target->IsImported() && dagCheckerParent &&
@@ -1368,15 +1341,35 @@ static const struct TargetPropertyNode : public 
cmGeneratorExpressionNode
         return propContent ? propContent : "";
       }
     }
+
     if (!interfacePropertyName.empty()) {
-      std::string result = this->EvaluateDependentExpression(
-        prop, context->LG, context, headTarget, target, &dagChecker);
+      cmGeneratorTarget const* headTarget =
+        context->HeadTarget && isInterfaceProperty ? context->HeadTarget
+                                                   : target;
+      result = this->EvaluateDependentExpression(
+        result, context->LG, context, headTarget, target, &dagChecker);
+      std::string linkedTargetsContent;
+      if (isInterfaceProperty) {
+        if (cmLinkInterfaceLibraries const* iface =
+              target->GetLinkInterfaceLibraries(context->Config, headTarget,
+                                                true)) {
+          linkedTargetsContent = getLinkedTargetsContent(
+            iface->Libraries, target, headTarget, context, &dagChecker,
+            interfacePropertyName);
+        }
+      } else {
+        if (cmLinkImplementationLibraries const* impl =
+              target->GetLinkImplementationLibraries(context->Config)) {
+          linkedTargetsContent =
+            getLinkedTargetsContent(impl->Libraries, target, target, context,
+                                    &dagChecker, interfacePropertyName);
+        }
+      }
       if (!linkedTargetsContent.empty()) {
         result += (result.empty() ? "" : ";") + linkedTargetsContent;
       }
-      return result;
     }
-    return prop;
+    return result;
   }
 } targetPropertyNode;
 

-----------------------------------------------------------------------

Summary of changes:
 Help/release/3.15.rst                |  17 +++
 Source/cmGeneratorExpressionNode.cxx | 208 +++++++++++++++--------------------
 Source/cmGeneratorTarget.cxx         | 144 +++++++++++++++++++++---
 Source/cmGeneratorTarget.h           |  12 ++
 Source/cmLinkItem.h                  |   4 +-
 5 files changed, 248 insertions(+), 137 deletions(-)


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
https://cmake.org/mailman/listinfo/cmake-commits

Reply via email to