[Cmake-commits] CMake branch, next, updated. v2.8.12.2-1563-gc0da77f

Stephen Kelly steveire at gmail.com
Thu Feb 20 11:40:12 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  c0da77f50251b68d982cab1a9c17f142849552e9 (commit)
       via  0460c8a662ff1ccf1de9441bd39088ce1c4d5445 (commit)
       via  492b2f46c67554ae01c85b98c0440eed769d4ed2 (commit)
       via  0ab51009c691eee9bd736baf404e4cc79fe5e1cf (commit)
       via  d51107beda361eee422b24d7e6718de2dc951de7 (commit)
       via  ad9f7469910f9c651f3fc7793cd64b7bc0cf2de2 (commit)
       via  99745177995ff85e34535411ce38a5b0d3d9795f (commit)
       via  2cdfe8d1ca9803d977ac76d6efe79153f0141949 (commit)
       via  cf080619aba2b68cbae94df950848f49aa7843ed (commit)
       via  16f9d9c9bc968874673cf40bd1787df4095de712 (commit)
       via  d804159f4f0c241d7da3b54213bbf5fe5958c38b (commit)
       via  e6e97b13f72185a043953bef72e9f32bb585f82a (commit)
       via  65b48d438d8745e6017bfee84f3352f550755454 (commit)
       via  27201405bdf4fa154e816b6c3a11ec4e0c2f42b8 (commit)
       via  44e784342d34d63db79214203108e3f968992d15 (commit)
      from  5122fe0a1a823f51f9c88d8a0538557c3383d5f7 (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=c0da77f50251b68d982cab1a9c17f142849552e9
commit c0da77f50251b68d982cab1a9c17f142849552e9
Merge: 5122fe0 0460c8a
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 20 11:40:09 2014 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Feb 20 11:40:09 2014 -0500

    Merge topic 'target-SOURCES-refactor' into next
    
    0460c8a6 Handle Mac OSX source flags for individual files lazily.
    492b2f46 cmGeneratorTarget: Classify sources on demand, not up front.
    0ab51009 cmGeneratorTarget: Use a method to access the definition file.
    d51107be cmTarget: Add GetTransitiveTargetClosure method.
    ad9f7469 cmTarget: Create a temporary cmTarget in checkInterfacePropertyCompatibility
    99745177 cmTarget: Avoid computing languages when computing transitive targets.
    2cdfe8d1 cmTarget: Move ComputeLinkInterface to the internal class.
    cf080619 cmTarget: Extract a ComputeLinkInterfaceLibraries method.
    16f9d9c9 cmTarget: Re-arrange the ComputeLinkInterface method.
    d804159f cmTarget: Extract a ComputeLinkImplementationLanguages method.
    e6e97b13 cmTarget: Change GetTransitivePropertyLinkLibraries to output targets.
    65b48d43 cmTarget: Find source files when classifying them.
    27201405 cmTarget: Move SourceFileFlags to cmGeneratorTarget.
    44e78434 CMake Nightly Date Stamp


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0460c8a662ff1ccf1de9441bd39088ce1c4d5445
commit 0460c8a662ff1ccf1de9441bd39088ce1c4d5445
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 17:38:06 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 bc6ea7f..1b24e93 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1020,6 +1020,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;
 }
 
@@ -1083,30 +1100,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=492b2f46c67554ae01c85b98c0440eed769d4ed2
commit 492b2f46c67554ae01c85b98c0440eed769d4ed2
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 17:38:05 2014 +0100

    cmGeneratorTarget: Classify sources on demand, not up front.
    
    Implement a Visitor to hold the sequence of source file tests
    for populating outputs.
    
    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..bc6ea7f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -43,8 +43,188 @@ 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 {};
+
+template<typename, typename>
+struct IsSameTag
+{
+  enum {
+    Result = false
+  };
+};
+
+template<typename Tag>
+struct IsSameTag<Tag, Tag>
+{
+  enum {
+    Result = true
+  };
+};
+
+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)
+  SourceFileFlagsConstructed(false),
+  ObjectSourcesDone(false),
+  IDLSourcesDone(false),
+  ExtraSourcesDone(false),
+  HeaderSourcesDone(false),
+  CustomCommandsDone(false),
+  ExternalObjectsDone(false),
+  ResxDone(false),
+  ModuleDefinitionFileDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
@@ -114,11 +294,35 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
     }
 }
 
+#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
+if (!this->DATA ## Done) \
+  { \
+  std::vector<cmSourceFile*> sourceFiles; \
+  this->Target->GetSourceFiles(sourceFiles); \
+  TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, this->DATA); \
+  for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
+      si != sourceFiles.end(); ++si) \
+    { \
+    if (!FindSourceFile(*si, this->Target)) \
+      { \
+      break; \
+      } \
+    visitor.Accept(*si); \
+    } \
+  this->DATA ## Done = true; \
+  } \
+data = this->DATA;
+
+#define IMPLEMENT_VISIT(DATA) \
+  IMPLEMENT_VISIT_IMPL(DATA, ) \
+
+#define COMMA ,
+
 //----------------------------------------------------------------------------
 void
-cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &objs) const
+cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &data) const
 {
-  objs = this->ObjectSources;
+  IMPLEMENT_VISIT(ObjectSources);
 }
 
 //----------------------------------------------------------------------------
@@ -147,49 +351,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 = this->Resx;
+  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 = this->Resx;
+  IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
+  srcs = data.ResxSources;
 }
 
 //----------------------------------------------------------------------------
@@ -301,106 +509,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 +563,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..381adc7 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,28 +112,40 @@ 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;
+  mutable std::string ModuleDefinitionFile;
+
+  mutable ResxData Resx;
+
+  mutable bool SourceFileFlagsConstructed;
+  mutable bool ObjectSourcesDone;
+  mutable bool IDLSourcesDone;
+  mutable bool ExtraSourcesDone;
+  mutable bool HeaderSourcesDone;
+  mutable bool CustomCommandsDone;
+  mutable bool ExternalObjectsDone;
+  mutable bool ResxDone;
+  mutable bool ModuleDefinitionFileDone;
+  mutable std::vector<cmSourceFile*> CustomCommands;
+  mutable std::vector<cmSourceFile*> ExtraSources;
+  mutable std::vector<cmSourceFile*> HeaderSources;
+  mutable std::vector<cmSourceFile*> ExternalObjects;
+  mutable std::vector<cmSourceFile*> IDLSources;
   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;
 
   void ConstructSourceFileFlags() const;
-  mutable bool SourceFileFlagsConstructed;
   mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
 
   cmGeneratorTarget(cmGeneratorTarget const&);
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=0ab51009c691eee9bd736baf404e4cc79fe5e1cf
commit 0ab51009c691eee9bd736baf404e4cc79fe5e1cf
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 17:38:05 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=d51107beda361eee422b24d7e6718de2dc951de7
commit d51107beda361eee422b24d7e6718de2dc951de7
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 17:37:48 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 e1487db..437b2a2 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;
@@ -5264,6 +5257,50 @@ 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=ad9f7469910f9c651f3fc7793cd64b7bc0cf2de2
commit ad9f7469910f9c651f3fc7793cd64b7bc0cf2de2
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 17:37:33 2014 +0100

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

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index c59bfac..e1487db 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=99745177995ff85e34535411ce38a5b0d3d9795f
commit 99745177995ff85e34535411ce38a5b0d3d9795f
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 17:37:33 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 da088ca..c59bfac 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,72 @@ 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)
+    {
+      this->Internal->ComputeLinkInterface(this, config,
+                                           i->second,
+                                              head,
+                                              i->second.ExplicitLibraries);
+    }
 
-  return i->second.Exists? &i->second : 0;
+  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;
 }
 
 //----------------------------------------------------------------------------
@@ -5209,7 +5267,7 @@ void cmTarget::GetTransitivePropertyTargets(const char* config,
                                       cmTarget const* headTarget,
                                       std::vector<cmTarget*> &tgts) const
 {
-  cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
+  cmTarget::LinkInterface const* iface = this->GetLinkInterfaceLibraries(config,
                                                                 headTarget);
   if (!iface)
     {
@@ -5370,8 +5428,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)
@@ -5497,10 +5555,6 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
     }
   else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
         || thisTarget->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.
     cmTarget::LinkImplementation const* impl = thisTarget->GetLinkImplementation(config,
@@ -5541,6 +5595,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
       sscanf(reps, "%u", &iface.Multiplicity);
       }
     }
+  iface.Complete = true;
 }
 
 //----------------------------------------------------------------------------
@@ -5569,6 +5624,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=2cdfe8d1ca9803d977ac76d6efe79153f0141949
commit 2cdfe8d1ca9803d977ac76d6efe79153f0141949
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 17:37:32 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 6c46b0b..da088ca 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);
@@ -5435,15 +5441,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.
@@ -5453,16 +5461,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)
@@ -5479,7 +5487,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;
@@ -5487,26 +5495,26 @@ 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)
     // 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,
+    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 = "_";
@@ -5523,12 +5531,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=cf080619aba2b68cbae94df950848f49aa7843ed
commit cf080619aba2b68cbae94df950848f49aa7843ed
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 17:37:32 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 49e1f36..6c46b0b 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);
@@ -5256,8 +5258,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 = "_";
@@ -5333,8 +5337,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)
     {
@@ -5361,8 +5367,78 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     LinkImplementation const* impl = this->GetLinkImplementation(config,
                                                               headTarget);
     iface.Libraries = impl->Libraries;
+    if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
+       !this->Internal->PolicyWarnedCMP0022)
+      {
+      // Compare the link implementation fallback link interface to the
+      // preferred new link interface property and warn if different.
+      cmListFileBacktrace lfbt;
+      cmGeneratorExpression ge(lfbt);
+      cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+                                      "INTERFACE_LINK_LIBRARIES", 0, 0);
+      std::vector<std::string> ifaceLibs;
+      const char* newExplicitLibraries =
+        this->GetProperty("INTERFACE_LINK_LIBRARIES");
+      cmSystemTools::ExpandListArgument(
+        ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
+                                                 config,
+                                                 false,
+                                                 headTarget,
+                                                 this, &dagChecker),
+        ifaceLibs);
+      if (ifaceLibs != impl->Libraries)
+        {
+        std::string oldLibraries;
+        std::string newLibraries;
+        const char *sep = "";
+        for(std::vector<std::string>::const_iterator it
+              = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
+          {
+          oldLibraries += sep;
+          oldLibraries += *it;
+          sep = ";";
+          }
+        sep = "";
+        for(std::vector<std::string>::const_iterator it
+              = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
+          {
+          newLibraries += sep;
+          newLibraries += *it;
+          sep = ";";
+          }
+        if(oldLibraries.empty())
+          { oldLibraries = "(empty)"; }
+        if(newLibraries.empty())
+          { newLibraries = "(empty)"; }
+
+        cmOStringStream w;
+        w <<
+          (this->Makefile->GetPolicies()
+           ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
+          "Target \"" << this->GetName() << "\" has an "
+          "INTERFACE_LINK_LIBRARIES property.  "
+          "This should be preferred as the source of the link interface "
+          "for this library but because CMP0022 is not set CMake is "
+          "ignoring the property and using the link implementation "
+          "as the link interface instead."
+          "\n"
+          "INTERFACE_LINK_LIBRARIES:\n"
+          "  " << newLibraries << "\n"
+          "Link implementation:\n"
+          "  " << oldLibraries << "\n";
+        this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+        this->Internal->PolicyWarnedCMP0022 = true;
+        }
+      }
     }
+  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
@@ -5373,7 +5449,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
       // 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)
+          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
         {
         emitted.insert(*li);
         }
@@ -5428,74 +5504,21 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
       // Targets using this archive need its language runtime libraries.
       iface.Languages = impl->Languages;
       }
-
-    if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
-       !this->Internal->PolicyWarnedCMP0022)
-      {
-      // Compare the link implementation fallback link interface to the
-      // preferred new link interface property and warn if different.
-      cmListFileBacktrace lfbt;
-      cmGeneratorExpression ge(lfbt);
-      cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
-                                      "INTERFACE_LINK_LIBRARIES", 0, 0);
-      std::vector<std::string> ifaceLibs;
-      const char* newExplicitLibraries =
-        this->GetProperty("INTERFACE_LINK_LIBRARIES");
-      cmSystemTools::ExpandListArgument(
-        ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
-                                                 config,
-                                                 false,
-                                                 headTarget,
-                                                 this, &dagChecker),
-        ifaceLibs);
-      if (ifaceLibs != impl->Libraries)
-        {
-        std::string oldLibraries;
-        std::string newLibraries;
-        const char *sep = "";
-        for(std::vector<std::string>::const_iterator it
-              = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
-          {
-          oldLibraries += sep;
-          oldLibraries += *it;
-          sep = ";";
-          }
-        sep = "";
-        for(std::vector<std::string>::const_iterator it
-              = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
-          {
-          newLibraries += sep;
-          newLibraries += *it;
-          sep = ";";
-          }
-        if(oldLibraries.empty())
-          { oldLibraries = "(empty)"; }
-        if(newLibraries.empty())
-          { newLibraries = "(empty)"; }
-
-        cmOStringStream w;
-        w <<
-          (this->Makefile->GetPolicies()
-           ->GetPolicyWarning(cmPolicies::CMP0022)) << "\n"
-          "Target \"" << this->GetName() << "\" has an "
-          "INTERFACE_LINK_LIBRARIES property.  "
-          "This should be preferred as the source of the link interface "
-          "for this library but because CMP0022 is not set CMake is "
-          "ignoring the property and using the link implementation "
-          "as the link interface instead."
-          "\n"
-          "INTERFACE_LINK_LIBRARIES:\n"
-          "  " << newLibraries << "\n"
-          "Link implementation:\n"
-          "  " << oldLibraries << "\n";
-        this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-        this->Internal->PolicyWarnedCMP0022 = true;
-        }
-      }
     }
 
   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";
@@ -5510,8 +5533,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=16f9d9c9bc968874673cf40bd1787df4095de712
commit 16f9d9c9bc968874673cf40bd1787df4095de712
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 17:37:31 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.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4a73d23..49e1f36 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5349,7 +5349,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)
@@ -5407,7 +5422,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
     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=d804159f4f0c241d7da3b54213bbf5fe5958c38b
commit d804159f4f0c241d7da3b54213bbf5fe5958c38b
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 17:37:30 2014 +0100

    cmTarget: Extract a ComputeLinkImplementationLanguages method.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 11ce7cd..4a73d23 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5520,6 +5520,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);
@@ -5602,7 +5603,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=e6e97b13f72185a043953bef72e9f32bb585f82a
commit e6e97b13f72185a043953bef72e9f32bb585f82a
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 17:37: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 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..11ce7cd 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,22 @@ 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=65b48d438d8745e6017bfee84f3352f550755454
commit 65b48d438d8745e6017bfee84f3352f550755454
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 17:35:34 2014 +0100

    cmTarget: Find source files when classifying them.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 4db27ca..a7ff56a 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -24,6 +24,24 @@
 
 #include "assert.h"
 
+
+//----------------------------------------------------------------------------
+bool FindSourceFile(cmSourceFile *sf, cmTarget *tgt)
+{
+  std::string e;
+  if((sf)->GetFullPath(&e).empty())
+    {
+    if(!e.empty())
+      {
+      cmake* cm = tgt->GetMakefile()->GetCMakeInstance();
+      cm->IssueMessage(cmake::FATAL_ERROR, e,
+                       tgt->GetBacktrace());
+      }
+    return false;
+    }
+  return true;
+}
+
 //----------------------------------------------------------------------------
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
   SourceFileFlagsConstructed(false)
@@ -305,6 +323,10 @@ void cmGeneratorTarget::ClassifySources()
       si != sources.end(); ++si)
     {
     cmSourceFile* sf = *si;
+    if (!FindSourceFile(sf, this->Target))
+      {
+      return;
+      }
     std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
     if(sf->GetCustomCommand())
       {
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..9f8dafe 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -522,28 +522,6 @@ bool cmTarget::IsBundleOnApple() const
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::FindSourceFiles()
-{
-  for(std::vector<cmSourceFile*>::const_iterator
-        si = this->SourceFiles.begin();
-      si != this->SourceFiles.end(); ++si)
-    {
-    std::string e;
-    if((*si)->GetFullPath(&e).empty())
-      {
-      if(!e.empty())
-        {
-        cmake* cm = this->Makefile->GetCMakeInstance();
-        cm->IssueMessage(cmake::FATAL_ERROR, e,
-                         this->GetBacktrace());
-        }
-      return false;
-      }
-    }
-  return true;
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
 {
   assert(this->GetType() != INTERFACE_LIBRARY);
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;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 8074a01..1f5ce01 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -210,7 +210,7 @@ if(BUILD_TESTING)
   ADD_TEST_MACRO(PreOrder PreOrder)
   ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
   set_tests_properties(MissingSourceFile PROPERTIES
-    PASS_REGULAR_EXPRESSION "CMake Error at CMakeLists.txt:3 \\(add_executable\\):[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
+    PASS_REGULAR_EXPRESSION "CMake Error in CMakeLists.txt:[ \r\n]*Cannot find source file:[ \r\n]*DoesNotExist/MissingSourceFile.c")
   if(CMAKE_Fortran_COMPILER)
     ADD_TEST_MACRO(FortranOnly FortranOnly)
   endif()
diff --git a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
index 411cd7c..b4188b3 100644
--- a/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
+++ b/Tests/RunCMake/ObjectLibrary/MissingSource-stderr.txt
@@ -1,9 +1,7 @@
-CMake Error at MissingSource.cmake:1 \(add_library\):
+CMake Error in CMakeLists.txt:
   Cannot find source file:
 
     missing.c
 
   Tried extensions( \.[A-Za-z+]+|
  )*
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/interface_library/global-interface-stderr.txt
index 24edd0f..80fd594 100644
--- a/Tests/RunCMake/interface_library/global-interface-stderr.txt
+++ b/Tests/RunCMake/interface_library/global-interface-stderr.txt
@@ -1,9 +1,7 @@
-CMake Error at global-interface.cmake:2 \(add_library\):
+CMake Error in CMakeLists.txt:
   Cannot find source file:
 
     GLOBAL
 
   Tried extensions \.c \.C \.c\+\+ \.cc \.cpp \.cxx \.m \.M \.mm \.h \.hh \.h\+\+ \.hm \.hpp
   \.hxx \.in \.txx
-Call Stack \(most recent call first\):
-  CMakeLists.txt:3 \(include\)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=27201405bdf4fa154e816b6c3a11ec4e0c2f42b8
commit 27201405bdf4fa154e816b6c3a11ec4e0c2f42b8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Thu Feb 6 11:24:37 2014 +0100
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Thu Feb 20 17:27:47 2014 +0100

    cmTarget: Move SourceFileFlags to cmGeneratorTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 175bb0e..4db27ca 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -25,7 +25,8 @@
 #include "assert.h"
 
 //----------------------------------------------------------------------------
-cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
+cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
+  SourceFileFlagsConstructed(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
@@ -876,3 +877,106 @@ bool cmStrictTargetComparison::operator()(cmTarget const* t1,
     }
   return nameResult < 0;
 }
+
+//----------------------------------------------------------------------------
+struct cmGeneratorTarget::SourceFileFlags
+cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
+{
+  struct SourceFileFlags flags;
+  this->ConstructSourceFileFlags();
+  std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
+    this->SourceFlagsMap.find(sf);
+  if(si != this->SourceFlagsMap.end())
+    {
+    flags = si->second;
+    }
+  return flags;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ConstructSourceFileFlags() const
+{
+  if(this->SourceFileFlagsConstructed)
+    {
+    return;
+    }
+  this->SourceFileFlagsConstructed = true;
+
+  // Process public headers to mark the source files.
+  if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "Headers";
+        flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
+        }
+      }
+    }
+
+  // Process private headers after public headers so that they take
+  // precedence if a file is listed in both.
+  if(const char* files = this->Target->GetProperty("PRIVATE_HEADER"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "PrivateHeaders";
+        flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
+        }
+      }
+    }
+
+  // Mark sources listed as resources.
+  if(const char* files = this->Target->GetProperty("RESOURCE"))
+    {
+    std::vector<std::string> relFiles;
+    cmSystemTools::ExpandListArgument(files, relFiles);
+    for(std::vector<std::string>::iterator it = relFiles.begin();
+        it != relFiles.end(); ++it)
+      {
+      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
+        {
+        SourceFileFlags& flags = this->SourceFlagsMap[sf];
+        flags.MacFolder = "Resources";
+        flags.Type = cmGeneratorTarget::SourceFileTypeResource;
+        }
+      }
+    }
+
+  // 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;
+          }
+        }
+      }
+    }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index a4caba1..9a3339d 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -88,6 +88,31 @@ public:
   /** Get sources that must be built before the given source.  */
   std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf) const;
 
+  /**
+   * Flags for a given source file as used in this target. Typically assigned
+   * via SET_TARGET_PROPERTIES when the property is a list of source files.
+   */
+  enum SourceFileType
+  {
+    SourceFileTypeNormal,
+    SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
+    SourceFileTypePublicHeader,  // is in "PUBLIC_HEADER" target property
+    SourceFileTypeResource,      // is in "RESOURCE" target property *or*
+                                 // has MACOSX_PACKAGE_LOCATION=="Resources"
+    SourceFileTypeMacContent     // has MACOSX_PACKAGE_LOCATION!="Resources"
+  };
+  struct SourceFileFlags
+  {
+    SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
+    SourceFileFlags(SourceFileFlags const& r):
+      Type(r.Type), MacFolder(r.MacFolder) {}
+    SourceFileType Type;
+    const char* MacFolder; // location inside Mac content folders
+  };
+
+  struct SourceFileFlags
+  GetTargetSourceFileFlags(const cmSourceFile* sf) const;
+
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -107,6 +132,10 @@ private:
   std::vector<cmTarget*> ObjectLibraries;
   mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
 
+  void ConstructSourceFileFlags() const;
+  mutable bool SourceFileFlagsConstructed;
+  mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
+
   cmGeneratorTarget(cmGeneratorTarget const&);
   void operator=(cmGeneratorTarget const&);
 };
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 484b28f..004f7ac 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -713,22 +713,23 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
 
   // Is this a resource file in this target? Add it to the resources group...
   //
-  cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
-  bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
+  cmGeneratorTarget::SourceFileFlags tsFlags =
+            this->GetGeneratorTarget(&cmtarget)->GetTargetSourceFileFlags(sf);
+  bool isResource = tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource;
 
   // Is this a "private" or "public" framework header file?
   // Set the ATTRIBUTES attribute appropriately...
   //
   if(cmtarget.IsFrameworkOnApple())
     {
-    if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
+    if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader)
       {
       cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
       attrs->AddObject(this->CreateString("Private"));
       settings->AddAttribute("ATTRIBUTES", attrs);
       isResource = true;
       }
-    else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
+    else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader)
       {
       cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
       attrs->AddObject(this->CreateString("Public"));
@@ -973,6 +974,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
   for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
     {
     cmTarget& cmtarget = l->second;
+    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
 
     // make sure ALL_BUILD, INSTALL, etc are only done once
     if(this->SpecialTargetEmitted(l->first.c_str()))
@@ -1011,8 +1013,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       cmXCodeObject* filetype =
         fr->GetObject()->GetObject("explicitFileType");
 
-      cmTarget::SourceFileFlags tsFlags =
-        cmtarget.GetTargetSourceFileFlags(*i);
+      cmGeneratorTarget::SourceFileFlags tsFlags =
+        gtgt->GetTargetSourceFileFlags(*i);
 
       if(filetype &&
          strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
@@ -1020,12 +1022,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
         externalObjFiles.push_back(xsf);
         }
       else if(this->IsHeaderFile(*i) ||
-        (tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
-        (tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
+        (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
+        (tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader))
         {
         headerFiles.push_back(xsf);
         }
-      else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
+      else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource)
         {
         resourceFiles.push_back(xsf);
         }
@@ -1048,7 +1050,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       // the externalObjFiles above, except each one is not a cmSourceFile
       // within the target.)
       std::vector<std::string> objs;
-      this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
+      gtgt->UseObjectLibraries(objs);
       for(std::vector<std::string>::const_iterator
             oi = objs.begin(); oi != objs.end(); ++oi)
         {
@@ -1138,9 +1140,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
       for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
           i != classes.end(); ++i)
         {
-        cmTarget::SourceFileFlags tsFlags =
-          cmtarget.GetTargetSourceFileFlags(*i);
-        if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
+        cmGeneratorTarget::SourceFileFlags tsFlags =
+          gtgt->GetTargetSourceFileFlags(*i);
+        if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent)
           {
           bundleFiles[tsFlags.MacFolder].push_back(*i);
           }
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 9a340dc..d3c3d81 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -20,7 +20,8 @@
 cmOSXBundleGenerator::
 cmOSXBundleGenerator(cmGeneratorTarget* target,
                      const char* configName)
- : Target(target->Target)
+ : GT(target)
+ , Target(target->Target)
  , Makefile(target->Target->GetMakefile())
  , LocalGenerator(Makefile->GetLocalGenerator())
  , ConfigName(configName)
@@ -34,7 +35,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target,
 //----------------------------------------------------------------------------
 bool cmOSXBundleGenerator::MustSkip()
 {
-  return !this->Target->HaveWellDefinedOutputFiles();
+  return !this->GT->Target->HaveWellDefinedOutputFiles();
 }
 
 //----------------------------------------------------------------------------
@@ -47,7 +48,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
   // Compute bundle directory names.
   std::string out = outpath;
   out += "/";
-  out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
+  out += this->GT->Target->GetAppBundleDirectory(this->ConfigName, false);
   cmSystemTools::MakeDirectory(out.c_str());
   this->Makefile->AddCMakeOutputFile(out);
 
@@ -57,9 +58,9 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
   // to be set.
   std::string plist = outpath;
   plist += "/";
-  plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
+  plist += this->GT->Target->GetAppBundleDirectory(this->ConfigName, true);
   plist += "/Info.plist";
-  this->LocalGenerator->GenerateAppleInfoPList(this->Target,
+  this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
                                                targetName.c_str(),
                                                plist.c_str());
   this->Makefile->AddCMakeOutputFile(plist);
@@ -77,20 +78,20 @@ void cmOSXBundleGenerator::CreateFramework(
 
   // Compute the location of the top-level foo.framework directory.
   std::string contentdir = outpath + "/" +
-    this->Target->GetFrameworkDirectory(this->ConfigName, true);
+    this->GT->Target->GetFrameworkDirectory(this->ConfigName, true);
   contentdir += "/";
 
   std::string newoutpath = outpath + "/" +
-    this->Target->GetFrameworkDirectory(this->ConfigName, false);
+    this->GT->Target->GetFrameworkDirectory(this->ConfigName, false);
 
-  std::string frameworkVersion = this->Target->GetFrameworkVersion();
+  std::string frameworkVersion = this->GT->Target->GetFrameworkVersion();
 
   // Configure the Info.plist file into the Resources directory.
   this->MacContentFolders->insert("Resources");
   std::string plist = newoutpath;
   plist += "/Resources/Info.plist";
   std::string name = cmSystemTools::GetFilenameName(targetName);
-  this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
+  this->LocalGenerator->GenerateFrameworkInfoPList(this->GT->Target,
                                                    name.c_str(),
                                                    plist.c_str());
 
@@ -172,16 +173,16 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
   // Compute bundle directory names.
   std::string out = root;
   out += "/";
-  out += this->Target->GetCFBundleDirectory(this->ConfigName, false);
+  out += this->GT->Target->GetCFBundleDirectory(this->ConfigName, false);
   cmSystemTools::MakeDirectory(out.c_str());
   this->Makefile->AddCMakeOutputFile(out);
 
   // Configure the Info.plist file.  Note that it needs the executable name
   // to be set.
   std::string plist =
-    this->Target->GetCFBundleDirectory(this->ConfigName, true);
+    this->GT->Target->GetCFBundleDirectory(this->ConfigName, true);
   plist += "/Info.plist";
-  this->LocalGenerator->GenerateAppleInfoPList(this->Target,
+  this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
                                                targetName.c_str(),
                                                plist.c_str());
   this->Makefile->AddCMakeOutputFile(plist);
@@ -199,9 +200,9 @@ GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
   for(std::vector<cmSourceFile*>::const_iterator
         si = sources.begin(); si != sources.end(); ++si)
     {
-    cmTarget::SourceFileFlags tsFlags =
-      this->Target->GetTargetSourceFileFlags(*si);
-    if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
+    cmGeneratorTarget::SourceFileFlags tsFlags =
+      this->GT->GetTargetSourceFileFlags(*si);
+    if(tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal)
       {
       (*generator)(**si, tsFlags.MacFolder);
       }
@@ -215,7 +216,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
   // Construct the full path to the content subdirectory.
 
   std::string macdir =
-    this->Target->GetMacContentDirectory(this->ConfigName,
+    this->GT->Target->GetMacContentDirectory(this->ConfigName,
                                          /*implib*/ false);
   macdir += "/";
   macdir += pkgloc;
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 29b7611..0cbe5b7 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -59,6 +59,7 @@ private:
   bool MustSkip();
 
 private:
+  cmGeneratorTarget* GT;
   cmTarget* Target;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index db34bd8..61f05a1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -83,17 +83,12 @@ public:
   cmTargetInternals()
     {
     this->PolicyWarnedCMP0022 = false;
-    this->SourceFileFlagsConstructed = false;
     }
   cmTargetInternals(cmTargetInternals const&)
     {
     this->PolicyWarnedCMP0022 = false;
-    this->SourceFileFlagsConstructed = false;
     }
   ~cmTargetInternals();
-  typedef cmTarget::SourceFileFlags SourceFileFlags;
-  mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
-  mutable bool SourceFileFlagsConstructed;
 
   // The backtrace when the target was created.
   cmListFileBacktrace Backtrace;
@@ -648,109 +643,6 @@ void cmTarget::ProcessSourceExpression(std::string const& expr)
 }
 
 //----------------------------------------------------------------------------
-struct cmTarget::SourceFileFlags
-cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
-{
-  struct SourceFileFlags flags;
-  this->ConstructSourceFileFlags();
-  std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
-    this->Internal->SourceFlagsMap.find(sf);
-  if(si != this->Internal->SourceFlagsMap.end())
-    {
-    flags = si->second;
-    }
-  return flags;
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::ConstructSourceFileFlags() const
-{
-  if(this->Internal->SourceFileFlagsConstructed)
-    {
-    return;
-    }
-  this->Internal->SourceFileFlagsConstructed = true;
-
-  // Process public headers to mark the source files.
-  if(const char* files = this->GetProperty("PUBLIC_HEADER"))
-    {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
-      {
-      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
-        {
-        SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
-        flags.MacFolder = "Headers";
-        flags.Type = cmTarget::SourceFileTypePublicHeader;
-        }
-      }
-    }
-
-  // Process private headers after public headers so that they take
-  // precedence if a file is listed in both.
-  if(const char* files = this->GetProperty("PRIVATE_HEADER"))
-    {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
-      {
-      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
-        {
-        SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
-        flags.MacFolder = "PrivateHeaders";
-        flags.Type = cmTarget::SourceFileTypePrivateHeader;
-        }
-      }
-    }
-
-  // Mark sources listed as resources.
-  if(const char* files = this->GetProperty("RESOURCE"))
-    {
-    std::vector<std::string> relFiles;
-    cmSystemTools::ExpandListArgument(files, relFiles);
-    for(std::vector<std::string>::iterator it = relFiles.begin();
-        it != relFiles.end(); ++it)
-      {
-      if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
-        {
-        SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
-        flags.MacFolder = "Resources";
-        flags.Type = cmTarget::SourceFileTypeResource;
-        }
-      }
-    }
-
-  // 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->Internal->SourceFlagsMap[sf];
-      if(flags.Type == cmTarget::SourceFileTypeNormal)
-        {
-        flags.MacFolder = location;
-        if(strcmp(location, "Resources") == 0)
-          {
-          flags.Type = cmTarget::SourceFileTypeResource;
-          }
-        else
-          {
-          flags.Type = cmTarget::SourceFileTypeMacContent;
-          }
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::MergeLinkLibraries( cmMakefile& mf,
                                    const char *selfname,
                                    const LinkLibraryVectorType& libs )
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 271824b..a02ed09 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -140,34 +140,6 @@ public:
     }
 
   /**
-   * Flags for a given source file as used in this target. Typically assigned
-   * via SET_TARGET_PROPERTIES when the property is a list of source files.
-   */
-  enum SourceFileType
-  {
-    SourceFileTypeNormal,
-    SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
-    SourceFileTypePublicHeader,  // is in "PUBLIC_HEADER" target property
-    SourceFileTypeResource,      // is in "RESOURCE" target property *or*
-                                 // has MACOSX_PACKAGE_LOCATION=="Resources"
-    SourceFileTypeMacContent     // has MACOSX_PACKAGE_LOCATION!="Resources"
-  };
-  struct SourceFileFlags
-  {
-    SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
-    SourceFileFlags(SourceFileFlags const& r):
-      Type(r.Type), MacFolder(r.MacFolder) {}
-    SourceFileType Type;
-    const char* MacFolder; // location inside Mac content folders
-  };
-
-  /**
-   * Get the flags for a given source file as used in this target
-   */
-  struct SourceFileFlags
-  GetTargetSourceFileFlags(const cmSourceFile* sf) const;
-
-  /**
    * Add sources to the target.
    */
   void AddSources(std::vector<std::string> const& srcs);
@@ -756,7 +728,6 @@ private:
   friend class cmTargetTraceDependencies;
   cmTargetInternalPointer Internal;
 
-  void ConstructSourceFileFlags() const;
   void ComputeVersionedName(std::string& vName,
                             std::string const& prefix,
                             std::string const& base,

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

Summary of changes:
 Source/CMakeVersion.cmake                          |    2 +-
 Source/cmGeneratorExpressionEvaluator.cxx          |   57 ++-
 Source/cmGeneratorTarget.cxx                       |  493 ++++++++++++++-----
 Source/cmGeneratorTarget.h                         |   63 ++-
 Source/cmGlobalGenerator.cxx                       |   36 --
 Source/cmGlobalGenerator.h                         |    1 -
 Source/cmGlobalXCodeGenerator.cxx                  |   28 +-
 Source/cmMakefileTargetGenerator.cxx               |   11 +-
 Source/cmNinjaTargetGenerator.cxx                  |    6 +-
 Source/cmOSXBundleGenerator.cxx                    |   33 +-
 Source/cmOSXBundleGenerator.h                      |    1 +
 Source/cmTarget.cxx                                |  517 +++++++++++---------
 Source/cmTarget.h                                  |   53 +-
 Source/cmVisualStudio10TargetGenerator.cxx         |    6 +-
 Tests/CMakeLists.txt                               |    2 +-
 .../CompatibleInterface/DebugProperties-stderr.txt |   14 +-
 .../ObjectLibrary/MissingSource-stderr.txt         |    4 +-
 .../interface_library/global-interface-stderr.txt  |    4 +-
 18 files changed, 810 insertions(+), 521 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list