[Cmake-commits] CMake branch, next, updated. v3.3.1-2528-g6fbcda2

Stephen Kelly steveire at gmail.com
Wed Aug 26 02:06:34 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  6fbcda20e178eaa6fb5c4fd0a78f3623f190ae60 (commit)
       via  b95c988484b1a65d6c94fbba53c756316449ef14 (commit)
      from  b847cf94af02e660f611e333e384d35c6c38f5c1 (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=6fbcda20e178eaa6fb5c4fd0a78f3623f190ae60
commit 6fbcda20e178eaa6fb5c4fd0a78f3623f190ae60
Merge: b847cf9 b95c988
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 26 02:06:31 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Wed Aug 26 02:06:31 2015 -0400

    Merge topic 'use-generator-target' into next
    
    b95c9884 Revert topic.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b95c988484b1a65d6c94fbba53c756316449ef14
commit b95c988484b1a65d6c94fbba53c756316449ef14
Author:     Stephen Kelly <steveire at gmail.com>
AuthorDate: Wed Aug 26 08:05:55 2015 +0200
Commit:     Stephen Kelly <steveire at gmail.com>
CommitDate: Wed Aug 26 08:06:05 2015 +0200

    Revert topic.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 5a5c1c1..59590fd 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -361,10 +361,8 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
   if(entry.Target)
     {
     // Follow the target dependencies.
-    cmGeneratorTarget* gtgt =
-        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
-    if(cmGeneratorTarget::LinkInterface const* iface =
-       gtgt->GetLinkInterface(this->Config, this->Target->Target))
+    if(cmTarget::LinkInterface const* iface =
+       entry.Target->GetLinkInterface(this->Config, this->Target->Target))
       {
       const bool isIface =
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -398,8 +396,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
 //----------------------------------------------------------------------------
 void
 cmComputeLinkDepends
-::FollowSharedDeps(int depender_index,
-                   cmGeneratorTarget::LinkInterface const* iface,
+::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
                    bool follow_interface)
 {
   // Follow dependencies if we have not followed them already.
@@ -462,10 +459,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   // Target items may have their own dependencies.
   if(entry.Target)
     {
-    cmGeneratorTarget* gtgt =
-        this->GlobalGenerator->GetGeneratorTarget(entry.Target);
-    if(cmGeneratorTarget::LinkInterface const* iface =
-       gtgt->GetLinkInterface(this->Config, this->Target->Target))
+    if(cmTarget::LinkInterface const* iface =
+       entry.Target->GetLinkInterface(this->Config, this->Target->Target))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -555,8 +550,8 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
 void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
-  cmLinkImplementation const* impl =
-    this->Target->GetLinkImplementation(this->Config);
+  cmTarget::LinkImplementation const* impl =
+    this->Target->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<cmLinkItem>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
@@ -935,10 +930,8 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
     {
     if(cmTarget const* target = this->EntryList[*ni].Target)
       {
-      cmGeneratorTarget* gtgt =
-          this->GlobalGenerator->GetGeneratorTarget(target);
-      if(cmGeneratorTarget::LinkInterface const* iface =
-         gtgt->GetLinkInterface(this->Config, this->Target->Target))
+      if(cmTarget::LinkInterface const* iface =
+         target->GetLinkInterface(this->Config, this->Target->Target))
         {
         if(iface->Multiplicity > count)
           {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index e61175a..b925a4f 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -13,7 +13,6 @@
 #define cmComputeLinkDepends_h
 
 #include "cmStandardIncludes.h"
-#include "cmGeneratorTarget.h"
 #include "cmTarget.h"
 
 #include "cmGraphAdjacencyList.h"
@@ -23,6 +22,8 @@
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmMakefile;
+class cmGeneratorTarget;
+class cmTarget;
 class cmake;
 
 /** \class cmComputeLinkDepends
@@ -101,7 +102,7 @@ private:
   std::queue<SharedDepEntry> SharedDepQueue;
   std::set<int> SharedDepFollowed;
   void FollowSharedDeps(int depender_index,
-                        cmGeneratorTarget::LinkInterface const* iface,
+                        cmTarget::LinkInterface const* iface,
                         bool follow_interface = false);
   void QueueSharedDependencies(int depender_index,
                                std::vector<cmLinkItem> const& deps);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 192ad5f..6ba0eed 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->HaveBuildTreeRPATH(this->Config) &&
+    (outputRuntime && this->Target->Target->HaveBuildTreeRPATH(this->Config) &&
      !linking_for_install);
   bool use_link_rpath =
     outputRuntime && linking_for_install &&
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 7488e09..c4a03a0 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -252,7 +252,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
         }
       }
 
-    cmLinkImplementation const* impl = depender->GetLinkImplementation(*it);
+    cmTarget::LinkImplementation const* impl =
+      depender->Target->GetLinkImplementation(*it);
 
     // A target should not depend on itself.
     emitted.insert(depender->GetName());
@@ -295,8 +296,8 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
                                              std::set<std::string> &emitted)
 {
   cmGeneratorTarget const* depender = this->Targets[depender_index];
-  if(cmGeneratorTarget::LinkInterface const* iface =
-                                dependee->GetLinkInterface(config,
+  if(cmTarget::LinkInterface const* iface =
+                                dependee->Target->GetLinkInterface(config,
                                                            depender->Target))
     {
     for(std::vector<cmLinkItem>::const_iterator
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 97eb6b9..cae60b7 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.
-  cmGeneratorTarget::LinkInterface const* iface = target->GetLinkInterface(
+  cmTarget::LinkInterface const* iface = target->Target->GetLinkInterface(
                                                               config,
                                                               target->Target);
   if (!iface)
@@ -909,8 +909,9 @@ cmExportFileGenerator
     }
 
   // Add the transitive link dependencies for this configuration.
-  if(cmGeneratorTarget::LinkInterface const* iface =
-                            target->GetLinkInterface(config, target->Target))
+  if(cmTarget::LinkInterface const* iface =
+                            target->Target
+                                  ->GetLinkInterface(config, target->Target))
     {
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index dfd51c7..933a256 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;
-    gtgt->GetCompileDefinitions(cdefs, buildType, "C");
+    target->GetCompileDefinitions(cdefs, buildType, "C");
 
     // Expand the list.
     for(std::vector<std::string>::const_iterator di = cdefs.begin();
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index b957379..03bc83a 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1108,8 +1108,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
 
     if(isInterfaceProperty)
       {
-      if(cmGeneratorTarget::LinkInterfaceLibraries const* iface =
-         gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true))
+      if(cmTarget::LinkInterfaceLibraries const* iface =
+         target->GetLinkInterfaceLibraries(context->Config, headTarget, true))
         {
         linkedTargetsContent =
           getLinkedTargetsContent(iface->Libraries, target,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 5c83879..dd58e7b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -34,18 +34,6 @@
 #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)
@@ -239,63 +227,18 @@ 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),
-  DebugIncludesDone(false),
-  DebugCompileOptionsDone(false),
-  DebugCompileFeaturesDone(false),
-  DebugCompileDefinitionsDone(false)
+  SourceFileFlagsConstructed(false)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
-
-  CreatePropertyGeneratorExpressions(
-        t->GetIncludeDirectoriesEntries(),
-        t->GetIncludeDirectoriesBacktraces(),
-        this->IncludeDirectoriesEntries);
-
-  CreatePropertyGeneratorExpressions(
-        t->GetCompileOptionsEntries(),
-        t->GetCompileOptionsBacktraces(),
-        this->CompileOptionsEntries);
-
-  CreatePropertyGeneratorExpressions(
-        t->GetCompileFeaturesEntries(),
-        t->GetCompileFeaturesBacktraces(),
-        this->CompileFeaturesEntries);
-
-  CreatePropertyGeneratorExpressions(
-        t->GetCompileDefinitionsEntries(),
-        t->GetCompileDefinitionsBacktraces(),
-        this->CompileDefinitionsEntries);
 }
 
 cmGeneratorTarget::~cmGeneratorTarget()
 {
-  cmDeleteAll(this->IncludeDirectoriesEntries);
-  cmDeleteAll(this->CompileOptionsEntries);
-  cmDeleteAll(this->CompileFeaturesEntries);
-  cmDeleteAll(this->CompileDefinitionsEntries);
   cmDeleteAll(this->LinkInformation);
   this->LinkInformation.clear();
 }
@@ -908,7 +851,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->HaveBuildTreeRPATH(config)
+  return this->Target->HaveBuildTreeRPATH(config)
       || this->Target->HaveInstallTreeRPATH();
 }
 
@@ -1230,11 +1173,8 @@ public:
       return;
       }
 
-    cmGeneratorTarget* gtgt =
-        this->Target->GetLocalGenerator()->GetGlobalGenerator()
-            ->GetGeneratorTarget(item.Target);
-    cmGeneratorTarget::LinkInterface const* iface =
-      gtgt->GetLinkInterface(this->Config, this->HeadTarget);
+    cmTarget::LinkInterface const* iface =
+      item.Target->GetLinkInterface(this->Config, this->HeadTarget);
     if(!iface) { return; }
 
     for(std::vector<std::string>::const_iterator
@@ -1335,8 +1275,8 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
 {
   // Get languages built in this target.
   UNORDERED_SET<std::string> languages;
-  cmLinkImplementation const* impl =
-                            this->GetLinkImplementation(config);
+  cmTarget::LinkImplementation const* impl =
+                            this->Target->GetLinkImplementation(config);
   assert(impl);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
@@ -1565,22 +1505,20 @@ 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);
-    cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target);
-    if(cmGeneratorTarget::LinkInterfaceLibraries const* iface =
-       gt->GetLinkInterfaceLibraries(config, headTarget, true))
+    if(cmTarget::LinkInterfaceLibraries const* iface =
+       item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
       {
       for(std::vector<cmLinkItem>::const_iterator
             it = iface->Libraries.begin();
           it != iface->Libraries.end(); ++it)
         {
-        processILibs(config, headTarget, *it, gg, tgts, emitted);
+        processILibs(config, headTarget, *it, tgts, emitted);
         }
       }
     }
@@ -1605,9 +1543,7 @@ cmGeneratorTarget::GetLinkImplementationClosure(
           it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
       {
-      processILibs(config, this->Target, *it,
-                   this->LocalGenerator->GetGlobalGenerator(),
-                   tgts, emitted);
+      processILibs(config, this->Target, *it, tgts , emitted);
       }
     }
   return tgts;
@@ -2021,536 +1957,13 @@ 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
 {
-  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;
-}
-
-//----------------------------------------------------------------------------
-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);
-}
-
-//----------------------------------------------------------------------------
-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);
-}
-
-//----------------------------------------------------------------------------
-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);
+  return this->Target->GetIncludeDirectories(config, lang);
 }
 
 //----------------------------------------------------------------------------
@@ -3941,594 +3354,3 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
 
   this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
 }
-
-//----------------------------------------------------------------------------
-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
-{
-  // 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(
-      config, iface, head, false);
-    }
-  if(!iface.AllDone)
-    {
-    iface.AllDone = true;
-    if(iface.Exists)
-      {
-      this->ComputeLinkInterface(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(
-      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->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
-cmGeneratorTarget::ComputeLinkInterfaceLibraries(
-  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(this->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
-     this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN)
-    {
-    // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
-    linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
-    explicitLibraries = this->Target->GetProperty(linkIfaceProp);
-    }
-  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.
-
-    // Lookup the per-configuration property.
-    linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-    linkIfaceProp += suffix;
-    explicitLibraries = this->Target->GetProperty(linkIfaceProp);
-
-    // If not set, try the generic property.
-    if(!explicitLibraries)
-      {
-      linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
-      explicitLibraries = this->Target->GetProperty(linkIfaceProp);
-      }
-    }
-
-  if(explicitLibraries &&
-     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 =
-      this->Target->GetProperty("INTERFACE_LINK_LIBRARIES");
-    if (newExplicitLibraries
-        && strcmp(newExplicitLibraries, explicitLibraries) != 0)
-      {
-      std::ostringstream w;
-      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
-        "Target \"" << this->Target->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";
-      this->LocalGenerator->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 &&
-     (this->Target->GetType() == cmTarget::EXECUTABLE ||
-      (this->Target->GetType() == cmTarget::MODULE_LIBRARY)))
-    {
-    return;
-    }
-  iface.Exists = true;
-  iface.ExplicitLibraries = explicitLibraries;
-
-  if(explicitLibraries)
-    {
-    // The interface libraries have been explicitly set.
-    this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
-                                headTarget, usage_requirements_only,
-                                iface.Libraries,
-                                iface.HadHeadSensitiveCondition);
-    }
-  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
-    // to the link implementation.
-    {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const* impl =
-      this->Target->GetLinkImplementationLibrariesInternal(config, headTarget);
-    iface.Libraries.insert(iface.Libraries.end(),
-                           impl->Libraries.begin(), impl->Libraries.end());
-    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 = this->Target->GetProperty(newProp))
-        {
-        bool hadHeadSensitiveConditionDummy = false;
-        this->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 \"" << 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 "
-          "ignoring the property and using the link implementation "
-          "as the link interface instead."
-          "\n"
-          "INTERFACE_LINK_LIBRARIES:\n"
-          "  " << newLibraries << "\n"
-          "Link implementation:\n"
-          "  " << oldLibraries << "\n";
-        this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str());
-        this->PolicyWarnedCMP0022 = true;
-        }
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
-                                             OptionalLinkInterface& iface,
-                                             cmTarget const* headTarget) const
-{
-  if(iface.ExplicitLibraries)
-    {
-    if(this->GetType() == cmTarget::SHARED_LIBRARY
-        || this->GetType() == cmTarget::STATIC_LIBRARY
-        || this->GetType() == cmTarget::INTERFACE_LIBRARY)
-      {
-      // Shared libraries may have runtime implementation dependencies
-      // on other shared libraries that are not in the interface.
-      UNORDERED_SET<std::string> emitted;
-      for(std::vector<cmLinkItem>::const_iterator
-          li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
-        {
-        emitted.insert(*li);
-        }
-      if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
-        {
-        cmLinkImplementation const* impl =
-            this->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 (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
-        || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
-    {
-    // The link implementation is the default link interface.
-    cmLinkImplementationLibraries const*
-      impl = this->Target->GetLinkImplementationLibrariesInternal(config,
-                                                                headTarget);
-    iface.ImplementationIsInterface = true;
-    iface.WrongConfigLibraries = impl->WrongConfigLibraries;
-    }
-
-  if(this->Target->LinkLanguagePropagatesToDependents())
-    {
-    // Targets using this archive need its language runtime libraries.
-    if(cmLinkImplementation const* impl =
-       this->GetLinkImplementation(config))
-      {
-      iface.Languages = impl->Languages;
-      }
-    }
-
-  if(this->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 = this->Target->GetProperty(propName))
-      {
-      sscanf(config_reps, "%u", &iface.Multiplicity);
-      }
-    else if(const char* reps =
-            this->Target->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
-      {
-      sscanf(reps, "%u", &iface.Multiplicity);
-      }
-    }
-}
-
-//----------------------------------------------------------------------------
-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->ComputeLinkImplementationLanguages(config, impl);
-    }
-  return &impl;
-}
-
-//----------------------------------------------------------------------------
-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->GlobalGenerator->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->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->GlobalGenerator
-                                ->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->GlobalGenerator
-                                  ->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
-{
-  // 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());
-}
-
-//----------------------------------------------------------------------------
-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 6d66bfe..15b3335 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -13,7 +13,6 @@
 #define cmGeneratorTarget_h
 
 #include "cmStandardIncludes.h"
-#include "cmLinkItem.h"
 
 class cmCustomCommand;
 class cmGlobalGenerator;
@@ -107,48 +106,6 @@ 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.  */
@@ -226,25 +183,6 @@ 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;
-
-  void ComputeLinkImplementationLanguages(const std::string& config,
-                                          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 GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) 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.  */
@@ -264,17 +202,6 @@ 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;
-
-  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;
 
@@ -390,8 +317,6 @@ public:
                             const std::string &report,
                             const std::string &compatibilityType) const;
 
-  class TargetPropertyEntry;
-
 private:
   friend class cmTargetTraceDependencies;
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -450,53 +375,6 @@ 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(const std::string& config,
-                            OptionalLinkInterface& iface,
-                            cmTarget const* head) const;
-  void ComputeLinkInterfaceLibraries(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;
-  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,
-                       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/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 846b6e2..1e57c33 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -330,8 +330,7 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
   const std::string &config, const std::string &language)
 {
   std::vector<std::string> compileDefinitions;
-  this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
-                                               config, language);
+  this->Target->GetCompileDefinitions(compileDefinitions, config, language);
   for (std::vector<std::string>::const_iterator cdI =
          compileDefinitions.begin();
        cdI != compileDefinitions.end(); ++cdI)
@@ -344,7 +343,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
                                               const std::string &language)
 {
   std::vector<std::string> includes =
-    this->GeneratorTarget->GetIncludeDirectories(config, language);
+    this->Target->GetIncludeDirectories(config, language);
   for (std::vector<std::string>::const_iterator includes_i = includes.begin();
        includes_i != includes.end(); ++includes_i)
     {
@@ -559,7 +558,7 @@ bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
 {
   bool output;
   std::vector<std::string> options;
-  this->GeneratorTarget->GetCompileOptions(options, config, language);
+  this->Target->GetCompileOptions(options, config, language);
   output =
     options.end() == std::find(options.begin(), options.end(), "-kernel");
   return output;
@@ -588,7 +587,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
 {
   std::vector<std::string> options;
   bool output = false;
-  this->GeneratorTarget->GetCompileOptions(options, config, language);
+  this->Target->GetCompileOptions(options, config, language);
   for (std::vector<std::string>::const_iterator options_i = options.begin();
        options_i != options.end(); ++options_i)
     {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index c0f1817..503c455 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1550,6 +1550,7 @@ 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/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 331caad..b240924 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -1134,8 +1134,7 @@ bool cmGlobalUnixMakefileGenerator3
 ::NeedRequiresStep(cmTarget const& target)
 {
   std::set<std::string> languages;
-  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&target);
-  gtgt->GetLanguages(languages,
+  target.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/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 28f0425..51dcab0 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -254,7 +254,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
     mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
                           no_working_directory, no_depends,
                           noCommandLines);
-
+  tgt->Compute();
   cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
   mf->AddGeneratorTarget(tgt, gt);
 
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 2bf04b4..b0aa243 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -90,7 +90,7 @@ bool cmGlobalVisualStudioGenerator::Compute()
         AddUtilityCommand("ALL_BUILD", true, no_working_dir,
                           no_depends, no_commands, false,
                           "Build all projects");
-
+      allBuild->Compute();
       cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
       allBuild->GetMakefile()->AddGeneratorTarget(allBuild, gt);
 
@@ -836,19 +836,17 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
 bool
 cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target)
 {
-  cmGeneratorTarget* gt = this->GetGeneratorTarget(&target);
-
   // check to see if this is a fortran build
   std::set<std::string> languages;
   {
   // Issue diagnostic if the source files depend on the config.
   std::vector<cmSourceFile*> sources;
-  if (!gt->GetConfigCommonSourceFiles(sources))
+  if (!target.GetConfigCommonSourceFiles(sources))
     {
     return false;
     }
   }
-  gt->GetLanguages(languages, "");
+  target.GetLanguages(languages, "");
   if(languages.size() == 1)
     {
     if(*languages.begin() == "Fortran")
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index eb547bd..4ba29f5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -463,7 +463,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
   cmTarget* allbuild = mf->AddUtilityCommand("ALL_BUILD", true, no_depends,
                         no_working_directory,
                         "echo", "Build all projects");
-
+  allbuild->Compute();
   cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
   mf->AddGeneratorTarget(allbuild, allBuildGt);
 
@@ -498,7 +498,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
                           true, no_depends,
                           no_working_directory,
                           "make", "-f", file.c_str());
-
+    check->Compute();
     cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
     mf->AddGeneratorTarget(check, checkGt);
     }
@@ -1124,7 +1124,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
 
     // organize the sources
     std::vector<cmSourceFile*> classes;
-    if (!gtgt->GetConfigCommonSourceFiles(classes))
+    if (!cmtarget.GetConfigCommonSourceFiles(classes))
       {
       return false;
       }
@@ -1383,8 +1383,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
   if(llang.empty()) { return; }
 
   // If the language is compiled as a source trust Xcode to link with it.
-  cmLinkImplementation const* impl =
-    gtgt->GetLinkImplementation("NOCONFIG");
+  cmTarget::LinkImplementation const* impl =
+    cmtarget.GetLinkImplementation("NOCONFIG");
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -1505,8 +1505,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
     }
 
   std::vector<cmSourceFile*> classes;
-  cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
-  if (!gtgt->GetConfigCommonSourceFiles(classes))
+  if (!cmtarget.GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1806,8 +1805,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
 
   // Compute the compilation flags for each language.
   std::set<std::string> languages;
-  cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
-  gtgt->GetLanguages(languages, configName);
+  target.GetLanguages(languages, configName);
   std::map<std::string, std::string> cflags;
   for (std::set<std::string>::iterator li = languages.begin();
        li != languages.end(); ++li)
@@ -1829,6 +1827,7 @@ 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())
     {
@@ -1856,7 +1855,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
     this->AppendDefines(ppDefs, exportMacro);
     }
   std::vector<std::string> targetDefines;
-  gtgt->GetCompileDefinitions(targetDefines, configName, "C");
+  target.GetCompileDefinitions(targetDefines, configName, "C");
   this->AppendDefines(ppDefs, targetDefines);
   buildSettings->AddAttribute
     ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
@@ -2558,8 +2557,7 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget)
   if(cmtarget.GetType() == cmTarget::UTILITY)
     {
     std::vector<cmSourceFile*> sources;
-    cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
-    if (!gtgt->GetConfigCommonSourceFiles(sources))
+    if (!cmtarget.GetConfigCommonSourceFiles(sources))
       {
       return 0;
       }
@@ -3087,8 +3085,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
         }
 
       std::vector<cmSourceFile*> classes;
-      cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
-      if (!gtgt->GetConfigCommonSourceFiles(classes))
+      if (!cmtarget.GetConfigCommonSourceFiles(classes))
         {
         return false;
         }
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index f1d914f..a5427de 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -56,21 +56,4 @@ struct cmLinkImplementationLibraries
   std::vector<cmLinkItem> WrongConfigLibraries;
 };
 
-struct cmLinkImplementation: public cmLinkImplementationLibraries
-{
-  // Languages whose runtime libraries must be linked.
-  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/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c1cc241..edb644d 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1083,8 +1083,7 @@ void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines,
                                              const std::string& lang)
 {
   std::vector<std::string> targetDefines;
-  cmGeneratorTarget* gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
-  gtgt->GetCompileDefinitions(targetDefines, config, lang);
+  target->GetCompileDefinitions(targetDefines, config, lang);
   this->AppendDefines(defines, targetDefines);
 }
 
@@ -1095,10 +1094,6 @@ 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))
     {
@@ -1109,7 +1104,7 @@ void cmLocalGenerator::AddCompileOptions(
       {
       cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
       }
-    gtgt->GetCompileOptions(opts, config, lang);
+    target->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
@@ -1130,7 +1125,7 @@ void cmLocalGenerator::AddCompileOptions(
       this->AppendFlags(flags, targetFlags);
       }
     std::vector<std::string> opts;
-    gtgt->GetCompileOptions(opts, config, lang);
+    target->GetCompileOptions(opts, config, lang);
     for(std::vector<std::string>::const_iterator i = opts.begin();
         i != opts.end(); ++i)
       {
@@ -1139,7 +1134,7 @@ void cmLocalGenerator::AddCompileOptions(
       }
     }
   std::vector<std::string> features;
-  gtgt->GetCompileFeatures(features, config);
+  target->GetCompileFeatures(features, config);
   for(std::vector<std::string>::const_iterator it = features.begin();
       it != features.end(); ++it)
     {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 589105e..ce370bc 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1257,9 +1257,7 @@ cmLocalUnixMakefileGenerator3
     {
     // Get the set of source languages in the target.
     std::set<std::string> languages;
-    cmGeneratorTarget *gtgt =
-        this->GlobalGenerator->GetGeneratorTarget(&target);
-    gtgt->GetLanguages(languages,
+    target.GetLanguages(languages,
                       this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
     fout << "\n"
          << "# Per-language clean rules from dependency scanning.\n"
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 3a44367..0d07536 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -305,12 +305,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
-  cmGeneratorTarget* gt =
-    this->GlobalGenerator->GetGeneratorTarget(&target);
-
   // get the classes from the source lists then add them to the groups
   std::vector<cmSourceFile*> classes;
-  if (!gt->GetConfigCommonSourceFiles(classes))
+  if (!target.GetConfigCommonSourceFiles(classes))
     {
     return;
     }
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 55ad852..5de6d37 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -763,7 +763,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
   targetOptions.Parse(defineFlags.c_str());
   targetOptions.ParseFinish();
   std::vector<std::string> targetDefines;
-  gt->GetCompileDefinitions(targetDefines, configName, "CXX");
+  target.GetCompileDefinitions(targetDefines, configName, "CXX");
   targetOptions.AddDefines(targetDefines);
   targetOptions.SetVerboseMakefile(
     this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
@@ -1469,13 +1469,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
   // We may be modifying the source groups temporarily, so make a copy.
   std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 
-  cmGeneratorTarget* gt =
-    this->GlobalGenerator->GetGeneratorTarget(&target);
-
   // get the classes from the source lists then add them to the groups
   this->ModuleDefinitionFile = "";
   std::vector<cmSourceFile*> classes;
-  if (!gt->GetConfigCommonSourceFiles(classes))
+  if (!target.GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1517,6 +1514,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
     {
     // VS >= 8 support per-config source locations so we
     // list object library content as external objects.
+    cmGeneratorTarget* gt =
+      this->GlobalGenerator->GetGeneratorTarget(&target);
     std::vector<std::string> objs;
     gt->UseObjectLibraries(objs, "");
     if(!objs.empty())
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index cf88a74..0b3df90 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->GeneratorTarget->GetLanguages(languages,
+  this->Target->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/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 0a4b546..f85e70e 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -403,9 +403,7 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg,
         )
     {
     std::vector<cmSourceFile*> srcFiles;
-    cmGeneratorTarget* gtgt =
-        lg->GetGlobalGenerator()->GetGeneratorTarget(target);
-    gtgt->GetConfigCommonSourceFiles(srcFiles);
+    target->GetConfigCommonSourceFiles(srcFiles);
     for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
         fileIt != srcFiles.end();
         ++fileIt)
@@ -476,6 +474,8 @@ 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);
 
@@ -663,10 +663,7 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
   const char* sepHeaders = "";
 
   std::vector<cmSourceFile*> srcFiles;
-  cmGeneratorTarget *gtgt = target->GetMakefile()
-                                  ->GetGlobalGenerator()
-                                  ->GetGeneratorTarget(target);
-  gtgt->GetConfigCommonSourceFiles(srcFiles);
+  target->GetConfigCommonSourceFiles(srcFiles);
 
   const char *skipMocSep = "";
   const char *skipUicSep = "";
@@ -1051,10 +1048,7 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target)
   cmMakefile *makefile = target->GetMakefile();
 
   std::vector<cmSourceFile*> srcFiles;
-  cmGeneratorTarget *gtgt = target->GetMakefile()
-                                  ->GetGlobalGenerator()
-                                  ->GetGeneratorTarget(target);
-  gtgt->GetConfigCommonSourceFiles(srcFiles);
+  target->GetConfigCommonSourceFiles(srcFiles);
 
   std::string qrcInputs;
   const char* qrcInputsSep = "";
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 40d7ebf..49b3239 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -77,11 +77,13 @@ public:
   cmTargetInternals()
     : Backtrace()
     {
+    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   cmTargetInternals(cmTargetInternals const&)
     : Backtrace()
     {
+    this->PolicyWarnedCMP0022 = false;
     this->UtilityItemsDone = false;
     }
   ~cmTargetInternals();
@@ -89,6 +91,36 @@ 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;
@@ -96,8 +128,27 @@ public:
   typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
+  // Cache link implementation computation from each configuration.
+  struct OptionalLinkImplementation: public cmTarget::LinkImplementation
+  {
+    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*, cmOptionalLinkImplementation> {};
+    public std::map<cmTarget const*, OptionalLinkImplementation> {};
   typedef std::map<std::string,
                    HeadToLinkImplementationMap> LinkImplMapType;
   LinkImplMapType LinkImplMap;
@@ -121,12 +172,16 @@ 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;
   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;
   std::vector<TargetPropertyEntry*> SourceEntries;
   std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
 
@@ -155,6 +210,10 @@ cmTarget::cmTarget()
   this->IsApple = false;
   this->IsImportedTarget = false;
   this->BuildInterfaceIncludesAppended = false;
+  this->DebugIncludesDone = false;
+  this->DebugCompileOptionsDone = false;
+  this->DebugCompileFeaturesDone = false;
+  this->DebugCompileDefinitionsDone = false;
   this->DebugSourcesDone = false;
   this->LinkImplementationLanguageIsContextDependent = true;
 }
@@ -397,6 +456,29 @@ 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);
+
+  CreatePropertyGeneratorExpressions(
+        this->Internal->CompileFeaturesEntries,
+        this->Internal->CompileFeaturesBacktraces,
+        this->Internal->CompileFeaturesItems);
+
+  CreatePropertyGeneratorExpressions(
+        this->Internal->CompileDefinitionsEntries,
+        this->Internal->CompileDefinitionsBacktraces,
+        this->Internal->CompileDefinitionsItems);
+}
+
 //----------------------------------------------------------------------------
 void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile)
 {
@@ -456,6 +538,8 @@ void cmTarget::ClearLinkMaps()
 {
   this->LinkImplementationLanguageIsContextDependent = true;
   this->Internal->LinkImplMap.clear();
+  this->Internal->LinkInterfaceMap.clear();
+  this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear();
   this->Internal->SourceFilesMap.clear();
 }
 
@@ -726,6 +810,62 @@ 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
 {
@@ -1214,46 +1354,6 @@ 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);
-}
-
-cmStringRange cmTarget::GetCompileOptionsEntries() const
-{
-  return cmMakeRange(this->Internal->CompileOptionsEntries);
-}
-
-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);
-}
-
-cmStringRange cmTarget::GetCompileDefinitionsEntries() const
-{
-  return cmMakeRange(this->Internal->CompileDefinitionsEntries);
-}
-
-cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
-{
-  return cmMakeRange(this->Internal->CompileDefinitionsBacktraces);
-}
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
 //----------------------------------------------------------------------------
 void
@@ -1851,126 +1951,630 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
+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)
 {
-  // Wipe out maps caching information affected by this property.
-  if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED"))
-    {
-    this->Internal->ImportInfoMap.clear();
-    }
-  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
+  cmMakefile *mf = tgt->GetMakefile();
+
+  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
     {
-    this->ClearLinkMaps();
+    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());
+      }
     }
 }
 
 //----------------------------------------------------------------------------
-static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
-  const std::string& prop, const char* value, cmMakefile* context,
-  bool imported)
+std::vector<std::string>
+cmTarget::GetIncludeDirectories(const std::string& config,
+                                const std::string& language) const
 {
-  // Look for link-type keywords in the value.
-  static cmsys::RegularExpression
-    keys("(^|;)(debug|optimized|general)(;|$)");
-  if(!keys.find(value))
+  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)
     {
-    return;
+    cmSystemTools::ExpandListArgument(debugProp, debugProperties);
     }
 
-  // Support imported and non-imported versions of the property.
-  const char* base = (imported?
-                      "IMPORTED_LINK_INTERFACE_LIBRARIES" :
-                      "LINK_INTERFACE_LIBRARIES");
+  bool debugIncludes = !this->DebugIncludesDone
+                    && std::find(debugProperties.begin(),
+                                 debugProperties.end(),
+                                 "INCLUDE_DIRECTORIES")
+                        != debugProperties.end();
 
-  // Report an error.
-  std::ostringstream e;
-  e << "Property " << prop << " may not contain link-type keyword \""
-    << keys.match(2) << "\".  "
-    << "The " << base << " property has a per-configuration "
-    << "version called " << base << "_<CONFIG> which may be "
-    << "used to specify per-configuration rules.";
-  if(!imported)
+  if (this->Makefile->IsConfigured())
     {
-    e << "  "
-      << "Alternatively, an IMPORTED library may be created, configured "
-      << "with a per-configuration location, and then named in the "
-      << "property value.  "
-      << "See the add_library command's IMPORTED mode for details."
-      << "\n"
-      << "If you have a list of libraries that already contains the "
-      << "keyword, use the target_link_libraries command with its "
-      << "LINK_INTERFACE_LIBRARIES mode to set the property.  "
-      << "The command automatically recognizes link-type keywords and sets "
-      << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
-      << "properties accordingly.";
+    this->DebugIncludesDone = true;
     }
-  context->IssueMessage(cmake::FATAL_ERROR, e.str());
-}
 
-//----------------------------------------------------------------------------
-static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
-                                                  cmMakefile* context)
-{
-  // Look for link-type keywords in the value.
-  static cmsys::RegularExpression
-    keys("(^|;)(debug|optimized|general)(;|$)");
-  if(!keys.find(value))
+  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"))
     {
-    return;
+    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));
+      }
     }
 
-  // Report an error.
-  std::ostringstream e;
+  processIncludeDirectories(this,
+                            linkInterfaceIncludeDirectoriesEntries,
+                            includes,
+                            uniqueIncludes,
+                            &dagChecker,
+                            config,
+                            debugIncludes,
+                            language);
 
-  e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
-    "keyword \"" << keys.match(2) << "\".  The INTERFACE_LINK_LIBRARIES "
-    "property may contain configuration-sensitive generator-expressions "
-    "which may be used to specify per-configuration rules.";
+  cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
 
-  context->IssueMessage(cmake::FATAL_ERROR, e.str());
+  return includes;
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::CheckProperty(const std::string& prop,
-                             cmMakefile* context) const
+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)
 {
-  // Certain properties need checking.
-  if(cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES"))
-    {
-    if(const char* value = this->GetProperty(prop))
-      {
-      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
-      }
-    }
-  if(cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES"))
+  cmMakefile *mf = tgt->GetMakefile();
+
+  for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
+      it = entries.begin(), end = entries.end(); it != end; ++it)
     {
-    if(const char* value = this->GetProperty(prop))
+    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)
       {
-      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+      std::string const& opt = *li;
+
+      if(uniqueOptions.insert(opt).second)
+        {
+        options.push_back(opt);
+        if (debugOptions)
+          {
+          usedOptions += " * " + opt + "\n";
+          }
+        }
       }
-    }
-  if(cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES"))
-    {
-    if(const char* value = this->GetProperty(prop))
+    if (!usedOptions.empty())
       {
-      cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+      mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+                            std::string("Used compile ") + logName
+                            + std::string(" for target ")
+                            + tgt->GetName() + ":\n"
+                            + usedOptions, (*it)->ge->GetBacktrace());
       }
     }
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::MarkAsImported()
+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)
 {
-  this->IsImportedTarget = true;
+  processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
+                                dagChecker, config, debugOptions, "options",
+                                language);
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::HaveWellDefinedOutputFiles() const
+void cmTarget::GetCompileOptions(std::vector<std::string> &result,
+                                 const std::string& config,
+                                 const std::string& language) const
 {
-  return
-    this->GetType() == cmTarget::STATIC_LIBRARY ||
-    this->GetType() == cmTarget::SHARED_LIBRARY ||
-    this->GetType() == cmTarget::MODULE_LIBRARY ||
+  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,
+      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);
+}
+
+//----------------------------------------------------------------------------
+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.
+  if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED"))
+    {
+    this->Internal->ImportInfoMap.clear();
+    }
+  if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
+    {
+    this->ClearLinkMaps();
+    }
+}
+
+//----------------------------------------------------------------------------
+static void cmTargetCheckLINK_INTERFACE_LIBRARIES(
+  const std::string& prop, const char* value, cmMakefile* context,
+  bool imported)
+{
+  // Look for link-type keywords in the value.
+  static cmsys::RegularExpression
+    keys("(^|;)(debug|optimized|general)(;|$)");
+  if(!keys.find(value))
+    {
+    return;
+    }
+
+  // Support imported and non-imported versions of the property.
+  const char* base = (imported?
+                      "IMPORTED_LINK_INTERFACE_LIBRARIES" :
+                      "LINK_INTERFACE_LIBRARIES");
+
+  // Report an error.
+  std::ostringstream e;
+  e << "Property " << prop << " may not contain link-type keyword \""
+    << keys.match(2) << "\".  "
+    << "The " << base << " property has a per-configuration "
+    << "version called " << base << "_<CONFIG> which may be "
+    << "used to specify per-configuration rules.";
+  if(!imported)
+    {
+    e << "  "
+      << "Alternatively, an IMPORTED library may be created, configured "
+      << "with a per-configuration location, and then named in the "
+      << "property value.  "
+      << "See the add_library command's IMPORTED mode for details."
+      << "\n"
+      << "If you have a list of libraries that already contains the "
+      << "keyword, use the target_link_libraries command with its "
+      << "LINK_INTERFACE_LIBRARIES mode to set the property.  "
+      << "The command automatically recognizes link-type keywords and sets "
+      << "the LINK_INTERFACE_LIBRARIES and LINK_INTERFACE_LIBRARIES_DEBUG "
+      << "properties accordingly.";
+    }
+  context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
+                                                  cmMakefile* context)
+{
+  // Look for link-type keywords in the value.
+  static cmsys::RegularExpression
+    keys("(^|;)(debug|optimized|general)(;|$)");
+  if(!keys.find(value))
+    {
+    return;
+    }
+
+  // Report an error.
+  std::ostringstream e;
+
+  e << "Property INTERFACE_LINK_LIBRARIES may not contain link-type "
+    "keyword \"" << keys.match(2) << "\".  The INTERFACE_LINK_LIBRARIES "
+    "property may contain configuration-sensitive generator-expressions "
+    "which may be used to specify per-configuration rules.";
+
+  context->IssueMessage(cmake::FATAL_ERROR, e.str());
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::CheckProperty(const std::string& prop,
+                             cmMakefile* context) const
+{
+  // Certain properties need checking.
+  if(cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES"))
+    {
+    if(const char* value = this->GetProperty(prop))
+      {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+      }
+    }
+  if(cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES"))
+    {
+    if(const char* value = this->GetProperty(prop))
+      {
+      cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+      }
+    }
+  if(cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES"))
+    {
+    if(const char* value = this->GetProperty(prop))
+      {
+      cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::MarkAsImported()
+{
+  this->IsImportedTarget = true;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::HaveWellDefinedOutputFiles() const
+{
+  return
+    this->GetType() == cmTarget::STATIC_LIBRARY ||
+    this->GetType() == cmTarget::SHARED_LIBRARY ||
+    this->GetType() == cmTarget::MODULE_LIBRARY ||
     this->GetType() == cmTarget::EXECUTABLE;
 }
 
@@ -2492,6 +3096,51 @@ 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())
@@ -2755,6 +3404,21 @@ 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");
@@ -3076,6 +3740,50 @@ 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
 {
@@ -3425,6 +4133,393 @@ 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)
@@ -3450,12 +4545,32 @@ void cmTargetInternals::AddInterfaceEntries(
     }
 }
 
-cmOptionalLinkImplementation&
-cmTarget::GetLinkImplMap(std::string const& config) const
+//----------------------------------------------------------------------------
+cmTarget::LinkImplementation const*
+cmTarget::GetLinkImplementation(const std::string& config) const
 {
+  // There is no link implementation for imported targets.
+  if(this->IsImported())
+    {
+    return 0;
+    }
+
   // Populate the link implementation for this configuration.
   std::string CONFIG = cmSystemTools::UpperCase(config);
-  return Internal->LinkImplMap[CONFIG][this];
+  cmTargetInternals::OptionalLinkImplementation&
+    impl = this->Internal->LinkImplMap[CONFIG][this];
+  if(!impl.LibrariesDone)
+    {
+    impl.LibrariesDone = true;
+    this->Internal
+      ->ComputeLinkImplementationLibraries(this, config, impl, this);
+    }
+  if(!impl.LanguagesDone)
+    {
+    impl.LanguagesDone = true;
+    this->Internal->ComputeLinkImplementationLanguages(this, config, impl);
+    }
+  return &impl;
 }
 
 //----------------------------------------------------------------------------
@@ -3488,36 +4603,39 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
     return &hm.begin()->second;
     }
 
-  cmOptionalLinkImplementation& impl = hm[head];
+  cmTargetInternals::OptionalLinkImplementation& impl = hm[head];
   if(!impl.LibrariesDone)
     {
     impl.LibrariesDone = true;
-    this->ComputeLinkImplementationLibraries(config, impl, head);
+    this->Internal
+      ->ComputeLinkImplementationLibraries(this, config, impl, head);
     }
   return &impl;
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkImplementationLibraries(
+void
+cmTargetInternals::ComputeLinkImplementationLibraries(
+  cmTarget const* thisTarget,
   const std::string& config,
-  cmOptionalLinkImplementation& impl,
+  OptionalLinkImplementation& impl,
   cmTarget const* head) const
 {
   // Collect libraries directly linked in this configuration.
   for (std::vector<cmValueWithOrigin>::const_iterator
-      le = this->Internal->LinkImplementationPropertyEntries.begin(),
-      end = this->Internal->LinkImplementationPropertyEntries.end();
+      le = this->LinkImplementationPropertyEntries.begin(),
+      end = this->LinkImplementationPropertyEntries.end();
       le != end; ++le)
     {
     std::vector<std::string> llibs;
     cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
+                                        thisTarget->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(this->Makefile, config, false, head, &dagChecker);
+      cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker);
     cmSystemTools::ExpandListArgument(evaluated, llibs);
     if(cge->GetHadHeadSensitiveCondition())
       {
@@ -3528,15 +4646,15 @@ void cmTarget::ComputeLinkImplementationLibraries(
         li != llibs.end(); ++li)
       {
       // Skip entries that resolve to the target itself or are empty.
-      std::string name = this->CheckCMP0004(*li);
-      if(name == this->GetName() || name.empty())
+      std::string name = thisTarget->CheckCMP0004(*li);
+      if(name == thisTarget->GetName() || name.empty())
         {
-        if(name == this->GetName())
+        if(name == thisTarget->GetName())
           {
           bool noMessage = false;
           cmake::MessageType messageType = cmake::FATAL_ERROR;
           std::ostringstream e;
-          switch(this->GetPolicyStatusCMP0038())
+          switch(thisTarget->GetPolicyStatusCMP0038())
             {
             case cmPolicies::WARN:
               {
@@ -3555,9 +4673,9 @@ void cmTarget::ComputeLinkImplementationLibraries(
 
           if(!noMessage)
             {
-            e << "Target \"" << this->GetName() << "\" links to itself.";
-            this->Makefile->GetCMakeInstance()->IssueMessage(
-              messageType, e.str(), this->GetBacktrace());
+            e << "Target \"" << thisTarget->GetName() << "\" links to itself.";
+            thisTarget->Makefile->GetCMakeInstance()->IssueMessage(
+              messageType, e.str(), thisTarget->GetBacktrace());
             if (messageType == cmake::FATAL_ERROR)
               {
               return;
@@ -3569,7 +4687,7 @@ void cmTarget::ComputeLinkImplementationLibraries(
 
       // The entry is meant for this configuration.
       impl.Libraries.push_back(
-        cmLinkImplItem(name, this->FindTargetToLink(name),
+        cmLinkImplItem(name, thisTarget->FindTargetToLink(name),
                        le->Backtrace, evaluated != le->Value));
       }
 
@@ -3577,35 +4695,51 @@ void cmTarget::ComputeLinkImplementationLibraries(
     for (std::set<std::string>::const_iterator it = seenProps.begin();
         it != seenProps.end(); ++it)
       {
-      if (!this->GetProperty(*it))
+      if (!thisTarget->GetProperty(*it))
         {
-        this->LinkImplicitNullProperties.insert(*it);
+        thisTarget->LinkImplicitNullProperties.insert(*it);
         }
       }
-    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
+    cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards);
     }
 
-  cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
+  cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config);
   cmTarget::LinkLibraryVectorType const& oldllibs =
-    this->GetOriginalLinkLibraries();
+    thisTarget->GetOriginalLinkLibraries();
   for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
       li != oldllibs.end(); ++li)
     {
     if(li->second != cmTarget::GENERAL && li->second != linkType)
       {
-      std::string name = this->CheckCMP0004(li->first);
-      if(name == this->GetName() || name.empty())
+      std::string name = thisTarget->CheckCMP0004(li->first);
+      if(name == thisTarget->GetName() || name.empty())
         {
         continue;
         }
       // Support OLD behavior for CMP0003.
       impl.WrongConfigLibraries.push_back(
-        cmLinkItem(name, this->FindTargetToLink(name)));
+        cmLinkItem(name, thisTarget->FindTargetToLink(name)));
       }
     }
 }
 
 //----------------------------------------------------------------------------
+void
+cmTargetInternals::ComputeLinkImplementationLanguages(
+  cmTarget const* thisTarget,
+  const std::string& config,
+  OptionalLinkImplementation& 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);
+  // 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);
@@ -3712,6 +4846,10 @@ cmTargetInternalPointer
 //----------------------------------------------------------------------------
 cmTargetInternalPointer::~cmTargetInternalPointer()
 {
+  cmDeleteAll(this->Pointer->IncludeDirectoriesItems);
+  cmDeleteAll(this->Pointer->CompileOptionsItems);
+  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 d032380..2007b40 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -132,11 +132,15 @@ public:
   void AddPostBuildCommand(cmCustomCommand const &cmd)
     {this->PostBuildCommands.push_back(cmd);}
 
+  void Compute();
+
   /**
    * Get the list of the source files used by this target
    */
   void GetSourceFiles(std::vector<cmSourceFile*> &files,
                       const std::string& config) const;
+  bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const;
+
   /**
    * Add sources to the target.
    */
@@ -229,15 +233,53 @@ public:
 
   void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
 
-  cmLinkImplementationLibraries const*
-    GetLinkImplementationLibraries(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;
 
-  void ComputeLinkImplementationLibraries(const std::string& config,
-                                          cmOptionalLinkImplementation& impl,
-                                          cmTarget const* head) const;
+    // Shared library dependencies needed for linking on some platforms.
+    std::vector<cmLinkItem> SharedDeps;
 
-  cmOptionalLinkImplementation&
-  GetLinkImplMap(std::string const& config) const;
+    // 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.
+    std::vector<std::string> Languages;
+  };
+  LinkImplementation const*
+    GetLinkImplementation(const std::string& config) const;
+
+  cmLinkImplementationLibraries const*
+    GetLinkImplementationLibraries(const std::string& config) const;
 
   cmTarget const* FindTargetToLink(std::string const& name) const;
 
@@ -289,6 +331,7 @@ 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
@@ -303,6 +346,18 @@ 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
+  // 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;
@@ -346,6 +401,9 @@ 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);
@@ -357,6 +415,12 @@ 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;
+
   bool IsNullImpliedByLinkLibraries(const std::string &p) const;
 
   std::string GetDebugGeneratorExpressions(const std::string &value,
@@ -375,18 +439,6 @@ public:
     return this->MaxLanguageStandards;
   }
 
-  cmStringRange GetIncludeDirectoriesEntries() const;
-  cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
-
-  cmStringRange GetCompileOptionsEntries() const;
-  cmBacktraceRange GetCompileOptionsBacktraces() const;
-
-  cmStringRange GetCompileFeaturesEntries() const;
-  cmBacktraceRange GetCompileFeaturesBacktraces() const;
-
-  cmStringRange GetCompileDefinitionsEntries() const;
-  cmBacktraceRange GetCompileDefinitionsBacktraces() const;
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
   const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
   return this->LinkLibrariesForVS6;}
@@ -501,7 +553,11 @@ private:
   bool IsApple;
   bool IsImportedTarget;
   bool BuildInterfaceIncludesAppended;
+  mutable bool DebugIncludesDone;
+  mutable bool DebugCompileOptionsDone;
+  mutable bool DebugCompileDefinitionsDone;
   mutable bool DebugSourcesDone;
+  mutable bool DebugCompileFeaturesDone;
   mutable bool LinkImplementationLanguageIsContextDependent;
 #if defined(_WIN32) && !defined(__CYGWIN__)
   bool LinkLibrariesForVS6Analyzed;
@@ -535,10 +591,23 @@ 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;
 
+  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();
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index e7716d8..823b550 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -965,7 +965,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   std::vector<cmSourceGroup> sourceGroups =
     this->Makefile->GetSourceGroups();
   std::vector<cmSourceFile*> classes;
-  if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes))
+  if (!this->Target->GetConfigCommonSourceFiles(classes))
     {
     return;
     }
@@ -1934,7 +1934,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   clOptions.Parse(flags.c_str());
   clOptions.Parse(defineFlags.c_str());
   std::vector<std::string> targetDefines;
-  this->GeneratorTarget->GetCompileDefinitions(targetDefines,
+  this->Target->GetCompileDefinitions(targetDefines,
                                       configName.c_str(), "CXX");
   clOptions.AddDefines(targetDefines);
   if(this->MSTools)

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

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/cmGhsMultiTargetGenerator.cxx       |    9 +-
 Source/cmGlobalGenerator.cxx               |    1 +
 Source/cmGlobalUnixMakefileGenerator3.cxx  |    3 +-
 Source/cmGlobalVisualStudio8Generator.cxx  |    2 +-
 Source/cmGlobalVisualStudioGenerator.cxx   |    8 +-
 Source/cmGlobalXCodeGenerator.cxx          |   25 +-
 Source/cmLinkItem.h                        |   17 -
 Source/cmLocalGenerator.cxx                |   13 +-
 Source/cmLocalUnixMakefileGenerator3.cxx   |    4 +-
 Source/cmLocalVisualStudio6Generator.cxx   |    5 +-
 Source/cmLocalVisualStudio7Generator.cxx   |    9 +-
 Source/cmMakefileTargetGenerator.cxx       |    2 +-
 Source/cmQtAutoGenerators.cxx              |   16 +-
 Source/cmTarget.cxx                        | 1440 +++++++++++++++++++++++++---
 Source/cmTarget.h                          |  107 ++-
 Source/cmVisualStudio10TargetGenerator.cxx |    4 +-
 25 files changed, 1451 insertions(+), 1588 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list