[Cmake-commits] CMake branch, next, updated. v2.8.12.2-1587-g7532e37

Stephen Kelly steveire at gmail.com
Thu Feb 20 16:56:59 EST 2014


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, next has been updated
       via  7532e3712d18ec60ef3f59e979b81b34fb7b99c9 (commit)
       via  ed24799e4d8d7c09f64a3118f58bea0a06068b88 (commit)
       via  2ca4b33b7a04ccde10e81e85b496c6373bae3b1e (commit)
       via  a0f0955fe2110041fee2223325bc4c6fcdae1d4d (commit)
       via  d5fd34d51de9e7372ccaf558a64d83d5850b3901 (commit)
       via  901b72fc372a5ba1a4c702096196a131b1aa08c5 (commit)
       via  846ab8c73fafbf01491c2885113302d906c59e0f (commit)
       via  ed339049d13b14738212ade74426958522e0af9b (commit)
       via  56e4c965fd7dfaf543e74400315e808385b37c0d (commit)
       via  c8c8f2b97fa87a1b3144956c7fbb413ae13630a5 (commit)
       via  a1923fe8eab19fa70736ff565e5ff87dd2ce88af (commit)
       via  8fd4a89f8f5304ee740520cdbe07ee3140f91e99 (commit)
      from  f9183eb38efda48630a47e624096fe1a88bc778b (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 -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7532e3712d18ec60ef3f59e979b81b34fb7b99c9
commit 7532e3712d18ec60ef3f59e979b81b34fb7b99c9
Merge: f9183eb ed24799
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 20 16:56:57 2014 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Feb 20 16:56:57 2014 -0500

    Merge topic 'target-SOURCES-refactor' into next
    
    ed24799e Handle Mac OSX source flags for individual files lazily.
    2ca4b33b cmGeneratorTarget: Classify sources on demand, not up front.
    a0f0955f cmGeneratorTarget: Use a method to access the definition file.
    d5fd34d5 cmTarget: Add GetTransitiveTargetClosure method.
    901b72fc cmTarget: Create a temporary cmTarget in checkInterfacePropertyCompatibility
    846ab8c7 cmTarget: Avoid computing languages when computing transitive targets.
    ed339049 cmTarget: Move ComputeLinkInterface to the internal class.
    56e4c965 cmTarget: Extract a ComputeLinkInterfaceLibraries method.
    c8c8f2b9 cmTarget: Re-arrange the ComputeLinkInterface method.
    a1923fe8 cmTarget: Extract a ComputeLinkImplementationLanguages method.
    8fd4a89f cmTarget: Change GetTransitivePropertyLinkLibraries to output targets.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed24799e4d8d7c09f64a3118f58bea0a06068b88
commit ed24799e4d8d7c09f64a3118f58bea0a06068b88
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Feb 14 12:24:13 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:37 2014 +0100

    Handle Mac OSX source flags for individual files lazily.
    
    The actual list of files will become config dependent in a follow-up
    commit.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 95cb827..004c610 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1035,6 +1035,23 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
     {
     flags = si->second;
     }
+  else
+    {
+    // Handle the MACOSX_PACKAGE_LOCATION property on source files that
+    // were not listed in one of the other lists.
+    if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
+      {
+      flags.MacFolder = location;
+      if(strcmp(location, "Resources") == 0)
+        {
+        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+        }
+      else
+        {
+        flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
+        }
+      }
+    }
   return flags;
 }
 
@@ -1098,30 +1115,4 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
         }
       }
     }
-
-  // Handle the MACOSX_PACKAGE_LOCATION property on source files that
-  // were not listed in one of the other lists.
-  std::vector<cmSourceFile*> sources;
-  this->GetSourceFiles(sources);
-  for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
-      si != sources.end(); ++si)
-    {
-    cmSourceFile* sf = *si;
-    if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
-      {
-      SourceFileFlags& flags = this->SourceFlagsMap[sf];
-      if(flags.Type == cmGeneratorTarget::SourceFileTypeNormal)
-        {
-        flags.MacFolder = location;
-        if(strcmp(location, "Resources") == 0)
-          {
-          flags.Type = cmGeneratorTarget::SourceFileTypeResource;
-          }
-        else
-          {
-          flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
-          }
-        }
-      }
-    }
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2ca4b33b7a04ccde10e81e85b496c6373bae3b1e
commit 2ca4b33b7a04ccde10e81e85b496c6373bae3b1e
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 21:07:31 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:37 2014 +0100

    cmGeneratorTarget: Classify sources on demand, not up front.
    
    Implement a Visitor to hold the sequence of source file tests
    for populating outputs.  Use VS 6 and 7 workaround from Brad
    King for lack of partial template specialization capability.
    
    This will make it possible to use context dependent generator
    expressions to determine the sources of a target.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index c7ef5bf..95cb827 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -43,6 +43,198 @@ bool FindSourceFile(cmSourceFile *sf, cmTarget *tgt)
 }
 
 //----------------------------------------------------------------------------
+void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
+                     cmTarget *target, cmake *cm)
+{
+  if(!badObjLib.empty())
+    {
+    cmOStringStream e;
+    e << "OBJECT library \"" << target->GetName() << "\" contains:\n";
+    for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin();
+        i != badObjLib.end(); ++i)
+      {
+      e << "  " << (*i)->GetLocation().GetName() << "\n";
+      }
+    e << "but may contain only headers and sources that compile.";
+    cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+                     target->GetBacktrace());
+    }
+}
+
+struct ObjectSourcesTag {};
+struct CustomCommandsTag {};
+struct ExtraSourcesTag {};
+struct HeaderSourcesTag {};
+struct ExternalObjectsTag {};
+struct IDLSourcesTag {};
+struct ResxTag {};
+struct ModuleDefinitionFileTag {};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1310
+template<typename Tag, typename OtherTag>
+struct IsSameTag
+{
+  enum {
+    Result = false
+  };
+};
+
+template<typename Tag>
+struct IsSameTag<Tag, Tag>
+{
+  enum {
+    Result = true
+  };
+};
+#else
+struct IsSameTagBase
+{
+  typedef char (&no_type)[1];
+  typedef char (&yes_type)[2];
+  template<typename T> struct Check;
+  template<typename T> static yes_type check(Check<T>*, Check<T>*);
+  static no_type check(...);
+};
+template<typename Tag1, typename Tag2>
+struct IsSameTag: public IsSameTagBase
+{
+  enum {
+    Result = (sizeof(check(static_cast< Check<Tag1>* >(0),
+                           static_cast< Check<Tag2>* >(0))) ==
+              sizeof(yes_type))
+  };
+};
+#endif
+
+template<bool, typename T>
+void doAccept(T&, cmSourceFile*)
+{
+}
+
+template<>
+void doAccept<true,
+              std::vector<cmSourceFile*> >(std::vector<cmSourceFile*>& files,
+                                           cmSourceFile* f)
+{
+  files.push_back(f);
+}
+
+template<>
+void doAccept<true,
+              cmGeneratorTarget::ResxData>(cmGeneratorTarget::ResxData& data,
+                                            cmSourceFile* f)
+{
+  // Build and save the name of the corresponding .h file
+  // This relationship will be used later when building the project files.
+  // Both names would have been auto generated from Visual Studio
+  // where the user supplied the file name and Visual Studio
+  // appended the suffix.
+  std::string resx = f->GetFullPath();
+  std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
+  data.ExpectedResxHeaders.insert(hFileName);
+  data.ResxSources.push_back(f);
+}
+
+template<>
+void doAccept<true, std::string>(std::string& data, cmSourceFile* f)
+{
+  data = f->GetFullPath();
+}
+
+//----------------------------------------------------------------------------
+template<typename Tag, typename DataType = std::vector<cmSourceFile*> >
+struct TagVisitor
+{
+  DataType& Data;
+  std::vector<cmSourceFile*> BadObjLibFiles;
+  cmTarget *Target;
+  cmGlobalGenerator *GlobalGenerator;
+  cmsys::RegularExpression Header;
+  bool IsObjLib;
+
+  TagVisitor(cmTarget *target, DataType& data)
+    : Data(data), Target(target),
+    GlobalGenerator(target->GetMakefile()
+                          ->GetLocalGenerator()->GetGlobalGenerator()),
+    Header(CM_HEADER_REGEX),
+    IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
+  {
+  }
+
+  ~TagVisitor()
+  {
+    reportBadObjLib(this->BadObjLibFiles, this->Target,
+                    this->GlobalGenerator->GetCMakeInstance());
+  }
+
+  void Accept(cmSourceFile *sf)
+  {
+    std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+    if(sf->GetCustomCommand())
+      {
+      doAccept<IsSameTag<Tag, CustomCommandsTag>::Result>(this->Data, sf);
+      }
+    else if(this->Target->GetType() == cmTarget::UTILITY)
+      {
+      doAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>(this->Data, sf);
+      }
+    else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
+      {
+      doAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>(this->Data, sf);
+      }
+    else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+      {
+      doAccept<IsSameTag<Tag, ExternalObjectsTag>::Result>(this->Data, sf);
+      if(this->IsObjLib)
+        {
+        this->BadObjLibFiles.push_back(sf);
+        }
+      }
+    else if(sf->GetLanguage())
+      {
+      doAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>(this->Data, sf);
+      }
+    else if(ext == "def")
+      {
+      doAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>(this->Data,
+                                                                sf);
+      if(this->IsObjLib)
+        {
+        this->BadObjLibFiles.push_back(sf);
+        }
+      }
+    else if(ext == "idl")
+      {
+      doAccept<IsSameTag<Tag, IDLSourcesTag>::Result>(this->Data, sf);
+      if(this->IsObjLib)
+        {
+        this->BadObjLibFiles.push_back(sf);
+        }
+      }
+    else if(ext == "resx")
+      {
+      doAccept<IsSameTag<Tag, ResxTag>::Result>(this->Data, sf);
+      }
+    else if(this->Header.find(sf->GetFullPath().c_str()))
+      {
+      doAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>(this->Data, sf);
+      }
+    else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
+      {
+      doAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>(this->Data, sf);
+      }
+    else
+      {
+      doAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>(this->Data, sf);
+      if(this->IsObjLib && ext != "txt")
+        {
+        this->BadObjLibFiles.push_back(sf);
+        }
+      }
+  }
+};
+
+//----------------------------------------------------------------------------
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
   SourceFileFlagsConstructed(false)
 {
@@ -114,11 +306,38 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
     }
 }
 
+#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
+  { \
+  std::vector<cmSourceFile*> sourceFiles; \
+  this->Target->GetSourceFiles(sourceFiles); \
+  TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
+  for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
+      si != sourceFiles.end(); ++si) \
+    { \
+    if (!FindSourceFile(*si, this->Target)) \
+      { \
+      break; \
+      } \
+    visitor.Accept(*si); \
+    } \
+  } \
+
+
+#define IMPLEMENT_VISIT(DATA) \
+  IMPLEMENT_VISIT_IMPL(DATA, EMPTY) \
+
+#define EMPTY
+#define COMMA ,
+
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &objs) const
+cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &data) const
 {
-  objs = this->ObjectSources;
+  IMPLEMENT_VISIT(ObjectSources);
+  if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
+    {
+    this->ObjectSources = data;
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -147,49 +366,53 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const
+void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& data) const
 {
-  srcs = this->ResxSources;
+  IMPLEMENT_VISIT(IDLSources);
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& srcs) const
+void
+cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& data) const
 {
-  srcs = this->IDLSources;
+  IMPLEMENT_VISIT(HeaderSources);
 }
 
 //----------------------------------------------------------------------------
-void
-cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& srcs) const
+void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& data) const
 {
-  srcs = this->HeaderSources;
+  IMPLEMENT_VISIT(ExtraSources);
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& srcs) const
+void
+cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& data) const
 {
-  srcs = this->ExtraSources;
+  IMPLEMENT_VISIT(CustomCommands);
 }
 
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& srcs) const
+cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& data) const
 {
-  srcs = this->CustomCommands;
+  IMPLEMENT_VISIT(ExternalObjects);
 }
 
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
 {
-  srcs = this->ExpectedResxHeaders;
+  ResxData data;
+  IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
+  srcs = data.ExpectedResxHeaders;
 }
 
 //----------------------------------------------------------------------------
-void
-cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& srcs) const
+void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const
 {
-  srcs = this->ExternalObjects;
+  ResxData data;
+  IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
+  srcs = data.ResxSources;
 }
 
 //----------------------------------------------------------------------------
@@ -301,106 +524,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::ClassifySources()
-{
-  cmsys::RegularExpression header(CM_HEADER_REGEX);
-
-  cmTarget::TargetType targetType = this->Target->GetType();
-  bool isObjLib = targetType == cmTarget::OBJECT_LIBRARY;
-
-  std::vector<cmSourceFile*> badObjLib;
-  std::vector<cmSourceFile*> sources;
-  this->Target->GetSourceFiles(sources);
-  for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
-      si != sources.end(); ++si)
-    {
-    cmSourceFile* sf = *si;
-    if (!FindSourceFile(sf, this->Target))
-      {
-      return;
-      }
-    std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
-    if(sf->GetCustomCommand())
-      {
-      this->CustomCommands.push_back(sf);
-      }
-    else if(targetType == cmTarget::UTILITY)
-      {
-      this->ExtraSources.push_back(sf);
-      }
-    else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
-      {
-      this->HeaderSources.push_back(sf);
-      }
-    else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
-      {
-      this->ExternalObjects.push_back(sf);
-      if(isObjLib) { badObjLib.push_back(sf); }
-      }
-    else if(sf->GetLanguage())
-      {
-      this->ObjectSources.push_back(sf);
-      }
-    else if(ext == "def")
-      {
-      this->ModuleDefinitionFile = sf->GetFullPath();
-      if(isObjLib) { badObjLib.push_back(sf); }
-      }
-    else if(ext == "idl")
-      {
-      this->IDLSources.push_back(sf);
-      if(isObjLib) { badObjLib.push_back(sf); }
-      }
-    else if(ext == "resx")
-      {
-      // Build and save the name of the corresponding .h file
-      // This relationship will be used later when building the project files.
-      // Both names would have been auto generated from Visual Studio
-      // where the user supplied the file name and Visual Studio
-      // appended the suffix.
-      std::string resx = sf->GetFullPath();
-      std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
-      this->ExpectedResxHeaders.insert(hFileName);
-      this->ResxSources.push_back(sf);
-      }
-    else if(header.find(sf->GetFullPath().c_str()))
-      {
-      this->HeaderSources.push_back(sf);
-      }
-    else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
-      {
-      // We only get here if a source file is not an external object
-      // and has an extension that is listed as an ignored file type.
-      // No message or diagnosis should be given.
-      this->ExtraSources.push_back(sf);
-      }
-    else
-      {
-      this->ExtraSources.push_back(sf);
-      if(isObjLib && ext != "txt")
-        {
-        badObjLib.push_back(sf);
-        }
-      }
-    }
-
-  if(!badObjLib.empty())
-    {
-    cmOStringStream e;
-    e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
-    for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
-        i != badObjLib.end(); ++i)
-      {
-      e << "  " << (*i)->GetLocation().GetName() << "\n";
-      }
-    e << "but may contain only headers and sources that compile.";
-    this->GlobalGenerator->GetCMakeInstance()
-      ->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                     this->Target->GetBacktrace());
-    }
-}
-
-//----------------------------------------------------------------------------
 void cmGeneratorTarget::LookupObjectLibraries()
 {
   std::vector<std::string> const& objLibs =
@@ -455,7 +578,9 @@ void cmGeneratorTarget::LookupObjectLibraries()
 //----------------------------------------------------------------------------
 std::string cmGeneratorTarget::GetModuleDefinitionFile() const
 {
-  return this->ModuleDefinitionFile;
+  std::string data;
+  IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
+  return data;
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 51d51f3..1e6ce64 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -82,7 +82,6 @@ public:
    */
   void TraceDependencies();
 
-  void ClassifySources();
   void LookupObjectLibraries();
 
   /** Get sources that must be built before the given source.  */
@@ -113,23 +112,19 @@ public:
   struct SourceFileFlags
   GetTargetSourceFileFlags(const cmSourceFile* sf) const;
 
+  struct ResxData {
+    mutable std::set<std::string> ExpectedResxHeaders;
+    mutable std::vector<cmSourceFile*> ResxSources;
+  };
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
   typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
   SourceEntriesType SourceEntries;
-  std::string ModuleDefinitionFile;
-
-  std::vector<cmSourceFile*> CustomCommands;
-  std::vector<cmSourceFile*> ExtraSources;
-  std::vector<cmSourceFile*> HeaderSources;
-  std::vector<cmSourceFile*> ExternalObjects;
-  std::vector<cmSourceFile*> IDLSources;
-  std::vector<cmSourceFile*> ResxSources;
+
   std::map<cmSourceFile const*, std::string> Objects;
   std::set<cmSourceFile const*> ExplicitObjectName;
-  std::set<std::string> ExpectedResxHeaders;
-  std::vector<cmSourceFile*> ObjectSources;
+  mutable std::vector<cmSourceFile*> ObjectSources;
   std::vector<cmTarget*> ObjectLibraries;
   mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
 
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index e143eba..f76c6d1 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1439,7 +1439,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects()
         continue;
         }
       cmGeneratorTarget* gt = ti->second;
-      gt->ClassifySources();
       gt->LookupObjectLibraries();
       this->ComputeTargetObjects(gt);
       }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a0f0955fe2110041fee2223325bc4c6fcdae1d4d
commit a0f0955fe2110041fee2223325bc4c6fcdae1d4d
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Fri Feb 14 10:23:23 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:36 2014 +0100

    cmGeneratorTarget: Use a method to access the definition file.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 32052ec..c7ef5bf 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -453,6 +453,12 @@ void cmGeneratorTarget::LookupObjectLibraries()
 }
 
 //----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetModuleDefinitionFile() const
+{
+  return this->ModuleDefinitionFile;
+}
+
+//----------------------------------------------------------------------------
 void
 cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9a3339d..51d51f3 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -52,7 +52,7 @@ public:
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator const* GlobalGenerator;
 
-  std::string ModuleDefinitionFile;
+  std::string GetModuleDefinitionFile() const;
 
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
@@ -118,6 +118,7 @@ private:
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
   typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
   SourceEntriesType SourceEntries;
+  std::string ModuleDefinitionFile;
 
   std::vector<cmSourceFile*> CustomCommands;
   std::vector<cmSourceFile*> ExtraSources;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index c3ca85d..5a841ed 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1650,9 +1650,10 @@ void cmMakefileTargetGenerator
   this->AppendTargetDepends(depends);
 
   // Add a dependency on the link definitions file, if any.
-  if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  if(!def.empty())
     {
-    depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
+    depends.push_back(def);
     }
 
   // Add user-specified dependencies.
@@ -2019,7 +2020,8 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
 //----------------------------------------------------------------------------
 void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
 {
-  if(this->GeneratorTarget->ModuleDefinitionFile.empty())
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  if(def.empty())
     {
     return;
     }
@@ -2035,8 +2037,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
   // Append the flag and value.  Use ConvertToLinkReference to help
   // vs6's "cl -link" pass it to the linker.
   std::string flag = defFileFlag;
-  flag += (this->LocalGenerator->ConvertToLinkReference(
-             this->GeneratorTarget->ModuleDefinitionFile.c_str()));
+  flag += (this->LocalGenerator->ConvertToLinkReference(def.c_str()));
   this->LocalGenerator->AppendFlags(flags, flag.c_str());
 }
 
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 900af8d..5f6fc2d 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -498,10 +498,10 @@ cmNinjaTargetGenerator
     {
     this->WriteObjectBuildStatement(*si);
     }
-  if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  if(!def.empty())
     {
-    this->ModuleDefinitionFile = this->ConvertToNinjaPath(
-      this->GeneratorTarget->ModuleDefinitionFile.c_str());
+    this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
     }
 
   {
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index ed7e243..d760b3f 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1666,10 +1666,10 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
   linkOptions.AddFlag("ImportLibrary", imLib.c_str());
   linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
   linkOptions.Parse(flags.c_str());
-  if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
+  std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
+  if(!def.empty())
     {
-    linkOptions.AddFlag("ModuleDefinitionFile",
-                        this->GeneratorTarget->ModuleDefinitionFile.c_str());
+    linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
     }
 
   this->LinkOptions[config] = pOptions.release();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d5fd34d51de9e7372ccaf558a64d83d5850b3901
commit d5fd34d51de9e7372ccaf558a64d83d5850b3901
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 18:27:31 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:36 2014 +0100

    cmTarget: Add GetTransitiveTargetClosure method.
    
    Replace calls to GetLinkInformation with calls to a method to get only
    the target closure, not the link languages etc.  The replaced calls
    are used while evaluating generator expressions only.  This makes
    transitive generator expression evaluation independent from
    the languages of a target.  In a follow-up topic, it will be possible
    to make the languages depend on generator expression evaluation, via
    evaluation of the SOURCES and INTERFACE_SOURCES target properties.
    
    Because the order of entries is not the same as the final link line,
    the order of debug output is different in the RunCMake.CompatibleInterface
    test, because the BOOL_PROP7 target property is evaluated first. Adjust
    the test to account for that new order.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e6b85cb..43adbfc 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4408,12 +4408,13 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
   assert((impliedByUse ^ explicitlySet)
       || (!impliedByUse && !explicitlySet));
 
-  cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
-  if(!info)
+  std::vector<cmTarget*> deps;
+  tgt->GetTransitiveTargetClosure(config, tgt, deps);
+
+  if(deps.empty())
     {
     return propContent;
     }
-  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
   bool propInitialized = explicitlySet;
 
   std::string report = " * Target \"";
@@ -4433,7 +4434,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     report += "\" property not set.\n";
     }
 
-  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+  for(std::vector<cmTarget*>::const_iterator li =
       deps.begin();
       li != deps.end(); ++li)
     {
@@ -4443,11 +4444,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     // target itself has a POSITION_INDEPENDENT_CODE which disagrees
     // with a dependency.
 
-    cmTarget const* theTarget = li->Target;
-    if (!theTarget)
-      {
-      continue;
-      }
+    cmTarget const* theTarget = *li;
 
     const bool ifaceIsSet = theTarget->GetProperties()
                             .find("INTERFACE_" + p)
@@ -4627,23 +4624,19 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
                              const char *interfaceProperty,
                              const char *config)
 {
-  cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
-  if(!info)
+  std::vector<cmTarget*> deps;
+  tgt->GetTransitiveTargetClosure(config, tgt, deps);
+
+  if(deps.empty())
     {
     return false;
     }
 
-  const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
-
-  for(cmComputeLinkInformation::ItemVector::const_iterator li =
+  for(std::vector<cmTarget*>::const_iterator li =
       deps.begin();
       li != deps.end(); ++li)
     {
-    if (!li->Target)
-      {
-      continue;
-      }
-    const char *prop = li->Target->GetProperty(interfaceProperty);
+    const char *prop = (*li)->GetProperty(interfaceProperty);
     if (!prop)
       {
       continue;
@@ -5262,6 +5255,51 @@ cmTarget::GetLinkInterfaceLibraries(const char* config,
 }
 
 //----------------------------------------------------------------------------
+void processILibs(const char* config,
+                  cmTarget const* headTarget,
+                  std::string const& name,
+                  std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
+{
+  if (cmTarget* tgt = headTarget->GetMakefile()
+                                ->FindTargetToUse(name.c_str()))
+    {
+    if (emitted.insert(tgt).second)
+      {
+      tgts.push_back(tgt);
+      std::vector<std::string> ilibs;
+      cmTarget::LinkInterface const* iface =
+                          tgt->GetLinkInterfaceLibraries(config, headTarget);
+      if (iface)
+        {
+        for(std::vector<std::string>::const_iterator
+            it = iface->Libraries.begin();
+            it != iface->Libraries.end(); ++it)
+          {
+          processILibs(config, headTarget, *it, tgts, emitted);
+          }
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetTransitiveTargetClosure(const char* config,
+                                      cmTarget const* headTarget,
+                                      std::vector<cmTarget*> &tgts) const
+{
+  std::set<cmTarget*> emitted;
+
+  cmTarget::LinkImplementation const* impl
+      = this->GetLinkImplementationLibraries(config, headTarget);
+
+  for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
+      it != impl->Libraries.end(); ++it)
+    {
+      processILibs(config, headTarget, *it, tgts, emitted);
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::GetTransitivePropertyTargets(const char* config,
                                       cmTarget const* headTarget,
                                       std::vector<cmTarget*> &tgts) const
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index f3cd874..5dec9e2 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -269,6 +269,9 @@ public:
   void GetTransitivePropertyTargets(const char* config,
                                         cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
+  void GetTransitiveTargetClosure(const char* config,
+                                        cmTarget const* headTarget,
+                                        std::vector<cmTarget*> &libs) const;
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */
diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt
index 17b8a5c..82a34d5 100644
--- a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt
+++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt
@@ -1,4 +1,11 @@
 CMake Debug Log:
+  Boolean compatibility of property "BOOL_PROP7" for target
+  "CompatibleInterface" \(result: "FALSE"\):
+
+   \* Target "CompatibleInterface" property is implied by use.
+   \* Target "iface1" property value "FALSE" \(Agree\)
++
+CMake Debug Log:
   Boolean compatibility of property "BOOL_PROP1" for target
   "CompatibleInterface" \(result: "TRUE"\):
 
@@ -40,13 +47,6 @@ CMake Debug Log:
    \* Target "iface2" property value "FALSE" \(Agree\)
 +
 CMake Debug Log:
-  Boolean compatibility of property "BOOL_PROP7" for target
-  "CompatibleInterface" \(result: "FALSE"\):
-
-   \* Target "CompatibleInterface" property is implied by use.
-   \* Target "iface1" property value "FALSE" \(Agree\)
-+
-CMake Debug Log:
   String compatibility of property "STRING_PROP1" for target
   "CompatibleInterface" \(result: "prop1"\):
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=901b72fc372a5ba1a4c702096196a131b1aa08c5
commit 901b72fc372a5ba1a4c702096196a131b1aa08c5
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Feb 12 13:48:47 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:36 2014 +0100

    cmTarget: Create a temporary cmTarget in checkInterfacePropertyCompatibility
    
    This simplifies further refactoring.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f9efcd1..e6b85cb 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4443,23 +4443,24 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     // target itself has a POSITION_INDEPENDENT_CODE which disagrees
     // with a dependency.
 
-    if (!li->Target)
+    cmTarget const* theTarget = li->Target;
+    if (!theTarget)
       {
       continue;
       }
 
-    const bool ifaceIsSet = li->Target->GetProperties()
+    const bool ifaceIsSet = theTarget->GetProperties()
                             .find("INTERFACE_" + p)
-                            != li->Target->GetProperties().end();
+                            != theTarget->GetProperties().end();
     PropertyType ifacePropContent =
-                    getTypedProperty<PropertyType>(li->Target,
+                    getTypedProperty<PropertyType>(theTarget,
                               ("INTERFACE_" + p).c_str(), 0);
 
     std::string reportEntry;
     if (ifaceIsSet)
       {
       reportEntry += " * Target \"";
-      reportEntry += li->Target->GetName();
+      reportEntry += theTarget->GetName();
       reportEntry += "\" property value \"";
       reportEntry += valueAsString<PropertyType>(ifacePropContent);
       reportEntry += "\" ";
@@ -4480,7 +4481,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
           e << "Property " << p << " on target \""
             << tgt->GetName() << "\" does\nnot match the "
             "INTERFACE_" << p << " property requirement\nof "
-            "dependency \"" << li->Target->GetName() << "\".\n";
+            "dependency \"" << theTarget->GetName() << "\".\n";
           cmSystemTools::Error(e.str().c_str());
           break;
           }
@@ -4514,7 +4515,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
             << tgt->GetName() << "\" is\nimplied to be " << defaultValue
             << " because it was used to determine the link libraries\n"
                "already. The INTERFACE_" << p << " property on\ndependency \""
-            << li->Target->GetName() << "\" is in conflict.\n";
+            << theTarget->GetName() << "\" is in conflict.\n";
           cmSystemTools::Error(e.str().c_str());
           break;
           }
@@ -4545,7 +4546,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
             {
             cmOStringStream e;
             e << "The INTERFACE_" << p << " property of \""
-              << li->Target->GetName() << "\" does\nnot agree with the value "
+              << theTarget->GetName() << "\" does\nnot agree with the value "
                 "of " << p << " already determined\nfor \""
               << tgt->GetName() << "\".\n";
             cmSystemTools::Error(e.str().c_str());

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=846ab8c73fafbf01491c2885113302d906c59e0f
commit 846ab8c73fafbf01491c2885113302d906c59e0f
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 15:02:09 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:52:36 2014 +0100

    cmTarget: Avoid computing languages when computing transitive targets.
    
    For the OLD CMP0022 behavior, we need to treat the implementation
    as the interface when computing the interface libraries.  Make it
    possible to do that without computing the link languages by adding
    a new GetLinkImplementationLibraries method.  Extend the existing
    GetLinkImplementation method to populate the languages if the
    libraries have already been computed and cached.
    
    Change GetTransitivePropertyTargets to invoke GetLinkInterfaceLibraries
    instead of GetLinkInterface.  This is key, as it is a method called
    by cmGeneratorExpressionEvaluator.
    
    Change the cmGeneratorExpressionEvaluator to invoke
    GetLinkImplementationLibraries instead of GetLinkImplementation.

diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index ebedf65..bdefcfb 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -1099,9 +1099,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
     else if (std::find_if(transBegin, transEnd,
                           cmStrCmp(interfacePropertyName)) != transEnd)
       {
-      const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
-                                                    context->Config,
-                                                    headTarget);
+      const cmTarget::LinkImplementation *impl
+          = target->GetLinkImplementationLibraries(context->Config,
+                                                   headTarget);
       if(impl)
         {
         linkedTargetsContent =
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 72a99ed..f9efcd1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -96,8 +96,11 @@ public:
   // Cache link interface computation from each configuration.
   struct OptionalLinkInterface: public cmTarget::LinkInterface
   {
-    OptionalLinkInterface(): Exists(false) {}
+    OptionalLinkInterface():
+      Exists(false), Complete(false), ExplicitLibraries(0) {}
     bool Exists;
+    bool Complete;
+    const char* ExplicitLibraries;
   };
   void ComputeLinkInterface(cmTarget const* thisTarget,
                             const char* config, OptionalLinkInterface& iface,
@@ -5191,17 +5194,70 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
     {
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
-    const char* explicitLibraries =
+    iface.ExplicitLibraries =
         this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
-    this->Internal->ComputeLinkInterface(this, config, iface,
-                                         head, explicitLibraries);
+    if (iface.Exists)
+      {
+      this->Internal->ComputeLinkInterface(this, config, iface,
+                                           head, iface.ExplicitLibraries);
+      }
+
+    // Store the information for this configuration.
+    cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
+    i = this->Internal->LinkInterfaceMap.insert(entry).first;
+    }
+  else if(!i->second.Complete && i->second.Exists)
+    {
+    this->Internal->ComputeLinkInterface(this, config, i->second, head,
+                                         i->second.ExplicitLibraries);
+    }
+
+  return i->second.Exists ? &i->second : 0;
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkInterface const*
+cmTarget::GetLinkInterfaceLibraries(const char* config,
+                                    cmTarget const* head) const
+{
+  // Imported targets have their own link interface.
+  if(this->IsImported())
+    {
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
+      {
+      return &info->LinkInterface;
+      }
+    return 0;
+    }
+
+  // Link interfaces are not supported for executables that do not
+  // export symbols.
+  if(this->GetType() == cmTarget::EXECUTABLE &&
+     !this->IsExecutableWithExports())
+    {
+    return 0;
+    }
+
+  // Lookup any existing link interface for this configuration.
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
+  cmTargetInternals::LinkInterfaceMapType::iterator
+    i = this->Internal->LinkInterfaceMap.find(key);
+  if(i == this->Internal->LinkInterfaceMap.end())
+    {
+    // Compute the link interface for this configuration.
+    cmTargetInternals::OptionalLinkInterface iface;
+    iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
+                                                                iface,
+                                                                head,
+                                                                iface.Exists);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
     i = this->Internal->LinkInterfaceMap.insert(entry).first;
     }
 
-  return i->second.Exists? &i->second : 0;
+  return i->second.Exists ? &i->second : 0;
 }
 
 //----------------------------------------------------------------------------
@@ -5209,8 +5265,8 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
                                       cmTarget const* headTarget,
                                       std::vector<cmTarget*> &tgts) const
 {
-  cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
-                                                                headTarget);
+  cmTarget::LinkInterface const* iface
+                        = this->GetLinkInterfaceLibraries(config, headTarget);
   if (!iface)
     {
     return;
@@ -5371,8 +5427,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
     // to the link implementation.
     {
     // The link implementation is the default link interface.
-    LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                              headTarget);
+    LinkImplementation const* impl =
+        this->GetLinkImplementationLibraries(config, headTarget);
     iface.Libraries = impl->Libraries;
     if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
        !this->Internal->PolicyWarnedCMP0022)
@@ -5538,6 +5594,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
       sscanf(reps, "%u", &iface.Multiplicity);
       }
     }
+  iface.Complete = true;
 }
 
 //----------------------------------------------------------------------------
@@ -5566,6 +5623,40 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
     i = this->Internal->LinkImplMap.insert(entry).first;
     }
+  else if (i->second.Languages.empty())
+    {
+    this->ComputeLinkImplementationLanguages(i->second);
+    }
+
+  return &i->second;
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkImplementation const*
+cmTarget::GetLinkImplementationLibraries(const char* config,
+                                         cmTarget const* head) const
+{
+  // There is no link implementation for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
+  // Lookup any existing link implementation for this configuration.
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
+  cmTargetInternals::LinkImplMapType::iterator
+    i = this->Internal->LinkImplMap.find(key);
+  if(i == this->Internal->LinkImplMap.end())
+    {
+    // Compute the link implementation for this configuration.
+    LinkImplementation impl;
+    this->ComputeLinkImplementation(config, impl, head);
+
+    // Store the information for this configuration.
+    cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
+    i = this->Internal->LinkImplMap.insert(entry).first;
+    }
 
   return &i->second;
 }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8bc5af4..f3cd874 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -264,6 +264,8 @@ public:
       if the target cannot be linked.  */
   LinkInterface const* GetLinkInterface(const char* config,
                                         cmTarget const* headTarget) const;
+  LinkInterface const* GetLinkInterfaceLibraries(const char* config,
+                                        cmTarget const* headTarget) const;
   void GetTransitivePropertyTargets(const char* config,
                                         cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
@@ -285,6 +287,9 @@ public:
   LinkImplementation const* GetLinkImplementation(const char* config,
                                                   cmTarget const* head) const;
 
+  LinkImplementation const* GetLinkImplementationLibraries(const char* config,
+                                                  cmTarget const* head) const;
+
   /** Link information from the transitive closure of the link
       implementation and the interfaces of its dependencies.  */
   struct LinkClosure

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed339049d13b14738212ade74426958522e0af9b
commit ed339049d13b14738212ade74426958522e0af9b
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 16:00:55 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:42:44 2014 +0100

    cmTarget: Move ComputeLinkInterface to the internal class.
    
    In a follow-up, this will use the OptionalLinkInterface in its
    API. That class is in the cmTargetInternals class.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index bfb216a..72a99ed 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -99,6 +99,11 @@ public:
     OptionalLinkInterface(): Exists(false) {}
     bool Exists;
   };
+  void ComputeLinkInterface(cmTarget const* thisTarget,
+                            const char* config, OptionalLinkInterface& iface,
+                            cmTarget const* head,
+                            const char *explicitLibraries) const;
+
   typedef std::map<TargetConfigPair, OptionalLinkInterface>
                                                           LinkInterfaceMapType;
   LinkInterfaceMapType LinkInterfaceMap;
@@ -5188,7 +5193,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
     cmTargetInternals::OptionalLinkInterface iface;
     const char* explicitLibraries =
         this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
-    this->ComputeLinkInterface(config, iface, head, explicitLibraries);
+    this->Internal->ComputeLinkInterface(this, config, iface,
+                                         head, explicitLibraries);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@@ -5436,15 +5442,17 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
-                                    cmTarget const* headTarget,
-                                    const char* explicitLibraries) const
+void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
+                                             const char* config,
+                                             OptionalLinkInterface& iface,
+                                             cmTarget const* headTarget,
+                                          const char* explicitLibraries) const
 {
   if(explicitLibraries)
     {
-    if(this->GetType() == cmTarget::SHARED_LIBRARY
-        || this->GetType() == cmTarget::STATIC_LIBRARY
-        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
+    if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
+        || thisTarget->GetType() == cmTarget::STATIC_LIBRARY
+        || thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       // Shared libraries may have runtime implementation dependencies
       // on other shared libraries that are not in the interface.
@@ -5454,16 +5462,16 @@ void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
         {
         emitted.insert(*li);
         }
-      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
+      if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
-        LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                                  headTarget);
+        cmTarget::LinkImplementation const* impl =
+            thisTarget->GetLinkImplementation(config, headTarget);
         for(std::vector<std::string>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
           if(emitted.insert(*li).second)
             {
-            if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
+            if(cmTarget* tgt = thisTarget->Makefile->FindTargetToUse(*li))
               {
               // This is a runtime dependency on another shared library.
               if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
@@ -5480,7 +5488,7 @@ void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
               }
             }
           }
-        if(this->LinkLanguagePropagatesToDependents())
+        if(thisTarget->LinkLanguagePropagatesToDependents())
           {
           // Targets using this archive need its language runtime libraries.
           iface.Languages = impl->Languages;
@@ -5488,22 +5496,22 @@ void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
         }
       }
     }
-  else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
-        || this->PolicyStatusCMP0022 == cmPolicies::OLD)
+  else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
+        || thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
     {
     // The link implementation is the default link interface.
-    LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                              headTarget);
+    cmTarget::LinkImplementation const*
+                impl = thisTarget->GetLinkImplementation(config, headTarget);
     iface.ImplementationIsInterface = true;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
-    if(this->LinkLanguagePropagatesToDependents())
+    if(thisTarget->LinkLanguagePropagatesToDependents())
       {
       // Targets using this archive need its language runtime libraries.
       iface.Languages = impl->Languages;
       }
     }
 
-  if(this->GetType() == cmTarget::STATIC_LIBRARY)
+  if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
     {
     // Construct the property name suffix for this configuration.
     std::string suffix = "_";
@@ -5520,12 +5528,12 @@ void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     // dependencies?
     std::string propName = "LINK_INTERFACE_MULTIPLICITY";
     propName += suffix;
-    if(const char* config_reps = this->GetProperty(propName.c_str()))
+    if(const char* config_reps = thisTarget->GetProperty(propName.c_str()))
       {
       sscanf(config_reps, "%u", &iface.Multiplicity);
       }
     else if(const char* reps =
-            this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+            thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
       {
       sscanf(reps, "%u", &iface.Multiplicity);
       }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 09c6f74..8bc5af4 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -690,10 +690,6 @@ private:
   void CheckPropertyCompatibility(cmComputeLinkInformation *info,
                                   const char* config) const;
 
-  void ComputeLinkInterface(const char* config, LinkInterface& iface,
-                            cmTarget const* head,
-                            const char *explicitLibraries) const;
-
   const char* ComputeLinkInterfaceLibraries(const char* config,
                                             LinkInterface& iface,
                                             cmTarget const* head,

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=56e4c965fd7dfaf543e74400315e808385b37c0d
commit 56e4c965fd7dfaf543e74400315e808385b37c0d
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 11:07:22 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:42:31 2014 +0100

    cmTarget: Extract a ComputeLinkInterfaceLibraries method.
    
    When evaluating the SOURCES property, we will need to be able to access
    the link libraries without accessing the link languages, as the languages
    depend on the SOURCES.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 99e0b50..bfb216a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5186,7 +5186,9 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
     {
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
-    iface.Exists = this->ComputeLinkInterface(config, iface, head);
+    const char* explicitLibraries =
+        this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
+    this->ComputeLinkInterface(config, iface, head, explicitLibraries);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@@ -5257,8 +5259,10 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
-                                    cmTarget const* headTarget) const
+const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
+                                           LinkInterface& iface,
+                                           cmTarget const* headTarget,
+                                           bool &exists) const
 {
   // Construct the property name suffix for this configuration.
   std::string suffix = "_";
@@ -5334,8 +5338,10 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
      (this->GetType() == cmTarget::EXECUTABLE ||
       (this->GetType() == cmTarget::MODULE_LIBRARY)))
     {
-    return false;
+    exists = false;
+    return 0;
     }
+  exists = true;
 
   if(explicitLibraries)
     {
@@ -5362,70 +5368,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     LinkImplementation const* impl = this->GetLinkImplementation(config,
                                                               headTarget);
     iface.Libraries = impl->Libraries;
-    }
-
-  if(explicitLibraries)
-    {
-    if(this->GetType() == cmTarget::SHARED_LIBRARY
-        || this->GetType() == cmTarget::STATIC_LIBRARY
-        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
-      {
-      // Shared libraries may have runtime implementation dependencies
-      // on other shared libraries that are not in the interface.
-      std::set<cmStdString> emitted;
-      for(std::vector<std::string>::const_iterator
-            li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
-        {
-        emitted.insert(*li);
-        }
-      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
-        {
-        LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                                  headTarget);
-        for(std::vector<std::string>::const_iterator
-              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
-          {
-          if(emitted.insert(*li).second)
-            {
-            if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
-              {
-              // This is a runtime dependency on another shared library.
-              if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
-                {
-                iface.SharedDeps.push_back(*li);
-                }
-              }
-            else
-              {
-              // TODO: Recognize shared library file names.  Perhaps this
-              // should be moved to cmComputeLinkInformation, but that creates
-              // a chicken-and-egg problem since this list is needed for its
-              // construction.
-              }
-            }
-          }
-        if(this->LinkLanguagePropagatesToDependents())
-          {
-          // Targets using this archive need its language runtime libraries.
-          iface.Languages = impl->Languages;
-          }
-        }
-      }
-    }
-  else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
-        || this->PolicyStatusCMP0022 == cmPolicies::OLD)
-    {
-    // The link implementation is the default link interface.
-    LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                              headTarget);
-    iface.ImplementationIsInterface = true;
-    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
-    if(this->LinkLanguagePropagatesToDependents())
-      {
-      // Targets using this archive need its language runtime libraries.
-      iface.Languages = impl->Languages;
-      }
-
     if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
        !this->Internal->PolicyWarnedCMP0022)
       {
@@ -5490,9 +5432,90 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
         }
       }
     }
+  return explicitLibraries;
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
+                                    cmTarget const* headTarget,
+                                    const char* explicitLibraries) const
+{
+  if(explicitLibraries)
+    {
+    if(this->GetType() == cmTarget::SHARED_LIBRARY
+        || this->GetType() == cmTarget::STATIC_LIBRARY
+        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
+      {
+      // Shared libraries may have runtime implementation dependencies
+      // on other shared libraries that are not in the interface.
+      std::set<cmStdString> emitted;
+      for(std::vector<std::string>::const_iterator
+          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
+        {
+        emitted.insert(*li);
+        }
+      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
+        {
+        LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                                  headTarget);
+        for(std::vector<std::string>::const_iterator
+              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
+          {
+          if(emitted.insert(*li).second)
+            {
+            if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
+              {
+              // This is a runtime dependency on another shared library.
+              if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
+                {
+                iface.SharedDeps.push_back(*li);
+                }
+              }
+            else
+              {
+              // TODO: Recognize shared library file names.  Perhaps this
+              // should be moved to cmComputeLinkInformation, but that creates
+              // a chicken-and-egg problem since this list is needed for its
+              // construction.
+              }
+            }
+          }
+        if(this->LinkLanguagePropagatesToDependents())
+          {
+          // Targets using this archive need its language runtime libraries.
+          iface.Languages = impl->Languages;
+          }
+        }
+      }
+    }
+  else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
+        || this->PolicyStatusCMP0022 == cmPolicies::OLD)
+    {
+    // The link implementation is the default link interface.
+    LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                              headTarget);
+    iface.ImplementationIsInterface = true;
+    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+    if(this->LinkLanguagePropagatesToDependents())
+      {
+      // Targets using this archive need its language runtime libraries.
+      iface.Languages = impl->Languages;
+      }
+    }
 
   if(this->GetType() == cmTarget::STATIC_LIBRARY)
     {
+    // Construct the property name suffix for this configuration.
+    std::string suffix = "_";
+    if(config && *config)
+      {
+      suffix += cmSystemTools::UpperCase(config);
+      }
+    else
+      {
+      suffix += "NOCONFIG";
+      }
+
     // How many repetitions are needed if this library has cyclic
     // dependencies?
     std::string propName = "LINK_INTERFACE_MULTIPLICITY";
@@ -5507,8 +5530,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
       sscanf(reps, "%u", &iface.Multiplicity);
       }
     }
-
-  return true;
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 234adba..09c6f74 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -690,8 +690,14 @@ private:
   void CheckPropertyCompatibility(cmComputeLinkInformation *info,
                                   const char* config) const;
 
-  bool ComputeLinkInterface(const char* config, LinkInterface& iface,
-                                        cmTarget const* head) const;
+  void ComputeLinkInterface(const char* config, LinkInterface& iface,
+                            cmTarget const* head,
+                            const char *explicitLibraries) const;
+
+  const char* ComputeLinkInterfaceLibraries(const char* config,
+                                            LinkInterface& iface,
+                                            cmTarget const* head,
+                                            bool &exists) const;
 
   void ComputeLinkImplementation(const char* config,
                                  LinkImplementation& impl,

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c8c8f2b97fa87a1b3144956c7fbb413ae13630a5
commit c8c8f2b97fa87a1b3144956c7fbb413ae13630a5
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 15:11:07 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:41:28 2014 +0100

    cmTarget: Re-arrange the ComputeLinkInterface method.
    
    Arrange the logic so that the part which deals with libraries only is
    at the top.  In a follow-up commit, this will be split into two methods.
    
    Ensure that the explanatory CMP0022 comment is only present in one
    location.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cdd904d..99e0b50 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5350,7 +5350,22 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
                                         false,
                                         headTarget,
                                         this, &dagChecker), iface.Libraries);
+    }
+  else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
+        || this->PolicyStatusCMP0022 == cmPolicies::OLD)
+    // If CMP0022 is NEW then the plain tll signature sets the
+    // INTERFACE_LINK_LIBRARIES, so if we get here then the project
+    // cleared the property explicitly and we should not fall back
+    // to the link implementation.
+    {
+    // The link implementation is the default link interface.
+    LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                              headTarget);
+    iface.Libraries = impl->Libraries;
+    }
 
+  if(explicitLibraries)
+    {
     if(this->GetType() == cmTarget::SHARED_LIBRARY
         || this->GetType() == cmTarget::STATIC_LIBRARY
         || this->GetType() == cmTarget::INTERFACE_LIBRARY)
@@ -5399,16 +5414,11 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     }
   else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
         || this->PolicyStatusCMP0022 == cmPolicies::OLD)
-    // If CMP0022 is NEW then the plain tll signature sets the
-    // INTERFACE_LINK_LIBRARIES, so if we get here then the project
-    // cleared the property explicitly and we should not fall back
-    // to the link implementation.
     {
     // The link implementation is the default link interface.
     LinkImplementation const* impl = this->GetLinkImplementation(config,
                                                               headTarget);
     iface.ImplementationIsInterface = true;
-    iface.Libraries = impl->Libraries;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     if(this->LinkLanguagePropagatesToDependents())
       {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a1923fe8eab19fa70736ff565e5ff87dd2ce88af
commit a1923fe8eab19fa70736ff565e5ff87dd2ce88af
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 11:26:08 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:35:16 2014 +0100

    cmTarget: Extract a ComputeLinkImplementationLanguages method.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 457627c..cdd904d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5521,6 +5521,7 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
     this->ComputeLinkImplementation(config, impl, head);
+    this->ComputeLinkImplementationLanguages(impl);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -5603,7 +5604,12 @@ void cmTarget::ComputeLinkImplementation(const char* config,
       impl.WrongConfigLibraries.push_back(item);
       }
     }
+}
 
+//----------------------------------------------------------------------------
+void
+cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
+{
   // This target needs runtime libraries for its source languages.
   std::set<cmStdString> languages;
   // Get languages used in our source files.
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 0d85259..234adba 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -696,6 +696,7 @@ private:
   void ComputeLinkImplementation(const char* config,
                                  LinkImplementation& impl,
                                  cmTarget const* head) const;
+  void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
   void ComputeLinkClosure(const char* config, LinkClosure& lc,
                           cmTarget const* head) const;
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8fd4a89f8f5304ee740520cdbe07ee3140f91e99
commit 8fd4a89f8f5304ee740520cdbe07ee3140f91e99
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 13 09:53:27 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 22:35:16 2014 +0100

    cmTarget: Change GetTransitivePropertyLinkLibraries to output targets.
    
    The callers already skip non-targets, so unify the target search.
    
    Change supporting functions to accept a container of targets instead
    of strings where possible.

diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 7036992..ebedf65 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -800,7 +800,7 @@ static const char* targetPropertyTransitiveWhitelist[] = {
 
 #undef TRANSITIVE_PROPERTY_NAME
 
-std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
+std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
                                   cmTarget const* target,
                                   cmTarget const* headTarget,
                                   cmGeneratorExpressionContext *context,
@@ -811,23 +811,21 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
 
   std::string sep;
   std::string depString;
-  for (std::vector<std::string>::const_iterator
-      it = libraries.begin();
-      it != libraries.end(); ++it)
+  for (std::vector<cmTarget*>::const_iterator
+      it = targets.begin();
+      it != targets.end(); ++it)
     {
-    if (*it == target->GetName())
+    if (*it == target)
       {
       // 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.
       continue;
       }
-    if (context->Makefile->FindTargetToUse(*it))
-      {
-      depString +=
-        sep + "$<TARGET_PROPERTY:" + *it + "," + interfacePropertyName + ">";
-      sep = ";";
-      }
+    depString +=
+      sep + "$<TARGET_PROPERTY:" +
+        (*it)->GetName() + "," + interfacePropertyName + ">";
+    sep = ";";
     }
   cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
   std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
@@ -843,6 +841,27 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
   return linkedTargetsContent;
 }
 
+std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
+                                  cmTarget const* target,
+                                  cmTarget const* headTarget,
+                                  cmGeneratorExpressionContext *context,
+                                  cmGeneratorExpressionDAGChecker *dagChecker,
+                                  const std::string &interfacePropertyName)
+{
+  std::vector<cmTarget*> tgts;
+  for (std::vector<std::string>::const_iterator
+      it = libraries.begin();
+      it != libraries.end(); ++it)
+    {
+    if (cmTarget *tgt = context->Makefile->FindTargetToUse(*it))
+      {
+      tgts.push_back(tgt);
+      }
+    }
+  return getLinkedTargetsContent(tgts, target, headTarget, context,
+                                 dagChecker, interfacePropertyName);
+}
+
 //----------------------------------------------------------------------------
 static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 {
@@ -1065,13 +1084,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                      cmStrCmp(propertyName)) != transEnd)
       {
 
-      std::vector<std::string> libs;
-      target->GetTransitivePropertyLinkLibraries(context->Config,
-                                                 headTarget, libs);
-      if (!libs.empty())
+      std::vector<cmTarget*> tgts;
+      target->GetTransitivePropertyTargets(context->Config,
+                                                 headTarget, tgts);
+      if (!tgts.empty())
         {
         linkedTargetsContent =
-                  getLinkedTargetsContent(libs, target,
+                  getLinkedTargetsContent(tgts, target,
                                           headTarget,
                                           context, &dagChecker,
                                           interfacePropertyName);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a7ff56a..32052ec 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -81,19 +81,12 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const
   return 0;
 }
 
-static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
+static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
                                   const char *config, cmTarget *headTarget,
                                   cmGeneratorExpressionDAGChecker *dagChecker,
                                   std::vector<std::string>& result,
                                   bool excludeImported)
 {
-  cmTarget* depTgt = mf->FindTargetToUse(name);
-
-  if (!depTgt)
-    {
-    return;
-    }
-
   cmListFileBacktrace lfbt;
 
   if (const char* dirs =
@@ -243,26 +236,25 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
                                           &dagChecker), result);
       }
 
-    std::set<cmStdString> uniqueDeps;
+    std::set<cmTarget*> uniqueDeps;
     for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
         li != impl->Libraries.end(); ++li)
       {
-      if (uniqueDeps.insert(*li).second)
+      cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
+      if (!tgt)
         {
-        cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
-
-        if (!tgt)
-          {
-          continue;
-          }
+        continue;
+        }
 
-        handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
+      if (uniqueDeps.insert(tgt).second)
+        {
+        handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
                                 &dagChecker, result, excludeImported);
 
-        std::vector<std::string> deps;
-        tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps);
+        std::vector<cmTarget*> deps;
+        tgt->GetTransitivePropertyTargets(config, this->Target, deps);
 
-        for(std::vector<std::string>::const_iterator di = deps.begin();
+        for(std::vector<cmTarget*>::const_iterator di = deps.begin();
             di != deps.end(); ++di)
           {
           if (uniqueDeps.insert(*di).second)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9f8dafe..457627c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5197,10 +5197,9 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetTransitivePropertyLinkLibraries(
-                                      const char* config,
+void cmTarget::GetTransitivePropertyTargets(const char* config,
                                       cmTarget const* headTarget,
-                                      std::vector<std::string> &libs) const
+                                      std::vector<cmTarget*> &tgts) const
 {
   cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
                                                                 headTarget);
@@ -5212,7 +5211,15 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
       || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
       || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
     {
-    libs = iface->Libraries;
+    for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
+        it != iface->Libraries.end(); ++it)
+      {
+      if (cmTarget* tgt = headTarget->GetMakefile()
+                                    ->FindTargetToUse(it->c_str()))
+        {
+        tgts.push_back(tgt);
+        }
+      }
     return;
     }
 
@@ -5230,12 +5237,23 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
   cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
                                               linkIfaceProp, 0, 0);
   dagChecker.SetTransitivePropertiesOnly();
+  std::vector<std::string> libs;
   cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
                                       this->Makefile,
                                       config,
                                       false,
                                       headTarget,
                                       this, &dagChecker), libs);
+
+  for(std::vector<std::string>::const_iterator it = libs.begin();
+      it != libs.end(); ++it)
+    {
+    if (cmTarget* tgt = headTarget->GetMakefile()
+                                  ->FindTargetToUse(it->c_str()))
+      {
+      tgts.push_back(tgt);
+      }
+    }
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 4d487f7..0d85259 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -264,9 +264,9 @@ public:
       if the target cannot be linked.  */
   LinkInterface const* GetLinkInterface(const char* config,
                                         cmTarget const* headTarget) const;
-  void GetTransitivePropertyLinkLibraries(const char* config,
+  void GetTransitivePropertyTargets(const char* config,
                                         cmTarget const* headTarget,
-                                        std::vector<std::string> &libs) const;
+                                        std::vector<cmTarget*> &libs) const;
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */

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

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list