瀏覽代碼

Cache context-independent includes on evaluation.

Generator expressions whose output depends on the configuration
now record that fact. The GetIncludeDirectories method can use
that result to cache the include directories for later calls.

GetIncludeDirectories is called multiple times for a target
for each configuration, so this should restore performance for
multi-config generators.
Stephen Kelly 13 年之前
父節點
當前提交
e48d84209c

+ 7 - 1
Source/cmGeneratorExpression.cxx

@@ -88,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
   context.Config = config;
   context.Quiet = quiet;
   context.HadError = false;
+  context.HadContextSensitiveCondition = false;
   context.HeadTarget = headTarget;
   context.CurrentTarget = currentTarget ? currentTarget : headTarget;
   context.Backtrace = this->Backtrace;
@@ -109,6 +110,10 @@ const char *cmCompiledGeneratorExpression::Evaluate(
       break;
       }
     }
+  if (!context.HadError)
+    {
+    this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
+    }
 
   this->Targets = context.Targets;
   // TODO: Return a std::string from here instead?
@@ -118,7 +123,8 @@ const char *cmCompiledGeneratorExpression::Evaluate(
 cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
               cmListFileBacktrace const& backtrace,
               const char *input)
-  : Backtrace(backtrace), Input(input ? input : "")
+  : Backtrace(backtrace), Input(input ? input : ""),
+    HadContextSensitiveCondition(false)
 {
   cmGeneratorExpressionLexer l;
   std::vector<cmGeneratorExpressionToken> tokens =

+ 5 - 0
Source/cmGeneratorExpression.h

@@ -100,6 +100,10 @@ public:
   {
     return this->Backtrace;
   }
+  bool GetHadContextSensitiveCondition() const
+  {
+    return this->HadContextSensitiveCondition;
+  }
 
 private:
   cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
@@ -118,6 +122,7 @@ private:
   mutable std::set<cmTarget*> Targets;
   mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
   mutable std::string Output;
+  mutable bool HadContextSensitiveCondition;
 };
 
 #endif

+ 23 - 2
Source/cmGeneratorExpressionEvaluator.cxx

@@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
                        const GeneratorExpressionContent *,
                        cmGeneratorExpressionDAGChecker *) const
   {
+    context->HadContextSensitiveCondition = true;
     return context->Config ? context->Config : "";
   }
 } configurationNode;
@@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
                   "Expression syntax not recognized.");
       return std::string();
       }
+    context->HadContextSensitiveCondition = true;
     if (!context->Config)
       {
       return parameters.front().empty() ? "1" : "0";
@@ -455,12 +457,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
         }
       if (propertyName == "POSITION_INDEPENDENT_CODE")
         {
+        context->HadContextSensitiveCondition = true;
         return target->GetLinkInterfaceDependentBoolProperty(
                     "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
         }
       if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
                                                        context->Config))
         {
+        context->HadContextSensitiveCondition = true;
         return target->GetLinkInterfaceDependentBoolProperty(
                                                 propertyName,
                                                 context->Config) ? "1" : "0";
@@ -468,6 +472,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       if (target->IsLinkInterfaceDependentStringProperty(propertyName,
                                                          context->Config))
         {
+        context->HadContextSensitiveCondition = true;
         const char *propContent =
                               target->GetLinkInterfaceDependentStringProperty(
                                                 propertyName,
@@ -486,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
       if (targetPropertyTransitiveWhitelist[i] == propertyName)
         {
         cmGeneratorExpression ge(context->Backtrace);
-        return ge.Parse(prop)->Evaluate(context->Makefile,
+        cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+        std::string result = cge->Evaluate(context->Makefile,
                             context->Config,
                             context->Quiet,
                             context->HeadTarget,
                             target,
                             &dagChecker);
+
+        if (cge->GetHadContextSensitiveCondition())
+          {
+          context->HadContextSensitiveCondition = true;
+          }
+        return result;
         }
       }
     return prop;
@@ -585,6 +597,9 @@ static const struct TargetPolicyNode : public cmGeneratorExpressionNode
           "be used with add_custom_command.");
       return std::string();
       }
+
+    context->HadContextSensitiveCondition = true;
+
     for (size_t i = 0;
          i < (sizeof(targetPolicyWhitelist) /
               sizeof(*targetPolicyWhitelist));
@@ -716,12 +731,18 @@ private:
       }
 
     cmGeneratorExpression ge(context->Backtrace);
-    return ge.Parse(propContent)->Evaluate(context->Makefile,
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
+    std::string result = cge->Evaluate(context->Makefile,
                         context->Config,
                         context->Quiet,
                         context->HeadTarget,
                         target,
                         &dagChecker);
+    if (cge->GetHadContextSensitiveCondition())
+      {
+      context->HadContextSensitiveCondition = true;
+      }
+    return result;
   }
 
 } linkedNode;

+ 1 - 0
Source/cmGeneratorExpressionEvaluator.h

@@ -32,6 +32,7 @@ struct cmGeneratorExpressionContext
                            // directly or indirectly in the property.
   bool Quiet;
   bool HadError;
+  bool HadContextSensitiveCondition;
 };
 
 struct cmGeneratorExpressionDAGChecker;

+ 30 - 11
Source/cmTarget.cxx

@@ -134,6 +134,7 @@ public:
       : ge(cge)
     {}
     const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+    std::vector<std::string> CachedIncludes;
   };
   std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
 };
@@ -2778,22 +2779,36 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
       end = this->Internal->IncludeDirectoriesEntries.end();
       it != end; ++it)
     {
-    std::vector<std::string> entryIncludes;
-    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
-                                              config,
-                                              false,
-                                              this,
-                                              &dagChecker),
-                                    entryIncludes);
+
+    bool testIsOff = true;
+    bool cacheIncludes = false;
+    std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
+    if(!entryIncludes.empty())
+      {
+      testIsOff = false;
+      }
+    else
+      {
+      cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
+                                                config,
+                                                false,
+                                                this,
+                                                &dagChecker),
+                                      entryIncludes);
+      if (!(*it)->ge->GetHadContextSensitiveCondition())
+        {
+        cacheIncludes = true;
+        }
+      }
     std::string usedIncludes;
-    for(std::vector<std::string>::const_iterator
+    for(std::vector<std::string>::iterator
           li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
       {
-      std::string inc = *li;
-      if (!cmSystemTools::IsOff(inc.c_str()))
+      if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
         {
-        cmSystemTools::ConvertToUnixSlashes(inc);
+        cmSystemTools::ConvertToUnixSlashes(*li);
         }
+      std::string inc = *li;
 
       if(uniqueIncludes.insert(inc).second)
         {
@@ -2804,6 +2819,10 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
           }
         }
       }
+    if (cacheIncludes)
+      {
+      (*it)->CachedIncludes = entryIncludes;
+      }
     if (!usedIncludes.empty())
       {
       this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,