Explorar o código

Keep track of properties used to determine linker libraries.

Those properties can't later be implicitly defined by the interface
of those link libraries.
Stephen Kelly %!s(int64=13) %!d(string=hai) anos
pai
achega
bf5ece51c3

+ 9 - 1
Source/cmGeneratorExpression.cxx

@@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate(
 
   for ( ; it != end; ++it)
     {
-    this->Output += (*it)->Evaluate(&context, dagChecker);
+    const std::string result = (*it)->Evaluate(&context, dagChecker);
+    this->Output += result;
+
+    for(std::set<cmStdString>::const_iterator
+          p = context.SeenTargetProperties.begin();
+          p != context.SeenTargetProperties.end(); ++p)
+      {
+      this->SeenTargetProperties[*p] += result + ";";
+      }
     if (context.HadError)
       {
       this->Output = "";

+ 4 - 0
Source/cmGeneratorExpression.h

@@ -83,6 +83,9 @@ public:
   std::set<cmTarget*> const& GetTargets() const
     { return this->Targets; }
 
+  std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
+    { return this->SeenTargetProperties; }
+
   ~cmCompiledGeneratorExpression();
 
   std::string GetInput() const
@@ -110,6 +113,7 @@ private:
   bool NeedsParsing;
 
   mutable std::set<cmTarget*> Targets;
+  mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
   mutable std::string Output;
 };
 

+ 8 - 0
Source/cmGeneratorExpressionEvaluator.cxx

@@ -380,6 +380,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
         }
       }
 
+    if (target == context->HeadTarget)
+      {
+      // Keep track of the properties seen while processing.
+      // The evaluation of the LINK_LIBRARIES generator expressions
+      // will check this to ensure that properties form a DAG.
+      context->SeenTargetProperties.insert(propertyName);
+      }
+
     if (propertyName.empty())
       {
       reportError(context, content->GetOriginalExpression(),

+ 1 - 0
Source/cmGeneratorExpressionEvaluator.h

@@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext
 {
   cmListFileBacktrace Backtrace;
   std::set<cmTarget*> Targets;
+  std::set<cmStdString> SeenTargetProperties;
   cmMakefile *Makefile;
   const char *Config;
   cmTarget *HeadTarget; // The target whose property is being evaluated.

+ 41 - 1
Source/cmTarget.cxx

@@ -2164,16 +2164,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config,
     {
     cmListFileBacktrace lfbt;
     cmGeneratorExpression ge(lfbt);
+    const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
 
     cmGeneratorExpressionDAGChecker dagChecker(lfbt,
                                         this->GetName(),
                                         "LINK_LIBRARIES", 0, 0);
-    cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
+    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
                                         config,
                                         false,
                                         head,
                                         &dagChecker),
                                       libs);
+
+    this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties());
     }
 }
 
@@ -4376,6 +4379,43 @@ const char* cmTarget::GetExportMacro()
     }
 }
 
+//----------------------------------------------------------------------------
+void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p,
+                                          std::set<std::string> &targets)
+{
+  const std::map<cmStdString, std::set<std::string> >::const_iterator findIt
+                                  = this->LinkDependentProperties.find(p);
+  if (findIt != this->LinkDependentProperties.end())
+    {
+    targets = findIt->second;
+    }
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
+{
+  return this->LinkImplicitNullProperties.find(p)
+      != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::AddLinkDependentTargetsForProperties(
+                              const std::map<cmStdString, cmStdString> &map)
+{
+  for (std::map<cmStdString, cmStdString>::const_iterator it = map.begin();
+       it != map.end(); ++it)
+    {
+    std::vector<std::string> targets;
+    cmSystemTools::ExpandListArgument(it->second.c_str(), targets);
+    this->LinkDependentProperties[it->first].insert(targets.begin(),
+                                                    targets.end());
+    if (!this->GetProperty(it->first.c_str()))
+      {
+      this->LinkImplicitNullProperties.insert(it->first);
+      }
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
 {

+ 10 - 0
Source/cmTarget.h

@@ -487,6 +487,13 @@ public:
   std::vector<std::string> GetIncludeDirectories(const char *config);
   void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
                      bool before = false);
+
+  void GetLinkDependentTargetsForProperty(const std::string &p,
+                                       std::set<std::string> &targets);
+  bool IsNullImpliedByLinkLibraries(const std::string &p);
+
+  void AddLinkDependentTargetsForProperties(
+          const std::map<cmStdString, cmStdString> &map);
 private:
   /**
    * A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -596,6 +603,9 @@ private:
   bool DLLPlatform;
   bool IsApple;
   bool IsImportedTarget;
+  mutable std::map<cmStdString, std::set<std::string> >
+                                                      LinkDependentProperties;
+  mutable std::set<std::string> LinkImplicitNullProperties;
 
   // Cache target output paths for each configuration.
   struct OutputInfo;