[Cmake-commits] CMake branch, next, updated. v2.8.12.2-1602-g7d0f231

Stephen Kelly steveire at gmail.com
Thu Feb 20 17:16:07 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  7d0f231b05e3e1da59a1651d5dc002832aa630d0 (commit)
       via  d1c2adcb28aa49807edc656540d344278f99e6d7 (commit)
       via  7419059bcb3fd50dae16e473003d8faff6a47d81 (commit)
       via  359f3994bf67ba2f50db1332efd2e618c2c1af78 (commit)
       via  b5ec46f2d46eeb8a28014d4c25edf506c778a3f4 (commit)
       via  dad683732906d65a320f2acddeef190ddeda7279 (commit)
       via  922b6ceb33cecf87b2fc8595754a2be5bb4fbe0d (commit)
       via  8050357b01241b26f2326c618543bf7ad00baf6a (commit)
       via  4bd81b8b454a3c2794a334b8f62d618a6a5d9f72 (commit)
       via  17959bfcbce2df77174c4cc55d52788edcc73a77 (commit)
       via  3e6c65029e293c3376050901f2004397c22513eb (commit)
       via  bd8cbbb8b0d7d3cb47588b5439e26372c69869de (commit)
       via  f48987a8e10cbca01bb0c5197f3aca76ddf7a966 (commit)
      from  1e7dcd02000057d1506afae7bdbdb3d4e15e5495 (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=7d0f231b05e3e1da59a1651d5dc002832aa630d0
commit 7d0f231b05e3e1da59a1651d5dc002832aa630d0
Merge: 1e7dcd0 d1c2adc
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 20 17:16:05 2014 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Feb 20 17:16:05 2014 -0500

    Merge topic 'target-SOURCES-refactor' into next
    
    d1c2adcb Handle Mac OSX source flags for individual files lazily.
    7419059b cmGeneratorTarget: Classify sources on demand, not up front.
    359f3994 cmGeneratorTarget: Use a method to access the definition file.
    b5ec46f2 cmTarget: Add GetTransitiveTargetClosure method.
    dad68373 cmTarget: Create a temporary cmTarget in checkInterfacePropertyCompatibility
    922b6ceb cmTarget: Avoid computing languages when computing transitive targets.
    8050357b cmTarget: Move ComputeLinkInterface to the internal class.
    4bd81b8b cmTarget: Extract a ComputeLinkInterfaceLibraries method.
    17959bfc cmTarget: Re-arrange the ComputeLinkInterface method.
    3e6c6502 cmTarget: Extract a ComputeLinkImplementationLanguages method.
    bd8cbbb8 cmTarget: Change GetTransitivePropertyLinkLibraries to output targets.
    f48987a8 cmTarget: Find source files on request.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d1c2adcb28aa49807edc656540d344278f99e6d7
commit d1c2adcb28aa49807edc656540d344278f99e6d7
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 23:15:31 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 a7b2ef3..38b6936 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1013,6 +1013,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;
 }
 
@@ -1076,30 +1093,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=7419059bcb3fd50dae16e473003d8faff6a47d81
commit 7419059bcb3fd50dae16e473003d8faff6a47d81
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 23:15:31 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 e2810ac..a7b2ef3 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -25,6 +25,198 @@
 #include "assert.h"
 
 //----------------------------------------------------------------------------
+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)
 {
@@ -96,11 +288,34 @@ 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) \
+    { \
+    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;
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -129,49 +344,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;
 }
 
 //----------------------------------------------------------------------------
@@ -283,102 +502,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;
-    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 =
@@ -433,7 +556,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=359f3994bf67ba2f50db1332efd2e618c2c1af78
commit 359f3994bf67ba2f50db1332efd2e618c2c1af78
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 23:15:31 2014 +0100

    cmGeneratorTarget: Use a method to access the definition file.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6223ed1..e2810ac 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -431,6 +431,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=b5ec46f2d46eeb8a28014d4c25edf506c778a3f4
commit b5ec46f2d46eeb8a28014d4c25edf506c778a3f4
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 23:15:31 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 301772e..c70ff3b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4424,12 +4424,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 \"";
@@ -4449,7 +4450,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)
     {
@@ -4459,11 +4460,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)
@@ -4643,23 +4640,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;
@@ -5278,6 +5271,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=dad683732906d65a320f2acddeef190ddeda7279
commit dad683732906d65a320f2acddeef190ddeda7279
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 23:15:31 2014 +0100

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

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2e10628..301772e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4459,23 +4459,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 += "\" ";
@@ -4496,7 +4497,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;
           }
@@ -4530,7 +4531,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;
           }
@@ -4561,7 +4562,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=922b6ceb33cecf87b2fc8595754a2be5bb4fbe0d
commit 922b6ceb33cecf87b2fc8595754a2be5bb4fbe0d
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 23:15:30 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 e60fe69..2e10628 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,
@@ -5207,17 +5210,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;
 }
 
 //----------------------------------------------------------------------------
@@ -5225,8 +5281,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;
@@ -5387,8 +5443,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)
@@ -5554,6 +5610,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
       sscanf(reps, "%u", &iface.Multiplicity);
       }
     }
+  iface.Complete = true;
 }
 
 //----------------------------------------------------------------------------
@@ -5582,6 +5639,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=8050357b01241b26f2326c618543bf7ad00baf6a
commit 8050357b01241b26f2326c618543bf7ad00baf6a
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 23:15:30 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 ec9ecf3..e60fe69 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;
@@ -5204,7 +5209,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);
@@ -5452,15 +5458,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.
@@ -5470,16 +5478,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)
@@ -5496,7 +5504,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;
@@ -5504,22 +5512,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 = "_";
@@ -5536,12 +5544,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=4bd81b8b454a3c2794a334b8f62d618a6a5d9f72
commit 4bd81b8b454a3c2794a334b8f62d618a6a5d9f72
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 23:15:30 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 a5c4e6c..ec9ecf3 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5202,7 +5202,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);
@@ -5273,8 +5275,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 = "_";
@@ -5350,8 +5354,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)
     {
@@ -5378,70 +5384,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)
       {
@@ -5506,9 +5448,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";
@@ -5523,8 +5546,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=17959bfcbce2df77174c4cc55d52788edcc73a77
commit 17959bfcbce2df77174c4cc55d52788edcc73a77
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 23:15:30 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 b6394d6..a5c4e6c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5366,7 +5366,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)
@@ -5415,16 +5430,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=3e6c65029e293c3376050901f2004397c22513eb
commit 3e6c65029e293c3376050901f2004397c22513eb
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 23:15:30 2014 +0100

    cmTarget: Extract a ComputeLinkImplementationLanguages method.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 82dcbd1..b6394d6 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5537,6 +5537,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);
@@ -5619,7 +5620,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=bd8cbbb8b0d7d3cb47588b5439e26372c69869de
commit bd8cbbb8b0d7d3cb47588b5439e26372c69869de
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 23:15:30 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 4db27ca..6223ed1 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -63,19 +63,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 =
@@ -225,26 +218,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 62e71a4..82dcbd1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5213,10 +5213,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);
@@ -5228,7 +5227,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;
     }
 
@@ -5246,12 +5253,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.  */

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

    cmTarget: Find source files on request.
    
    In a follow-up, the list of sources will become dependent on
    the config, so check for existence in cmTarget::GetSourceFiles
    instead of up-front with cmGlobalGenerator::CheckTargets().

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 4f3328d..e143eba 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1148,12 +1148,6 @@ void cmGlobalGenerator::Generate()
     return;
     }
 
-  // Check that all targets are valid.
-  if(!this->CheckTargets())
-    {
-    return;
-    }
-
   this->FinalizeTargetCompileInfo();
 
 #ifdef CMAKE_BUILD_WITH_CMAKE
@@ -1306,35 +1300,6 @@ bool cmGlobalGenerator::ComputeTargetDepends()
 }
 
 //----------------------------------------------------------------------------
-bool cmGlobalGenerator::CheckTargets()
-{
-  // Make sure all targets can find their source files.
-  for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
-    {
-    cmTargets& targets =
-      this->LocalGenerators[i]->GetMakefile()->GetTargets();
-    for(cmTargets::iterator ti = targets.begin();
-        ti != targets.end(); ++ti)
-      {
-      cmTarget& target = ti->second;
-      if(target.GetType() == cmTarget::EXECUTABLE ||
-         target.GetType() == cmTarget::STATIC_LIBRARY ||
-         target.GetType() == cmTarget::SHARED_LIBRARY ||
-         target.GetType() == cmTarget::MODULE_LIBRARY ||
-         target.GetType() == cmTarget::OBJECT_LIBRARY ||
-         target.GetType() == cmTarget::UTILITY)
-        {
-        if(!target.FindSourceFiles())
-          {
-          return false;
-          }
-        }
-      }
-    }
-  return true;
-}
-
-//----------------------------------------------------------------------------
 void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
 {
 #ifdef CMAKE_BUILD_WITH_CMAKE
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 753eebf..b66f01e 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -340,7 +340,6 @@ protected:
 
   virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
 
-  bool CheckTargets();
   typedef std::vector<std::pair<cmQtAutoGenerators,
                                 cmTarget const*> > AutogensType;
   void CreateQtAutoGeneratorsTargets(AutogensType& autogens);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 61f05a1..62e71a4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -522,10 +522,11 @@ bool cmTarget::IsBundleOnApple() const
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::FindSourceFiles()
+void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 {
+  assert(this->GetType() != INTERFACE_LIBRARY);
   for(std::vector<cmSourceFile*>::const_iterator
-        si = this->SourceFiles.begin();
+      si = this->SourceFiles.begin();
       si != this->SourceFiles.end(); ++si)
     {
     std::string e;
@@ -535,18 +536,11 @@ bool cmTarget::FindSourceFiles()
         {
         cmake* cm = this->Makefile->GetCMakeInstance();
         cm->IssueMessage(cmake::FATAL_ERROR, e,
-                         this->GetBacktrace());
+                          this->GetBacktrace());
         }
-      return false;
+      return;
       }
     }
-  return true;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
-{
-  assert(this->GetType() != INTERFACE_LIBRARY);
   files = this->SourceFiles;
 }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index a02ed09..4d487f7 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -330,11 +330,6 @@ public:
   void
   GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
 
-  /**
-   * Make sure the full path to all source files is known.
-   */
-  bool FindSourceFiles();
-
   ///! Return the preferred linker language for this target
   const char* GetLinkerLanguage(const char* config = 0,
                                 cmTarget const* head = 0) const;

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

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list