[Cmake-commits] CMake branch, next, updated. v3.3.1-2482-gf91dd93

Stephen Kelly steveire at gmail.com
Tue Aug 25 16:38:15 EDT 2015


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  f91dd93d9afdb02268c285214abed9d8cc50f191 (commit)
       via  4898c4c0b79a0f39eb198d4b463688447b09d813 (commit)
       via  55933ca008a56fd038f80437ec815c3592dca676 (commit)
       via  0aa85bd05d6f1b19ee839a955b1ae7f45fd96761 (commit)
       via  622b158d186c4e38bed4097a7422d43c1e26bad1 (commit)
       via  61b3fdd7ce4424d6b986e5670c50c092483a7f3d (commit)
       via  4d8072b195d6547a92de835ef27ae205cc7c6609 (commit)
       via  2d347e68723dbd6e86877856ebff3bd13e5c4dab (commit)
       via  88f26ac1060a9062361f232c4ef4e5f78cd5c4f8 (commit)
       via  81fb482213b07ef4909de7d8246f120848b17437 (commit)
       via  09bd59c75114dd177c685a62a34a3010ff2250a0 (commit)
       via  8d45ba34d64cb5d7d71d8ade8b5f2226cd9e4734 (commit)
       via  6ee49bf15acc52ea8b0a32c3e64bfaf75be95846 (commit)
       via  2962880e25943d5c7670ca34986366c3f41fb67d (commit)
       via  7707a52f41947c1db1674563a6258f908c8efd6f (commit)
      from  ec0bc1765d8bff3c13835eff266ecfee9ecf00aa (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=f91dd93d9afdb02268c285214abed9d8cc50f191
commit f91dd93d9afdb02268c285214abed9d8cc50f191
Merge: ec0bc17 4898c4c
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 25 16:38:13 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Aug 25 16:38:13 2015 -0400

    Merge topic 'use-generator-target' into next
    
    4898c4c0 cmGeneratorTarget: Move GetConfigCommonSourceFiles from cmTarget.
    55933ca0 cmGeneratorTarget: Move GetLanguages from cmTarget.
    0aa85bd0 cmGeneratorTarget: Move ComputeLinkImplementationLanguages from cmTarget.
    622b158d cmGeneratorTarget: Move HaveBuildTreeRPath from cmTarget.
    61b3fdd7 cmGeneratorTarget: Move GetLinkImplementation from cmTarget.
    4d8072b1 cmTarget: Add GetLinkImplMap method.
    2d347e68 cmLinkItem: Add cmOptionalLinkImplementation type.
    88f26ac1 cmLinkItem: Add cmLinkImplementation type.
    81fb4822 cmGeneratorTarget: Move compile defintions processing from cmTarget.
    09bd59c7 cmGeneratorTarget: Move compile features processing from cmTarget.
    8d45ba34 cmGeneratorTarget: Move compile options processing from cmTarget.
    6ee49bf1 cmGeneratorTarget: Move include directory processing from cmTarget.
    2962880e cmGeneratorTarget: Move link iface helpers from cmTarget.
    7707a52f cmGeneratorTarget: Move GetLinkInterface from cmTarget.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4898c4c0b79a0f39eb198d4b463688447b09d813
commit 4898c4c0b79a0f39eb198d4b463688447b09d813
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:50 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:11 2015 +0200

    cmGeneratorTarget: Move GetConfigCommonSourceFiles from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 06c6137..9390b92 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4397,11 +4397,68 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
 }
 
 //----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetConfigCommonSourceFiles(
+    std::vector<cmSourceFile*>& files) const
+{
+  std::vector<std::string> configs;
+  this->Makefile->GetConfigurations(configs);
+  if (configs.empty())
+    {
+    configs.push_back("");
+    }
+
+  std::vector<std::string>::const_iterator it = configs.begin();
+  const std::string& firstConfig = *it;
+  this->Target->GetSourceFiles(files, firstConfig);
+
+  for ( ; it != configs.end(); ++it)
+    {
+    std::vector<cmSourceFile*> configFiles;
+    this->Target->GetSourceFiles(configFiles, *it);
+    if (configFiles != files)
+      {
+      std::string firstConfigFiles;
+      const char* sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
+           fi != files.end(); ++fi)
+        {
+        firstConfigFiles += sep;
+        firstConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
+        }
+
+      std::string thisConfigFiles;
+      sep = "";
+      for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
+           fi != configFiles.end(); ++fi)
+        {
+        thisConfigFiles += sep;
+        thisConfigFiles += (*fi)->GetFullPath();
+        sep = "\n  ";
+        }
+      std::ostringstream e;
+      e << "Target \"" << this->GetName()
+        << "\" has source files which vary by "
+        "configuration. This is not supported by the \""
+        << this->LocalGenerator->GetGlobalGenerator()->GetName()
+        << "\" generator.\n"
+          "Config \"" << firstConfig << "\":\n"
+          "  " << firstConfigFiles << "\n"
+          "Config \"" << *it << "\":\n"
+          "  " << thisConfigFiles << "\n";
+      this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str());
+      return false;
+      }
+    }
+  return true;
+}
+
+//----------------------------------------------------------------------------
 void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
                             const std::string& config) const
 {
   std::vector<cmSourceFile*> sourceFiles;
-  this->Target->GetSourceFiles(sourceFiles, config);
+  this->GetSourceFiles(sourceFiles, config);
   for(std::vector<cmSourceFile*>::const_iterator
         i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
     {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e7ec23a..6d66bfe 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -241,6 +241,8 @@ public:
   void GetLanguages(std::set<std::string>& languages,
                     std::string const& config) const;
 
+  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+
   bool HaveBuildTreeRPATH(const std::string& config) const;
 
   /** Full path with trailing slash to the top-level directory
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b70f3c9..756daa0 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1124,7 +1124,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
 
     // organize the sources
     std::vector<cmSourceFile*> classes;
-    if (!cmtarget.GetConfigCommonSourceFiles(classes))
+    if (!gtgt->GetConfigCommonSourceFiles(classes))
       {
       return false;
       }
@@ -1505,7 +1505,8 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
     }
 
   std::vector<cmSourceFile*> classes;
-  if (!cmtarget.GetConfigCommonSourceFiles(classes))
+  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+  if (!gtgt->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -2557,7 +2558,8 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
   if(cmtarget.GetType() == cmTarget::UTILITY)
     {
     std::vector<cmSourceFile*> sources;
-    if (!cmtarget.GetConfigCommonSourceFiles(sources))
+    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+    if (!gtgt->GetConfigCommonSourceFiles(sources))
       {
       return 0;
       }
@@ -3085,7 +3087,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
         }
 
       std::vector<cmSourceFile*> classes;
-      if (!cmtarget.GetConfigCommonSourceFiles(classes))
+      cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
+      if (!gtgt->GetConfigCommonSourceFiles(classes))
         {
         return false;
         }
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index c58e7e4..0a4b546 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -403,7 +403,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg,
         )
     {
     std::vector<cmSourceFile*> srcFiles;
-    target->GetConfigCommonSourceFiles(srcFiles);
+    cmGeneratorTarget* gtgt =
+        lg->GetGlobalGenerator()->GetGeneratorTarget(target);
+    gtgt->GetConfigCommonSourceFiles(srcFiles);
     for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
         fileIt != srcFiles.end();
         ++fileIt)
@@ -661,7 +663,10 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
   const char* sepHeaders = "";
 
   std::vector<cmSourceFile*> srcFiles;
-  target->GetConfigCommonSourceFiles(srcFiles);
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  gtgt->GetConfigCommonSourceFiles(srcFiles);
 
   const char *skipMocSep = "";
   const char *skipUicSep = "";
@@ -1046,7 +1051,10 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
   cmMakefile *makefile = target->GetMakefile();
 
   std::vector<cmSourceFile*> srcFiles;
-  target->GetConfigCommonSourceFiles(srcFiles);
+  cmGeneratorTarget *gtgt = target->GetMakefile()
+                                  ->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(target);
+  gtgt->GetConfigCommonSourceFiles(srcFiles);
 
   std::string qrcInputs;
   const char* qrcInputsSep = "";
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 682e9b9..40d7ebf 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -726,62 +726,6 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files,
 }
 
 //----------------------------------------------------------------------------
-bool
-cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const
-{
-  std::vector<std::string> configs;
-  this->Makefile->GetConfigurations(configs);
-  if (configs.empty())
-    {
-    configs.push_back("");
-    }
-
-  std::vector<std::string>::const_iterator it = configs.begin();
-  const std::string& firstConfig = *it;
-  this->GetSourceFiles(files, firstConfig);
-
-  for ( ; it != configs.end(); ++it)
-    {
-    std::vector<cmSourceFile*> configFiles;
-    this->GetSourceFiles(configFiles, *it);
-    if (configFiles != files)
-      {
-      std::string firstConfigFiles;
-      const char* sep = "";
-      for (std::vector<cmSourceFile*>::const_iterator fi = files.begin();
-           fi != files.end(); ++fi)
-        {
-        firstConfigFiles += sep;
-        firstConfigFiles += (*fi)->GetFullPath();
-        sep = "\n  ";
-        }
-
-      std::string thisConfigFiles;
-      sep = "";
-      for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin();
-           fi != configFiles.end(); ++fi)
-        {
-        thisConfigFiles += sep;
-        thisConfigFiles += (*fi)->GetFullPath();
-        sep = "\n  ";
-        }
-      std::ostringstream e;
-      e << "Target \"" << this->Name << "\" has source files which vary by "
-        "configuration. This is not supported by the \""
-        << this->Makefile->GetGlobalGenerator()->GetName()
-        << "\" generator.\n"
-          "Config \"" << firstConfig << "\":\n"
-          "  " << firstConfigFiles << "\n"
-          "Config \"" << *it << "\":\n"
-          "  " << thisConfigFiles << "\n";
-      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
-      return false;
-      }
-    }
-  return true;
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
                               const std::string& config) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8dee560..d032380 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -137,8 +137,6 @@ public:
    */
   void GetSourceFiles(std::vector<cmSourceFile*> &files,
                       const std::string& config) const;
-  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
-
   /**
    * Add sources to the target.
    */

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=55933ca008a56fd038f80437ec815c3592dca676
commit 55933ca008a56fd038f80437ec815c3592dca676
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:50 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:10 2015 +0200

    cmGeneratorTarget: Move GetLanguages from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 8e126b9..06c6137 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4397,6 +4397,57 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
 }
 
 //----------------------------------------------------------------------------
+void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
+                            const std::string& config) const
+{
+  std::vector<cmSourceFile*> sourceFiles;
+  this->Target->GetSourceFiles(sourceFiles, config);
+  for(std::vector<cmSourceFile*>::const_iterator
+        i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
+    {
+    const std::string& lang = (*i)->GetLanguage();
+    if(!lang.empty())
+      {
+      languages.insert(lang);
+      }
+    }
+
+  std::vector<cmGeneratorTarget*> objectLibraries;
+  std::vector<cmSourceFile const*> externalObjects;
+  if (!this->Makefile->IsConfigured())
+    {
+    std::vector<cmTarget*> objectTargets;
+    this->Target->GetObjectLibrariesCMP0026(objectTargets);
+    objectLibraries.reserve(objectTargets.size());
+    for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin();
+         it != objectTargets.end(); ++it)
+      {
+      objectLibraries.push_back(this->LocalGenerator->GetGlobalGenerator()
+                                ->GetGeneratorTarget(*it));
+      }
+    }
+  else
+    {
+    this->GetExternalObjects(externalObjects, config);
+    for(std::vector<cmSourceFile const*>::const_iterator
+          i = externalObjects.begin(); i != externalObjects.end(); ++i)
+      {
+      std::string objLib = (*i)->GetObjectLibrary();
+      if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+        {
+        objectLibraries.push_back(this->LocalGenerator->GetGlobalGenerator()
+                                  ->GetGeneratorTarget(tgt));
+        }
+      }
+    }
+  for(std::vector<cmGeneratorTarget*>::const_iterator
+      i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
+    {
+    (*i)->GetLanguages(languages, config);
+    }
+}
+
+//----------------------------------------------------------------------------
 void cmGeneratorTarget::ComputeLinkImplementationLanguages(
   const std::string& config,
   cmOptionalLinkImplementation& impl) const
@@ -4404,7 +4455,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLanguages(
   // This target needs runtime libraries for its source languages.
   std::set<std::string> languages;
   // Get languages used in our source files.
-  this->Target->GetLanguages(languages, config);
+  this->GetLanguages(languages, config);
   // Copy the set of langauges to the link implementation.
   impl.Languages.insert(impl.Languages.begin(),
                         languages.begin(), languages.end());
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 7cb3acd..e7ec23a 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -233,6 +233,14 @@ public:
                                           cmOptionalLinkImplementation& impl
                                           ) const;
 
+  // Compute the set of languages compiled by the target.  This is
+  // computed every time it is called because the languages can change
+  // when source file properties are changed and we do not have enough
+  // information to forward these property changes to the targets
+  // until we have per-target object file properties.
+  void GetLanguages(std::set<std::string>& languages,
+                    std::string const& config) const;
+
   bool HaveBuildTreeRPATH(const std::string& config) const;
 
   /** Full path with trailing slash to the top-level directory
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index b240924..331caad 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -1134,7 +1134,8 @@ bool cmGlobalUnixMakefileGenerator3
 ::NeedRequiresStep(cmTarget const& target)
 {
   std::set<std::string> languages;
-  target.GetLanguages(languages,
+  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&target);
+  gtgt->GetLanguages(languages,
                 target.GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   for(std::set<std::string>::const_iterator l = languages.begin();
       l != languages.end(); ++l)
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index dda4829..b70f3c9 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1805,7 +1805,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 
   // Compute the compilation flags for each language.
   std::set<std::string> languages;
-  target.GetLanguages(languages, configName);
+  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
+  gtgt->GetLanguages(languages, configName);
   std::map<std::string, std::string> cflags;
   for (std::set<std::string>::iterator li = languages.begin();
        li != languages.end(); ++li)
@@ -1827,7 +1828,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
       AddCompileOptions(flags, &target, lang, configName);
     }
 
-  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
   std::string llang = gtgt->GetLinkerLanguage(configName);
   if(binary && llang.empty())
     {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index ce370bc..589105e 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1257,7 +1257,9 @@ cmLocalUnixMakefileGenerator3
     {
     // Get the set of source languages in the target.
     std::set<std::string> languages;
-    target.GetLanguages(languages,
+    cmGeneratorTarget *gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(&target);
+    gtgt->GetLanguages(languages,
                       this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     fout << "\n"
          << "# Per-language clean rules from dependency scanning.\n"
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 0b3df90..cf88a74 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -276,7 +276,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 {
   // write language flags for target
   std::set<std::string> languages;
-  this->Target->GetLanguages(languages,
+  this->GeneratorTarget->GetLanguages(languages,
                       this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
   // put the compiler in the rules.make file so that if it changes
   // things rebuild
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e8a315d..682e9b9 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3132,50 +3132,6 @@ cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetLanguages(std::set<std::string>& languages,
-                            const std::string& config) const
-{
-  std::vector<cmSourceFile*> sourceFiles;
-  this->GetSourceFiles(sourceFiles, config);
-  for(std::vector<cmSourceFile*>::const_iterator
-        i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
-    {
-    const std::string& lang = (*i)->GetLanguage();
-    if(!lang.empty())
-      {
-      languages.insert(lang);
-      }
-    }
-
-  std::vector<cmTarget*> objectLibraries;
-  std::vector<cmSourceFile const*> externalObjects;
-  if (!this->Makefile->IsConfigured())
-    {
-    this->GetObjectLibrariesCMP0026(objectLibraries);
-    }
-  else
-    {
-    cmGeneratorTarget* gt = this->Makefile->GetGlobalGenerator()
-                                ->GetGeneratorTarget(this);
-    gt->GetExternalObjects(externalObjects, config);
-    for(std::vector<cmSourceFile const*>::const_iterator
-          i = externalObjects.begin(); i != externalObjects.end(); ++i)
-      {
-      std::string objLib = (*i)->GetObjectLibrary();
-      if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
-        {
-        objectLibraries.push_back(tgt);
-        }
-      }
-    }
-  for(std::vector<cmTarget*>::const_iterator
-      i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
-    {
-    (*i)->GetLanguages(languages, config);
-    }
-}
-
-//----------------------------------------------------------------------------
 cmTarget::ImportInfo const*
 cmTarget::GetImportInfo(const std::string& config) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 1db4ba1..8dee560 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -305,14 +305,6 @@ public:
       If no macro should be defined null is returned.  */
   const char* GetExportMacro() const;
 
-  // Compute the set of languages compiled by the target.  This is
-  // computed every time it is called because the languages can change
-  // when source file properties are changed and we do not have enough
-  // information to forward these property changes to the targets
-  // until we have per-target object file properties.
-  void GetLanguages(std::set<std::string>& languages,
-                    std::string const& config) const;
-
   /** Return whether this target is an executable with symbol exports
       enabled.  */
   bool IsExecutableWithExports() const;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0aa85bd05d6f1b19ee839a955b1ae7f45fd96761
commit 0aa85bd05d6f1b19ee839a955b1ae7f45fd96761
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:50 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:10 2015 +0200

    cmGeneratorTarget: Move ComputeLinkImplementationLanguages from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a4999ce..8e126b9 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4391,12 +4391,26 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
   if(!impl.LanguagesDone)
     {
     impl.LanguagesDone = true;
-    this->Target->ComputeLinkImplementationLanguages(config, impl);
+    this->ComputeLinkImplementationLanguages(config, impl);
     }
   return &impl;
 }
 
 //----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLanguages(
+  const std::string& config,
+  cmOptionalLinkImplementation& impl) const
+{
+  // This target needs runtime libraries for its source languages.
+  std::set<std::string> languages;
+  // Get languages used in our source files.
+  this->Target->GetLanguages(languages, config);
+  // Copy the set of langauges to the link implementation.
+  impl.Languages.insert(impl.Languages.begin(),
+                        languages.begin(), languages.end());
+}
+
+//----------------------------------------------------------------------------
 bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
 {
   if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH"))
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e5dbc69..7cb3acd 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -229,6 +229,10 @@ public:
   cmLinkImplementation const*
     GetLinkImplementation(const std::string& config) const;
 
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          cmOptionalLinkImplementation& impl
+                                          ) const;
+
   bool HaveBuildTreeRPATH(const std::string& config) const;
 
   /** Full path with trailing slash to the top-level directory
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 621d1b0..e8a315d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3706,20 +3706,6 @@ void cmTarget::ComputeLinkImplementationLibraries(
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementationLanguages(
-  const std::string& config,
-  cmOptionalLinkImplementation& impl) const
-{
-  // This target needs runtime libraries for its source languages.
-  std::set<std::string> languages;
-  // Get languages used in our source files.
-  this->GetLanguages(languages, config);
-  // Copy the set of langauges to the link implementation.
-  impl.Languages.insert(impl.Languages.begin(),
-                        languages.begin(), languages.end());
-}
-
-//----------------------------------------------------------------------------
 cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
 {
   cmTarget const* tgt = this->Makefile->FindTargetToUse(name);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8866e65..1db4ba1 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -237,9 +237,6 @@ public:
   void ComputeLinkImplementationLibraries(const std::string& config,
                                           cmOptionalLinkImplementation& impl,
                                           cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(const std::string& config,
-                                          cmOptionalLinkImplementation& impl
-                                          ) const;
 
   cmOptionalLinkImplementation&
   GetLinkImplMap(std::string const& config) const;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=622b158d186c4e38bed4097a7422d43c1e26bad1
commit 622b158d186c4e38bed4097a7422d43c1e26bad1
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:49 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:10 2015 +0200

    cmGeneratorTarget: Move HaveBuildTreeRPath from cmTarget.

diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 6ba0eed..192ad5f 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1925,7 +1925,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
     (outputRuntime && this->Target->Target->HaveInstallTreeRPATH() &&
      linking_for_install);
   bool use_build_rpath =
-    (outputRuntime && this->Target->Target->HaveBuildTreeRPATH(this->Config) &&
+    (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&
      !linking_for_install);
   bool use_link_rpath =
     outputRuntime && linking_for_install &&
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 5f73162..a4999ce 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -908,7 +908,7 @@ cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
   // If either a build or install tree rpath is set then the rpath
   // will likely change between the build tree and install tree and
   // this target must be relinked.
-  return this->Target->HaveBuildTreeRPATH(config)
+  return this->HaveBuildTreeRPATH(config)
       || this->Target->HaveInstallTreeRPATH();
 }
 
@@ -4395,3 +4395,18 @@ cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
     }
   return &impl;
 }
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
+{
+  if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+    {
+    return false;
+    }
+  if(cmLinkImplementationLibraries const* impl =
+     this->Target->GetLinkImplementationLibraries(config))
+    {
+    return !impl->Libraries.empty();
+    }
+  return false;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 91837db..e5dbc69 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -229,6 +229,8 @@ public:
   cmLinkImplementation const*
     GetLinkImplementation(const std::string& config) const;
 
+  bool HaveBuildTreeRPATH(const std::string& config) const;
+
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6252ed5..621d1b0 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2811,21 +2811,6 @@ void cmTarget::SetPropertyDefault(const std::string& property,
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
-{
-  if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
-    {
-    return false;
-    }
-  if(cmLinkImplementationLibraries const* impl =
-     this->GetLinkImplementationLibraries(config))
-    {
-    return !impl->Libraries.empty();
-    }
-  return false;
-}
-
-//----------------------------------------------------------------------------
 bool cmTarget::HaveInstallTreeRPATH() const
 {
   const char* install_rpath = this->GetProperty("INSTALL_RPATH");
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 1d353ab..8866e65 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -294,7 +294,6 @@ public:
   bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
                         const char* newExt = 0) const;
 
-  bool HaveBuildTreeRPATH(const std::string& config) const;
   bool HaveInstallTreeRPATH() const;
 
   // Get the properties

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=61b3fdd7ce4424d6b986e5670c50c092483a7f3d
commit 61b3fdd7ce4424d6b986e5670c50c092483a7f3d
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:49 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:10 2015 +0200

    cmGeneratorTarget: Move GetLinkImplementation from cmTarget.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 67790bc..5a5c1c1 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -556,7 +556,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
   cmLinkImplementation const* impl =
-    this->Target->Target->GetLinkImplementation(this->Config);
+    this->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<cmLinkItem>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index ec9c61b..7488e09 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -252,8 +252,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
         }
       }
 
-    cmLinkImplementation const* impl =
-      depender->Target->GetLinkImplementation(*it);
+    cmLinkImplementation const* impl = depender->GetLinkImplementation(*it);
 
     // A target should not depend on itself.
     emitted.insert(depender->GetName());
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 9449207..5f73162 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1336,7 +1336,7 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
   // Get languages built in this target.
   UNORDERED_SET<std::string> languages;
   cmLinkImplementation const* impl =
-                            this->Target->GetLinkImplementation(config);
+                            this->GetLinkImplementation(config);
   assert(impl);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
@@ -4295,7 +4295,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
       if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
         cmLinkImplementation const* impl =
-            this->Target->GetLinkImplementation(config);
+            this->GetLinkImplementation(config);
         for(std::vector<cmLinkImplItem>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
@@ -4336,7 +4336,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
     {
     // Targets using this archive need its language runtime libraries.
     if(cmLinkImplementation const* impl =
-       this->Target->GetLinkImplementation(config))
+       this->GetLinkImplementation(config))
       {
       iface.Languages = impl->Languages;
       }
@@ -4370,3 +4370,28 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
       }
     }
 }
+
+//----------------------------------------------------------------------------
+const cmLinkImplementation *
+cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
+{
+  // There is no link implementation for imported targets.
+  if(this->Target->IsImported())
+    {
+    return 0;
+    }
+
+  cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+  if(!impl.LibrariesDone)
+    {
+    impl.LibrariesDone = true;
+    this->Target->ComputeLinkImplementationLibraries(config, impl,
+                                                     this->Target);
+    }
+  if(!impl.LanguagesDone)
+    {
+    impl.LanguagesDone = true;
+    this->Target->ComputeLinkImplementationLanguages(config, impl);
+    }
+  return &impl;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9456bb1..91837db 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -226,6 +226,9 @@ public:
   LinkClosure const* GetLinkClosure(const std::string& config) const;
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
 
+  cmLinkImplementation const*
+    GetLinkImplementation(const std::string& config) const;
+
   /** Full path with trailing slash to the top-level directory
       holding object files for this target.  Includes the build
       time config name placeholder if needed for the generator.  */
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 75604a2..dda4829 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1384,7 +1384,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
 
   // If the language is compiled as a source trust Xcode to link with it.
   cmLinkImplementation const* impl =
-    cmtarget.GetLinkImplementation("NOCONFIG");
+    gtgt->GetLinkImplementation("NOCONFIG");
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index a14e1c2..6252ed5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3565,30 +3565,6 @@ void cmTargetInternals::AddInterfaceEntries(
     }
 }
 
-//----------------------------------------------------------------------------
-const cmLinkImplementation *
-cmTarget::GetLinkImplementation(const std::string& config) const
-{
-  // There is no link implementation for imported targets.
-  if(this->IsImported())
-    {
-    return 0;
-    }
-
-  cmOptionalLinkImplementation& impl = this->GetLinkImplMap(config);
-  if(!impl.LibrariesDone)
-    {
-    impl.LibrariesDone = true;
-    this->ComputeLinkImplementationLibraries(config, impl, this);
-    }
-  if(!impl.LanguagesDone)
-    {
-    impl.LanguagesDone = true;
-    this->ComputeLinkImplementationLanguages(config, impl);
-    }
-  return &impl;
-}
-
 cmOptionalLinkImplementation&
 cmTarget::GetLinkImplMap(std::string const& config) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 6411d12..1d353ab 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -231,9 +231,6 @@ public:
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  cmLinkImplementation const*
-    GetLinkImplementation(const std::string& config) const;
-
   cmLinkImplementationLibraries const*
     GetLinkImplementationLibraries(const std::string& config) const;
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4d8072b195d6547a92de835ef27ae205cc7c6609
commit 4d8072b195d6547a92de835ef27ae205cc7c6609
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:49 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:10 2015 +0200

    cmTarget: Add GetLinkImplMap method.
    
    This is a temporary refactoring artifact.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 18d1220..a14e1c2 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3575,10 +3575,7 @@ cmTarget::GetLinkImplementation(const std::string& config) const
     return 0;
     }
 
-  // Populate the link implementation for this configuration.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmOptionalLinkImplementation&
-    impl = this->Internal->LinkImplMap[CONFIG][this];
+  cmOptionalLinkImplementation& impl = this->GetLinkImplMap(config);
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
@@ -3592,6 +3589,14 @@ cmTarget::GetLinkImplementation(const std::string& config) const
   return &impl;
 }
 
+cmOptionalLinkImplementation&
+cmTarget::GetLinkImplMap(std::string const& config) const
+{
+  // Populate the link implementation for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  return Internal->LinkImplMap[CONFIG][this];
+}
+
 //----------------------------------------------------------------------------
 cmLinkImplementationLibraries const*
 cmTarget::GetLinkImplementationLibraries(const std::string& config) const
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d49b23e..6411d12 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -244,6 +244,9 @@ public:
                                           cmOptionalLinkImplementation& impl
                                           ) const;
 
+  cmOptionalLinkImplementation&
+  GetLinkImplMap(std::string const& config) const;
+
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
   /** Strip off leading and trailing whitespace from an item named in

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2d347e68723dbd6e86877856ebff3bd13e5c4dab
commit 2d347e68723dbd6e86877856ebff3bd13e5c4dab
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:48 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:09 2015 +0200

    cmLinkItem: Add cmOptionalLinkImplementation type.
    
    Move the associated Compute* methods to the cmTarget class.

diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index accc83c..f1d914f 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -62,4 +62,15 @@ struct cmLinkImplementation: public cmLinkImplementationLibraries
   std::vector<std::string> Languages;
 };
 
+// Cache link implementation computation from each configuration.
+struct cmOptionalLinkImplementation: public cmLinkImplementation
+{
+  cmOptionalLinkImplementation():
+    LibrariesDone(false), LanguagesDone(false),
+    HadHeadSensitiveCondition(false) {}
+  bool LibrariesDone;
+  bool LanguagesDone;
+  bool HadHeadSensitiveCondition;
+};
+
 #endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e6408c4..18d1220 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -96,27 +96,8 @@ public:
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
-  // Cache link implementation computation from each configuration.
-  struct OptionalLinkImplementation: public cmLinkImplementation
-  {
-    OptionalLinkImplementation():
-      LibrariesDone(false), LanguagesDone(false),
-      HadHeadSensitiveCondition(false) {}
-    bool LibrariesDone;
-    bool LanguagesDone;
-    bool HadHeadSensitiveCondition;
-  };
-  void ComputeLinkImplementationLibraries(cmTarget const* thisTarget,
-                                          const std::string& config,
-                                          OptionalLinkImplementation& impl,
-                                          cmTarget const* head) const;
-  void ComputeLinkImplementationLanguages(cmTarget const* thisTarget,
-                                          const std::string& config,
-                                          OptionalLinkImplementation& impl
-                                          ) const;
-
   struct HeadToLinkImplementationMap:
-    public std::map<cmTarget const*, OptionalLinkImplementation> {};
+    public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
   typedef std::map<std::string,
                    HeadToLinkImplementationMap> LinkImplMapType;
   LinkImplMapType LinkImplMap;
@@ -3596,18 +3577,17 @@ cmTarget::GetLinkImplementation(const std::string& config) const
 
   // Populate the link implementation for this configuration.
   std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::OptionalLinkImplementation&
+  cmOptionalLinkImplementation&
     impl = this->Internal->LinkImplMap[CONFIG][this];
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
-    this->Internal
-      ->ComputeLinkImplementationLibraries(this, config, impl, this);
+    this->ComputeLinkImplementationLibraries(config, impl, this);
     }
   if(!impl.LanguagesDone)
     {
     impl.LanguagesDone = true;
-    this->Internal->ComputeLinkImplementationLanguages(this, config, impl);
+    this->ComputeLinkImplementationLanguages(config, impl);
     }
   return &impl;
 }
@@ -3642,39 +3622,36 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
     return &hm.begin()->second;
     }
 
-  cmTargetInternals::OptionalLinkImplementation& impl = hm[head];
+  cmOptionalLinkImplementation& impl = hm[head];
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
-    this->Internal
-      ->ComputeLinkImplementationLibraries(this, config, impl, head);
+    this->ComputeLinkImplementationLibraries(config, impl, head);
     }
   return &impl;
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLibraries(
-  cmTarget const* thisTarget,
+void cmTarget::ComputeLinkImplementationLibraries(
   const std::string& config,
-  OptionalLinkImplementation& impl,
+  cmOptionalLinkImplementation& impl,
   cmTarget const* head) const
 {
   // Collect libraries directly linked in this configuration.
   for (std::vector<cmValueWithOrigin>::const_iterator
-      le = this->LinkImplementationPropertyEntries.begin(),
-      end = this->LinkImplementationPropertyEntries.end();
+      le = this->Internal->LinkImplementationPropertyEntries.begin(),
+      end = this->Internal->LinkImplementationPropertyEntries.end();
       le != end; ++le)
     {
     std::vector<std::string> llibs;
     cmGeneratorExpressionDAGChecker dagChecker(
-                                        thisTarget->GetName(),
+                                        this->GetName(),
                                         "LINK_LIBRARIES", 0, 0);
     cmGeneratorExpression ge(le->Backtrace);
     cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
       ge.Parse(le->Value);
     std::string const evaluated =
-      cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker);
+      cge->Evaluate(this->Makefile, config, false, head, &dagChecker);
     cmSystemTools::ExpandListArgument(evaluated, llibs);
     if(cge->GetHadHeadSensitiveCondition())
       {
@@ -3685,15 +3662,15 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
         li != llibs.end(); ++li)
       {
       // Skip entries that resolve to the target itself or are empty.
-      std::string name = thisTarget->CheckCMP0004(*li);
-      if(name == thisTarget->GetName() || name.empty())
+      std::string name = this->CheckCMP0004(*li);
+      if(name == this->GetName() || name.empty())
         {
-        if(name == thisTarget->GetName())
+        if(name == this->GetName())
           {
           bool noMessage = false;
           cmake::MessageType messageType = cmake::FATAL_ERROR;
           std::ostringstream e;
-          switch(thisTarget->GetPolicyStatusCMP0038())
+          switch(this->GetPolicyStatusCMP0038())
             {
             case cmPolicies::WARN:
               {
@@ -3712,9 +3689,9 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
 
           if(!noMessage)
             {
-            e << "Target \"" << thisTarget->GetName() << "\" links to itself.";
-            thisTarget->Makefile->GetCMakeInstance()->IssueMessage(
-              messageType, e.str(), thisTarget->GetBacktrace());
+            e << "Target \"" << this->GetName() << "\" links to itself.";
+            this->Makefile->GetCMakeInstance()->IssueMessage(
+              messageType, e.str(), this->GetBacktrace());
             if (messageType == cmake::FATAL_ERROR)
               {
               return;
@@ -3726,7 +3703,7 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
 
       // The entry is meant for this configuration.
       impl.Libraries.push_back(
-        cmLinkImplItem(name, thisTarget->FindTargetToLink(name),
+        cmLinkImplItem(name, this->FindTargetToLink(name),
                        le->Backtrace, evaluated != le->Value));
       }
 
@@ -3734,45 +3711,43 @@ cmTargetInternals::ComputeLinkImplementationLibraries(
     for (std::set<std::string>::const_iterator it = seenProps.begin();
         it != seenProps.end(); ++it)
       {
-      if (!thisTarget->GetProperty(*it))
+      if (!this->GetProperty(*it))
         {
-        thisTarget->LinkImplicitNullProperties.insert(*it);
+        this->LinkImplicitNullProperties.insert(*it);
         }
       }
-    cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards);
+    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
     }
 
-  cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config);
+  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
   cmTarget::LinkLibraryVectorType const& oldllibs =
-    thisTarget->GetOriginalLinkLibraries();
+    this->GetOriginalLinkLibraries();
   for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
       li != oldllibs.end(); ++li)
     {
     if(li->second != cmTarget::GENERAL && li->second != linkType)
       {
-      std::string name = thisTarget->CheckCMP0004(li->first);
-      if(name == thisTarget->GetName() || name.empty())
+      std::string name = this->CheckCMP0004(li->first);
+      if(name == this->GetName() || name.empty())
         {
         continue;
         }
       // Support OLD behavior for CMP0003.
       impl.WrongConfigLibraries.push_back(
-        cmLinkItem(name, thisTarget->FindTargetToLink(name)));
+        cmLinkItem(name, this->FindTargetToLink(name)));
       }
     }
 }
 
 //----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkImplementationLanguages(
-  cmTarget const* thisTarget,
+void cmTarget::ComputeLinkImplementationLanguages(
   const std::string& config,
-  OptionalLinkImplementation& impl) const
+  cmOptionalLinkImplementation& impl) const
 {
   // This target needs runtime libraries for its source languages.
   std::set<std::string> languages;
   // Get languages used in our source files.
-  thisTarget->GetLanguages(languages, config);
+  this->GetLanguages(languages, config);
   // Copy the set of langauges to the link implementation.
   impl.Languages.insert(impl.Languages.begin(),
                         languages.begin(), languages.end());
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 19cc220..d49b23e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -237,6 +237,13 @@ public:
   cmLinkImplementationLibraries const*
     GetLinkImplementationLibraries(const std::string& config) const;
 
+  void ComputeLinkImplementationLibraries(const std::string& config,
+                                          cmOptionalLinkImplementation& impl,
+                                          cmTarget const* head) const;
+  void ComputeLinkImplementationLanguages(const std::string& config,
+                                          cmOptionalLinkImplementation& impl
+                                          ) const;
+
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
   /** Strip off leading and trailing whitespace from an item named in

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=88f26ac1060a9062361f232c4ef4e5f78cd5c4f8
commit 88f26ac1060a9062361f232c4ef4e5f78cd5c4f8
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 17:37:48 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:09 2015 +0200

    cmLinkItem: Add cmLinkImplementation type.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 2e5331d..67790bc 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -555,7 +555,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
 void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
-  cmTarget::LinkImplementation const* impl =
+  cmLinkImplementation const* impl =
     this->Target->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<cmLinkItem>::const_iterator
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index fd4b567..ec9c61b 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -252,7 +252,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
         }
       }
 
-    cmTarget::LinkImplementation const* impl =
+    cmLinkImplementation const* impl =
       depender->Target->GetLinkImplementation(*it);
 
     // A target should not depend on itself.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 4f1a54b..9449207 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1335,7 +1335,7 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
 {
   // Get languages built in this target.
   UNORDERED_SET<std::string> languages;
-  cmTarget::LinkImplementation const* impl =
+  cmLinkImplementation const* impl =
                             this->Target->GetLinkImplementation(config);
   assert(impl);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
@@ -4294,7 +4294,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
         }
       if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
-        cmTarget::LinkImplementation const* impl =
+        cmLinkImplementation const* impl =
             this->Target->GetLinkImplementation(config);
         for(std::vector<cmLinkImplItem>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
@@ -4335,7 +4335,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
   if(this->Target->LinkLanguagePropagatesToDependents())
     {
     // Targets using this archive need its language runtime libraries.
-    if(cmTarget::LinkImplementation const* impl =
+    if(cmLinkImplementation const* impl =
        this->Target->GetLinkImplementation(config))
       {
       iface.Languages = impl->Languages;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 33fd637..75604a2 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1383,7 +1383,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
   if(llang.empty()) { return; }
 
   // If the language is compiled as a source trust Xcode to link with it.
-  cmTarget::LinkImplementation const* impl =
+  cmLinkImplementation const* impl =
     cmtarget.GetLinkImplementation("NOCONFIG");
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index a5427de..accc83c 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -56,4 +56,10 @@ struct cmLinkImplementationLibraries
   std::vector<cmLinkItem> WrongConfigLibraries;
 };
 
+struct cmLinkImplementation: public cmLinkImplementationLibraries
+{
+  // Languages whose runtime libraries must be linked.
+  std::vector<std::string> Languages;
+};
+
 #endif
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index d1b7755..e6408c4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -97,7 +97,7 @@ public:
   ImportInfoMapType ImportInfoMap;
 
   // Cache link implementation computation from each configuration.
-  struct OptionalLinkImplementation: public cmTarget::LinkImplementation
+  struct OptionalLinkImplementation: public cmLinkImplementation
   {
     OptionalLinkImplementation():
       LibrariesDone(false), LanguagesDone(false),
@@ -3585,7 +3585,7 @@ void cmTargetInternals::AddInterfaceEntries(
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkImplementation const*
+const cmLinkImplementation *
 cmTarget::GetLinkImplementation(const std::string& config) const
 {
   // There is no link implementation for imported targets.
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 34a75ea..19cc220 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -231,12 +231,7 @@ public:
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  struct LinkImplementation: public cmLinkImplementationLibraries
-  {
-    // Languages whose runtime libraries must be linked.
-    std::vector<std::string> Languages;
-  };
-  LinkImplementation const*
+  cmLinkImplementation const*
     GetLinkImplementation(const std::string& config) const;
 
   cmLinkImplementationLibraries const*

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=81fb482213b07ef4909de7d8246f120848b17437
commit 81fb482213b07ef4909de7d8246f120848b17437
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 5 00:00:53 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:09 2015 +0200

    cmGeneratorTarget: Move compile defintions processing from cmTarget.

diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 933a256..dfd51c7 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -609,7 +609,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
 
     // the compilerdefines for this target
     std::vector<std::string> cdefs;
-    target->GetCompileDefinitions(cdefs, buildType, "C");
+    gtgt->GetCompileDefinitions(cdefs, buildType, "C");
 
     // Expand the list.
     for(std::vector<std::string>::const_iterator di = cdefs.begin();
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 393ade9..4f1a54b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -262,7 +262,8 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   SourceFileFlagsConstructed(false),
   DebugIncludesDone(false),
   DebugCompileOptionsDone(false),
-  DebugCompileFeaturesDone(false)
+  DebugCompileFeaturesDone(false),
+  DebugCompileDefinitionsDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
@@ -282,6 +283,11 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
         t->GetCompileFeaturesEntries(),
         t->GetCompileFeaturesBacktraces(),
         this->CompileFeaturesEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileDefinitionsEntries(),
+        t->GetCompileDefinitionsBacktraces(),
+        this->CompileDefinitionsEntries);
 }
 
 cmGeneratorTarget::~cmGeneratorTarget()
@@ -289,6 +295,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
   cmDeleteAll(this->IncludeDirectoriesEntries);
   cmDeleteAll(this->CompileOptionsEntries);
   cmDeleteAll(this->CompileFeaturesEntries);
+  cmDeleteAll(this->CompileDefinitionsEntries);
   cmDeleteAll(this->LinkInformation);
   this->LinkInformation.clear();
 }
@@ -2445,6 +2452,108 @@ void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result,
 }
 
 //----------------------------------------------------------------------------
+static void processCompileDefinitions(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions,
+      std::string const& language)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions,
+                                "definitions", language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
+                                            const std::string& config,
+                                            const std::string& language) const
+{
+  UNORDERED_SET<std::string> uniqueOptions;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_DEFINITIONS", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugDefines = !this->DebugCompileDefinitionsDone
+                          && std::find(debugProperties.begin(),
+                                debugProperties.end(),
+                                "COMPILE_DEFINITIONS")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsConfigured())
+    {
+    this->DebugCompileDefinitionsDone = true;
+    }
+
+  processCompileDefinitions(this,
+                            this->CompileDefinitionsEntries,
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines,
+                            language);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileDefinitionsEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_DEFINITIONS",
+    linkInterfaceCompileDefinitionsEntries);
+  if (!config.empty())
+    {
+    std::string configPropName = "COMPILE_DEFINITIONS_"
+                                        + cmSystemTools::UpperCase(config);
+    const char *configProp = this->Target->GetProperty(configPropName);
+    if (configProp)
+      {
+      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
+        {
+        case cmPolicies::WARN:
+          {
+          std::ostringstream e;
+          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
+          this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING,
+                                       e.str());
+          }
+        case cmPolicies::OLD:
+          {
+          cmGeneratorExpression ge;
+          cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                                                      ge.Parse(configProp);
+          linkInterfaceCompileDefinitionsEntries
+                .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+          }
+          break;
+        case cmPolicies::NEW:
+        case cmPolicies::REQUIRED_ALWAYS:
+        case cmPolicies::REQUIRED_IF_USED:
+          break;
+        }
+      }
+    }
+
+  processCompileDefinitions(this,
+                            linkInterfaceCompileDefinitionsEntries,
+                            list,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugDefines,
+                            language);
+
+  cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
+}
+
+//----------------------------------------------------------------------------
 void cmGeneratorTarget::GenerateTargetManifest(
                                               const std::string& config) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e57485f..9456bb1 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -252,6 +252,10 @@ public:
   void GetCompileFeatures(std::vector<std::string> &features,
                           const std::string& config) const;
 
+  void GetCompileDefinitions(std::vector<std::string> &result,
+                             const std::string& config,
+                             const std::string& language) const;
+
   bool IsSystemIncludeDirectory(const std::string& dir,
                                 const std::string& config) const;
 
@@ -459,10 +463,12 @@ private:
   mutable bool DebugIncludesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileFeaturesDone;
+  mutable bool DebugCompileDefinitionsDone;
 
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
+  std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 503c455..c0f1817 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1550,7 +1550,6 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes,
         ti != targets.end(); ++ti)
       {
       cmTarget* t = &ti->second;
-      t->Compute();
       cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
       this->GeneratorTargets[t] = gt;
       generatorTargets[t] = gt;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 4ba29f5..33fd637 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1855,7 +1855,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     this->AppendDefines(ppDefs, exportMacro);
     }
   std::vector<std::string> targetDefines;
-  target.GetCompileDefinitions(targetDefines, configName, "C");
+  gtgt->GetCompileDefinitions(targetDefines, configName, "C");
   this->AppendDefines(ppDefs, targetDefines);
   buildSettings->AddAttribute
     ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a7e4191..c1cc241 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1083,7 +1083,8 @@ void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
                                              const std::string& lang)
 {
   std::vector<std::string> targetDefines;
-  target->GetCompileDefinitions(targetDefines, config, lang);
+  cmGeneratorTarget* gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
+  gtgt->GetCompileDefinitions(targetDefines, config, lang);
   this->AppendDefines(defines, targetDefines);
 }
 
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index f85e70e..c58e7e4 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -474,8 +474,6 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg,
                                 /*byproducts=*/rcc_output, depends,
                                 commandLines, false, autogenComment.c_str());
 
-    autogenTarget->Compute();
-
     cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
     makefile->AddGeneratorTarget(autogenTarget, gt);
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7a23e9d..d1b7755 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -146,7 +146,6 @@ public:
   std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
   std::vector<std::string> CompileDefinitionsEntries;
   std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
-  std::vector<TargetPropertyEntry*> CompileDefinitionsItems;
   std::vector<TargetPropertyEntry*> SourceEntries;
   std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
 
@@ -175,7 +174,6 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
-  this->DebugCompileDefinitionsDone = false;
   this->DebugSourcesDone = false;
   this->LinkImplementationLanguageIsContextDependent = true;
 }
@@ -418,14 +416,6 @@ void CreatePropertyGeneratorExpressions(
     }
 }
 
-void cmTarget::Compute()
-{
-  CreatePropertyGeneratorExpressions(
-        this->Internal->CompileDefinitionsEntries,
-        this->Internal->CompileDefinitionsBacktraces,
-        this->Internal->CompileDefinitionsItems);
-}
-
 //----------------------------------------------------------------------------
 void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
 {
@@ -1329,6 +1319,16 @@ cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
   return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
 }
 
+cmStringRange cmTarget::GetCompileDefinitionsEntries() const
+{
+  return cmMakeRange(this->Internal->CompileDefinitionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -1926,156 +1926,6 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
 }
 
 //----------------------------------------------------------------------------
-static void processCompileOptionsInternal(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions, const char *logName,
-      std::string const& language)
-{
-  cmMakefile *mf = tgt->GetMakefile();
-
-  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-      it = entries.begin(), end = entries.end(); it != end; ++it)
-    {
-    std::vector<std::string> entryOptions;
-    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
-                                              config,
-                                              false,
-                                              tgt,
-                                              dagChecker,
-                                              language),
-                                    entryOptions);
-    std::string usedOptions;
-    for(std::vector<std::string>::iterator
-          li = entryOptions.begin(); li != entryOptions.end(); ++li)
-      {
-      std::string const& opt = *li;
-
-      if(uniqueOptions.insert(opt).second)
-        {
-        options.push_back(opt);
-        if (debugOptions)
-          {
-          usedOptions += " * " + opt + "\n";
-          }
-        }
-      }
-    if (!usedOptions.empty())
-      {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
-                            std::string("Used compile ") + logName
-                            + std::string(" for target ")
-                            + tgt->GetName() + ":\n"
-                            + usedOptions, (*it)->ge->GetBacktrace());
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-static void processCompileDefinitions(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions,
-      std::string const& language)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions,
-                                "definitions", language);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
-                                            const std::string& config,
-                                            const std::string& language) const
-{
-  UNORDERED_SET<std::string> uniqueOptions;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_DEFINITIONS", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugDefines = !this->DebugCompileDefinitionsDone
-                          && std::find(debugProperties.begin(),
-                                debugProperties.end(),
-                                "COMPILE_DEFINITIONS")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsConfigured())
-    {
-    this->DebugCompileDefinitionsDone = true;
-    }
-
-  processCompileDefinitions(this,
-                            this->Internal->CompileDefinitionsItems,
-                            list,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugDefines,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileDefinitionsEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_DEFINITIONS",
-    linkInterfaceCompileDefinitionsEntries);
-  if (!config.empty())
-    {
-    std::string configPropName = "COMPILE_DEFINITIONS_"
-                                        + cmSystemTools::UpperCase(config);
-    const char *configProp = this->GetProperty(configPropName);
-    if (configProp)
-      {
-      switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
-        {
-        case cmPolicies::WARN:
-          {
-          std::ostringstream e;
-          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043);
-          this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
-                                       e.str());
-          }
-        case cmPolicies::OLD:
-          {
-          cmGeneratorExpression ge;
-          cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-                                                      ge.Parse(configProp);
-          linkInterfaceCompileDefinitionsEntries
-                .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
-          }
-          break;
-        case cmPolicies::NEW:
-        case cmPolicies::REQUIRED_ALWAYS:
-        case cmPolicies::REQUIRED_IF_USED:
-          break;
-        }
-      }
-    }
-
-  processCompileDefinitions(this,
-                            linkInterfaceCompileDefinitionsEntries,
-                            list,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugDefines,
-                            language);
-
-  cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
 {
   // Wipe out maps caching information affected by this property.
@@ -4035,7 +3885,6 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
-  cmDeleteAll(this->Pointer->CompileDefinitionsItems);
   cmDeleteAll(this->Pointer->SourceEntries);
   delete this->Pointer;
 }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index aae558e..34a75ea 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -132,8 +132,6 @@ public:
   void AddPostBuildCommand(cmCustomCommand const &cmd)
     {this->PostBuildCommands.push_back(cmd);}
 
-  void Compute();
-
   /**
    * Get the list of the source files used by this target
    */
@@ -309,10 +307,6 @@ public:
       If no macro should be defined null is returned.  */
   const char* GetExportMacro() const;
 
-  void GetCompileDefinitions(std::vector<std::string> &result,
-                             const std::string& config,
-                             const std::string& language) const;
-
   // Compute the set of languages compiled by the target.  This is
   // computed every time it is called because the languages can change
   // when source file properties are changed and we do not have enough
@@ -402,6 +396,9 @@ public:
   cmStringRange GetCompileFeaturesEntries() const;
   cmBacktraceRange GetCompileFeaturesBacktraces() const;
 
+  cmStringRange GetCompileDefinitionsEntries() const;
+  cmBacktraceRange GetCompileDefinitionsBacktraces() const;
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -516,7 +513,6 @@ private:
   bool IsApple;
   bool IsImportedTarget;
   bool BuildInterfaceIncludesAppended;
-  mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugSourcesDone;
   mutable bool LinkImplementationLanguageIsContextDependent;
 #if defined(_WIN32) && !defined(__CYGWIN__)

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=09bd59c75114dd177c685a62a34a3010ff2250a0
commit 09bd59c75114dd177c685a62a34a3010ff2250a0
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 4 23:48:58 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:09 2015 +0200

    cmGeneratorTarget: Move compile features processing from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a56d95d..393ade9 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -261,7 +261,8 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   : Target(t),
   SourceFileFlagsConstructed(false),
   DebugIncludesDone(false),
-  DebugCompileOptionsDone(false)
+  DebugCompileOptionsDone(false),
+  DebugCompileFeaturesDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
@@ -276,12 +277,18 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
         t->GetCompileOptionsEntries(),
         t->GetCompileOptionsBacktraces(),
         this->CompileOptionsEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileFeaturesEntries(),
+        t->GetCompileFeaturesBacktraces(),
+        this->CompileFeaturesEntries);
 }
 
 cmGeneratorTarget::~cmGeneratorTarget()
 {
   cmDeleteAll(this->IncludeDirectoriesEntries);
   cmDeleteAll(this->CompileOptionsEntries);
+  cmDeleteAll(this->CompileFeaturesEntries);
   cmDeleteAll(this->LinkInformation);
   this->LinkInformation.clear();
 }
@@ -2371,6 +2378,73 @@ void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result,
 }
 
 //----------------------------------------------------------------------------
+static void processCompileFeatures(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "features",
+                                std::string());
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result,
+                                  const std::string& config) const
+{
+  UNORDERED_SET<std::string> uniqueFeatures;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_FEATURES",
+                                             0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugFeatures = !this->DebugCompileFeaturesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "COMPILE_FEATURES")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsConfigured())
+    {
+    this->DebugCompileFeaturesDone = true;
+    }
+
+  processCompileFeatures(this,
+                            this->CompileFeaturesEntries,
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileFeaturesEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_FEATURES",
+    linkInterfaceCompileFeaturesEntries);
+
+  processCompileFeatures(this,
+                         linkInterfaceCompileFeaturesEntries,
+                            result,
+                            uniqueFeatures,
+                            &dagChecker,
+                            config,
+                            debugFeatures);
+
+  cmDeleteAll(linkInterfaceCompileFeaturesEntries);
+}
+
+//----------------------------------------------------------------------------
 void cmGeneratorTarget::GenerateTargetManifest(
                                               const std::string& config) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 99dc746..e57485f 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -249,6 +249,9 @@ public:
                          const std::string& config,
                          const std::string& language) const;
 
+  void GetCompileFeatures(std::vector<std::string> &features,
+                          const std::string& config) const;
+
   bool IsSystemIncludeDirectory(const std::string& dir,
                                 const std::string& config) const;
 
@@ -455,9 +458,11 @@ private:
   mutable bool PolicyWarnedCMP0022;
   mutable bool DebugIncludesDone;
   mutable bool DebugCompileOptionsDone;
+  mutable bool DebugCompileFeaturesDone;
 
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
+  std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 89515ff..a7e4191 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1138,7 +1138,7 @@ void cmLocalGenerator::AddCompileOptions(
       }
     }
   std::vector<std::string> features;
-  target->GetCompileFeatures(features, config);
+  gtgt->GetCompileFeatures(features, config);
   for(std::vector<std::string>::const_iterator it = features.begin();
       it != features.end(); ++it)
     {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 466f98a..7a23e9d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -144,7 +144,6 @@ public:
   std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
   std::vector<std::string> CompileFeaturesEntries;
   std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
-  std::vector<TargetPropertyEntry*> CompileFeaturesItems;
   std::vector<std::string> CompileDefinitionsEntries;
   std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
   std::vector<TargetPropertyEntry*> CompileDefinitionsItems;
@@ -176,7 +175,6 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
-  this->DebugCompileFeaturesDone = false;
   this->DebugCompileDefinitionsDone = false;
   this->DebugSourcesDone = false;
   this->LinkImplementationLanguageIsContextDependent = true;
@@ -423,11 +421,6 @@ void CreatePropertyGeneratorExpressions(
 void cmTarget::Compute()
 {
   CreatePropertyGeneratorExpressions(
-        this->Internal->CompileFeaturesEntries,
-        this->Internal->CompileFeaturesBacktraces,
-        this->Internal->CompileFeaturesItems);
-
-  CreatePropertyGeneratorExpressions(
         this->Internal->CompileDefinitionsEntries,
         this->Internal->CompileDefinitionsBacktraces,
         this->Internal->CompileDefinitionsItems);
@@ -1326,6 +1319,16 @@ cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
   return cmMakeRange(this->Internal->CompileOptionsBacktraces);
 }
 
+cmStringRange cmTarget::GetCompileFeaturesEntries() const
+{
+  return cmMakeRange(this->Internal->CompileFeaturesEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileFeaturesBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -2073,73 +2076,6 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list,
 }
 
 //----------------------------------------------------------------------------
-static void processCompileFeatures(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions, "features",
-                                std::string());
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileFeatures(std::vector<std::string> &result,
-                                  const std::string& config) const
-{
-  UNORDERED_SET<std::string> uniqueFeatures;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_FEATURES",
-                                             0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugFeatures = !this->DebugCompileFeaturesDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "COMPILE_FEATURES")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsConfigured())
-    {
-    this->DebugCompileFeaturesDone = true;
-    }
-
-  processCompileFeatures(this,
-                            this->Internal->CompileFeaturesItems,
-                            result,
-                            uniqueFeatures,
-                            &dagChecker,
-                            config,
-                            debugFeatures);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileFeaturesEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_FEATURES",
-    linkInterfaceCompileFeaturesEntries);
-
-  processCompileFeatures(this,
-                         linkInterfaceCompileFeaturesEntries,
-                            result,
-                            uniqueFeatures,
-                            &dagChecker,
-                            config,
-                            debugFeatures);
-
-  cmDeleteAll(linkInterfaceCompileFeaturesEntries);
-}
-
-//----------------------------------------------------------------------------
 void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
 {
   // Wipe out maps caching information affected by this property.
@@ -4099,7 +4035,6 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
-  cmDeleteAll(this->Pointer->CompileFeaturesItems);
   cmDeleteAll(this->Pointer->CompileDefinitionsItems);
   cmDeleteAll(this->Pointer->SourceEntries);
   delete this->Pointer;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 05b6aec..aae558e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -375,9 +375,6 @@ public:
 
   void AppendBuildInterfaceIncludes();
 
-  void GetCompileFeatures(std::vector<std::string> &features,
-                          const std::string& config) const;
-
   bool IsNullImpliedByLinkLibraries(const std::string &p) const;
 
   std::string GetDebugGeneratorExpressions(const std::string &value,
@@ -402,6 +399,9 @@ public:
   cmStringRange GetCompileOptionsEntries() const;
   cmBacktraceRange GetCompileOptionsBacktraces() const;
 
+  cmStringRange GetCompileFeaturesEntries() const;
+  cmBacktraceRange GetCompileFeaturesBacktraces() const;
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -518,7 +518,6 @@ private:
   bool BuildInterfaceIncludesAppended;
   mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugSourcesDone;
-  mutable bool DebugCompileFeaturesDone;
   mutable bool LinkImplementationLanguageIsContextDependent;
 #if defined(_WIN32) && !defined(__CYGWIN__)
   bool LinkLibrariesForVS6Analyzed;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8d45ba34d64cb5d7d71d8ade8b5f2226cd9e4734
commit 8d45ba34d64cb5d7d71d8ade8b5f2226cd9e4734
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 4 23:43:56 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:09 2015 +0200

    cmGeneratorTarget: Move compile options processing from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 01967da..a56d95d 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -260,7 +260,8 @@ void CreatePropertyGeneratorExpressions(
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   : Target(t),
   SourceFileFlagsConstructed(false),
-  DebugIncludesDone(false)
+  DebugIncludesDone(false),
+  DebugCompileOptionsDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
@@ -270,11 +271,17 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
         t->GetIncludeDirectoriesEntries(),
         t->GetIncludeDirectoriesBacktraces(),
         this->IncludeDirectoriesEntries);
+
+  CreatePropertyGeneratorExpressions(
+        t->GetCompileOptionsEntries(),
+        t->GetCompileOptionsBacktraces(),
+        this->CompileOptionsEntries);
 }
 
 cmGeneratorTarget::~cmGeneratorTarget()
 {
   cmDeleteAll(this->IncludeDirectoriesEntries);
+  cmDeleteAll(this->CompileOptionsEntries);
   cmDeleteAll(this->LinkInformation);
   this->LinkInformation.clear();
 }
@@ -2245,6 +2252,125 @@ cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
+static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions, const char *logName,
+      std::string const& language)
+{
+  cmMakefile *mf = tgt->Target->GetMakefile();
+
+  for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    std::vector<std::string> entryOptions;
+    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+                                              config,
+                                              false,
+                                              tgt->Target,
+                                              dagChecker,
+                                              language),
+                                    entryOptions);
+    std::string usedOptions;
+    for(std::vector<std::string>::iterator
+          li = entryOptions.begin(); li != entryOptions.end(); ++li)
+      {
+      std::string const& opt = *li;
+
+      if(uniqueOptions.insert(opt).second)
+        {
+        options.push_back(opt);
+        if (debugOptions)
+          {
+          usedOptions += " * " + opt + "\n";
+          }
+        }
+      }
+    if (!usedOptions.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used compile ") + logName
+                            + std::string(" for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedOptions, (*it)->ge->GetBacktrace());
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+static void processCompileOptions(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &options,
+      UNORDERED_SET<std::string> &uniqueOptions,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugOptions,
+      std::string const& language)
+{
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "options",
+                                language);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result,
+                                 const std::string& config,
+                                 const std::string& language) const
+{
+  UNORDERED_SET<std::string> uniqueOptions;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "COMPILE_OPTIONS", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugOptions = !this->DebugCompileOptionsDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "COMPILE_OPTIONS")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsConfigured())
+    {
+    this->DebugCompileOptionsDone = true;
+    }
+
+  processCompileOptions(this,
+                            this->CompileOptionsEntries,
+                            result,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugOptions,
+                            language);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceCompileOptionsEntries;
+
+  AddInterfaceEntries(
+    this, config, "INTERFACE_COMPILE_OPTIONS",
+    linkInterfaceCompileOptionsEntries);
+
+  processCompileOptions(this,
+                        linkInterfaceCompileOptionsEntries,
+                            result,
+                            uniqueOptions,
+                            &dagChecker,
+                            config,
+                            debugOptions,
+                            language);
+
+  cmDeleteAll(linkInterfaceCompileOptionsEntries);
+}
+
+//----------------------------------------------------------------------------
 void cmGeneratorTarget::GenerateTargetManifest(
                                               const std::string& config) const
 {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 9407d1f..99dc746 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -245,6 +245,10 @@ public:
   std::vector<std::string> GetIncludeDirectories(
       const std::string& config, const std::string& lang) const;
 
+  void GetCompileOptions(std::vector<std::string> &result,
+                         const std::string& config,
+                         const std::string& language) const;
+
   bool IsSystemIncludeDirectory(const std::string& dir,
                                 const std::string& config) const;
 
@@ -450,8 +454,10 @@ private:
 
   mutable bool PolicyWarnedCMP0022;
   mutable bool DebugIncludesDone;
+  mutable bool DebugCompileOptionsDone;
 
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
+  std::vector<TargetPropertyEntry*> CompileOptionsEntries;
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index edb644d..89515ff 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1094,6 +1094,10 @@ void cmLocalGenerator::AddCompileOptions(
   )
 {
   std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX";
+
+  cmGeneratorTarget* gtgt =
+      this->GlobalGenerator->GetGeneratorTarget(target);
+
   if(const char* langFlagRegexStr =
      this->Makefile->GetDefinition(langFlagRegexVar))
     {
@@ -1104,7 +1108,7 @@ void cmLocalGenerator::AddCompileOptions(
       {
       cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
       }
-    target->GetCompileOptions(opts, config, lang);
+    gtgt->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
@@ -1125,7 +1129,7 @@ void cmLocalGenerator::AddCompileOptions(
       this->AppendFlags(flags, targetFlags);
       }
     std::vector<std::string> opts;
-    target->GetCompileOptions(opts, config, lang);
+    gtgt->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index fb4241b..466f98a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -142,7 +142,6 @@ public:
   std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
   std::vector<std::string> CompileOptionsEntries;
   std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
-  std::vector<TargetPropertyEntry*> CompileOptionsItems;
   std::vector<std::string> CompileFeaturesEntries;
   std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
   std::vector<TargetPropertyEntry*> CompileFeaturesItems;
@@ -177,7 +176,6 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
-  this->DebugCompileOptionsDone = false;
   this->DebugCompileFeaturesDone = false;
   this->DebugCompileDefinitionsDone = false;
   this->DebugSourcesDone = false;
@@ -425,11 +423,6 @@ void CreatePropertyGeneratorExpressions(
 void cmTarget::Compute()
 {
   CreatePropertyGeneratorExpressions(
-        this->Internal->CompileOptionsEntries,
-        this->Internal->CompileOptionsBacktraces,
-        this->Internal->CompileOptionsItems);
-
-  CreatePropertyGeneratorExpressions(
         this->Internal->CompileFeaturesEntries,
         this->Internal->CompileFeaturesBacktraces,
         this->Internal->CompileFeaturesItems);
@@ -1323,6 +1316,16 @@ cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
   return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
 }
 
+cmStringRange cmTarget::GetCompileOptionsEntries() const
+{
+  return cmMakeRange(this->Internal->CompileOptionsEntries);
+}
+
+cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const
+{
+  return cmMakeRange(this->Internal->CompileOptionsBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -1968,77 +1971,6 @@ static void processCompileOptionsInternal(cmTarget const* tgt,
 }
 
 //----------------------------------------------------------------------------
-static void processCompileOptions(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &options,
-      UNORDERED_SET<std::string> &uniqueOptions,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugOptions,
-      std::string const& language)
-{
-  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
-                                dagChecker, config, debugOptions, "options",
-                                language);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetCompileOptions(std::vector<std::string> &result,
-                                 const std::string& config,
-                                 const std::string& language) const
-{
-  UNORDERED_SET<std::string> uniqueOptions;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "COMPILE_OPTIONS", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugOptions = !this->DebugCompileOptionsDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "COMPILE_OPTIONS")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsConfigured())
-    {
-    this->DebugCompileOptionsDone = true;
-    }
-
-  processCompileOptions(this,
-                            this->Internal->CompileOptionsItems,
-                            result,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugOptions,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceCompileOptionsEntries;
-
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_COMPILE_OPTIONS",
-    linkInterfaceCompileOptionsEntries);
-
-  processCompileOptions(this,
-                        linkInterfaceCompileOptionsEntries,
-                            result,
-                            uniqueOptions,
-                            &dagChecker,
-                            config,
-                            debugOptions,
-                            language);
-
-  cmDeleteAll(linkInterfaceCompileOptionsEntries);
-}
-
-//----------------------------------------------------------------------------
 static void processCompileDefinitions(cmTarget const* tgt,
       const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
       std::vector<std::string> &options,
@@ -4167,7 +4099,6 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
-  cmDeleteAll(this->Pointer->CompileOptionsItems);
   cmDeleteAll(this->Pointer->CompileFeaturesItems);
   cmDeleteAll(this->Pointer->CompileDefinitionsItems);
   cmDeleteAll(this->Pointer->SourceEntries);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 13e4f2d..05b6aec 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -375,9 +375,6 @@ public:
 
   void AppendBuildInterfaceIncludes();
 
-  void GetCompileOptions(std::vector<std::string> &result,
-                         const std::string& config,
-                         const std::string& language) const;
   void GetCompileFeatures(std::vector<std::string> &features,
                           const std::string& config) const;
 
@@ -402,6 +399,9 @@ public:
   cmStringRange GetIncludeDirectoriesEntries() const;
   cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
 
+  cmStringRange GetCompileOptionsEntries() const;
+  cmBacktraceRange GetCompileOptionsBacktraces() const;
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -516,7 +516,6 @@ private:
   bool IsApple;
   bool IsImportedTarget;
   bool BuildInterfaceIncludesAppended;
-  mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugSourcesDone;
   mutable bool DebugCompileFeaturesDone;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6ee49bf15acc52ea8b0a32c3e64bfaf75be95846
commit 6ee49bf15acc52ea8b0a32c3e64bfaf75be95846
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 4 23:14:53 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:08 2015 +0200

    cmGeneratorTarget: Move include directory processing from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 1e8e83b..01967da 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -34,6 +34,18 @@
 #define UNORDERED_SET std::set
 #endif
 
+class cmGeneratorTarget::TargetPropertyEntry {
+  static cmLinkImplItem NoLinkImplItem;
+public:
+  TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
+                      cmLinkImplItem const& item = NoLinkImplItem)
+    : ge(cge), LinkImplItem(item)
+  {}
+  const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+  cmLinkImplItem const& LinkImplItem;
+};
+cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
+
 //----------------------------------------------------------------------------
 void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
                      cmGeneratorTarget const* target, cmake *cm)
@@ -227,18 +239,42 @@ struct TagVisitor
   }
 };
 
+void CreatePropertyGeneratorExpressions(
+    cmStringRange const& entries,
+    cmBacktraceRange const& backtraces,
+    std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+    bool evaluateForBuildsystem = false)
+{
+  std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin();
+  for (std::vector<std::string>::const_iterator it = entries.begin();
+       it != entries.end(); ++it, ++btIt)
+    {
+    cmGeneratorExpression ge(*btIt);
+    cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it);
+    cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
+    items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+    }
+}
+
 //----------------------------------------------------------------------------
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   : Target(t),
-  SourceFileFlagsConstructed(false)
+  SourceFileFlagsConstructed(false),
+  DebugIncludesDone(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
+
+  CreatePropertyGeneratorExpressions(
+        t->GetIncludeDirectoriesEntries(),
+        t->GetIncludeDirectoriesBacktraces(),
+        this->IncludeDirectoriesEntries);
 }
 
 cmGeneratorTarget::~cmGeneratorTarget()
 {
+  cmDeleteAll(this->IncludeDirectoriesEntries);
   cmDeleteAll(this->LinkInformation);
   this->LinkInformation.clear();
 }
@@ -1964,13 +2000,248 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
     }
   return "";
 }
+//----------------------------------------------------------------------------
+static void processIncludeDirectories(cmGeneratorTarget const* tgt,
+      const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+      std::vector<std::string> &includes,
+      UNORDERED_SET<std::string> &uniqueIncludes,
+      cmGeneratorExpressionDAGChecker *dagChecker,
+      const std::string& config, bool debugIncludes,
+      const std::string& language)
+{
+  cmMakefile *mf = tgt->Target->GetMakefile();
+
+  for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
+    {
+    cmLinkImplItem const& item = (*it)->LinkImplItem;
+    std::string const& targetName = item;
+    bool const fromImported = item.Target && item.Target->IsImported();
+    bool const checkCMP0027 = item.FromGenex;
+    std::vector<std::string> entryIncludes;
+    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+                                              config,
+                                              false,
+                                              tgt->Target,
+                                              dagChecker, language),
+                                    entryIncludes);
+
+    std::string usedIncludes;
+    for(std::vector<std::string>::iterator
+          li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
+      {
+      if (fromImported
+          && !cmSystemTools::FileExists(li->c_str()))
+        {
+        std::ostringstream e;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        if (checkCMP0027)
+          {
+          switch(tgt->Target->GetPolicyStatusCMP0027())
+            {
+            case cmPolicies::WARN:
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
+            case cmPolicies::OLD:
+              messageType = cmake::AUTHOR_WARNING;
+              break;
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::NEW:
+              break;
+            }
+          }
+        e << "Imported target \"" << targetName << "\" includes "
+             "non-existent path\n  \"" << *li << "\"\nin its "
+             "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
+             "* The path was deleted, renamed, or moved to another "
+             "location.\n"
+             "* An install or uninstall procedure did not complete "
+             "successfully.\n"
+             "* The installation package was faulty and references files it "
+             "does not provide.\n";
+        tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+        return;
+        }
+
+      if (!cmSystemTools::FileIsFullPath(li->c_str()))
+        {
+        std::ostringstream e;
+        bool noMessage = false;
+        cmake::MessageType messageType = cmake::FATAL_ERROR;
+        if (!targetName.empty())
+          {
+          e << "Target \"" << targetName << "\" contains relative "
+            "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
+            "  \"" << *li << "\"";
+          }
+        else
+          {
+          switch(tgt->Target->GetPolicyStatusCMP0021())
+            {
+            case cmPolicies::WARN:
+              {
+              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
+              messageType = cmake::AUTHOR_WARNING;
+              }
+              break;
+            case cmPolicies::OLD:
+              noMessage = true;
+            case cmPolicies::REQUIRED_IF_USED:
+            case cmPolicies::REQUIRED_ALWAYS:
+            case cmPolicies::NEW:
+              // Issue the fatal message.
+              break;
+            }
+          e << "Found relative path while evaluating include directories of "
+          "\"" << tgt->GetName() << "\":\n  \"" << *li << "\"\n";
+          }
+        if (!noMessage)
+          {
+          tgt->GetLocalGenerator()->IssueMessage(messageType, e.str());
+          if (messageType == cmake::FATAL_ERROR)
+            {
+            return;
+            }
+          }
+        }
+
+      if (!cmSystemTools::IsOff(li->c_str()))
+        {
+        cmSystemTools::ConvertToUnixSlashes(*li);
+        }
+      std::string inc = *li;
+
+      if(uniqueIncludes.insert(inc).second)
+        {
+        includes.push_back(inc);
+        if (debugIncludes)
+          {
+          usedIncludes += " * " + inc + "\n";
+          }
+        }
+      }
+    if (!usedIncludes.empty())
+      {
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used includes for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedIncludes, (*it)->ge->GetBacktrace());
+      }
+    }
+}
+
+
+//----------------------------------------------------------------------------
+static void AddInterfaceEntries(
+  cmGeneratorTarget const* thisTarget, std::string const& config,
+  std::string const& prop,
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+{
+  if(cmLinkImplementationLibraries const* impl =
+     thisTarget->Target->GetLinkImplementationLibraries(config))
+    {
+    for (std::vector<cmLinkImplItem>::const_iterator
+           it = impl->Libraries.begin(), end = impl->Libraries.end();
+         it != end; ++it)
+      {
+      if(it->Target)
+        {
+        std::string genex =
+          "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+        cmGeneratorExpression ge(it->Backtrace);
+        cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+        cge->SetEvaluateForBuildsystem(true);
+        entries.push_back(
+          new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
+        }
+      }
+    }
+}
 
 //----------------------------------------------------------------------------
 std::vector<std::string>
 cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
                                          const std::string& lang) const
 {
-  return this->Target->GetIncludeDirectories(config, lang);
+  std::vector<std::string> includes;
+  UNORDERED_SET<std::string> uniqueIncludes;
+
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+                                             "INCLUDE_DIRECTORIES", 0, 0);
+
+  std::vector<std::string> debugProperties;
+  const char *debugProp =
+              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+  if (debugProp)
+    {
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+    }
+
+  bool debugIncludes = !this->DebugIncludesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "INCLUDE_DIRECTORIES")
+                        != debugProperties.end();
+
+  if (this->Makefile->IsConfigured())
+    {
+    this->DebugIncludesDone = true;
+    }
+
+  processIncludeDirectories(this,
+                            this->IncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes,
+                            lang);
+
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+    linkInterfaceIncludeDirectoriesEntries;
+  AddInterfaceEntries(
+    this, config, "INTERFACE_INCLUDE_DIRECTORIES",
+    linkInterfaceIncludeDirectoriesEntries);
+
+  if(this->Makefile->IsOn("APPLE"))
+    {
+    cmLinkImplementationLibraries const* impl =
+        this->Target->GetLinkImplementationLibraries(config);
+    for(std::vector<cmLinkImplItem>::const_iterator
+        it = impl->Libraries.begin();
+        it != impl->Libraries.end(); ++it)
+      {
+      std::string libDir = cmSystemTools::CollapseFullPath(*it);
+
+      static cmsys::RegularExpression
+        frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
+      if(!frameworkCheck.find(libDir))
+        {
+        continue;
+        }
+
+      libDir = frameworkCheck.match(1);
+
+      cmGeneratorExpression ge;
+      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+                ge.Parse(libDir.c_str());
+      linkInterfaceIncludeDirectoriesEntries
+              .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge));
+      }
+    }
+
+  processIncludeDirectories(this,
+                            linkInterfaceIncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes,
+                            lang);
+
+  cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+
+  return includes;
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 46341d3..9407d1f 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -360,6 +360,8 @@ public:
                             const std::string &report,
                             const std::string &compatibilityType) const;
 
+  class TargetPropertyEntry;
+
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -447,6 +449,9 @@ private:
   mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
 
   mutable bool PolicyWarnedCMP0022;
+  mutable bool DebugIncludesDone;
+
+  std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e941fb6..fb4241b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -140,7 +140,6 @@ public:
   };
   std::vector<std::string> IncludeDirectoriesEntries;
   std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
-  std::vector<TargetPropertyEntry*> IncludeDirectoriesItems;
   std::vector<std::string> CompileOptionsEntries;
   std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
   std::vector<TargetPropertyEntry*> CompileOptionsItems;
@@ -178,7 +177,6 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
-  this->DebugIncludesDone = false;
   this->DebugCompileOptionsDone = false;
   this->DebugCompileFeaturesDone = false;
   this->DebugCompileDefinitionsDone = false;
@@ -427,11 +425,6 @@ void CreatePropertyGeneratorExpressions(
 void cmTarget::Compute()
 {
   CreatePropertyGeneratorExpressions(
-        this->Internal->IncludeDirectoriesEntries,
-        this->Internal->IncludeDirectoriesBacktraces,
-        this->Internal->IncludeDirectoriesItems);
-
-  CreatePropertyGeneratorExpressions(
         this->Internal->CompileOptionsEntries,
         this->Internal->CompileOptionsBacktraces,
         this->Internal->CompileOptionsItems);
@@ -1320,6 +1313,16 @@ cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs)
   this->SystemIncludeDirectories.insert(incs.begin(), incs.end());
 }
 
+cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
+{
+  return cmMakeRange(this->Internal->IncludeDirectoriesEntries);
+}
+
+cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const
+{
+  return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces);
+}
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -1917,222 +1920,6 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
 }
 
 //----------------------------------------------------------------------------
-static void processIncludeDirectories(cmTarget const* tgt,
-      const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
-      std::vector<std::string> &includes,
-      UNORDERED_SET<std::string> &uniqueIncludes,
-      cmGeneratorExpressionDAGChecker *dagChecker,
-      const std::string& config, bool debugIncludes,
-      const std::string& language)
-{
-  cmMakefile *mf = tgt->GetMakefile();
-
-  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
-      it = entries.begin(), end = entries.end(); it != end; ++it)
-    {
-    cmLinkImplItem const& item = (*it)->LinkImplItem;
-    std::string const& targetName = item;
-    bool const fromImported = item.Target && item.Target->IsImported();
-    bool const checkCMP0027 = item.FromGenex;
-    std::vector<std::string> entryIncludes;
-    cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
-                                              config,
-                                              false,
-                                              tgt,
-                                              dagChecker, language),
-                                    entryIncludes);
-
-    std::string usedIncludes;
-    for(std::vector<std::string>::iterator
-          li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
-      {
-      if (fromImported
-          && !cmSystemTools::FileExists(li->c_str()))
-        {
-        std::ostringstream e;
-        cmake::MessageType messageType = cmake::FATAL_ERROR;
-        if (checkCMP0027)
-          {
-          switch(tgt->GetPolicyStatusCMP0027())
-            {
-            case cmPolicies::WARN:
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
-            case cmPolicies::OLD:
-              messageType = cmake::AUTHOR_WARNING;
-              break;
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::NEW:
-              break;
-            }
-          }
-        e << "Imported target \"" << targetName << "\" includes "
-             "non-existent path\n  \"" << *li << "\"\nin its "
-             "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
-             "* The path was deleted, renamed, or moved to another "
-             "location.\n"
-             "* An install or uninstall procedure did not complete "
-             "successfully.\n"
-             "* The installation package was faulty and references files it "
-             "does not provide.\n";
-        tgt->GetMakefile()->IssueMessage(messageType, e.str());
-        return;
-        }
-
-      if (!cmSystemTools::FileIsFullPath(li->c_str()))
-        {
-        std::ostringstream e;
-        bool noMessage = false;
-        cmake::MessageType messageType = cmake::FATAL_ERROR;
-        if (!targetName.empty())
-          {
-          e << "Target \"" << targetName << "\" contains relative "
-            "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
-            "  \"" << *li << "\"";
-          }
-        else
-          {
-          switch(tgt->GetPolicyStatusCMP0021())
-            {
-            case cmPolicies::WARN:
-              {
-              e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n";
-              messageType = cmake::AUTHOR_WARNING;
-              }
-              break;
-            case cmPolicies::OLD:
-              noMessage = true;
-            case cmPolicies::REQUIRED_IF_USED:
-            case cmPolicies::REQUIRED_ALWAYS:
-            case cmPolicies::NEW:
-              // Issue the fatal message.
-              break;
-            }
-          e << "Found relative path while evaluating include directories of "
-          "\"" << tgt->GetName() << "\":\n  \"" << *li << "\"\n";
-          }
-        if (!noMessage)
-          {
-          tgt->GetMakefile()->IssueMessage(messageType, e.str());
-          if (messageType == cmake::FATAL_ERROR)
-            {
-            return;
-            }
-          }
-        }
-
-      if (!cmSystemTools::IsOff(li->c_str()))
-        {
-        cmSystemTools::ConvertToUnixSlashes(*li);
-        }
-      std::string inc = *li;
-
-      if(uniqueIncludes.insert(inc).second)
-        {
-        includes.push_back(inc);
-        if (debugIncludes)
-          {
-          usedIncludes += " * " + inc + "\n";
-          }
-        }
-      }
-    if (!usedIncludes.empty())
-      {
-      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
-                            std::string("Used includes for target ")
-                            + tgt->GetName() + ":\n"
-                            + usedIncludes, (*it)->ge->GetBacktrace());
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-std::vector<std::string>
-cmTarget::GetIncludeDirectories(const std::string& config,
-                                const std::string& language) const
-{
-  std::vector<std::string> includes;
-  UNORDERED_SET<std::string> uniqueIncludes;
-
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             "INCLUDE_DIRECTORIES", 0, 0);
-
-  std::vector<std::string> debugProperties;
-  const char *debugProp =
-              this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
-  if (debugProp)
-    {
-    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
-    }
-
-  bool debugIncludes = !this->DebugIncludesDone
-                    && std::find(debugProperties.begin(),
-                                 debugProperties.end(),
-                                 "INCLUDE_DIRECTORIES")
-                        != debugProperties.end();
-
-  if (this->Makefile->IsConfigured())
-    {
-    this->DebugIncludesDone = true;
-    }
-
-  processIncludeDirectories(this,
-                            this->Internal->IncludeDirectoriesItems,
-                            includes,
-                            uniqueIncludes,
-                            &dagChecker,
-                            config,
-                            debugIncludes,
-                            language);
-
-  std::vector<cmTargetInternals::TargetPropertyEntry*>
-    linkInterfaceIncludeDirectoriesEntries;
-  this->Internal->AddInterfaceEntries(
-    this, config, "INTERFACE_INCLUDE_DIRECTORIES",
-    linkInterfaceIncludeDirectoriesEntries);
-
-  if(this->Makefile->IsOn("APPLE"))
-    {
-    cmLinkImplementationLibraries const* impl =
-        this->GetLinkImplementationLibraries(config);
-    for(std::vector<cmLinkImplItem>::const_iterator
-        it = impl->Libraries.begin();
-        it != impl->Libraries.end(); ++it)
-      {
-      std::string libDir = cmSystemTools::CollapseFullPath(*it);
-
-      static cmsys::RegularExpression
-        frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
-      if(!frameworkCheck.find(libDir))
-        {
-        continue;
-        }
-
-      libDir = frameworkCheck.match(1);
-
-      cmGeneratorExpression ge;
-      cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
-                ge.Parse(libDir.c_str());
-      linkInterfaceIncludeDirectoriesEntries
-              .push_back(new cmTargetInternals::TargetPropertyEntry(cge));
-      }
-    }
-
-  processIncludeDirectories(this,
-                            linkInterfaceIncludeDirectoriesEntries,
-                            includes,
-                            uniqueIncludes,
-                            &dagChecker,
-                            config,
-                            debugIncludes,
-                            language);
-
-  cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
-
-  return includes;
-}
-
-//----------------------------------------------------------------------------
 static void processCompileOptionsInternal(cmTarget const* tgt,
       const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries,
       std::vector<std::string> &options,
@@ -4380,7 +4167,6 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
-  cmDeleteAll(this->Pointer->IncludeDirectoriesItems);
   cmDeleteAll(this->Pointer->CompileOptionsItems);
   cmDeleteAll(this->Pointer->CompileFeaturesItems);
   cmDeleteAll(this->Pointer->CompileDefinitionsItems);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 103a7e8..13e4f2d 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -364,9 +364,6 @@ public:
   /** @return whether this target have a well defined output file name. */
   bool HaveWellDefinedOutputFiles() const;
 
-  std::vector<std::string> GetIncludeDirectories(
-                     const std::string& config,
-                     const std::string& language) const;
   void InsertInclude(std::string const& entry,
                      cmListFileBacktrace const& bt,
                      bool before = false);
@@ -402,6 +399,9 @@ public:
     return this->MaxLanguageStandards;
   }
 
+  cmStringRange GetIncludeDirectoriesEntries() const;
+  cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -516,7 +516,6 @@ private:
   bool IsApple;
   bool IsImportedTarget;
   bool BuildInterfaceIncludesAppended;
-  mutable bool DebugIncludesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugSourcesDone;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2962880e25943d5c7670ca34986366c3f41fb67d
commit 2962880e25943d5c7670ca34986366c3f41fb67d
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 4 19:22:30 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:08 2015 +0200

    cmGeneratorTarget: Move link iface helpers from cmTarget.

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index cf4019c..1e8e83b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -3363,6 +3363,51 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
 }
 
 //----------------------------------------------------------------------------
+void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
+                               std::vector<cmLinkItem>& items) const
+{
+  for(std::vector<std::string>::const_iterator i = names.begin();
+      i != names.end(); ++i)
+    {
+    std::string name = this->Target->CheckCMP0004(*i);
+    if(name == this->GetName() || name.empty())
+      {
+      continue;
+      }
+    items.push_back(cmLinkItem(name, this->Target->FindTargetToLink(name)));
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
+                               std::string const& value,
+                               std::string const& config,
+                               cmTarget const* headTarget,
+                               bool usage_requirements_only,
+                               std::vector<cmLinkItem>& items,
+                               bool& hadHeadSensitiveCondition) const
+{
+  cmGeneratorExpression ge;
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  // The $<LINK_ONLY> expression may be in a link interface to specify private
+  // link dependencies that are otherwise excluded from usage requirements.
+  if(usage_requirements_only)
+    {
+    dagChecker.SetTransitivePropertiesOnly();
+    }
+  std::vector<std::string> libs;
+  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
+  cmSystemTools::ExpandListArgument(cge->Evaluate(
+                                      this->Makefile,
+                                      config,
+                                      false,
+                                      headTarget,
+                                      this->Target, &dagChecker), libs);
+  this->LookupLinkItems(libs, items);
+  hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+}
+
+//----------------------------------------------------------------------------
 cmGeneratorTarget::LinkInterface const* cmGeneratorTarget::GetLinkInterface(
                                                   const std::string& config,
                                                   cmTarget const* head) const
@@ -3397,14 +3442,14 @@ cmGeneratorTarget::LinkInterface const* cmGeneratorTarget::GetLinkInterface(
     {
     iface.LibrariesDone = true;
     this->ComputeLinkInterfaceLibraries(
-      this->Target, config, iface, head, false);
+      config, iface, head, false);
     }
   if(!iface.AllDone)
     {
     iface.AllDone = true;
     if(iface.Exists)
       {
-      this->ComputeLinkInterface(this->Target, config, iface, head);
+      this->ComputeLinkInterface(config, iface, head);
       }
     }
 
@@ -3450,7 +3495,7 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
     {
     iface.LibrariesDone = true;
     this->ComputeLinkInterfaceLibraries(
-      this->Target, config, iface, head, usage_requirements_only);
+      config, iface, head, usage_requirements_only);
     }
 
   return iface.Exists? &iface : 0;
@@ -3487,13 +3532,13 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
     iface.AllDone = true;
     iface.Multiplicity = info->Multiplicity;
     cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
-    this->Target->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
+    this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
                           headTarget, usage_requirements_only,
                           iface.Libraries,
                           iface.HadHeadSensitiveCondition);
     std::vector<std::string> deps;
     cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
-    this->Target->LookupLinkItems(deps, iface.SharedDeps);
+    this->LookupLinkItems(deps, iface.SharedDeps);
     }
 
   return &iface;
@@ -3502,7 +3547,6 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
 //----------------------------------------------------------------------------
 void
 cmGeneratorTarget::ComputeLinkInterfaceLibraries(
-  cmTarget const* thisTarget,
   const std::string& config,
   OptionalLinkInterface& iface,
   cmTarget const* headTarget,
@@ -3523,15 +3567,15 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
   // libraries and executables that export symbols.
   const char* explicitLibraries = 0;
   std::string linkIfaceProp;
-  if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
-     thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN)
+  if(this->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+     this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN)
     {
     // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
     linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+    explicitLibraries = this->Target->GetProperty(linkIfaceProp);
     }
-  else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
-          thisTarget->IsExecutableWithExports())
+  else if(this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
+          this->Target->IsExecutableWithExports())
     {
     // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
     // shared lib or executable.
@@ -3539,30 +3583,30 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
     // Lookup the per-configuration property.
     linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
     linkIfaceProp += suffix;
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+    explicitLibraries = this->Target->GetProperty(linkIfaceProp);
 
     // If not set, try the generic property.
     if(!explicitLibraries)
       {
       linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-      explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+      explicitLibraries = this->Target->GetProperty(linkIfaceProp);
       }
     }
 
   if(explicitLibraries &&
-     thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+     this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
      !this->PolicyWarnedCMP0022)
     {
     // Compare the explicitly set old link interface properties to the
     // preferred new link interface property one and warn if different.
     const char* newExplicitLibraries =
-      thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
+      this->Target->GetProperty("INTERFACE_LINK_LIBRARIES");
     if (newExplicitLibraries
         && strcmp(newExplicitLibraries, explicitLibraries) != 0)
       {
       std::ostringstream w;
       w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-        "Target \"" << thisTarget->GetName() << "\" has an "
+        "Target \"" << this->Target->GetName() << "\" has an "
         "INTERFACE_LINK_LIBRARIES property which differs from its " <<
         linkIfaceProp << " properties."
         "\n"
@@ -3570,7 +3614,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
         "  " << newExplicitLibraries << "\n" <<
         linkIfaceProp << ":\n"
         "  " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
-      thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+      this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
       this->PolicyWarnedCMP0022 = true;
       }
     }
@@ -3578,8 +3622,8 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
   // There is no implicit link interface for executables or modules
   // so if none was explicitly set then there is no link interface.
   if(!explicitLibraries &&
-     (thisTarget->GetType() == cmTarget::EXECUTABLE ||
-      (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
+     (this->Target->GetType() == cmTarget::EXECUTABLE ||
+      (this->Target->GetType() == cmTarget::MODULE_LIBRARY)))
     {
     return;
     }
@@ -3589,13 +3633,13 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
   if(explicitLibraries)
     {
     // The interface libraries have been explicitly set.
-    thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
+    this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
                                 headTarget, usage_requirements_only,
                                 iface.Libraries,
                                 iface.HadHeadSensitiveCondition);
     }
-  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
-        || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+  else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || this->Target->GetPolicyStatusCMP0022() == 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
@@ -3603,20 +3647,20 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
     {
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const* impl =
-      thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
+      this->Target->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.Libraries.insert(iface.Libraries.end(),
                            impl->Libraries.begin(), impl->Libraries.end());
-    if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+    if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
        !this->PolicyWarnedCMP0022 && !usage_requirements_only)
       {
       // Compare the link implementation fallback link interface to the
       // preferred new link interface property and warn if different.
       std::vector<cmLinkItem> ifaceLibs;
       static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
-      if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
+      if(const char* newExplicitLibraries = this->Target->GetProperty(newProp))
         {
         bool hadHeadSensitiveConditionDummy = false;
-        thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
+        this->ExpandLinkItems(newProp, newExplicitLibraries, config,
                                     headTarget, usage_requirements_only,
                                 ifaceLibs, hadHeadSensitiveConditionDummy);
         }
@@ -3631,7 +3675,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 
         std::ostringstream w;
         w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-          "Target \"" << thisTarget->GetName() << "\" has an "
+          "Target \"" << this->Target->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 "
@@ -3642,7 +3686,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
           "  " << newLibraries << "\n"
           "Link implementation:\n"
           "  " << oldLibraries << "\n";
-        thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+        this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
         this->PolicyWarnedCMP0022 = true;
         }
       }
@@ -3650,16 +3694,15 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
 }
 
 //----------------------------------------------------------------------------
-void cmGeneratorTarget::ComputeLinkInterface(cmTarget const* thisTarget,
-                                             const std::string& config,
+void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
                                              OptionalLinkInterface& iface,
                                              cmTarget const* headTarget) const
 {
   if(iface.ExplicitLibraries)
     {
-    if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
-        || thisTarget->GetType() == cmTarget::STATIC_LIBRARY
-        || thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY)
+    if(this->GetType() == cmTarget::SHARED_LIBRARY
+        || this->GetType() == cmTarget::STATIC_LIBRARY
+        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
       {
       // Shared libraries may have runtime implementation dependencies
       // on other shared libraries that are not in the interface.
@@ -3669,10 +3712,10 @@ void cmGeneratorTarget::ComputeLinkInterface(cmTarget const* thisTarget,
         {
         emitted.insert(*li);
         }
-      if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
+      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
         cmTarget::LinkImplementation const* impl =
-            thisTarget->GetLinkImplementation(config);
+            this->Target->GetLinkImplementation(config);
         for(std::vector<cmLinkImplItem>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
@@ -3698,28 +3741,28 @@ void cmGeneratorTarget::ComputeLinkInterface(cmTarget const* thisTarget,
         }
       }
     }
-  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
-        || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+  else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
     {
     // The link implementation is the default link interface.
     cmLinkImplementationLibraries const*
-      impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
+      impl = this->Target->GetLinkImplementationLibrariesInternal(config,
                                                                 headTarget);
     iface.ImplementationIsInterface = true;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     }
 
-  if(thisTarget->LinkLanguagePropagatesToDependents())
+  if(this->Target->LinkLanguagePropagatesToDependents())
     {
     // Targets using this archive need its language runtime libraries.
     if(cmTarget::LinkImplementation const* impl =
-       thisTarget->GetLinkImplementation(config))
+       this->Target->GetLinkImplementation(config))
       {
       iface.Languages = impl->Languages;
       }
     }
 
-  if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
+  if(this->GetType() == cmTarget::STATIC_LIBRARY)
     {
     // Construct the property name suffix for this configuration.
     std::string suffix = "_";
@@ -3736,12 +3779,12 @@ void cmGeneratorTarget::ComputeLinkInterface(cmTarget const* thisTarget,
     // dependencies?
     std::string propName = "LINK_INTERFACE_MULTIPLICITY";
     propName += suffix;
-    if(const char* config_reps = thisTarget->GetProperty(propName))
+    if(const char* config_reps = this->Target->GetProperty(propName))
       {
       sscanf(config_reps, "%u", &iface.Multiplicity);
       }
     else if(const char* reps =
-            thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+            this->Target->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
       {
       sscanf(reps, "%u", &iface.Multiplicity);
       }
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e0d3425..46341d3 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -431,12 +431,10 @@ private:
     bool HadHeadSensitiveCondition;
     const char* ExplicitLibraries;
   };
-  void ComputeLinkInterface(cmTarget const* thisTarget,
-                            const std::string& config,
+  void ComputeLinkInterface(const std::string& config,
                             OptionalLinkInterface& iface,
                             cmTarget const* head) const;
-  void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
-                                     const std::string& config,
+  void ComputeLinkInterfaceLibraries(const std::string& config,
                                      OptionalLinkInterface& iface,
                                      cmTarget const* head,
                                      bool usage_requirements_only) const;
@@ -450,6 +448,14 @@ private:
 
   mutable bool PolicyWarnedCMP0022;
 
+  void ExpandLinkItems(std::string const& prop, std::string const& value,
+                       std::string const& config, cmTarget const* headTarget,
+                       bool usage_requirements_only,
+                       std::vector<cmLinkItem>& items,
+                       bool& hadHeadSensitiveCondition) const;
+  void LookupLinkItems(std::vector<std::string> const& names,
+                       std::vector<cmLinkItem>& items) const;
+
   typedef std::pair<std::string, bool> OutputNameKey;
   typedef std::map<OutputNameKey, std::string> OutputNameMapType;
   mutable OutputNameMapType OutputNameMap;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index aa60311..e941fb6 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3062,51 +3062,6 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::ExpandLinkItems(std::string const& prop,
-                               std::string const& value,
-                               std::string const& config,
-                               cmTarget const* headTarget,
-                               bool usage_requirements_only,
-                               std::vector<cmLinkItem>& items,
-                               bool& hadHeadSensitiveCondition) const
-{
-  cmGeneratorExpression ge;
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
-  // The $<LINK_ONLY> expression may be in a link interface to specify private
-  // link dependencies that are otherwise excluded from usage requirements.
-  if(usage_requirements_only)
-    {
-    dagChecker.SetTransitivePropertiesOnly();
-    }
-  std::vector<std::string> libs;
-  cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
-  cmSystemTools::ExpandListArgument(cge->Evaluate(
-                                      this->Makefile,
-                                      config,
-                                      false,
-                                      headTarget,
-                                      this, &dagChecker), libs);
-  this->LookupLinkItems(libs, items);
-  hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::LookupLinkItems(std::vector<std::string> const& names,
-                               std::vector<cmLinkItem>& items) const
-{
-  for(std::vector<std::string>::const_iterator i = names.begin();
-      i != names.end(); ++i)
-    {
-    std::string name = this->CheckCMP0004(*i);
-    if(name == this->GetName() || name.empty())
-      {
-      continue;
-      }
-    items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
-    }
-}
-
-//----------------------------------------------------------------------------
 const char* cmTarget::GetSuffixVariableInternal(bool implib) const
 {
   switch(this->GetType())
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 25de6a6..103a7e8 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -558,14 +558,6 @@ private:
     GetLinkImplementationLibrariesInternal(const std::string& config,
                                            cmTarget const* head) const;
 
-  void ExpandLinkItems(std::string const& prop, std::string const& value,
-                       std::string const& config, cmTarget const* headTarget,
-                       bool usage_requirements_only,
-                       std::vector<cmLinkItem>& items,
-                       bool& hadHeadSensitiveCondition) const;
-  void LookupLinkItems(std::vector<std::string> const& names,
-                       std::vector<cmLinkItem>& items) const;
-
   std::string ProcessSourceItemCMP0049(const std::string& s);
 
   void ClearLinkMaps();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7707a52f41947c1db1674563a6258f908c8efd6f
commit 7707a52f41947c1db1674563a6258f908c8efd6f
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Tue Aug 4 19:22:30 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Tue Aug 25 22:37:06 2015 +0200

    cmGeneratorTarget: Move GetLinkInterface from cmTarget.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 59590fd..2e5331d 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -361,8 +361,10 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
   if(entry.Target)
     {
     // Follow the target dependencies.
-    if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->Target->Target))
+    cmGeneratorTarget* gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
+    if(cmGeneratorTarget::LinkInterface const* iface =
+       gtgt->GetLinkInterface(this->Config, this->Target->Target))
       {
       const bool isIface =
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -396,7 +398,8 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
 //----------------------------------------------------------------------------
 void
 cmComputeLinkDepends
-::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
+::FollowSharedDeps(int depender_index,
+                   cmGeneratorTarget::LinkInterface const* iface,
                    bool follow_interface)
 {
   // Follow dependencies if we have not followed them already.
@@ -459,8 +462,10 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   // Target items may have their own dependencies.
   if(entry.Target)
     {
-    if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->Target->Target))
+    cmGeneratorTarget* gtgt =
+        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
+    if(cmGeneratorTarget::LinkInterface const* iface =
+       gtgt->GetLinkInterface(this->Config, this->Target->Target))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -930,8 +935,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
     {
     if(cmTarget const* target = this->EntryList[*ni].Target)
       {
-      if(cmTarget::LinkInterface const* iface =
-         target->GetLinkInterface(this->Config, this->Target->Target))
+      cmGeneratorTarget* gtgt =
+          this->GlobalGenerator->GetGeneratorTarget(target);
+      if(cmGeneratorTarget::LinkInterface const* iface =
+         gtgt->GetLinkInterface(this->Config, this->Target->Target))
         {
         if(iface->Multiplicity > count)
           {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index b925a4f..e61175a 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -13,6 +13,7 @@
 #define cmComputeLinkDepends_h
 
 #include "cmStandardIncludes.h"
+#include "cmGeneratorTarget.h"
 #include "cmTarget.h"
 
 #include "cmGraphAdjacencyList.h"
@@ -22,8 +23,6 @@
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmMakefile;
-class cmGeneratorTarget;
-class cmTarget;
 class cmake;
 
 /** \class cmComputeLinkDepends
@@ -102,7 +101,7 @@ private:
   std::queue<SharedDepEntry> SharedDepQueue;
   std::set<int> SharedDepFollowed;
   void FollowSharedDeps(int depender_index,
-                        cmTarget::LinkInterface const* iface,
+                        cmGeneratorTarget::LinkInterface const* iface,
                         bool follow_interface = false);
   void QueueSharedDependencies(int depender_index,
                                std::vector<cmLinkItem> const& deps);
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index c4a03a0..fd4b567 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -296,8 +296,8 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
                                              std::set<std::string> &emitted)
 {
   cmGeneratorTarget const* depender = this->Targets[depender_index];
-  if(cmTarget::LinkInterface const* iface =
-                                dependee->Target->GetLinkInterface(config,
+  if(cmGeneratorTarget::LinkInterface const* iface =
+                                dependee->GetLinkInterface(config,
                                                            depender->Target))
     {
     for(std::vector<cmLinkItem>::const_iterator
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index cae60b7..97eb6b9 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -796,7 +796,7 @@ cmExportFileGenerator
                     std::vector<std::string>& missingTargets)
 {
   // Add the transitive link dependencies for this configuration.
-  cmTarget::LinkInterface const* iface = target->Target->GetLinkInterface(
+  cmGeneratorTarget::LinkInterface const* iface = target->GetLinkInterface(
                                                               config,
                                                               target->Target);
   if (!iface)
@@ -909,9 +909,8 @@ cmExportFileGenerator
     }
 
   // Add the transitive link dependencies for this configuration.
-  if(cmTarget::LinkInterface const* iface =
-                            target->Target
-                                  ->GetLinkInterface(config, target->Target))
+  if(cmGeneratorTarget::LinkInterface const* iface =
+                            target->GetLinkInterface(config, target->Target))
     {
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 03bc83a..b957379 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1108,8 +1108,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
     if(isInterfaceProperty)
       {
-      if(cmTarget::LinkInterfaceLibraries const* iface =
-         target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+      if(cmGeneratorTarget::LinkInterfaceLibraries const* iface =
+         gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true))
         {
         linkedTargetsContent =
           getLinkedTargetsContent(iface->Libraries, target,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index dd58e7b..cf4019c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1173,8 +1173,11 @@ public:
       return;
       }
 
-    cmTarget::LinkInterface const* iface =
-      item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+    cmGeneratorTarget* gtgt =
+        this->Target->GetLocalGenerator()->GetGlobalGenerator()
+            ->GetGeneratorTarget(item.Target);
+    cmGeneratorTarget::LinkInterface const* iface =
+      gtgt->GetLinkInterface(this->Config, this->HeadTarget);
     if(!iface) { return; }
 
     for(std::vector<std::string>::const_iterator
@@ -1505,20 +1508,22 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
 void processILibs(const std::string& config,
                   cmTarget const* headTarget,
                   cmLinkItem const& item,
+                  cmGlobalGenerator* gg,
                   std::vector<cmTarget const*>& tgts,
                   std::set<cmTarget const*>& emitted)
 {
   if (item.Target && emitted.insert(item.Target).second)
     {
     tgts.push_back(item.Target);
-    if(cmTarget::LinkInterfaceLibraries const* iface =
-       item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
+    cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target);
+    if(cmGeneratorTarget::LinkInterfaceLibraries const* iface =
+       gt->GetLinkInterfaceLibraries(config, headTarget, true))
       {
       for(std::vector<cmLinkItem>::const_iterator
             it = iface->Libraries.begin();
           it != iface->Libraries.end(); ++it)
         {
-        processILibs(config, headTarget, *it, tgts, emitted);
+        processILibs(config, headTarget, *it, gg, tgts, emitted);
         }
       }
     }
@@ -1543,7 +1548,9 @@ cmGeneratorTarget::GetLinkImplementationClosure(
           it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
       {
-      processILibs(config, this->Target, *it, tgts , emitted);
+      processILibs(config, this->Target, *it,
+                   this->LocalGenerator->GetGlobalGenerator(),
+                   tgts, emitted);
       }
     }
   return tgts;
@@ -3354,3 +3361,389 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
 
   this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
 }
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkInterface const* cmGeneratorTarget::GetLinkInterface(
+                                                  const std::string& config,
+                                                  cmTarget const* head) const
+{
+  // Imported targets have their own link interface.
+  if(this->Target->IsImported())
+    {
+    return this->GetImportLinkInterface(config, head, false);
+    }
+
+  // Link interfaces are not supported for executables that do not
+  // export symbols.
+  if(this->GetType() == cmTarget::EXECUTABLE &&
+     !this->Target->IsExecutableWithExports())
+    {
+    return 0;
+    }
+
+  // Lookup any existing link interface for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  HeadToLinkInterfaceMap& hm = this->LinkInterfaceMap[CONFIG];
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  OptionalLinkInterface& iface = hm[head];
+  if(!iface.LibrariesDone)
+    {
+    iface.LibrariesDone = true;
+    this->ComputeLinkInterfaceLibraries(
+      this->Target, config, iface, head, false);
+    }
+  if(!iface.AllDone)
+    {
+    iface.AllDone = true;
+    if(iface.Exists)
+      {
+      this->ComputeLinkInterface(this->Target, config, iface, head);
+      }
+    }
+
+  return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkInterfaceLibraries const*
+cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
+                                    cmTarget const* head,
+                                    bool usage_requirements_only) const
+{
+  // Imported targets have their own link interface.
+  if(this->Target->IsImported())
+    {
+    return this->GetImportLinkInterface(config, head, usage_requirements_only);
+    }
+
+  // Link interfaces are not supported for executables that do not
+  // export symbols.
+  if(this->GetType() == cmTarget::EXECUTABLE &&
+     !this->Target->IsExecutableWithExports())
+    {
+    return 0;
+    }
+
+  // Lookup any existing link interface for this configuration.
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  HeadToLinkInterfaceMap& hm =
+    (usage_requirements_only ?
+     this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
+     this->LinkInterfaceMap[CONFIG]);
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  OptionalLinkInterface& iface = hm[head];
+  if(!iface.LibrariesDone)
+    {
+    iface.LibrariesDone = true;
+    this->ComputeLinkInterfaceLibraries(
+      this->Target, config, iface, head, usage_requirements_only);
+    }
+
+  return iface.Exists? &iface : 0;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::LinkInterface const*
+cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
+                                 cmTarget const* headTarget,
+                                 bool usage_requirements_only) const
+{
+  cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
+  if(!info)
+    {
+    return 0;
+    }
+
+  std::string CONFIG = cmSystemTools::UpperCase(config);
+  HeadToLinkInterfaceMap& hm =
+    (usage_requirements_only ?
+     this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
+     this->LinkInterfaceMap[CONFIG]);
+
+  // If the link interface does not depend on the head target
+  // then return the one we computed first.
+  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+    {
+    return &hm.begin()->second;
+    }
+
+  OptionalLinkInterface& iface = hm[headTarget];
+  if(!iface.AllDone)
+    {
+    iface.AllDone = true;
+    iface.Multiplicity = info->Multiplicity;
+    cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+    this->Target->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
+                          headTarget, usage_requirements_only,
+                          iface.Libraries,
+                          iface.HadHeadSensitiveCondition);
+    std::vector<std::string> deps;
+    cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+    this->Target->LookupLinkItems(deps, iface.SharedDeps);
+    }
+
+  return &iface;
+}
+
+//----------------------------------------------------------------------------
+void
+cmGeneratorTarget::ComputeLinkInterfaceLibraries(
+  cmTarget const* thisTarget,
+  const std::string& config,
+  OptionalLinkInterface& iface,
+  cmTarget const* headTarget,
+  bool usage_requirements_only) const
+{
+  // Construct the property name suffix for this configuration.
+  std::string suffix = "_";
+  if(!config.empty())
+    {
+    suffix += cmSystemTools::UpperCase(config);
+    }
+  else
+    {
+    suffix += "NOCONFIG";
+    }
+
+  // An explicit list of interface libraries may be set for shared
+  // libraries and executables that export symbols.
+  const char* explicitLibraries = 0;
+  std::string linkIfaceProp;
+  if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+     thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN)
+    {
+    // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
+    linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
+    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+    }
+  else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
+          thisTarget->IsExecutableWithExports())
+    {
+    // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
+    // shared lib or executable.
+
+    // Lookup the per-configuration property.
+    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+    linkIfaceProp += suffix;
+    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+
+    // If not set, try the generic property.
+    if(!explicitLibraries)
+      {
+      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+      explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
+      }
+    }
+
+  if(explicitLibraries &&
+     thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+     !this->PolicyWarnedCMP0022)
+    {
+    // Compare the explicitly set old link interface properties to the
+    // preferred new link interface property one and warn if different.
+    const char* newExplicitLibraries =
+      thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
+    if (newExplicitLibraries
+        && strcmp(newExplicitLibraries, explicitLibraries) != 0)
+      {
+      std::ostringstream w;
+      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+        "Target \"" << thisTarget->GetName() << "\" has an "
+        "INTERFACE_LINK_LIBRARIES property which differs from its " <<
+        linkIfaceProp << " properties."
+        "\n"
+        "INTERFACE_LINK_LIBRARIES:\n"
+        "  " << newExplicitLibraries << "\n" <<
+        linkIfaceProp << ":\n"
+        "  " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
+      thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+      this->PolicyWarnedCMP0022 = true;
+      }
+    }
+
+  // There is no implicit link interface for executables or modules
+  // so if none was explicitly set then there is no link interface.
+  if(!explicitLibraries &&
+     (thisTarget->GetType() == cmTarget::EXECUTABLE ||
+      (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
+    {
+    return;
+    }
+  iface.Exists = true;
+  iface.ExplicitLibraries = explicitLibraries;
+
+  if(explicitLibraries)
+    {
+    // The interface libraries have been explicitly set.
+    thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
+                                headTarget, usage_requirements_only,
+                                iface.Libraries,
+                                iface.HadHeadSensitiveCondition);
+    }
+  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || thisTarget->GetPolicyStatusCMP0022() == 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.
+    cmLinkImplementationLibraries const* impl =
+      thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
+    iface.Libraries.insert(iface.Libraries.end(),
+                           impl->Libraries.begin(), impl->Libraries.end());
+    if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+       !this->PolicyWarnedCMP0022 && !usage_requirements_only)
+      {
+      // Compare the link implementation fallback link interface to the
+      // preferred new link interface property and warn if different.
+      std::vector<cmLinkItem> ifaceLibs;
+      static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
+      if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
+        {
+        bool hadHeadSensitiveConditionDummy = false;
+        thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
+                                    headTarget, usage_requirements_only,
+                                ifaceLibs, hadHeadSensitiveConditionDummy);
+        }
+      if (ifaceLibs != iface.Libraries)
+        {
+        std::string oldLibraries = cmJoin(impl->Libraries, ";");
+        std::string newLibraries = cmJoin(ifaceLibs, ";");
+        if(oldLibraries.empty())
+          { oldLibraries = "(empty)"; }
+        if(newLibraries.empty())
+          { newLibraries = "(empty)"; }
+
+        std::ostringstream w;
+        w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
+          "Target \"" << thisTarget->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";
+        thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+        this->PolicyWarnedCMP0022 = true;
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkInterface(cmTarget const* thisTarget,
+                                             const std::string& config,
+                                             OptionalLinkInterface& iface,
+                                             cmTarget const* headTarget) const
+{
+  if(iface.ExplicitLibraries)
+    {
+    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.
+      UNORDERED_SET<std::string> emitted;
+      for(std::vector<cmLinkItem>::const_iterator
+          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
+        {
+        emitted.insert(*li);
+        }
+      if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
+        {
+        cmTarget::LinkImplementation const* impl =
+            thisTarget->GetLinkImplementation(config);
+        for(std::vector<cmLinkImplItem>::const_iterator
+              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
+          {
+          if(emitted.insert(*li).second)
+            {
+            if(li->Target)
+              {
+              // This is a runtime dependency on another shared library.
+              if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
+                {
+                iface.SharedDeps.push_back(*li);
+                }
+              }
+            else
+              {
+              // TODO: Recognize shared library file names.  Perhaps this
+              // should be moved to cmComputeLinkInformation, but that creates
+              // a chicken-and-egg problem since this list is needed for its
+              // construction.
+              }
+            }
+          }
+        }
+      }
+    }
+  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
+        || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+    {
+    // The link implementation is the default link interface.
+    cmLinkImplementationLibraries const*
+      impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
+                                                                headTarget);
+    iface.ImplementationIsInterface = true;
+    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
+    }
+
+  if(thisTarget->LinkLanguagePropagatesToDependents())
+    {
+    // Targets using this archive need its language runtime libraries.
+    if(cmTarget::LinkImplementation const* impl =
+       thisTarget->GetLinkImplementation(config))
+      {
+      iface.Languages = impl->Languages;
+      }
+    }
+
+  if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    // Construct the property name suffix for this configuration.
+    std::string suffix = "_";
+    if(!config.empty())
+      {
+      suffix += cmSystemTools::UpperCase(config);
+      }
+    else
+      {
+      suffix += "NOCONFIG";
+      }
+
+    // How many repetitions are needed if this library has cyclic
+    // dependencies?
+    std::string propName = "LINK_INTERFACE_MULTIPLICITY";
+    propName += suffix;
+    if(const char* config_reps = thisTarget->GetProperty(propName))
+      {
+      sscanf(config_reps, "%u", &iface.Multiplicity);
+      }
+    else if(const char* reps =
+            thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
+      {
+      sscanf(reps, "%u", &iface.Multiplicity);
+      }
+    }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 15b3335..e0d3425 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -13,6 +13,7 @@
 #define cmGeneratorTarget_h
 
 #include "cmStandardIncludes.h"
+#include "cmLinkItem.h"
 
 class cmCustomCommand;
 class cmGlobalGenerator;
@@ -106,6 +107,48 @@ public:
   const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p,
                          const std::string& config) const;
 
+  /** The link interface specifies transitive library dependencies and
+      other information needed by targets that link to this target.  */
+  struct LinkInterfaceLibraries
+  {
+    // Libraries listed in the interface.
+    std::vector<cmLinkItem> Libraries;
+  };
+
+  struct LinkInterface: public LinkInterfaceLibraries
+  {
+    // Languages whose runtime libraries must be linked.
+    std::vector<std::string> Languages;
+
+    // Shared library dependencies needed for linking on some platforms.
+    std::vector<cmLinkItem> SharedDeps;
+
+    // Number of repetitions of a strongly connected component of two
+    // or more static libraries.
+    int Multiplicity;
+
+    // Libraries listed for other configurations.
+    // Needed only for OLD behavior of CMP0003.
+    std::vector<cmLinkItem> WrongConfigLibraries;
+
+    bool ImplementationIsInterface;
+
+    LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
+  };
+
+  /** Get the link interface for the given configuration.  Returns 0
+      if the target cannot be linked.  */
+  LinkInterface const* GetLinkInterface(const std::string& config,
+                                        cmTarget const* headTarget) const;
+
+  LinkInterface const*
+    GetImportLinkInterface(const std::string& config, cmTarget const* head,
+                           bool usage_requirements_only) const;
+
+  LinkInterfaceLibraries const*
+    GetLinkInterfaceLibraries(const std::string& config,
+                              cmTarget const* headTarget,
+                              bool usage_requirements_only) const;
 
   /** Get the full path to the target according to the settings in its
       makefile and the configuration type.  */
@@ -375,6 +418,38 @@ private:
   };
   mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap;
 
+  // Cache link interface computation from each configuration.
+  struct OptionalLinkInterface: public LinkInterface
+  {
+    OptionalLinkInterface():
+      LibrariesDone(false), AllDone(false),
+      Exists(false), HadHeadSensitiveCondition(false),
+      ExplicitLibraries(0) {}
+    bool LibrariesDone;
+    bool AllDone;
+    bool Exists;
+    bool HadHeadSensitiveCondition;
+    const char* ExplicitLibraries;
+  };
+  void ComputeLinkInterface(cmTarget const* thisTarget,
+                            const std::string& config,
+                            OptionalLinkInterface& iface,
+                            cmTarget const* head) const;
+  void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
+                                     const std::string& config,
+                                     OptionalLinkInterface& iface,
+                                     cmTarget const* head,
+                                     bool usage_requirements_only) const;
+
+  struct HeadToLinkInterfaceMap:
+    public std::map<cmTarget const*, OptionalLinkInterface> {};
+  typedef std::map<std::string, HeadToLinkInterfaceMap>
+                                                          LinkInterfaceMapType;
+  mutable LinkInterfaceMapType LinkInterfaceMap;
+  mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
+
+  mutable bool PolicyWarnedCMP0022;
+
   typedef std::pair<std::string, bool> OutputNameKey;
   typedef std::map<OutputNameKey, std::string> OutputNameMapType;
   mutable OutputNameMapType OutputNameMap;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 49b3239..aa60311 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -77,13 +77,11 @@ public:
   cmTargetInternals()
     : Backtrace()
     {
-    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   cmTargetInternals(cmTargetInternals const&)
     : Backtrace()
     {
-    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   ~cmTargetInternals();
@@ -91,36 +89,6 @@ public:
   // The backtrace when the target was created.
   cmListFileBacktrace Backtrace;
 
-  // Cache link interface computation from each configuration.
-  struct OptionalLinkInterface: public cmTarget::LinkInterface
-  {
-    OptionalLinkInterface():
-      LibrariesDone(false), AllDone(false),
-      Exists(false), HadHeadSensitiveCondition(false),
-      ExplicitLibraries(0) {}
-    bool LibrariesDone;
-    bool AllDone;
-    bool Exists;
-    bool HadHeadSensitiveCondition;
-    const char* ExplicitLibraries;
-  };
-  void ComputeLinkInterface(cmTarget const* thisTarget,
-                            const std::string& config,
-                            OptionalLinkInterface& iface,
-                            cmTarget const* head) const;
-  void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget,
-                                     const std::string& config,
-                                     OptionalLinkInterface& iface,
-                                     cmTarget const* head,
-                                     bool usage_requirements_only);
-
-  struct HeadToLinkInterfaceMap:
-    public std::map<cmTarget const*, OptionalLinkInterface> {};
-  typedef std::map<std::string, HeadToLinkInterfaceMap>
-                                                          LinkInterfaceMapType;
-  LinkInterfaceMapType LinkInterfaceMap;
-  LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap;
-  bool PolicyWarnedCMP0022;
 
   typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
@@ -538,8 +506,6 @@ void cmTarget::ClearLinkMaps()
 {
   this->LinkImplementationLanguageIsContextDependent = true;
   this->Internal->LinkImplMap.clear();
-  this->Internal->LinkInterfaceMap.clear();
-  this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear();
   this->Internal->SourceFilesMap.clear();
 }
 
@@ -4133,393 +4099,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
-                                                  const std::string& config,
-                                                  cmTarget const* head) const
-{
-  // Imported targets have their own link interface.
-  if(this->IsImported())
-    {
-    return this->GetImportLinkInterface(config, head, false);
-    }
-
-  // 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.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    this->Internal->LinkInterfaceMap[CONFIG];
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[head];
-  if(!iface.LibrariesDone)
-    {
-    iface.LibrariesDone = true;
-    this->Internal->ComputeLinkInterfaceLibraries(
-      this, config, iface, head, false);
-    }
-  if(!iface.AllDone)
-    {
-    iface.AllDone = true;
-    if(iface.Exists)
-      {
-      this->Internal->ComputeLinkInterface(this, config, iface, head);
-      }
-    }
-
-  return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterfaceLibraries const*
-cmTarget::GetLinkInterfaceLibraries(const std::string& config,
-                                    cmTarget const* head,
-                                    bool usage_requirements_only) const
-{
-  // Imported targets have their own link interface.
-  if(this->IsImported())
-    {
-    return this->GetImportLinkInterface(config, head, usage_requirements_only);
-    }
-
-  // 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.
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    (usage_requirements_only ?
-     this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
-     this->Internal->LinkInterfaceMap[CONFIG]);
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[head];
-  if(!iface.LibrariesDone)
-    {
-    iface.LibrariesDone = true;
-    this->Internal->ComputeLinkInterfaceLibraries(
-      this, config, iface, head, usage_requirements_only);
-    }
-
-  return iface.Exists? &iface : 0;
-}
-
-//----------------------------------------------------------------------------
-cmTarget::LinkInterface const*
-cmTarget::GetImportLinkInterface(const std::string& config,
-                                 cmTarget const* headTarget,
-                                 bool usage_requirements_only) const
-{
-  cmTarget::ImportInfo const* info = this->GetImportInfo(config);
-  if(!info)
-    {
-    return 0;
-    }
-
-  std::string CONFIG = cmSystemTools::UpperCase(config);
-  cmTargetInternals::HeadToLinkInterfaceMap& hm =
-    (usage_requirements_only ?
-     this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] :
-     this->Internal->LinkInterfaceMap[CONFIG]);
-
-  // If the link interface does not depend on the head target
-  // then return the one we computed first.
-  if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
-    {
-    return &hm.begin()->second;
-    }
-
-  cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget];
-  if(!iface.AllDone)
-    {
-    iface.AllDone = true;
-    iface.Multiplicity = info->Multiplicity;
-    cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
-    this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
-                          headTarget, usage_requirements_only,
-                          iface.Libraries,
-                          iface.HadHeadSensitiveCondition);
-    std::vector<std::string> deps;
-    cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
-    this->LookupLinkItems(deps, iface.SharedDeps);
-    }
-
-  return &iface;
-}
-
-//----------------------------------------------------------------------------
-void
-cmTargetInternals::ComputeLinkInterfaceLibraries(
-  cmTarget const* thisTarget,
-  const std::string& config,
-  OptionalLinkInterface& iface,
-  cmTarget const* headTarget,
-  bool usage_requirements_only)
-{
-  // Construct the property name suffix for this configuration.
-  std::string suffix = "_";
-  if(!config.empty())
-    {
-    suffix += cmSystemTools::UpperCase(config);
-    }
-  else
-    {
-    suffix += "NOCONFIG";
-    }
-
-  // An explicit list of interface libraries may be set for shared
-  // libraries and executables that export symbols.
-  const char* explicitLibraries = 0;
-  std::string linkIfaceProp;
-  if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
-     thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN)
-    {
-    // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
-    linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-    }
-  else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY ||
-          thisTarget->IsExecutableWithExports())
-    {
-    // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
-    // shared lib or executable.
-
-    // Lookup the per-configuration property.
-    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-    linkIfaceProp += suffix;
-    explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-
-    // If not set, try the generic property.
-    if(!explicitLibraries)
-      {
-      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-      explicitLibraries = thisTarget->GetProperty(linkIfaceProp);
-      }
-    }
-
-  if(explicitLibraries &&
-     thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
-     !this->PolicyWarnedCMP0022)
-    {
-    // Compare the explicitly set old link interface properties to the
-    // preferred new link interface property one and warn if different.
-    const char* newExplicitLibraries =
-      thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES");
-    if (newExplicitLibraries
-        && strcmp(newExplicitLibraries, explicitLibraries) != 0)
-      {
-      std::ostringstream w;
-      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-        "Target \"" << thisTarget->GetName() << "\" has an "
-        "INTERFACE_LINK_LIBRARIES property which differs from its " <<
-        linkIfaceProp << " properties."
-        "\n"
-        "INTERFACE_LINK_LIBRARIES:\n"
-        "  " << newExplicitLibraries << "\n" <<
-        linkIfaceProp << ":\n"
-        "  " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n";
-      thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-      this->PolicyWarnedCMP0022 = true;
-      }
-    }
-
-  // There is no implicit link interface for executables or modules
-  // so if none was explicitly set then there is no link interface.
-  if(!explicitLibraries &&
-     (thisTarget->GetType() == cmTarget::EXECUTABLE ||
-      (thisTarget->GetType() == cmTarget::MODULE_LIBRARY)))
-    {
-    return;
-    }
-  iface.Exists = true;
-  iface.ExplicitLibraries = explicitLibraries;
-
-  if(explicitLibraries)
-    {
-    // The interface libraries have been explicitly set.
-    thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
-                                headTarget, usage_requirements_only,
-                                iface.Libraries,
-                                iface.HadHeadSensitiveCondition);
-    }
-  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
-        || thisTarget->GetPolicyStatusCMP0022() == 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.
-    cmLinkImplementationLibraries const* impl =
-      thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget);
-    iface.Libraries.insert(iface.Libraries.end(),
-                           impl->Libraries.begin(), impl->Libraries.end());
-    if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
-       !this->PolicyWarnedCMP0022 && !usage_requirements_only)
-      {
-      // Compare the link implementation fallback link interface to the
-      // preferred new link interface property and warn if different.
-      std::vector<cmLinkItem> ifaceLibs;
-      static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
-      if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp))
-        {
-        bool hadHeadSensitiveConditionDummy = false;
-        thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config,
-                                    headTarget, usage_requirements_only,
-                                ifaceLibs, hadHeadSensitiveConditionDummy);
-        }
-      if (ifaceLibs != iface.Libraries)
-        {
-        std::string oldLibraries = cmJoin(impl->Libraries, ";");
-        std::string newLibraries = cmJoin(ifaceLibs, ";");
-        if(oldLibraries.empty())
-          { oldLibraries = "(empty)"; }
-        if(newLibraries.empty())
-          { newLibraries = "(empty)"; }
-
-        std::ostringstream w;
-        w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-          "Target \"" << thisTarget->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";
-        thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-        this->PolicyWarnedCMP0022 = true;
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
-                                             const std::string& config,
-                                             OptionalLinkInterface& iface,
-                                             cmTarget const* headTarget) const
-{
-  if(iface.ExplicitLibraries)
-    {
-    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.
-      UNORDERED_SET<std::string> emitted;
-      for(std::vector<cmLinkItem>::const_iterator
-          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
-        {
-        emitted.insert(*li);
-        }
-      if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
-        {
-        cmTarget::LinkImplementation const* impl =
-            thisTarget->GetLinkImplementation(config);
-        for(std::vector<cmLinkImplItem>::const_iterator
-              li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
-          {
-          if(emitted.insert(*li).second)
-            {
-            if(li->Target)
-              {
-              // This is a runtime dependency on another shared library.
-              if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
-                {
-                iface.SharedDeps.push_back(*li);
-                }
-              }
-            else
-              {
-              // TODO: Recognize shared library file names.  Perhaps this
-              // should be moved to cmComputeLinkInformation, but that creates
-              // a chicken-and-egg problem since this list is needed for its
-              // construction.
-              }
-            }
-          }
-        }
-      }
-    }
-  else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN
-        || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD)
-    {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const*
-      impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
-                                                                headTarget);
-    iface.ImplementationIsInterface = true;
-    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
-    }
-
-  if(thisTarget->LinkLanguagePropagatesToDependents())
-    {
-    // Targets using this archive need its language runtime libraries.
-    if(cmTarget::LinkImplementation const* impl =
-       thisTarget->GetLinkImplementation(config))
-      {
-      iface.Languages = impl->Languages;
-      }
-    }
-
-  if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
-    {
-    // Construct the property name suffix for this configuration.
-    std::string suffix = "_";
-    if(!config.empty())
-      {
-      suffix += cmSystemTools::UpperCase(config);
-      }
-    else
-      {
-      suffix += "NOCONFIG";
-      }
-
-    // How many repetitions are needed if this library has cyclic
-    // dependencies?
-    std::string propName = "LINK_INTERFACE_MULTIPLICITY";
-    propName += suffix;
-    if(const char* config_reps = thisTarget->GetProperty(propName))
-      {
-      sscanf(config_reps, "%u", &iface.Multiplicity);
-      }
-    else if(const char* reps =
-            thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
-      {
-      sscanf(reps, "%u", &iface.Multiplicity);
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
 void cmTargetInternals::AddInterfaceEntries(
   cmTarget const* thisTarget, std::string const& config,
   std::string const& prop, std::vector<TargetPropertyEntry*>& entries)
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2007b40..25de6a6 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -233,43 +233,6 @@ public:
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  /** The link interface specifies transitive library dependencies and
-      other information needed by targets that link to this target.  */
-  struct LinkInterfaceLibraries
-  {
-    // Libraries listed in the interface.
-    std::vector<cmLinkItem> Libraries;
-  };
-  struct LinkInterface: public LinkInterfaceLibraries
-  {
-    // Languages whose runtime libraries must be linked.
-    std::vector<std::string> Languages;
-
-    // Shared library dependencies needed for linking on some platforms.
-    std::vector<cmLinkItem> SharedDeps;
-
-    // Number of repetitions of a strongly connected component of two
-    // or more static libraries.
-    int Multiplicity;
-
-    // Libraries listed for other configurations.
-    // Needed only for OLD behavior of CMP0003.
-    std::vector<cmLinkItem> WrongConfigLibraries;
-
-    bool ImplementationIsInterface;
-
-    LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
-  };
-
-  /** Get the link interface for the given configuration.  Returns 0
-      if the target cannot be linked.  */
-  LinkInterface const* GetLinkInterface(const std::string& config,
-                                        cmTarget const* headTarget) const;
-  LinkInterfaceLibraries const*
-    GetLinkInterfaceLibraries(const std::string& config,
-                              cmTarget const* headTarget,
-                              bool usage_requirements_only) const;
-
   struct LinkImplementation: public cmLinkImplementationLibraries
   {
     // Languages whose runtime libraries must be linked.
@@ -591,11 +554,6 @@ private:
   void ComputeImportInfo(std::string const& desired_config,
                          ImportInfo& info) const;
 
-
-  LinkInterface const*
-    GetImportLinkInterface(const std::string& config, cmTarget const* head,
-                           bool usage_requirements_only) const;
-
   cmLinkImplementationLibraries const*
     GetLinkImplementationLibrariesInternal(const std::string& config,
                                            cmTarget const* head) const;

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

Summary of changes:
 Source/cmComputeLinkDepends.cxx           |   25 +-
 Source/cmComputeLinkDepends.h             |    5 +-
 Source/cmComputeLinkInformation.cxx       |    2 +-
 Source/cmComputeTargetDepends.cxx         |    7 +-
 Source/cmExportFileGenerator.cxx          |    7 +-
 Source/cmExtraCodeBlocksGenerator.cxx     |    2 +-
 Source/cmGeneratorExpressionNode.cxx      |    4 +-
 Source/cmGeneratorTarget.cxx              | 1200 +++++++++++++++++++++++-
 Source/cmGeneratorTarget.h                |  122 +++
 Source/cmGlobalGenerator.cxx              |    1 -
 Source/cmGlobalUnixMakefileGenerator3.cxx |    3 +-
 Source/cmGlobalXCodeGenerator.cxx         |   21 +-
 Source/cmLinkItem.h                       |   17 +
 Source/cmLocalGenerator.cxx               |   13 +-
 Source/cmLocalUnixMakefileGenerator3.cxx  |    4 +-
 Source/cmMakefileTargetGenerator.cxx      |    2 +-
 Source/cmQtAutoGenerators.cxx             |   16 +-
 Source/cmTarget.cxx                       | 1432 +++--------------------------
 Source/cmTarget.h                         |  107 +--
 19 files changed, 1560 insertions(+), 1430 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list