[Cmake-commits] CMake branch, next, updated. v3.0.0-3847-g236ce96

Brad King brad.king at kitware.com
Mon Jun 23 09:27:29 EDT 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  236ce96e840c23b67609824342a7767225163c05 (commit)
       via  19cd62625a67ce2e33ecff79690c5a7158788de1 (commit)
       via  61b5980543cd01ccd543679533406e12e266ea06 (commit)
       via  f5c18c9c1c0434f3481b1684af5fe6e0ea823f87 (commit)
       via  281eb3d8a6a4983a33d5a8d70a0e21ebb3bd115f (commit)
       via  d912220eaaa92f3e8524c33e1684ebbf84eba521 (commit)
       via  edce43514d854a84d2a00c975268f898bd1dda45 (commit)
       via  097be4139df044c86daadb665ec224ee66e6b3bb (commit)
       via  4dad5fd20bfa330b3131fd5cafa709d85c1b58ec (commit)
       via  a272344228174958a8b2346793d3272eb432dad8 (commit)
       via  069d60fe039ae1d797a26786f3cd4c23afc27b07 (commit)
       via  47ab3ca64105cdfcc7b57ffe037aa93d8226b945 (commit)
       via  9f3ed029ce830f0395e102258758a4b3680e5d0f (commit)
       via  6f0951af011d28366cf31ff621238f026cb8d895 (commit)
       via  0dc9e88d76fa74440fc3b38032738a21ce72f2d7 (commit)
       via  4ac72455fd7027039d498f007fdfe7c1d819b9f9 (commit)
       via  bcdb7ff9df8fb831e952a3909da11da51773a30f (commit)
       via  bd9b667bbe83b112a9ea4448605fac980d2d8a68 (commit)
       via  06328dd58ee3de5d716b0d2b259927da2e173c1d (commit)
       via  56aed7005ae17e979f4635240539041e66d9220a (commit)
       via  cbf689c7dd39dc0952361b63e8322a0408b4569b (commit)
       via  2f0004c143455387c4b6ecac2458fcec4d57643f (commit)
       via  962f2c3529d39e293549d16963c59f1508c5a81c (commit)
       via  e838e0a977bf3ca07509f4af39d5f93d598f84f4 (commit)
       via  7b85938973782ec6d09b1debe6ad48d3ba887683 (commit)
       via  8d15a1bbfbefff919d8a7aa0d04f54d08d1f1a11 (commit)
       via  6354df92b12746dcb0f6fa263af2adf649cf1f3f (commit)
      from  b41f6e86307035dae1b1154a22443eaff378d2db (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=236ce96e840c23b67609824342a7767225163c05
commit 236ce96e840c23b67609824342a7767225163c05
Merge: b41f6e8 19cd626
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 23 09:27:26 2014 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Jun 23 09:27:26 2014 -0400

    Merge topic 'refactor-link-internals' into next
    
    19cd6262 cmTarget: De-duplicate link interface evaluation code for $<LINK_ONLY>
    61b59805 cmTarget: De-duplicate link interface genex code for $<LINK_ONLY>
    f5c18c9c cmTarget: Drop GetDirectLinkLibraries methods
    281eb3d8 cmTarget: Improve HaveBuildTreeRPATH implementation
    d912220e cmTarget: Lookup targets in LinkInterface and LinkImplementation
    edce4351 cmExportFileGenerator: Make SetImportLinkProperty a template
    097be413 cmTarget: Add GetUtilityItems to get target ordering dependencies
    4dad5fd2 cmTarget: Add cmLinkItem to refer to a target by name and pointer
    a2723442 Fix scope of transitive target name lookups
    069d60fe cmTarget: Add method to lookup other targets in a target's scope
    47ab3ca6 cmTarget: Constify GetLinkImplementationClosure results
    9f3ed029 cmTarget: Constify GetTransitivePropertyTargets results
    6f0951af cmTarget: Drop 'head' target from GetImportInfo
    0dc9e88d cmTarget: Remove 'head' argument from GetLinkImplementation
    4ac72455 cmTarget: Drop 'head' argument from GetLinkClosure
    bcdb7ff9 cmTarget: Remove 'head' argument from GetLinkerLanguage
    ...


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=19cd62625a67ce2e33ecff79690c5a7158788de1
commit 19cd62625a67ce2e33ecff79690c5a7158788de1
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 14:27:42 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:08 2014 -0400

    cmTarget: De-duplicate link interface evaluation code for $<LINK_ONLY>
    
    Add a 'linking' parameter to GetLinkInterfaceLibraries to indicate
    whether the $<LINK_ONLY> generator expression should evaluate or return
    an empty string.  Teach GetTransitivePropertyTargets to use the method
    with linking==false instead of duplicating INTERFACE_LINK_LIBRARIES
    evaluation code.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index b86a5d8..de40c1e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -126,11 +126,13 @@ public:
   typedef std::map<TargetConfigPair, OptionalLinkInterface>
                                                           LinkInterfaceMapType;
   LinkInterfaceMapType LinkInterfaceMap;
+  LinkInterfaceMapType LinkInterfaceTransitiveOnlyMap;
   bool PolicyWarnedCMP0022;
 
   typedef std::map<TargetConfigPair, cmTarget::LinkInterface>
                                                     ImportLinkInterfaceMapType;
   ImportLinkInterfaceMapType ImportLinkInterfaceMap;
+  ImportLinkInterfaceMapType ImportLinkInterfaceTransitiveOnlyMap;
 
   typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
@@ -510,7 +512,9 @@ void cmTarget::ClearLinkMaps()
   this->LinkImplementationLanguageIsContextDependent = true;
   this->Internal->LinkImplMap.clear();
   this->Internal->LinkInterfaceMap.clear();
+  this->Internal->LinkInterfaceTransitiveOnlyMap.clear();
   this->Internal->ImportLinkInterfaceMap.clear();
+  this->Internal->ImportLinkInterfaceTransitiveOnlyMap.clear();
   this->Internal->LinkClosureMap.clear();
   for (cmTargetLinkInformationMap::const_iterator it
       = this->LinkInformation.begin();
@@ -6038,7 +6042,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    return this->GetImportLinkInterface(config, head);
+    return this->GetImportLinkInterface(config, head, true);
     }
 
   // Link interfaces are not supported for executables that do not
@@ -6059,7 +6063,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
     iface.ExplicitLibraries =
-        this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
+      this->ComputeLinkInterfaceLibraries(config, iface, head, true,
+                                          iface.Exists);
     if (iface.Exists)
       {
       this->Internal->ComputeLinkInterface(this, config, iface,
@@ -6082,12 +6087,13 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
 //----------------------------------------------------------------------------
 cmTarget::LinkInterface const*
 cmTarget::GetLinkInterfaceLibraries(const std::string& config,
-                                    cmTarget const* head) const
+                                    cmTarget const* head,
+                                    bool linking) const
 {
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    return this->GetImportLinkInterface(config, head);
+    return this->GetImportLinkInterface(config, head, linking);
     }
 
   // Link interfaces are not supported for executables that do not
@@ -6100,21 +6106,24 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config,
 
   // Lookup any existing link interface for this configuration.
   TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+  cmTargetInternals::LinkInterfaceMapType& lim =
+    linking? this->Internal->LinkInterfaceMap :
+             this->Internal->LinkInterfaceTransitiveOnlyMap;
 
-  cmTargetInternals::LinkInterfaceMapType::iterator
-    i = this->Internal->LinkInterfaceMap.find(key);
-  if(i == this->Internal->LinkInterfaceMap.end())
+  cmTargetInternals::LinkInterfaceMapType::iterator i = lim.find(key);
+  if(i == lim.end())
     {
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
     iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
                                                                 iface,
                                                                 head,
+                                                                linking,
                                                                 iface.Exists);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
-    i = this->Internal->LinkInterfaceMap.insert(entry).first;
+    i = lim.insert(entry).first;
     }
 
   return i->second.Exists ? &i->second : 0;
@@ -6123,7 +6132,8 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config,
 //----------------------------------------------------------------------------
 cmTarget::LinkInterface const*
 cmTarget::GetImportLinkInterface(const std::string& config,
-                                 cmTarget const* headTarget) const
+                                 cmTarget const* headTarget,
+                                 bool linking) const
 {
   cmTarget::ImportInfo const* info = this->GetImportInfo(config);
   if(!info)
@@ -6132,16 +6142,18 @@ cmTarget::GetImportLinkInterface(const std::string& config,
     }
 
   TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config));
+  cmTargetInternals::ImportLinkInterfaceMapType& lim =
+    linking? this->Internal->ImportLinkInterfaceMap :
+             this->Internal->ImportLinkInterfaceTransitiveOnlyMap;
 
-  cmTargetInternals::ImportLinkInterfaceMapType::iterator i =
-    this->Internal->ImportLinkInterfaceMap.find(key);
-  if(i == this->Internal->ImportLinkInterfaceMap.end())
+  cmTargetInternals::ImportLinkInterfaceMapType::iterator i = lim.find(key);
+  if(i == lim.end())
     {
     LinkInterface iface;
     iface.Multiplicity = info->Multiplicity;
     cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
     this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
-                          headTarget, true, iface.Libraries);
+                          headTarget, linking, iface.Libraries);
     {
     std::vector<std::string> deps;
     cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
@@ -6150,7 +6162,7 @@ cmTarget::GetImportLinkInterface(const std::string& config,
 
     cmTargetInternals::ImportLinkInterfaceMapType::value_type
       entry(key, iface);
-    i = this->Internal->ImportLinkInterfaceMap.insert(entry).first;
+    i = lim.insert(entry).first;
     }
   return &i->second;
 }
@@ -6166,7 +6178,7 @@ void processILibs(const std::string& config,
     {
     tgts.push_back(item.Target);
     if(cmTarget::LinkInterface const* iface =
-       item.Target->GetLinkInterfaceLibraries(config, headTarget))
+       item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
       {
       for(std::vector<cmLinkItem>::const_iterator
             it = iface->Libraries.begin();
@@ -6206,15 +6218,8 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
                                       cmTarget const* headTarget,
                                       std::vector<cmTarget const*> &tgts) const
 {
-  cmTarget::LinkInterface const* iface
-                        = this->GetLinkInterfaceLibraries(config, headTarget);
-  if (!iface)
-    {
-    return;
-    }
-  if(this->GetType() != STATIC_LIBRARY
-      || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
-      || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+  if(cmTarget::LinkInterface const* iface =
+     this->GetLinkInterfaceLibraries(config, headTarget, false))
     {
     for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin();
         it != iface->Libraries.end(); ++it)
@@ -6224,29 +6229,6 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
         tgts.push_back(it->Target);
         }
       }
-    return;
-    }
-
-  const char* linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
-  const char* interfaceLibs = this->GetProperty(linkIfaceProp);
-
-  if (!interfaceLibs)
-    {
-    return;
-    }
-
-  // The interface libraries have been explicitly set.
-  std::vector<cmLinkItem> libs;
-  this->ExpandLinkItems(linkIfaceProp, interfaceLibs, config,
-                        headTarget, false, libs);
-
-  for(std::vector<cmLinkItem>::const_iterator it = libs.begin();
-      it != libs.end(); ++it)
-    {
-    if (it->Target)
-      {
-      tgts.push_back(it->Target);
-      }
     }
 }
 
@@ -6254,7 +6236,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
 const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
                                            LinkInterface& iface,
                                            cmTarget const* headTarget,
-                                           bool &exists) const
+                                           bool linking, bool &exists) const
 {
   // Construct the property name suffix for this configuration.
   std::string suffix = "_";
@@ -6339,7 +6321,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
     {
     // The interface libraries have been explicitly set.
     this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
-                          headTarget, true, iface.Libraries);
+                          headTarget, linking, iface.Libraries);
     }
   else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
         || this->PolicyStatusCMP0022 == cmPolicies::OLD)
@@ -6353,7 +6335,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
         this->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.Libraries = impl->Libraries;
     if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
-       !this->Internal->PolicyWarnedCMP0022)
+       !this->Internal->PolicyWarnedCMP0022 && linking)
       {
       // Compare the link implementation fallback link interface to the
       // preferred new link interface property and warn if different.
@@ -6362,7 +6344,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
       if(const char* newExplicitLibraries = this->GetProperty(newProp))
         {
         this->ExpandLinkItems(newProp, newExplicitLibraries, config,
-                              headTarget, true, ifaceLibs);
+                              headTarget, linking, ifaceLibs);
         }
       if (ifaceLibs != impl->Libraries)
         {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3df5bdd..3b1a88f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -280,7 +280,8 @@ public:
   LinkInterface const* GetLinkInterface(const std::string& config,
                                         cmTarget const* headTarget) const;
   LinkInterface const* GetLinkInterfaceLibraries(const std::string& config,
-                                        cmTarget const* headTarget) const;
+                                        cmTarget const* headTarget,
+                                        bool linking) const;
   void GetTransitivePropertyTargets(const std::string& config,
                                     cmTarget const* headTarget,
                                     std::vector<cmTarget const*> &libs) const;
@@ -757,11 +758,12 @@ private:
 
   LinkInterface const*
     GetImportLinkInterface(const std::string& config,
-                           cmTarget const* head) const;
+                           cmTarget const* head, bool linking) const;
 
   const char* ComputeLinkInterfaceLibraries(const std::string& config,
                                             LinkInterface& iface,
                                             cmTarget const* head,
+                                            bool linking,
                                             bool &exists) const;
 
   LinkImplementation const*

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=61b5980543cd01ccd543679533406e12e266ea06
commit 61b5980543cd01ccd543679533406e12e266ea06
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 14:25:40 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:08 2014 -0400

    cmTarget: De-duplicate link interface genex code for $<LINK_ONLY>
    
    Add a 'linking' parameter to ExpandLinkItems so that it knows whether to
    use SetTransitivePropertiesOnly while evaluating generator expressions.
    Use it in GetTransitivePropertyTargets to avoid duplicating the genex
    code.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 71d03df..b86a5d8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3688,10 +3688,16 @@ void cmTarget::ExpandLinkItems(std::string const& prop,
                                std::string const& value,
                                std::string const& config,
                                cmTarget const* headTarget,
+                               bool linking,
                                std::vector<cmLinkItem>& items) const
 {
   cmGeneratorExpression ge;
   cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  if(!linking && this->GetType() == cmTarget::STATIC_LIBRARY &&
+     prop == "INTERFACE_LINK_LIBRARIES")
+    {
+    dagChecker.SetTransitivePropertiesOnly();
+    }
   std::vector<std::string> libs;
   cmSystemTools::ExpandListArgument(ge.Parse(value)->Evaluate(
                                       this->Makefile,
@@ -6135,7 +6141,7 @@ cmTarget::GetImportLinkInterface(const std::string& config,
     iface.Multiplicity = info->Multiplicity;
     cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
     this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
-                          headTarget, iface.Libraries);
+                          headTarget, true, iface.Libraries);
     {
     std::vector<std::string> deps;
     cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
@@ -6230,24 +6236,16 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
     }
 
   // The interface libraries have been explicitly set.
-  cmGeneratorExpression ge;
-  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                             linkIfaceProp, 0, 0);
-  dagChecker.SetTransitivePropertiesOnly();
-  std::vector<std::string> libs;
-  cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
-                                      this->Makefile,
-                                      config,
-                                      false,
-                                      headTarget,
-                                      this, &dagChecker), libs);
+  std::vector<cmLinkItem> libs;
+  this->ExpandLinkItems(linkIfaceProp, interfaceLibs, config,
+                        headTarget, false, libs);
 
-  for(std::vector<std::string>::const_iterator it = libs.begin();
+  for(std::vector<cmLinkItem>::const_iterator it = libs.begin();
       it != libs.end(); ++it)
     {
-    if (cmTarget const* tgt = this->FindTargetToLink(*it))
+    if (it->Target)
       {
-      tgts.push_back(tgt);
+      tgts.push_back(it->Target);
       }
     }
 }
@@ -6341,7 +6339,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
     {
     // The interface libraries have been explicitly set.
     this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
-                          headTarget, iface.Libraries);
+                          headTarget, true, iface.Libraries);
     }
   else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
         || this->PolicyStatusCMP0022 == cmPolicies::OLD)
@@ -6364,7 +6362,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
       if(const char* newExplicitLibraries = this->GetProperty(newProp))
         {
         this->ExpandLinkItems(newProp, newExplicitLibraries, config,
-                              headTarget, ifaceLibs);
+                              headTarget, true, ifaceLibs);
         }
       if (ifaceLibs != impl->Libraries)
         {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3f534f2..3df5bdd 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -777,7 +777,7 @@ private:
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
-                       std::vector<cmLinkItem>& items) const;
+                       bool linking, std::vector<cmLinkItem>& items) const;
   void LookupLinkItems(std::vector<std::string> const& names,
                        std::vector<cmLinkItem>& items) const;
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f5c18c9c1c0434f3481b1684af5fe6e0ea823f87
commit f5c18c9c1c0434f3481b1684af5fe6e0ea823f87
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 14:12:18 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:08 2014 -0400

    cmTarget: Drop GetDirectLinkLibraries methods
    
    Inline the implementation in the last remaining caller and drop the
    methods.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f4a0224..71d03df 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1227,47 +1227,6 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) const
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetDirectLinkLibraries(const std::string& config,
-                                      std::vector<std::string> &libs) const
-{
-  this->GetDirectLinkLibrariesInternal(config, libs, this);
-}
-
-//----------------------------------------------------------------------------
-void cmTarget::GetDirectLinkLibrariesInternal(const std::string& config,
-                                              std::vector<std::string> &libs,
-                                              cmTarget const* head) const
-{
-  const char *prop = this->GetProperty("LINK_LIBRARIES");
-  if (prop)
-    {
-    cmGeneratorExpression ge;
-    const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
-
-    cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
-                                        "LINK_LIBRARIES", 0, 0);
-    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
-                                        config,
-                                        false,
-                                        head,
-                                        &dagChecker),
-                                      libs);
-
-    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
-    for (std::set<std::string>::const_iterator it = seenProps.begin();
-        it != seenProps.end(); ++it)
-      {
-      if (!this->GetProperty(*it))
-        {
-        this->LinkImplicitNullProperties.insert(*it);
-        }
-      }
-    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
-    }
-}
-
-//----------------------------------------------------------------------------
 std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
                                   cmTarget::LinkLibraryType llt) const
 {
@@ -6634,7 +6593,33 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
 {
   // Collect libraries directly linked in this configuration.
   std::vector<std::string> llibs;
-  this->GetDirectLinkLibrariesInternal(config, llibs, head);
+  if(const char *prop = this->GetProperty("LINK_LIBRARIES"))
+    {
+    cmGeneratorExpression ge;
+    const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+
+    cmGeneratorExpressionDAGChecker dagChecker(
+                                        this->GetName(),
+                                        "LINK_LIBRARIES", 0, 0);
+    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
+                                        config,
+                                        false,
+                                        head,
+                                        &dagChecker),
+                                      llibs);
+
+    std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+    for (std::set<std::string>::const_iterator it = seenProps.begin();
+        it != seenProps.end(); ++it)
+      {
+      if (!this->GetProperty(*it))
+        {
+        this->LinkImplicitNullProperties.insert(*it);
+        }
+      }
+    cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards);
+    }
+
   for(std::vector<std::string>::const_iterator li = llibs.begin();
       li != llibs.end(); ++li)
     {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2e0df42..3f534f2 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -169,8 +169,6 @@ public:
   return this->LinkLibraries;}
   const LinkLibraryVectorType &GetOriginalLinkLibraries() const
     {return this->OriginalLinkLibraries;}
-  void GetDirectLinkLibraries(const std::string& config,
-                              std::vector<std::string> &) const;
 
   /** Compute the link type to use for the given configuration.  */
   LinkLibraryType ComputeLinkType(const std::string& config) const;
@@ -766,9 +764,6 @@ private:
                                             cmTarget const* head,
                                             bool &exists) const;
 
-  void GetDirectLinkLibrariesInternal(const std::string& config,
-                                      std::vector<std::string>& libs,
-                                      cmTarget const* head) const;
   LinkImplementation const*
     GetLinkImplementationLibrariesInternal(const std::string& config,
                                            cmTarget const* head) const;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=281eb3d8a6a4983a33d5a8d70a0e21ebb3bd115f
commit 281eb3d8a6a4983a33d5a8d70a0e21ebb3bd115f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 14:08:43 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:08 2014 -0400

    cmTarget: Improve HaveBuildTreeRPATH implementation
    
    Use GetLinkImplementationLibraries instead of GetDirectLinkLibraries
    because it tells us whether there will be any libraries to link after
    evaluating generator expressions.  Also GetDirectLinkLibraries will be
    dropped soon.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7a63db4..f4a0224 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -4551,9 +4551,12 @@ bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
     {
     return false;
     }
-  std::vector<std::string> libs;
-  this->GetDirectLinkLibraries(config, libs);
-  return !libs.empty();
+  if(LinkImplementation const* impl =
+     this->GetLinkImplementationLibraries(config))
+    {
+    return !impl->Libraries.empty();
+    }
+  return false;
 }
 
 //----------------------------------------------------------------------------

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d912220eaaa92f3e8524c33e1684ebbf84eba521
commit d912220eaaa92f3e8524c33e1684ebbf84eba521
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 11:49:10 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:07 2014 -0400

    cmTarget: Lookup targets in LinkInterface and LinkImplementation
    
    Instead of storing just the string names in these structures, lookup any
    target associated with each item and store its cmTarget pointer.  Use
    the cmLinkItem class to hold the name and pointer together.  Update
    client sites to use the pre-stored lookup result instead of looking up
    the target name again.
    
    Create a cmTarget::LookupLinkItems helper method to handle the lookup.
    Since lookups are now moving from cmComputeLinkDepends::AddLinkEntries
    to cmTarget::LookupLinkItems, move use of CheckCMP0004 to the latter.
    This drops use of CheckCMP0004 from entries added for _LIB_DEPENDS
    variables by cmComputeLinkDepends::AddVarLinkEntries, but I do not
    think that use was intentional originally anyway.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 1b2d1cb..6170e92 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -292,8 +292,7 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item)
 }
 
 //----------------------------------------------------------------------------
-int cmComputeLinkDepends::AddLinkEntry(int depender_index,
-                                       std::string const& item)
+int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
 {
   // Check if the item entry has already been added.
   std::map<std::string, int>::iterator lei = this->LinkEntryIndex.find(item);
@@ -310,7 +309,7 @@ int cmComputeLinkDepends::AddLinkEntry(int depender_index,
   int index = lei->second;
   LinkEntry& entry = this->EntryList[index];
   entry.Item = item;
-  entry.Target = this->FindTargetToLink(depender_index, entry.Item);
+  entry.Target = item.Target;
   entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
                   item.substr(0, 10) != "-framework");
 
@@ -370,11 +369,11 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
       this->FollowSharedDeps(depender_index, iface);
 
       // Support for CMP0003.
-      for(std::vector<std::string>::const_iterator
+      for(std::vector<cmLinkItem>::const_iterator
             oi = iface->WrongConfigLibraries.begin();
           oi != iface->WrongConfigLibraries.end(); ++oi)
         {
-        this->CheckWrongConfigItem(depender_index, *oi);
+        this->CheckWrongConfigItem(*oi);
         }
       }
     }
@@ -406,9 +405,9 @@ cmComputeLinkDepends
 void
 cmComputeLinkDepends
 ::QueueSharedDependencies(int depender_index,
-                          std::vector<std::string> const& deps)
+                          std::vector<cmLinkItem> const& deps)
 {
-  for(std::vector<std::string>::const_iterator li = deps.begin();
+  for(std::vector<cmLinkItem>::const_iterator li = deps.begin();
       li != deps.end(); ++li)
     {
     SharedDepEntry qe;
@@ -432,8 +431,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
     // Initialize the item entry.
     LinkEntry& entry = this->EntryList[lei->second];
     entry.Item = dep.Item;
-    entry.Target = this->FindTargetToLink(dep.DependerIndex,
-                                          dep.Item);
+    entry.Target = dep.Item.Target;
 
     // This item was added specifically because it is a dependent
     // shared library.  It may get special treatment
@@ -472,7 +470,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
   cmSystemTools::ExpandListArgument(value, deplist);
 
   // Look for entries meant for this configuration.
-  std::vector<std::string> actual_libs;
+  std::vector<cmLinkItem> actual_libs;
   cmTarget::LinkLibraryType llt = cmTarget::GENERAL;
   bool haveLLT = false;
   for(std::vector<std::string>::const_iterator di = deplist.begin();
@@ -520,11 +518,13 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index,
       // If the library is meant for this link type then use it.
       if(llt == cmTarget::GENERAL || llt == this->LinkType)
         {
-        actual_libs.push_back(*di);
+        cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+        actual_libs.push_back(item);
         }
       else if(this->OldLinkDirMode)
         {
-        this->CheckWrongConfigItem(depender_index, *di);
+        cmLinkItem item(*di, this->FindTargetToLink(depender_index, *di));
+        this->CheckWrongConfigItem(item);
         }
 
       // Reset the link type until another explicit type is given.
@@ -544,36 +544,36 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
   cmTarget::LinkImplementation const* impl =
     this->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
-  for(std::vector<std::string>::const_iterator
+  for(std::vector<cmLinkItem>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
       wi != impl->WrongConfigLibraries.end(); ++wi)
     {
-    this->CheckWrongConfigItem(-1, *wi);
+    this->CheckWrongConfigItem(*wi);
     }
 }
 
 //----------------------------------------------------------------------------
 void
-cmComputeLinkDepends::AddLinkEntries(int depender_index,
-                                     std::vector<std::string> const& libs)
+cmComputeLinkDepends::AddLinkEntries(
+  int depender_index, std::vector<cmLinkItem> const& libs)
 {
   // Track inferred dependency sets implied by this list.
   std::map<int, DependSet> dependSets;
 
   // Loop over the libraries linked directly by the depender.
-  for(std::vector<std::string>::const_iterator li = libs.begin();
+  for(std::vector<cmLinkItem>::const_iterator li = libs.begin();
       li != libs.end(); ++li)
     {
     // Skip entries that will resolve to the target getting linked or
     // are empty.
-    std::string item = this->Target->CheckCMP0004(*li);
+    cmLinkItem const& item = *li;
     if(item == this->Target->GetName() || item.empty())
       {
       continue;
       }
 
     // Add a link entry for this item.
-    int dependee_index = this->AddLinkEntry(depender_index, item);
+    int dependee_index = this->AddLinkEntry(*li);
 
     // The dependee must come after the depender.
     if(depender_index >= 0)
@@ -961,8 +961,7 @@ void cmComputeLinkDepends::DisplayFinalEntries()
 }
 
 //----------------------------------------------------------------------------
-void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
-                                                std::string const& item)
+void cmComputeLinkDepends::CheckWrongConfigItem(cmLinkItem const& item)
 {
   if(!this->OldLinkDirMode)
     {
@@ -972,9 +971,8 @@ void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
   // For CMake 2.4 bug-compatibility we need to consider the output
   // directories of targets linked in another configuration as link
   // directories.
-  cmTarget const* tgt = this->FindTargetToLink(depender_index, item);
-  if(tgt && !tgt->IsImported())
+  if(item.Target && !item.Target->IsImported())
     {
-    this->OldWrongConfigItems.insert(tgt);
+    this->OldWrongConfigItems.insert(item.Target);
     }
 }
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 440dc0d..3207ecb 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -77,11 +77,11 @@ private:
 
   std::map<std::string, int>::iterator
   AllocateLinkEntry(std::string const& item);
-  int AddLinkEntry(int depender_index, std::string const& item);
+  int AddLinkEntry(cmLinkItem const& item);
   void AddVarLinkEntries(int depender_index, const char* value);
   void AddDirectLinkEntries();
   void AddLinkEntries(int depender_index,
-                      std::vector<std::string> const& libs);
+                      std::vector<cmLinkItem> const& libs);
   cmTarget const* FindTargetToLink(int depender_index,
                                    const std::string& name);
 
@@ -103,7 +103,7 @@ private:
   // of the interface.
   struct SharedDepEntry
   {
-    std::string Item;
+    cmLinkItem Item;
     int DependerIndex;
   };
   std::queue<SharedDepEntry> SharedDepQueue;
@@ -112,7 +112,7 @@ private:
                         cmTarget::LinkInterface const* iface,
                         bool follow_interface = false);
   void QueueSharedDependencies(int depender_index,
-                               std::vector<std::string> const& deps);
+                               std::vector<cmLinkItem> const& deps);
   void HandleSharedDependency(SharedDepEntry const& dep);
 
   // Dependency inferral for each link item.
@@ -163,7 +163,7 @@ private:
 
   // Compatibility help.
   bool OldLinkDirMode;
-  void CheckWrongConfigItem(int depender_index, std::string const& item);
+  void CheckWrongConfigItem(cmLinkItem const& item);
   std::set<cmTarget const*> OldWrongConfigItems;
 };
 
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 6196542..3929af4 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -249,13 +249,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
         const_cast<cmTarget*>(depender)->AddUtility(objLib);
         }
       }
-    std::vector<std::string> tlibs;
-    depender->GetDirectLinkLibraries(*it, tlibs);
+
+    cmTarget::LinkImplementation const* impl =
+      depender->GetLinkImplementation(*it);
 
     // A target should not depend on itself.
     emitted.insert(depender->GetName());
-    for(std::vector<std::string>::const_iterator lib = tlibs.begin();
-        lib != tlibs.end(); ++lib)
+    for(std::vector<cmLinkItem>::const_iterator
+          lib = impl->Libraries.begin();
+        lib != impl->Libraries.end(); ++lib)
       {
       // Don't emit the same library twice for this target.
       if(emitted.insert(*lib).second)
@@ -269,11 +271,11 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
 
   // Loop over all utility dependencies.
   {
-  std::set<std::string> const& tutils = depender->GetUtilities();
+  std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
   std::set<std::string> emitted;
   // A target should not depend on itself.
   emitted.insert(depender->GetName());
-  for(std::set<std::string>::const_iterator util = tutils.begin();
+  for(std::set<cmLinkItem>::const_iterator util = tutils.begin();
       util != tutils.end(); ++util)
     {
     // Don't emit the same utility twice for this target.
@@ -295,7 +297,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
   if(cmTarget::LinkInterface const* iface =
                                 dependee->GetLinkInterface(config, depender))
     {
-    for(std::vector<std::string>::const_iterator
+    for(std::vector<cmLinkItem>::const_iterator
         lib = iface->Libraries.begin();
         lib != iface->Libraries.end(); ++lib)
       {
@@ -311,12 +313,11 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
 
 //----------------------------------------------------------------------------
 void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
-                                             const std::string& dependee_name,
+                                             cmLinkItem const& dependee_name,
                                              std::set<std::string> &emitted)
 {
   cmTarget const* depender = this->Targets[depender_index];
-  cmTarget const* dependee =
-    depender->GetMakefile()->FindTargetToUse(dependee_name);
+  cmTarget const* dependee = dependee_name.Target;
   // Skip targets that will not really be linked.  This is probably a
   // name conflict between an external library and an executable
   // within the project.
@@ -344,16 +345,15 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
 }
 
 //----------------------------------------------------------------------------
-void cmComputeTargetDepends::AddTargetDepend(int depender_index,
-                                             const std::string& dependee_name,
-                                             bool linking)
+void cmComputeTargetDepends::AddTargetDepend(
+  int depender_index, cmLinkItem const& dependee_name,
+  bool linking)
 {
   // Get the depender.
   cmTarget const* depender = this->Targets[depender_index];
 
   // Check the target's makefile first.
-  cmTarget const* dependee =
-    depender->GetMakefile()->FindTargetToUse(dependee_name);
+  cmTarget const* dependee = dependee_name.Target;
 
   if(!dependee && !linking &&
     (depender->GetType() != cmTarget::GLOBAL_TARGET))
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index b99199f..902f342 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -20,6 +20,7 @@
 
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
+class cmLinkItem;
 class cmTarget;
 class cmTargetDependSet;
 
@@ -46,13 +47,13 @@ private:
   void CollectDepends();
   void CollectTargetDepends(int depender_index);
   void AddTargetDepend(int depender_index,
-                       const std::string& dependee_name,
+                       cmLinkItem const& dependee_name,
                        bool linking);
   void AddTargetDepend(int depender_index, cmTarget const* dependee,
                        bool linking);
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
   void AddInterfaceDepends(int depender_index,
-                           const std::string& dependee_name,
+                           cmLinkItem const& dependee_name,
                            std::set<std::string> &emitted);
   void AddInterfaceDepends(int depender_index, cmTarget const* dependee,
                            const std::string& config,
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index f491882..c925869 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -800,7 +800,7 @@ static const char* targetPropertyTransitiveWhitelist[] = {
 #undef TRANSITIVE_PROPERTY_NAME
 
 std::string getLinkedTargetsContent(
-                                  const std::vector<cmTarget const*> &targets,
+                                  std::vector<cmTarget const*> &targets,
                                   cmTarget const* target,
                                   cmTarget const* headTarget,
                                   cmGeneratorExpressionContext *context,
@@ -841,7 +841,7 @@ std::string getLinkedTargetsContent(
   return linkedTargetsContent;
 }
 
-std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
+std::string getLinkedTargetsContent(std::vector<cmLinkItem> const &libraries,
                                   cmTarget const* target,
                                   cmTarget const* headTarget,
                                   cmGeneratorExpressionContext *context,
@@ -849,13 +849,13 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
                                   const std::string &interfacePropertyName)
 {
   std::vector<cmTarget const*> tgts;
-  for (std::vector<std::string>::const_iterator
+  for (std::vector<cmLinkItem>::const_iterator
       it = libraries.begin();
       it != libraries.end(); ++it)
     {
-    if (cmTarget const *tgt = target->FindTargetToLink(*it))
+    if (it->Target)
       {
-      tgts.push_back(tgt);
+      tgts.push_back(it->Target);
       }
     }
   return getLinkedTargetsContent(tgts, target, headTarget, context,
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 36c5648..fd82d17 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -475,10 +475,10 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
       }
 
     std::set<cmTarget const*> uniqueDeps;
-    for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
+    for(std::vector<cmLinkItem>::const_iterator li = impl->Libraries.begin();
         li != impl->Libraries.end(); ++li)
       {
-      cmTarget const* tgt = this->Target->FindTargetToLink(*li);
+      cmTarget const* tgt = li->Target;
       if (!tgt)
         {
         continue;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6e4f65f..7a63db4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -2311,7 +2311,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
     if(this->Makefile->IsOn("APPLE"))
       {
       LinkImplementation const* impl = this->GetLinkImplementation(config);
-      for(std::vector<std::string>::const_iterator
+      for(std::vector<cmLinkItem>::const_iterator
           it = impl->Libraries.begin();
           it != impl->Libraries.end(); ++it)
         {
@@ -3513,13 +3513,11 @@ public:
     Makefile(target->GetMakefile()), Target(target)
   { this->Visited.insert(target); }
 
-  void Visit(cmTarget const* from, const std::string& name)
+  void Visit(cmLinkItem const& item)
     {
-    cmTarget const *target = from->FindTargetToLink(name);
-
-    if(!target)
+    if(!item.Target)
       {
-      if(name.find("::") != std::string::npos)
+      if(item.find("::") != std::string::npos)
         {
         bool noMessage = false;
         cmake::MessageType messageType = cmake::FATAL_ERROR;
@@ -3545,7 +3543,7 @@ public:
         if(!noMessage)
           {
           e << "Target \"" << this->Target->GetName()
-            << "\" links to target \"" << name
+            << "\" links to target \"" << item
             << "\" but the target was not found.  Perhaps a find_package() "
             "call is missing for an IMPORTED target, or an ALIAS target is "
             "missing?";
@@ -3556,13 +3554,13 @@ public:
         }
       return;
       }
-    if(!this->Visited.insert(target).second)
+    if(!this->Visited.insert(item.Target).second)
       {
       return;
       }
 
     cmTarget::LinkInterface const* iface =
-      target->GetLinkInterface(this->Config, this->HeadTarget);
+      item.Target->GetLinkInterface(this->Config, this->HeadTarget);
     if(!iface) { return; }
 
     for(std::vector<std::string>::const_iterator
@@ -3571,10 +3569,10 @@ public:
       this->Languages.insert(*li);
       }
 
-    for(std::vector<std::string>::const_iterator
+    for(std::vector<cmLinkItem>::const_iterator
           li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
       {
-      this->Visit(target, *li);
+      this->Visit(*li);
       }
     }
 private:
@@ -3677,10 +3675,10 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
 
   // Add interface languages from linked targets.
   cmTargetCollectLinkLanguages cll(this, config, languages, this);
-  for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
+  for(std::vector<cmLinkItem>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
-    cll.Visit(this, *li);
+    cll.Visit(*li);
     }
 
   // Store the transitive closure of languages.
@@ -3731,16 +3729,34 @@ void cmTarget::ExpandLinkItems(std::string const& prop,
                                std::string const& value,
                                std::string const& config,
                                cmTarget const* headTarget,
-                               std::vector<std::string>& libs) const
+                               std::vector<cmLinkItem>& items) const
 {
   cmGeneratorExpression ge;
   cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  std::vector<std::string> libs;
   cmSystemTools::ExpandListArgument(ge.Parse(value)->Evaluate(
                                       this->Makefile,
                                       config,
                                       false,
                                       headTarget,
                                       this, &dagChecker), libs);
+  this->LookupLinkItems(libs, items);
+}
+
+//----------------------------------------------------------------------------
+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)));
+    }
 }
 
 //----------------------------------------------------------------------------
@@ -6158,7 +6174,11 @@ cmTarget::GetImportLinkInterface(const std::string& config,
     cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
     this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
                           headTarget, iface.Libraries);
-    cmSystemTools::ExpandListArgument(info->SharedDeps, iface.SharedDeps);
+    {
+    std::vector<std::string> deps;
+    cmSystemTools::ExpandListArgument(info->SharedDeps, deps);
+    this->LookupLinkItems(deps, iface.SharedDeps);
+    }
 
     cmTargetInternals::ImportLinkInterfaceMapType::value_type
       entry(key, iface);
@@ -6170,22 +6190,21 @@ cmTarget::GetImportLinkInterface(const std::string& config,
 //----------------------------------------------------------------------------
 void processILibs(const std::string& config,
                   cmTarget const* headTarget,
-                  cmTarget const* curTarget,
-                  std::string const& name,
+                  cmLinkItem const& item,
                   std::vector<cmTarget const*>& tgts,
                   std::set<cmTarget const*>& emitted)
 {
-  if (cmTarget const* tgt = curTarget->FindTargetToLink(name))
+  if (item.Target && emitted.insert(item.Target).second)
     {
-    tgts.push_back(tgt);
+    tgts.push_back(item.Target);
     if(cmTarget::LinkInterface const* iface =
-       tgt->GetLinkInterfaceLibraries(config, headTarget))
+       item.Target->GetLinkInterfaceLibraries(config, headTarget))
       {
-      for(std::vector<std::string>::const_iterator
-          it = iface->Libraries.begin();
+      for(std::vector<cmLinkItem>::const_iterator
+            it = iface->Libraries.begin();
           it != iface->Libraries.end(); ++it)
         {
-        processILibs(config, headTarget, tgt, *it, tgts, emitted);
+        processILibs(config, headTarget, *it, tgts, emitted);
         }
       }
     }
@@ -6205,10 +6224,10 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
     cmTarget::LinkImplementation const* impl
       = this->GetLinkImplementationLibraries(config);
 
-    for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
+    for(std::vector<cmLinkItem>::const_iterator it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
       {
-      processILibs(config, this, this, *it, tgts , emitted);
+      processILibs(config, this, *it, tgts , emitted);
       }
     }
   return tgts;
@@ -6229,12 +6248,12 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
       || this->GetPolicyStatusCMP0022() == cmPolicies::WARN
       || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
     {
-    for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
+    for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin();
         it != iface->Libraries.end(); ++it)
       {
-      if (cmTarget const* tgt = this->FindTargetToLink(*it))
+      if (it->Target)
         {
-        tgts.push_back(tgt);
+        tgts.push_back(it->Target);
         }
       }
     return;
@@ -6378,7 +6397,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
       {
       // Compare the link implementation fallback link interface to the
       // preferred new link interface property and warn if different.
-      std::vector<std::string> ifaceLibs;
+      std::vector<cmLinkItem> ifaceLibs;
       std::string newProp = "INTERFACE_LINK_LIBRARIES";
       if(const char* newExplicitLibraries = this->GetProperty(newProp))
         {
@@ -6390,7 +6409,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
         std::string oldLibraries;
         std::string newLibraries;
         const char *sep = "";
-        for(std::vector<std::string>::const_iterator it
+        for(std::vector<cmLinkItem>::const_iterator it
               = impl->Libraries.begin(); it != impl->Libraries.end(); ++it)
           {
           oldLibraries += sep;
@@ -6398,7 +6417,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
           sep = ";";
           }
         sep = "";
-        for(std::vector<std::string>::const_iterator it
+        for(std::vector<cmLinkItem>::const_iterator it
               = ifaceLibs.begin(); it != ifaceLibs.end(); ++it)
           {
           newLibraries += sep;
@@ -6449,7 +6468,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
       // Shared libraries may have runtime implementation dependencies
       // on other shared libraries that are not in the interface.
       std::set<std::string> emitted;
-      for(std::vector<std::string>::const_iterator
+      for(std::vector<cmLinkItem>::const_iterator
           li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
         {
         emitted.insert(*li);
@@ -6458,15 +6477,15 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
         {
         cmTarget::LinkImplementation const* impl =
             thisTarget->GetLinkImplementation(config);
-        for(std::vector<std::string>::const_iterator
+        for(std::vector<cmLinkItem>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
           if(emitted.insert(*li).second)
             {
-            if(cmTarget* tgt = thisTarget->Makefile->FindTargetToUse(*li))
+            if(li->Target)
               {
               // This is a runtime dependency on another shared library.
-              if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
+              if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
                 {
                 iface.SharedDeps.push_back(*li);
                 }
@@ -6617,10 +6636,10 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
       li != llibs.end(); ++li)
     {
     // Skip entries that resolve to the target itself or are empty.
-    std::string item = this->CheckCMP0004(*li);
-    if(item == this->GetName() || item.empty())
+    std::string name = this->CheckCMP0004(*li);
+    if(name == this->GetName() || name.empty())
       {
-      if(item == this->GetName())
+      if(name == this->GetName())
         {
         bool noMessage = false;
         cmake::MessageType messageType = cmake::FATAL_ERROR;
@@ -6659,7 +6678,8 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
       }
 
     // The entry is meant for this configuration.
-    impl.Libraries.push_back(item);
+    impl.Libraries.push_back(
+      cmLinkItem(name, this->FindTargetToLink(name)));
     }
 
   cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
@@ -6669,13 +6689,14 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
     {
     if(li->second != cmTarget::GENERAL && li->second != linkType)
       {
-      std::string item = this->CheckCMP0004(li->first);
-      if(item == this->GetName() || item.empty())
+      std::string name = this->CheckCMP0004(li->first);
+      if(name == this->GetName() || name.empty())
         {
         continue;
         }
       // Support OLD behavior for CMP0003.
-      impl.WrongConfigLibraries.push_back(item);
+      impl.WrongConfigLibraries.push_back(
+        cmLinkItem(name, this->FindTargetToLink(name)));
       }
     }
 }
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index c56fa98..2e0df42 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -259,10 +259,10 @@ public:
     std::vector<std::string> Languages;
 
     // Libraries listed in the interface.
-    std::vector<std::string> Libraries;
+    std::vector<cmLinkItem> Libraries;
 
     // Shared library dependencies needed for linking on some platforms.
-    std::vector<std::string> SharedDeps;
+    std::vector<cmLinkItem> SharedDeps;
 
     // Number of repetitions of a strongly connected component of two
     // or more static libraries.
@@ -270,7 +270,7 @@ public:
 
     // Libraries listed for other configurations.
     // Needed only for OLD behavior of CMP0003.
-    std::vector<std::string> WrongConfigLibraries;
+    std::vector<cmLinkItem> WrongConfigLibraries;
 
     bool ImplementationIsInterface;
 
@@ -297,11 +297,11 @@ public:
     std::vector<std::string> Languages;
 
     // Libraries linked directly in this configuration.
-    std::vector<std::string> Libraries;
+    std::vector<cmLinkItem> Libraries;
 
     // Libraries linked directly in other configurations.
     // Needed only for OLD behavior of CMP0003.
-    std::vector<std::string> WrongConfigLibraries;
+    std::vector<cmLinkItem> WrongConfigLibraries;
   };
   LinkImplementation const*
     GetLinkImplementation(const std::string& config) const;
@@ -782,7 +782,9 @@ private:
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,
-                       std::vector<std::string>& libs) const;
+                       std::vector<cmLinkItem>& items) const;
+  void LookupLinkItems(std::vector<std::string> const& names,
+                       std::vector<cmLinkItem>& items) const;
 
   std::string ProcessSourceItemCMP0049(const std::string& s);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=edce43514d854a84d2a00c975268f898bd1dda45
commit edce43514d854a84d2a00c975268f898bd1dda45
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 09:38:04 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:22:07 2014 -0400

    cmExportFileGenerator: Make SetImportLinkProperty a template
    
    Allow the vector of property entries to have any element type
    that can convert to std::string.

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 9f5eee5..1f39d7a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -865,15 +865,16 @@ cmExportFileGenerator
 }
 
 //----------------------------------------------------------------------------
+template <typename T>
 void
 cmExportFileGenerator
 ::SetImportLinkProperty(std::string const& suffix,
                         cmTarget* target,
                         const std::string& propName,
-                        std::vector<std::string> const& entries,
+                        std::vector<T> const& entries,
                         ImportPropertyMap& properties,
                         std::vector<std::string>& missingTargets
-                       )
+  )
 {
   // Skip the property if there are no entries.
   if(entries.empty())
@@ -884,7 +885,7 @@ cmExportFileGenerator
   // Construct the property value.
   std::string link_entries;
   const char* sep = "";
-  for(std::vector<std::string>::const_iterator li = entries.begin();
+  for(typename std::vector<T>::const_iterator li = entries.begin();
       li != entries.end(); ++li)
     {
     // Separate this from the previous entry.
@@ -902,7 +903,6 @@ cmExportFileGenerator
   properties[prop] = link_entries;
 }
 
-
 //----------------------------------------------------------------------------
 void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
                                                     const std::string& config)
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index abd8ad5..919924e 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -95,9 +95,11 @@ protected:
                                  std::string const& suffix, cmTarget* target,
                                  ImportPropertyMap& properties,
                                  std::vector<std::string>& missingTargets);
+
+  template <typename T>
   void SetImportLinkProperty(std::string const& suffix,
                              cmTarget* target, const std::string& propName,
-                             std::vector<std::string> const& entries,
+                             std::vector<T> const& entries,
                              ImportPropertyMap& properties,
                              std::vector<std::string>& missingTargets);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=097be4139df044c86daadb665ec224ee66e6b3bb
commit 097be4139df044c86daadb665ec224ee66e6b3bb
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 10:58:23 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:21:56 2014 -0400

    cmTarget: Add GetUtilityItems to get target ordering dependencies
    
    Add a method like GetUtilities but that provides the target names
    already looked up and resolved to cmTarget pointers internally.  Update
    call site in cmComputeTargetDepends::AddTargetDepend to use the
    already-found target instead of looking it up again.

diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index a5df060..6196542 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -421,12 +421,11 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
   if(dependee->IsImported())
     {
     // Skip imported targets but follow their utility dependencies.
-    std::set<std::string> const& utils = dependee->GetUtilities();
-    for(std::set<std::string>::const_iterator i = utils.begin();
+    std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
+    for(std::set<cmLinkItem>::const_iterator i = utils.begin();
         i != utils.end(); ++i)
       {
-      if(cmTarget const* transitive_dependee =
-         dependee->GetMakefile()->FindTargetToUse(*i))
+      if(cmTarget const* transitive_dependee = i->Target)
         {
         this->AddTargetDepend(depender_index, transitive_dependee, false);
         }
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e4f26d1..6e4f65f 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -95,11 +95,13 @@ public:
     : Backtrace(NULL)
     {
     this->PolicyWarnedCMP0022 = false;
+    this->UtilityItemsDone = false;
     }
   cmTargetInternals(cmTargetInternals const&)
     : Backtrace(NULL)
     {
     this->PolicyWarnedCMP0022 = false;
+    this->UtilityItemsDone = false;
     }
   ~cmTargetInternals();
 
@@ -151,6 +153,9 @@ public:
                                                           SourceFilesMapType;
   SourceFilesMapType SourceFilesMap;
 
+  std::set<cmLinkItem> UtilityItems;
+  bool UtilityItemsDone;
+
   struct TargetPropertyEntry {
     TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
       const std::string &targetName = std::string())
@@ -471,6 +476,22 @@ cmListFileBacktrace const* cmTarget::GetUtilityBacktrace(
 }
 
 //----------------------------------------------------------------------------
+std::set<cmLinkItem> const& cmTarget::GetUtilityItems() const
+{
+  if(!this->Internal->UtilityItemsDone)
+    {
+    this->Internal->UtilityItemsDone = true;
+    for(std::set<std::string>::const_iterator i = this->Utilities.begin();
+        i != this->Utilities.end(); ++i)
+      {
+      this->Internal->UtilityItems.insert(
+        cmLinkItem(*i, this->Makefile->FindTargetToUse(*i)));
+      }
+    }
+  return this->Internal->UtilityItems;
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::FinishConfigure()
 {
   // Erase any cached link information that might have been comptued
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 97c8bf0..c56fa98 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -227,6 +227,7 @@ public:
   void AddUtility(const std::string& u, cmMakefile *makefile = 0);
   ///! Get the utilities used by this target
   std::set<std::string>const& GetUtilities() const { return this->Utilities; }
+  std::set<cmLinkItem>const& GetUtilityItems() const;
   cmListFileBacktrace const* GetUtilityBacktrace(const std::string& u) const;
 
   /** Finalize the target at the end of the Configure step.  */

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4dad5fd20bfa330b3131fd5cafa709d85c1b58ec
commit 4dad5fd20bfa330b3131fd5cafa709d85c1b58ec
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 10:55:33 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:07 2014 -0400

    cmTarget: Add cmLinkItem to refer to a target by name and pointer
    
    Many items named in target_link_libraries calls are targets, but not
    all.  Create a cmLinkItem type that acts like std::string so it can name
    an item but also has a pointer to a cmTarget that is the result of
    looking up the item name in the referencing target's scope.  This will
    be useful to avoid duplicate lookup operations later.

diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 049d3ea..97c8bf0 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -43,6 +43,18 @@ class cmTarget;
 class cmGeneratorTarget;
 class cmTargetTraceDependencies;
 
+// Basic information about each link item.
+class cmLinkItem: public std::string
+{
+  typedef std::string std_string;
+public:
+  cmLinkItem(): std_string(), Target(0) {}
+  cmLinkItem(const std_string& n,
+             cmTarget const* t): std_string(n), Target(t) {}
+  cmLinkItem(cmLinkItem const& r): std_string(r), Target(r.Target) {}
+  cmTarget const* Target;
+};
+
 struct cmTargetLinkInformationMap:
   public std::map<std::string, cmComputeLinkInformation*>
 {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a272344228174958a8b2346793d3272eb432dad8
commit a272344228174958a8b2346793d3272eb432dad8
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 10:10:18 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:07 2014 -0400

    Fix scope of transitive target name lookups
    
    In cmTarget, cmGeneratorTarget, and cmGeneratorExpressionEvaluator, fix
    target name lookups to occur in the cmMakefile context of the target
    that referenced the name, not the current 'head' target.  The context
    matters for imported targets because they are directory-scoped instead
    of globally unique.  We already do this in cmComputeLinkDepends and
    cmComputeTargetDepends.
    
    Extend the InterfaceLibrary test with an example covering this behavior.

diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 3dee601..f491882 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -828,7 +828,7 @@ std::string getLinkedTargetsContent(
     sep = ";";
     }
   cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
-  std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
+  std::string linkedTargetsContent = cge->Evaluate(target->GetMakefile(),
                       context->Config,
                       context->Quiet,
                       headTarget,
@@ -853,7 +853,7 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
       it = libraries.begin();
       it != libraries.end(); ++it)
     {
-    if (cmTarget const *tgt = context->Makefile->FindTargetToUse(*it))
+    if (cmTarget const *tgt = target->FindTargetToLink(*it))
       {
       tgts.push_back(tgt);
       }
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 392b377..36c5648 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -478,7 +478,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
     for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
         li != impl->Libraries.end(); ++li)
       {
-      cmTarget const* tgt = this->Makefile->FindTargetToUse(*li);
+      cmTarget const* tgt = this->Target->FindTargetToLink(*li);
       if (!tgt)
         {
         continue;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9a6c93c..e4f26d1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3492,9 +3492,9 @@ public:
     Makefile(target->GetMakefile()), Target(target)
   { this->Visited.insert(target); }
 
-  void Visit(const std::string& name)
+  void Visit(cmTarget const* from, const std::string& name)
     {
-    cmTarget *target = this->Makefile->FindTargetToUse(name);
+    cmTarget const *target = from->FindTargetToLink(name);
 
     if(!target)
       {
@@ -3553,7 +3553,7 @@ public:
     for(std::vector<std::string>::const_iterator
           li = iface->Libraries.begin(); li != iface->Libraries.end(); ++li)
       {
-      this->Visit(*li);
+      this->Visit(target, *li);
       }
     }
 private:
@@ -3659,7 +3659,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
   for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
-    cll.Visit(*li);
+    cll.Visit(this, *li);
     }
 
   // Store the transitive closure of languages.
@@ -6149,13 +6149,12 @@ cmTarget::GetImportLinkInterface(const std::string& config,
 //----------------------------------------------------------------------------
 void processILibs(const std::string& config,
                   cmTarget const* headTarget,
+                  cmTarget const* curTarget,
                   std::string const& name,
                   std::vector<cmTarget const*>& tgts,
                   std::set<cmTarget const*>& emitted)
 {
-  cmTarget* tgt = headTarget->GetMakefile()
-                                  ->FindTargetToUse(name);
-  if (tgt && emitted.insert(tgt).second)
+  if (cmTarget const* tgt = curTarget->FindTargetToLink(name))
     {
     tgts.push_back(tgt);
     if(cmTarget::LinkInterface const* iface =
@@ -6165,7 +6164,7 @@ void processILibs(const std::string& config,
           it = iface->Libraries.begin();
           it != iface->Libraries.end(); ++it)
         {
-        processILibs(config, headTarget, *it, tgts, emitted);
+        processILibs(config, headTarget, tgt, *it, tgts, emitted);
         }
       }
     }
@@ -6188,7 +6187,7 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
     for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
       {
-      processILibs(config, this, *it, tgts , emitted);
+      processILibs(config, this, this, *it, tgts , emitted);
       }
     }
   return tgts;
@@ -6212,8 +6211,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
     for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
         it != iface->Libraries.end(); ++it)
       {
-      if (cmTarget const* tgt = headTarget->GetMakefile()
-                                    ->FindTargetToUse(*it))
+      if (cmTarget const* tgt = this->FindTargetToLink(*it))
         {
         tgts.push_back(tgt);
         }
@@ -6245,8 +6243,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
   for(std::vector<std::string>::const_iterator it = libs.begin();
       it != libs.end(); ++it)
     {
-    if (cmTarget* tgt = headTarget->GetMakefile()
-                                  ->FindTargetToUse(*it))
+    if (cmTarget const* tgt = this->FindTargetToLink(*it))
       {
       tgts.push_back(tgt);
       }
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 81b34e6..d4f49c2 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -8,8 +8,18 @@ target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
 
 add_subdirectory(headerdir)
 
+# Add an interface target in a subdirectory that uses an imported interface.
+add_subdirectory(ifacedir)
+
+# Poison an imported interface with the same name as that in the subdir
+# to ensure that the transitive lookup occurs in the subdir.
+add_library(imp::iface INTERFACE IMPORTED)
+set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP OFF)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/does_not_exist.cpp)
+
 add_executable(InterfaceLibrary definetestexe.cpp)
-target_link_libraries(InterfaceLibrary iface_nodepends headeriface)
+target_link_libraries(InterfaceLibrary iface_nodepends headeriface subiface)
 
 add_subdirectory(libsdir)
 
diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp
index e7a10c1..30f2925 100644
--- a/Tests/InterfaceLibrary/definetestexe.cpp
+++ b/Tests/InterfaceLibrary/definetestexe.cpp
@@ -15,7 +15,9 @@
 #error Expected IFACE_HEADER_BUILDDIR
 #endif
 
+extern int sub();
+
 int main(int,char**)
 {
-  return 0;
+  return sub();
 }
diff --git a/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt b/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt
new file mode 100644
index 0000000..228715e
--- /dev/null
+++ b/Tests/InterfaceLibrary/ifacedir/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_library(imp::iface INTERFACE IMPORTED)
+set_property(TARGET imp::iface APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET imp::iface PROPERTY INTERFACE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sub.cpp)
+
+add_library(subiface INTERFACE)
+target_link_libraries(subiface INTERFACE imp::iface)
+set_property(TARGET subiface PROPERTY INTERFACE_SOMEPROP ON)
diff --git a/Tests/InterfaceLibrary/ifacedir/sub.cpp b/Tests/InterfaceLibrary/ifacedir/sub.cpp
new file mode 100644
index 0000000..165a66a
--- /dev/null
+++ b/Tests/InterfaceLibrary/ifacedir/sub.cpp
@@ -0,0 +1 @@
+int sub() { return 0; }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=069d60fe039ae1d797a26786f3cd4c23afc27b07
commit 069d60fe039ae1d797a26786f3cd4c23afc27b07
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 09:45:46 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:06 2014 -0400

    cmTarget: Add method to lookup other targets in a target's scope
    
    Move the main implementation of cmComputeLinkDepends::FindTargetToLink
    into cmTarget.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 1b83ee8..1b2d1cb 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -623,40 +623,15 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
                                                  const std::string& name)
 {
   // Look for a target in the scope of the depender.
-  cmMakefile* mf = this->Makefile;
+  cmTarget const* from = this->Target;
   if(depender_index >= 0)
     {
     if(cmTarget const* depender = this->EntryList[depender_index].Target)
       {
-      mf = depender->GetMakefile();
+      from = depender;
       }
     }
-  cmTarget const* tgt = mf->FindTargetToUse(name);
-
-  // Skip targets that will not really be linked.  This is probably a
-  // name conflict between an external library and an executable
-  // within the project.
-  if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
-     !tgt->IsExecutableWithExports())
-    {
-    tgt = 0;
-    }
-
-  if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
-    {
-    cmOStringStream e;
-    e << "Target \"" << this->Target->GetName() << "\" links to "
-      "OBJECT library \"" << tgt->GetName() << "\" but this is not "
-      "allowed.  "
-      "One may link only to STATIC or SHARED libraries, or to executables "
-      "with the ENABLE_EXPORTS property set.";
-    this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
-                                      this->Target->GetBacktrace());
-    tgt = 0;
-    }
-
-  // Return the target found, if any.
-  return tgt;
+  return from->FindTargetToLink(name);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 4ef481a..9a6c93c 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -6681,6 +6681,37 @@ cmTarget::ComputeLinkImplementationLanguages(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
+cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
+{
+  cmTarget const* tgt = this->Makefile->FindTargetToUse(name);
+
+  // Skip targets that will not really be linked.  This is probably a
+  // name conflict between an external library and an executable
+  // within the project.
+  if(tgt && tgt->GetType() == cmTarget::EXECUTABLE &&
+     !tgt->IsExecutableWithExports())
+    {
+    tgt = 0;
+    }
+
+  if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
+    {
+    cmOStringStream e;
+    e << "Target \"" << this->GetName() << "\" links to "
+      "OBJECT library \"" << tgt->GetName() << "\" but this is not "
+      "allowed.  "
+      "One may link only to STATIC or SHARED libraries, or to executables "
+      "with the ENABLE_EXPORTS property set.";
+    cmake* cm = this->Makefile->GetCMakeInstance();
+    cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
+    tgt = 0;
+    }
+
+  // Return the target found, if any.
+  return tgt;
+}
+
+//----------------------------------------------------------------------------
 std::string cmTarget::CheckCMP0004(std::string const& item) const
 {
   // Strip whitespace off the library names because we used to do this
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index cb68559..049d3ea 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -308,6 +308,8 @@ public:
   };
   LinkClosure const* GetLinkClosure(const std::string& config) const;
 
+  cmTarget const* FindTargetToLink(std::string const& name) const;
+
   /** Strip off leading and trailing whitespace from an item named in
       the link dependencies of this target.  */
   std::string CheckCMP0004(std::string const& item) const;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=47ab3ca64105cdfcc7b57ffe037aa93d8226b945
commit 47ab3ca64105cdfcc7b57ffe037aa93d8226b945
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 10:09:46 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:06 2014 -0400

    cmTarget: Constify GetLinkImplementationClosure results
    
    Populate a vector of "cmTarget const*" instead of "cmTarget*".

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 96f28af..4ef481a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -177,7 +177,7 @@ public:
                                 CachedLinkInterfaceSourcesEntries;
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileFeaturesEntries;
-  mutable std::map<std::string, std::vector<cmTarget*> >
+  mutable std::map<std::string, std::vector<cmTarget const*> >
                                 CachedLinkImplementationClosure;
 
   mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
@@ -5219,7 +5219,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
   assert((impliedByUse ^ explicitlySet)
       || (!impliedByUse && !explicitlySet));
 
-  std::vector<cmTarget*> const& deps =
+  std::vector<cmTarget const*> const& deps =
     tgt->GetLinkImplementationClosure(config);
 
   if(deps.empty())
@@ -5245,7 +5245,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
     report += "\" property not set.\n";
     }
 
-  for(std::vector<cmTarget*>::const_iterator li =
+  for(std::vector<cmTarget const*>::const_iterator li =
       deps.begin();
       li != deps.end(); ++li)
     {
@@ -5435,7 +5435,7 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
                              const std::string& interfaceProperty,
                              const std::string& config)
 {
-  std::vector<cmTarget*> const& deps =
+  std::vector<cmTarget const*> const& deps =
     tgt->GetLinkImplementationClosure(config);
 
   if(deps.empty())
@@ -5443,8 +5443,7 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
     return false;
     }
 
-  for(std::vector<cmTarget*>::const_iterator li =
-      deps.begin();
+  for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
       li != deps.end(); ++li)
     {
     const char *prop = (*li)->GetProperty(interfaceProperty);
@@ -6151,7 +6150,8 @@ cmTarget::GetImportLinkInterface(const std::string& config,
 void processILibs(const std::string& config,
                   cmTarget const* headTarget,
                   std::string const& name,
-                  std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
+                  std::vector<cmTarget const*>& tgts,
+                  std::set<cmTarget const*>& emitted)
 {
   cmTarget* tgt = headTarget->GetMakefile()
                                   ->FindTargetToUse(name);
@@ -6172,15 +6172,15 @@ void processILibs(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
-std::vector<cmTarget*> const&
+std::vector<cmTarget const*> const&
 cmTarget::GetLinkImplementationClosure(const std::string& config) const
 {
-  std::vector<cmTarget*>& tgts =
+  std::vector<cmTarget const*>& tgts =
     this->Internal->CachedLinkImplementationClosure[config];
   if(!this->Internal->CacheLinkImplementationClosureDone[config])
     {
     this->Internal->CacheLinkImplementationClosureDone[config] = true;
-    std::set<cmTarget*> emitted;
+    std::set<cmTarget const*> emitted;
 
     cmTarget::LinkImplementation const* impl
       = this->GetLinkImplementationLibraries(config);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index fae1bbb..cb68559 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -273,7 +273,7 @@ public:
   void GetTransitivePropertyTargets(const std::string& config,
                                     cmTarget const* headTarget,
                                     std::vector<cmTarget const*> &libs) const;
-  std::vector<cmTarget*> const&
+  std::vector<cmTarget const*> const&
     GetLinkImplementationClosure(const std::string& config) const;
 
   /** The link implementation specifies the direct library

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=9f3ed029ce830f0395e102258758a4b3680e5d0f
commit 9f3ed029ce830f0395e102258758a4b3680e5d0f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 09:55:20 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:06 2014 -0400

    cmTarget: Constify GetTransitivePropertyTargets results
    
    Populate a vector of "cmTarget const*" instead of "cmTarget*".

diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index cefdd63..3dee601 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -799,7 +799,8 @@ static const char* targetPropertyTransitiveWhitelist[] = {
 
 #undef TRANSITIVE_PROPERTY_NAME
 
-std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
+std::string getLinkedTargetsContent(
+                                  const std::vector<cmTarget const*> &targets,
                                   cmTarget const* target,
                                   cmTarget const* headTarget,
                                   cmGeneratorExpressionContext *context,
@@ -810,7 +811,7 @@ std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
 
   std::string sep;
   std::string depString;
-  for (std::vector<cmTarget*>::const_iterator
+  for (std::vector<cmTarget const*>::const_iterator
       it = targets.begin();
       it != targets.end(); ++it)
     {
@@ -847,12 +848,12 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
                                   cmGeneratorExpressionDAGChecker *dagChecker,
                                   const std::string &interfacePropertyName)
 {
-  std::vector<cmTarget*> tgts;
+  std::vector<cmTarget const*> tgts;
   for (std::vector<std::string>::const_iterator
       it = libraries.begin();
       it != libraries.end(); ++it)
     {
-    if (cmTarget *tgt = context->Makefile->FindTargetToUse(*it))
+    if (cmTarget const *tgt = context->Makefile->FindTargetToUse(*it))
       {
       tgts.push_back(tgt);
       }
@@ -1082,7 +1083,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                      cmStrCmp(propertyName)) != transEnd)
       {
 
-      std::vector<cmTarget*> tgts;
+      std::vector<cmTarget const*> tgts;
       target->GetTransitivePropertyTargets(context->Config,
                                                  headTarget, tgts);
       if (!tgts.empty())
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 381a0ed..392b377 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -252,7 +252,7 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
   return 0;
 }
 
-static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
+static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
                                   const std::string& config,
                                   cmTarget *headTarget,
                                   cmGeneratorExpressionDAGChecker *dagChecker,
@@ -474,11 +474,11 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
                                           &dagChecker), result);
       }
 
-    std::set<cmTarget*> uniqueDeps;
+    std::set<cmTarget const*> uniqueDeps;
     for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
         li != impl->Libraries.end(); ++li)
       {
-      cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
+      cmTarget const* tgt = this->Makefile->FindTargetToUse(*li);
       if (!tgt)
         {
         continue;
@@ -489,10 +489,10 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
         handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
                                 &dagChecker, result, excludeImported);
 
-        std::vector<cmTarget*> deps;
+        std::vector<cmTarget const*> deps;
         tgt->GetTransitivePropertyTargets(config, this->Target, deps);
 
-        for(std::vector<cmTarget*>::const_iterator di = deps.begin();
+        for(std::vector<cmTarget const*>::const_iterator di = deps.begin();
             di != deps.end(); ++di)
           {
           if (uniqueDeps.insert(*di).second)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cc647af..96f28af 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -6197,7 +6197,7 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
 //----------------------------------------------------------------------------
 void cmTarget::GetTransitivePropertyTargets(const std::string& config,
                                       cmTarget const* headTarget,
-                                      std::vector<cmTarget*> &tgts) const
+                                      std::vector<cmTarget const*> &tgts) const
 {
   cmTarget::LinkInterface const* iface
                         = this->GetLinkInterfaceLibraries(config, headTarget);
@@ -6212,7 +6212,7 @@ void cmTarget::GetTransitivePropertyTargets(const std::string& config,
     for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
         it != iface->Libraries.end(); ++it)
       {
-      if (cmTarget* tgt = headTarget->GetMakefile()
+      if (cmTarget const* tgt = headTarget->GetMakefile()
                                     ->FindTargetToUse(*it))
         {
         tgts.push_back(tgt);
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 0773194..fae1bbb 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -271,8 +271,8 @@ public:
   LinkInterface const* GetLinkInterfaceLibraries(const std::string& config,
                                         cmTarget const* headTarget) const;
   void GetTransitivePropertyTargets(const std::string& config,
-                                        cmTarget const* headTarget,
-                                        std::vector<cmTarget*> &libs) const;
+                                    cmTarget const* headTarget,
+                                    std::vector<cmTarget const*> &libs) const;
   std::vector<cmTarget*> const&
     GetLinkImplementationClosure(const std::string& config) const;
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6f0951af011d28366cf31ff621238f026cb8d895
commit 6f0951af011d28366cf31ff621238f026cb8d895
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 10:36:21 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:06 2014 -0400

    cmTarget: Drop 'head' target from GetImportInfo
    
    Move generator expression evaluation for imported library lists out of
    GetImportInfo and into a new GetImportLinkInterface helper.  This avoids
    duplicating the computation and storage of all imported target info just
    because some of it is parameterized on the 'head' target.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 86cab4e..cc647af 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -64,11 +64,16 @@ struct cmTarget::OutputInfo
 //----------------------------------------------------------------------------
 struct cmTarget::ImportInfo
 {
+  ImportInfo(): NoSOName(false), Multiplicity(0) {}
   bool NoSOName;
+  int Multiplicity;
   std::string Location;
   std::string SOName;
   std::string ImportLibrary;
-  cmTarget::LinkInterface LinkInterface;
+  std::string Languages;
+  std::string Libraries;
+  std::string LibrariesProp;
+  std::string SharedDeps;
 };
 
 //----------------------------------------------------------------------------
@@ -121,11 +126,14 @@ public:
   LinkInterfaceMapType LinkInterfaceMap;
   bool PolicyWarnedCMP0022;
 
+  typedef std::map<TargetConfigPair, cmTarget::LinkInterface>
+                                                    ImportLinkInterfaceMapType;
+  ImportLinkInterfaceMapType ImportLinkInterfaceMap;
+
   typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
 
-  typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
-                                                            ImportInfoMapType;
+  typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
   typedef std::map<std::string, cmTarget::CompileInfo> CompileInfoMapType;
@@ -481,6 +489,7 @@ void cmTarget::ClearLinkMaps()
   this->LinkImplementationLanguageIsContextDependent = true;
   this->Internal->LinkImplMap.clear();
   this->Internal->LinkInterfaceMap.clear();
+  this->Internal->ImportLinkInterfaceMap.clear();
   this->Internal->LinkClosureMap.clear();
   for (cmTargetLinkInformationMap::const_iterator it
       = this->LinkInformation.begin();
@@ -3853,7 +3862,7 @@ std::string cmTarget::GetSOName(const std::string& config) const
   if(this->IsImported())
     {
     // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
       {
       if(info->NoSOName)
         {
@@ -3921,7 +3930,7 @@ bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
   else
     {
     // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
       {
       if(!info->NoSOName && !info->SOName.empty())
         {
@@ -4007,7 +4016,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(
 {
   if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
       {
       return info->NoSOName;
       }
@@ -4131,7 +4140,7 @@ std::string
 cmTarget::ImportedGetFullPath(const std::string& config, bool implib) const
 {
   std::string result;
-  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
+  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
     {
     result = implib? info->ImportLibrary : info->Location;
     }
@@ -5670,8 +5679,7 @@ bool cmTarget::IsChrpathUsed(const std::string& config) const
 
 //----------------------------------------------------------------------------
 cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const std::string& config,
-                        cmTarget const* headTarget) const
+cmTarget::GetImportInfo(const std::string& config) const
 {
   // There is no imported information for non-imported targets.
   if(!this->IsImported())
@@ -5690,16 +5698,15 @@ cmTarget::GetImportInfo(const std::string& config,
     {
     config_upper = "NOCONFIG";
     }
-  TargetConfigPair key(headTarget, config_upper);
   typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
 
   ImportInfoMapType::const_iterator i =
-    this->Internal->ImportInfoMap.find(key);
+    this->Internal->ImportInfoMap.find(config_upper);
   if(i == this->Internal->ImportInfoMap.end())
     {
     ImportInfo info;
-    this->ComputeImportInfo(config_upper, info, headTarget);
-    ImportInfoMapType::value_type entry(key, info);
+    this->ComputeImportInfo(config_upper, info);
+    ImportInfoMapType::value_type entry(config_upper, info);
     i = this->Internal->ImportInfoMap.insert(entry).first;
     }
 
@@ -5851,8 +5858,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
 
 //----------------------------------------------------------------------------
 void cmTarget::ComputeImportInfo(std::string const& desired_config,
-                                 ImportInfo& info,
-                                 cmTarget const* headTarget) const
+                                 ImportInfo& info) const
 {
   // This method finds information about an imported target from its
   // properties.  The "IMPORTED_" namespace is reserved for properties
@@ -5891,8 +5897,8 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     }
   if(propertyLibs)
     {
-    this->ExpandLinkItems(linkProp, propertyLibs, desired_config,
-                          headTarget, info.LinkInterface.Libraries);
+    info.LibrariesProp = linkProp;
+    info.Libraries = propertyLibs;
     }
   }
   if(this->GetType() == INTERFACE_LIBRARY)
@@ -5978,13 +5984,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
   linkProp += suffix;
   if(const char* config_libs = this->GetProperty(linkProp))
     {
-    cmSystemTools::ExpandListArgument(config_libs,
-                                      info.LinkInterface.SharedDeps);
+    info.SharedDeps = config_libs;
     }
   else if(const char* libs =
           this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
     {
-    cmSystemTools::ExpandListArgument(libs, info.LinkInterface.SharedDeps);
+    info.SharedDeps = libs;
     }
   }
 
@@ -5995,14 +6000,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     linkProp += suffix;
     if(const char* config_libs = this->GetProperty(linkProp))
       {
-      cmSystemTools::ExpandListArgument(config_libs,
-                                        info.LinkInterface.Languages);
+      info.Languages = config_libs;
       }
     else if(const char* libs =
             this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
       {
-      cmSystemTools::ExpandListArgument(libs,
-                                        info.LinkInterface.Languages);
+      info.Languages = libs;
       }
     }
 
@@ -6013,12 +6016,12 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     linkProp += suffix;
     if(const char* config_reps = this->GetProperty(linkProp))
       {
-      sscanf(config_reps, "%u", &info.LinkInterface.Multiplicity);
+      sscanf(config_reps, "%u", &info.Multiplicity);
       }
     else if(const char* reps =
             this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
       {
-      sscanf(reps, "%u", &info.LinkInterface.Multiplicity);
+      sscanf(reps, "%u", &info.Multiplicity);
       }
     }
 }
@@ -6031,11 +6034,7 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
-      {
-      return &info->LinkInterface;
-      }
-    return 0;
+    return this->GetImportLinkInterface(config, head);
     }
 
   // Link interfaces are not supported for executables that do not
@@ -6084,11 +6083,7 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config,
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
-      {
-      return &info->LinkInterface;
-      }
-    return 0;
+    return this->GetImportLinkInterface(config, head);
     }
 
   // Link interfaces are not supported for executables that do not
@@ -6122,6 +6117,37 @@ cmTarget::GetLinkInterfaceLibraries(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
+cmTarget::LinkInterface const*
+cmTarget::GetImportLinkInterface(const std::string& config,
+                                 cmTarget const* headTarget) const
+{
+  cmTarget::ImportInfo const* info = this->GetImportInfo(config);
+  if(!info)
+    {
+    return 0;
+    }
+
+  TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config));
+
+  cmTargetInternals::ImportLinkInterfaceMapType::iterator i =
+    this->Internal->ImportLinkInterfaceMap.find(key);
+  if(i == this->Internal->ImportLinkInterfaceMap.end())
+    {
+    LinkInterface iface;
+    iface.Multiplicity = info->Multiplicity;
+    cmSystemTools::ExpandListArgument(info->Languages, iface.Languages);
+    this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
+                          headTarget, iface.Libraries);
+    cmSystemTools::ExpandListArgument(info->SharedDeps, iface.SharedDeps);
+
+    cmTargetInternals::ImportLinkInterfaceMapType::value_type
+      entry(key, iface);
+    i = this->Internal->ImportLinkInterfaceMap.insert(entry).first;
+    }
+  return &i->second;
+}
+
+//----------------------------------------------------------------------------
 void processILibs(const std::string& config,
                   cmTarget const* headTarget,
                   std::string const& name,
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8cf962f..0773194 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -730,10 +730,9 @@ private:
 
   // Cache import information from properties for each configuration.
   struct ImportInfo;
-  ImportInfo const* GetImportInfo(const std::string& config,
-                                        cmTarget const* workingTarget) const;
-  void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
-                                        cmTarget const* head) const;
+  ImportInfo const* GetImportInfo(const std::string& config) const;
+  void ComputeImportInfo(std::string const& desired_config,
+                         ImportInfo& info) const;
 
   // Cache target compile paths for each configuration.
   struct CompileInfo;
@@ -743,6 +742,10 @@ private:
   void CheckPropertyCompatibility(cmComputeLinkInformation *info,
                                   const std::string& config) const;
 
+  LinkInterface const*
+    GetImportLinkInterface(const std::string& config,
+                           cmTarget const* head) const;
+
   const char* ComputeLinkInterfaceLibraries(const std::string& config,
                                             LinkInterface& iface,
                                             cmTarget const* head,

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0dc9e88d76fa74440fc3b38032738a21ce72f2d7
commit 0dc9e88d76fa74440fc3b38032738a21ce72f2d7
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jun 12 16:22:11 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:17:00 2014 -0400

    cmTarget: Remove 'head' argument from GetLinkImplementation
    
    Many of the 'head' arguments added by commit v2.8.11~289^2~1 (Make
    linking APIs aware of 'head' target, 2013-01-04) turned out not to be
    needed.  The "link implementation" of a target never needs to be
    computed with anything but itself as the 'head' target (except for
    CMP0022 OLD behavior because then it is the link interface).
    
    Remove the unused 'head' target paths.  Add "internal" versions of
    cmTarget::GetDirectLinkLibraries and GetLinkImplementationLibraries
    to support the CMP0022 OLD behavior without otherwise exposing the
    'head' target option of these methods.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 1aabdeb..1b83ee8 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -542,7 +542,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
   cmTarget::LinkImplementation const* impl =
-    this->Target->GetLinkImplementation(this->Config, this->Target);
+    this->Target->GetLinkImplementation(this->Config);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<std::string>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 8e75807..a5df060 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -250,7 +250,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
         }
       }
     std::vector<std::string> tlibs;
-    depender->GetDirectLinkLibraries(*it, tlibs, depender);
+    depender->GetDirectLinkLibraries(*it, tlibs);
 
     // A target should not depend on itself.
     emitted.insert(depender->GetName());
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 7dcb335..cefdd63 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -1098,8 +1098,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
                           cmStrCmp(interfacePropertyName)) != transEnd)
       {
       const cmTarget::LinkImplementation *impl
-          = target->GetLinkImplementationLibraries(context->Config,
-                                                   headTarget);
+        = target->GetLinkImplementationLibraries(context->Config);
       if(impl)
         {
         linkedTargetsContent =
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index a7576ed..381a0ed 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -449,7 +449,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
   if (iter == this->SystemIncludesCache.end())
     {
     cmTarget::LinkImplementation const* impl
-                  = this->Target->GetLinkImplementation(config, this->Target);
+      = this->Target->GetLinkImplementation(config);
     if(!impl)
       {
       return false;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 29a5955..9a36df5 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1255,7 +1255,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
 
   // If the language is compiled as a source trust Xcode to link with it.
   cmTarget::LinkImplementation const* impl =
-    cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget);
+    cmtarget.GetLinkImplementation("NOCONFIG");
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f380052..86cab4e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1198,8 +1198,15 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) const
 
 //----------------------------------------------------------------------------
 void cmTarget::GetDirectLinkLibraries(const std::string& config,
-                            std::vector<std::string> &libs,
-                            cmTarget const* head) const
+                                      std::vector<std::string> &libs) const
+{
+  this->GetDirectLinkLibrariesInternal(config, libs, this);
+}
+
+//----------------------------------------------------------------------------
+void cmTarget::GetDirectLinkLibrariesInternal(const std::string& config,
+                                              std::vector<std::string> &libs,
+                                              cmTarget const* head) const
 {
   const char *prop = this->GetProperty("LINK_LIBRARIES");
   if (prop)
@@ -2273,8 +2280,7 @@ cmTarget::GetIncludeDirectories(const std::string& config) const
 
     if(this->Makefile->IsOn("APPLE"))
       {
-      LinkImplementation const* impl = this->GetLinkImplementation(config,
-                                                                   this);
+      LinkImplementation const* impl = this->GetLinkImplementation(config);
       for(std::vector<std::string>::const_iterator
           it = impl->Libraries.begin();
           it != impl->Libraries.end(); ++it)
@@ -3632,7 +3638,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config,
 {
   // Get languages built in this target.
   std::set<std::string> languages;
-  LinkImplementation const* impl = this->GetLinkImplementation(config, this);
+  LinkImplementation const* impl = this->GetLinkImplementation(config);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -4500,7 +4506,7 @@ bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const
     return false;
     }
   std::vector<std::string> libs;
-  this->GetDirectLinkLibraries(config, libs, this);
+  this->GetDirectLinkLibraries(config, libs);
   return !libs.empty();
 }
 
@@ -6151,7 +6157,7 @@ cmTarget::GetLinkImplementationClosure(const std::string& config) const
     std::set<cmTarget*> emitted;
 
     cmTarget::LinkImplementation const* impl
-      = this->GetLinkImplementationLibraries(config, this);
+      = this->GetLinkImplementationLibraries(config);
 
     for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
         it != impl->Libraries.end(); ++it)
@@ -6321,7 +6327,7 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
     {
     // The link implementation is the default link interface.
     LinkImplementation const* impl =
-        this->GetLinkImplementationLibraries(config, headTarget);
+        this->GetLinkImplementationLibrariesInternal(config, headTarget);
     iface.Libraries = impl->Libraries;
     if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
        !this->Internal->PolicyWarnedCMP0022)
@@ -6407,7 +6413,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
       if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
         {
         cmTarget::LinkImplementation const* impl =
-            thisTarget->GetLinkImplementation(config, headTarget);
+            thisTarget->GetLinkImplementation(config);
         for(std::vector<std::string>::const_iterator
               li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
           {
@@ -6438,7 +6444,8 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
     {
     // The link implementation is the default link interface.
     cmTarget::LinkImplementation const*
-                impl = thisTarget->GetLinkImplementation(config, headTarget);
+      impl = thisTarget->GetLinkImplementationLibrariesInternal(config,
+                                                                headTarget);
     iface.ImplementationIsInterface = true;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     }
@@ -6447,7 +6454,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
     {
     // Targets using this archive need its language runtime libraries.
     if(cmTarget::LinkImplementation const* impl =
-       thisTarget->GetLinkImplementation(config, headTarget))
+       thisTarget->GetLinkImplementation(config))
       {
       iface.Languages = impl->Languages;
       }
@@ -6485,8 +6492,7 @@ void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
 
 //----------------------------------------------------------------------------
 cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const std::string& config,
-                                cmTarget const* head) const
+cmTarget::GetLinkImplementation(const std::string& config) const
 {
   // There is no link implementation for imported targets.
   if(this->IsImported())
@@ -6495,7 +6501,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     }
 
   // Lookup any existing link implementation for this configuration.
-  TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+  TargetConfigPair key(this, cmSystemTools::UpperCase(config));
 
   cmTargetInternals::LinkImplMapType::iterator
     i = this->Internal->LinkImplMap.find(key);
@@ -6503,8 +6509,8 @@ cmTarget::GetLinkImplementation(const std::string& config,
     {
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
-    this->ComputeLinkImplementation(config, impl, head);
-    this->ComputeLinkImplementationLanguages(config, impl, head);
+    this->ComputeLinkImplementation(config, impl, this);
+    this->ComputeLinkImplementationLanguages(config, impl, this);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -6512,7 +6518,7 @@ cmTarget::GetLinkImplementation(const std::string& config,
     }
   else if (i->second.Languages.empty())
     {
-    this->ComputeLinkImplementationLanguages(config, i->second, head);
+    this->ComputeLinkImplementationLanguages(config, i->second, this);
     }
 
   return &i->second;
@@ -6520,8 +6526,15 @@ cmTarget::GetLinkImplementation(const std::string& config,
 
 //----------------------------------------------------------------------------
 cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementationLibraries(const std::string& config,
-                                         cmTarget const* head) const
+cmTarget::GetLinkImplementationLibraries(const std::string& config) const
+{
+  return this->GetLinkImplementationLibrariesInternal(config, this);
+}
+
+//----------------------------------------------------------------------------
+cmTarget::LinkImplementation const*
+cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
+                                                 cmTarget const* head) const
 {
   // There is no link implementation for imported targets.
   if(this->IsImported())
@@ -6555,7 +6568,7 @@ void cmTarget::ComputeLinkImplementation(const std::string& config,
 {
   // Collect libraries directly linked in this configuration.
   std::vector<std::string> llibs;
-  this->GetDirectLinkLibraries(config, llibs, head);
+  this->GetDirectLinkLibrariesInternal(config, llibs, head);
   for(std::vector<std::string>::const_iterator li = llibs.begin();
       li != llibs.end(); ++li)
     {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8c6955e..8cf962f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -158,8 +158,7 @@ public:
   const LinkLibraryVectorType &GetOriginalLinkLibraries() const
     {return this->OriginalLinkLibraries;}
   void GetDirectLinkLibraries(const std::string& config,
-                              std::vector<std::string> &,
-                              cmTarget const* head) const;
+                              std::vector<std::string> &) const;
 
   /** Compute the link type to use for the given configuration.  */
   LinkLibraryType ComputeLinkType(const std::string& config) const;
@@ -291,12 +290,11 @@ public:
     // Needed only for OLD behavior of CMP0003.
     std::vector<std::string> WrongConfigLibraries;
   };
-  LinkImplementation const* GetLinkImplementation(const std::string& config,
-                                                  cmTarget const* head) const;
+  LinkImplementation const*
+    GetLinkImplementation(const std::string& config) const;
 
-  LinkImplementation const* GetLinkImplementationLibraries(
-                                                  const std::string& config,
-                                                  cmTarget const* head) const;
+  LinkImplementation const*
+    GetLinkImplementationLibraries(const std::string& config) const;
 
   /** Link information from the transitive closure of the link
       implementation and the interfaces of its dependencies.  */
@@ -750,6 +748,12 @@ private:
                                             cmTarget const* head,
                                             bool &exists) const;
 
+  void GetDirectLinkLibrariesInternal(const std::string& config,
+                                      std::vector<std::string>& libs,
+                                      cmTarget const* head) const;
+  LinkImplementation const*
+    GetLinkImplementationLibrariesInternal(const std::string& config,
+                                           cmTarget const* head) const;
   void ComputeLinkImplementation(const std::string& config,
                                  LinkImplementation& impl,
                                  cmTarget const* head) const;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4ac72455fd7027039d498f007fdfe7c1d819b9f9
commit 4ac72455fd7027039d498f007fdfe7c1d819b9f9
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jun 12 16:21:45 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:45 2014 -0400

    cmTarget: Drop 'head' argument from GetLinkClosure
    
    It is only ever passed the 'this' target itself.

diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index bcafe2d..e1852a3 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -569,8 +569,7 @@ bool cmComputeLinkInformation::Compute()
 void cmComputeLinkInformation::AddImplicitLinkInfo()
 {
   // The link closure lists all languages whose implicit info is needed.
-  cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
-                                                          this->Target);
+  cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
@@ -1969,7 +1968,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   // present.  This is done even when skipping rpath support.
   {
   cmTarget::LinkClosure const* lc =
-    this->Target->GetLinkClosure(this->Config, this->Target);
+    this->Target->GetLinkClosure(this->Config);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f52c94d..f380052 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -136,8 +136,7 @@ public:
                    cmTarget::LinkImplementation> LinkImplMapType;
   LinkImplMapType LinkImplMap;
 
-  typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
-                                                          LinkClosureMapType;
+  typedef std::map<std::string, cmTarget::LinkClosure> LinkClosureMapType;
   LinkClosureMapType LinkClosureMap;
 
   typedef std::map<TargetConfigPair, std::vector<cmSourceFile*> >
@@ -3554,21 +3553,20 @@ private:
 //----------------------------------------------------------------------------
 std::string cmTarget::GetLinkerLanguage(const std::string& config) const
 {
-  return this->GetLinkClosure(config, this)->LinkerLanguage;
+  return this->GetLinkClosure(config)->LinkerLanguage;
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(
-                                                  const std::string& config,
-                                                  cmTarget const* head) const
+cmTarget::LinkClosure const*
+cmTarget::GetLinkClosure(const std::string& config) const
 {
-  TargetConfigPair key(head, cmSystemTools::UpperCase(config));
+  std::string key(cmSystemTools::UpperCase(config));
   cmTargetInternals::LinkClosureMapType::iterator
     i = this->Internal->LinkClosureMap.find(key);
   if(i == this->Internal->LinkClosureMap.end())
     {
     LinkClosure lc;
-    this->ComputeLinkClosure(config, lc, head);
+    this->ComputeLinkClosure(config, lc);
     cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
     i = this->Internal->LinkClosureMap.insert(entry).first;
     }
@@ -3629,12 +3627,12 @@ public:
 };
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
-                                  cmTarget const* head) const
+void cmTarget::ComputeLinkClosure(const std::string& config,
+                                  LinkClosure& lc) const
 {
   // Get languages built in this target.
   std::set<std::string> languages;
-  LinkImplementation const* impl = this->GetLinkImplementation(config, head);
+  LinkImplementation const* impl = this->GetLinkImplementation(config, this);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -3642,7 +3640,7 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
     }
 
   // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages, head);
+  cmTargetCollectLinkLanguages cll(this, config, languages, this);
   for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 26a1e86..8c6955e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -308,8 +308,7 @@ public:
     // Languages whose runtime libraries must be linked.
     std::vector<std::string> Languages;
   };
-  LinkClosure const* GetLinkClosure(const std::string& config,
-                                    cmTarget const* head) const;
+  LinkClosure const* GetLinkClosure(const std::string& config) const;
 
   /** Strip off leading and trailing whitespace from an item named in
       the link dependencies of this target.  */
@@ -757,8 +756,7 @@ private:
   void ComputeLinkImplementationLanguages(const std::string& config,
                                           LinkImplementation& impl,
                                           cmTarget const* head) const;
-  void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
-                          cmTarget const* head) const;
+  void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
 
   void ExpandLinkItems(std::string const& prop, std::string const& value,
                        std::string const& config, cmTarget const* headTarget,

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bcdb7ff9df8fb831e952a3909da11da51773a30f
commit bcdb7ff9df8fb831e952a3909da11da51773a30f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jun 12 16:20:08 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:45 2014 -0400

    cmTarget: Remove 'head' argument from GetLinkerLanguage
    
    It is only ever called with the 'this' target as the head.
    
    Co-Author: Stephen Kelly <steveire at gmail.com>

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 32b0777..f52c94d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3552,11 +3552,9 @@ private:
 };
 
 //----------------------------------------------------------------------------
-std::string cmTarget::GetLinkerLanguage(const std::string& config,
-                                        cmTarget const* head) const
+std::string cmTarget::GetLinkerLanguage(const std::string& config) const
 {
-  cmTarget const* headTarget = head ? head : this;
-  return this->GetLinkClosure(config, headTarget)->LinkerLanguage;
+  return this->GetLinkClosure(config, this)->LinkerLanguage;
 }
 
 //----------------------------------------------------------------------------
@@ -3842,8 +3840,7 @@ bool cmTarget::HasSOName(const std::string& config) const
   return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
            this->GetType() == cmTarget::MODULE_LIBRARY) &&
           !this->GetPropertyAsBool("NO_SONAME") &&
-          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
-                                                                this)));
+          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
 }
 
 //----------------------------------------------------------------------------
@@ -4216,7 +4213,7 @@ void cmTarget::GetFullNameInternal(const std::string& config,
   const char* suffixVar = this->GetSuffixVariableInternal(implib);
 
   // Check for language-specific default prefix and suffix.
-  std::string ll = this->GetLinkerLanguage(config, this);
+  std::string ll = this->GetLinkerLanguage(config);
   if(!ll.empty())
     {
     if(!targetSuffix && suffixVar && *suffixVar)
@@ -4555,7 +4552,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const std::string& config) const
     }
 
   // Check for rpath support on this platform.
-  std::string ll = this->GetLinkerLanguage(config, this);
+  std::string ll = this->GetLinkerLanguage(config);
   if(!ll.empty())
     {
     std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
@@ -5644,7 +5641,7 @@ bool cmTarget::IsChrpathUsed(const std::string& config) const
 #if defined(CMAKE_USE_ELF_PARSER)
   // Enable if the rpath flag uses a separator and the target uses ELF
   // binaries.
-  std::string ll = this->GetLinkerLanguage(config, this);
+  std::string ll = this->GetLinkerLanguage(config);
   if(!ll.empty())
     {
     std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 5bcbb3d..26a1e86 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -355,8 +355,7 @@ public:
   GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
 
   ///! Return the preferred linker language for this target
-  std::string GetLinkerLanguage(const std::string& config = "",
-                                cmTarget const* head = 0) const;
+  std::string GetLinkerLanguage(const std::string& config = "") const;
 
   /** Get the full name of the target according to the settings in its
       makefile.  */

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bd9b667bbe83b112a9ea4448605fac980d2d8a68
commit bd9b667bbe83b112a9ea4448605fac980d2d8a68
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jun 12 16:15:10 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:45 2014 -0400

    cmComputeLinkInformation: Remove 'head' argument
    
    It is only ever constructed with the current target as its own 'head'.
    
    Co-Author: Stephen Kelly <steveire at gmail.com>

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 336097b..1aabdeb 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -172,12 +172,10 @@ satisfy dependencies.
 
 //----------------------------------------------------------------------------
 cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget const* target, const std::string& config,
-                       cmTarget const* head)
+::cmComputeLinkDepends(cmTarget const* target, const std::string& config)
 {
   // Store context information.
   this->Target = target;
-  this->HeadTarget = head;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -356,7 +354,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
     {
     // Follow the target dependencies.
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+       entry.Target->GetLinkInterface(this->Config, this->Target))
       {
       const bool isIface =
                       entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@@ -455,7 +453,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   if(entry.Target)
     {
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
+       entry.Target->GetLinkInterface(this->Config, this->Target))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -544,7 +542,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
   cmTarget::LinkImplementation const* impl =
-    this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
+    this->Target->GetLinkImplementation(this->Config, this->Target);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<std::string>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
@@ -955,7 +953,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
     if(cmTarget const* target = this->EntryList[*ni].Target)
       {
       if(cmTarget::LinkInterface const* iface =
-         target->GetLinkInterface(this->Config, this->HeadTarget))
+         target->GetLinkInterface(this->Config, this->Target))
         {
         if(iface->Multiplicity > count)
           {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 13fc993..440dc0d 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -32,8 +32,7 @@ class cmake;
 class cmComputeLinkDepends
 {
 public:
-  cmComputeLinkDepends(cmTarget const* target, const std::string& config,
-                       cmTarget const* head);
+  cmComputeLinkDepends(cmTarget const* target, const std::string& config);
   ~cmComputeLinkDepends();
 
   // Basic information about each link item.
@@ -60,7 +59,6 @@ private:
 
   // Context information.
   cmTarget const* Target;
-  cmTarget const* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator const* GlobalGenerator;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 0ce04a5..bcafe2d 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -239,12 +239,10 @@ because this need be done only for shared libraries without soname-s.
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget const* target, const std::string& config,
-                           cmTarget const* headTarget)
+::cmComputeLinkInformation(cmTarget const* target, const std::string& config)
 {
   // Store context information.
   this->Target = target;
-  this->HeadTarget = headTarget;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -267,7 +265,7 @@ cmComputeLinkInformation
   this->OrderDependentRPath = 0;
 
   // Get the language used for linking this target.
-  this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
+  this->LinkLanguage = this->Target->GetLinkerLanguage(config);
   if(this->LinkLanguage.empty())
     {
     // The Compute method will do nothing, so skip the rest of the
@@ -505,8 +503,7 @@ bool cmComputeLinkInformation::Compute()
     }
 
   // Compute the ordered link line items.
-  cmComputeLinkDepends cld(this->Target, this->Config,
-                           this->HeadTarget);
+  cmComputeLinkDepends cld(this->Target, this->Config);
   cld.SetOldLinkDirMode(this->OldLinkDirMode);
   cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
 
@@ -573,7 +570,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
 {
   // The link closure lists all languages whose implicit info is needed.
   cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
-                                                          this->HeadTarget);
+                                                          this->Target);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
@@ -1972,7 +1969,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
   // present.  This is done even when skipping rpath support.
   {
   cmTarget::LinkClosure const* lc =
-    this->Target->GetLinkClosure(this->Config, this->HeadTarget);
+    this->Target->GetLinkClosure(this->Config, this->Target);
   for(std::vector<std::string>::const_iterator li = lc->Languages.begin();
       li != lc->Languages.end(); ++li)
     {
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index e345fe2..e5d674a 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -29,8 +29,7 @@ class cmOrderDirectories;
 class cmComputeLinkInformation
 {
 public:
-  cmComputeLinkInformation(cmTarget const* target, const std::string& config,
-                           cmTarget const* headTarget);
+  cmComputeLinkInformation(cmTarget const* target, const std::string& config);
   ~cmComputeLinkInformation();
   bool Compute();
 
@@ -75,7 +74,6 @@ private:
 
   // Context information.
   cmTarget const* Target;
-  cmTarget const* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index f6a92bd..32b0777 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -6953,7 +6953,7 @@ cmTarget::GetLinkInformation(const std::string& config) const
     {
     // Compute information for this configuration.
     cmComputeLinkInformation* info =
-      new cmComputeLinkInformation(this, config, this);
+      new cmComputeLinkInformation(this, config);
     if(!info || !info->Compute())
       {
       delete info;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=06328dd58ee3de5d716b0d2b259927da2e173c1d
commit 06328dd58ee3de5d716b0d2b259927da2e173c1d
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jun 12 16:10:00 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:45 2014 -0400

    cmTarget: Remove 'head' argument from GetLinkInformation
    
    No call sites use it anyway.
    
    Co-Author: Stephen Kelly <steveire at gmail.com>

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 566a16a..f6a92bd 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -6943,19 +6943,17 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const std::string& config,
-                             cmTarget const* head) const
+cmTarget::GetLinkInformation(const std::string& config) const
 {
-  cmTarget const* headTarget = head ? head : this;
   // Lookup any existing information for this configuration.
-  TargetConfigPair key(headTarget, cmSystemTools::UpperCase(config));
+  std::string key(cmSystemTools::UpperCase(config));
   cmTargetLinkInformationMap::iterator
     i = this->LinkInformation.find(key);
   if(i == this->LinkInformation.end())
     {
     // Compute information for this configuration.
     cmComputeLinkInformation* info =
-      new cmComputeLinkInformation(this, config, headTarget);
+      new cmComputeLinkInformation(this, config, this);
     if(!info || !info->Compute())
       {
       delete info;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 86108b7..5bcbb3d 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -44,11 +44,9 @@ class cmGeneratorTarget;
 class cmTargetTraceDependencies;
 
 struct cmTargetLinkInformationMap:
-  public std::map<std::pair<cmTarget const* , std::string>,
-                  cmComputeLinkInformation*>
+  public std::map<std::string, cmComputeLinkInformation*>
 {
-  typedef std::map<std::pair<cmTarget const* , std::string>,
-                   cmComputeLinkInformation*> derived;
+  typedef std::map<std::string, cmComputeLinkInformation*> derived;
   cmTargetLinkInformationMap() {}
   cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
   ~cmTargetLinkInformationMap();
@@ -442,8 +440,8 @@ public:
     * install tree.  For example: "\@rpath/" or "\@loader_path/". */
   std::string GetInstallNameDirForInstallTree() const;
 
-  cmComputeLinkInformation* GetLinkInformation(const std::string& config,
-                                               cmTarget const* head = 0) const;
+  cmComputeLinkInformation*
+    GetLinkInformation(const std::string& config) const;
 
   // Get the properties
   cmPropertyMap &GetProperties() const { return this->Properties; }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=56aed7005ae17e979f4635240539041e66d9220a
commit 56aed7005ae17e979f4635240539041e66d9220a
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Jun 11 10:40:36 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:44 2014 -0400

    cmTarget: Cache GetLinkImplementationClosure results
    
    Store them internally and return by reference to avoid duplicate
    computation.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 72c46ed..566a16a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -170,12 +170,15 @@ public:
                                 CachedLinkInterfaceSourcesEntries;
   mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
                                 CachedLinkInterfaceCompileFeaturesEntries;
+  mutable std::map<std::string, std::vector<cmTarget*> >
+                                CachedLinkImplementationClosure;
 
   mutable std::map<std::string, bool> CacheLinkInterfaceIncludeDirectoriesDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileDefinitionsDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileOptionsDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceSourcesDone;
   mutable std::map<std::string, bool> CacheLinkInterfaceCompileFeaturesDone;
+  mutable std::map<std::string, bool> CacheLinkImplementationClosureDone;
 };
 
 //----------------------------------------------------------------------------
@@ -5206,8 +5209,8 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
   assert((impliedByUse ^ explicitlySet)
       || (!impliedByUse && !explicitlySet));
 
-  std::vector<cmTarget*> deps;
-  tgt->GetLinkImplementationClosure(config, deps);
+  std::vector<cmTarget*> const& deps =
+    tgt->GetLinkImplementationClosure(config);
 
   if(deps.empty())
     {
@@ -5422,8 +5425,8 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
                              const std::string& interfaceProperty,
                              const std::string& config)
 {
-  std::vector<cmTarget*> deps;
-  tgt->GetLinkImplementationClosure(config, deps);
+  std::vector<cmTarget*> const& deps =
+    tgt->GetLinkImplementationClosure(config);
 
   if(deps.empty())
     {
@@ -6142,19 +6145,26 @@ void processILibs(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetLinkImplementationClosure(const std::string& config,
-                                      std::vector<cmTarget*> &tgts) const
+std::vector<cmTarget*> const&
+cmTarget::GetLinkImplementationClosure(const std::string& config) const
 {
-  std::set<cmTarget*> emitted;
+  std::vector<cmTarget*>& tgts =
+    this->Internal->CachedLinkImplementationClosure[config];
+  if(!this->Internal->CacheLinkImplementationClosureDone[config])
+    {
+    this->Internal->CacheLinkImplementationClosureDone[config] = true;
+    std::set<cmTarget*> emitted;
 
-  cmTarget::LinkImplementation const* impl
+    cmTarget::LinkImplementation const* impl
       = this->GetLinkImplementationLibraries(config, this);
 
-  for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
-      it != impl->Libraries.end(); ++it)
-    {
-      processILibs(config, this, *it, tgts, emitted);
+    for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
+        it != impl->Libraries.end(); ++it)
+      {
+      processILibs(config, this, *it, tgts , emitted);
+      }
     }
+  return tgts;
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2211338..86108b7 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -276,8 +276,8 @@ public:
   void GetTransitivePropertyTargets(const std::string& config,
                                         cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
-  void GetLinkImplementationClosure(const std::string& config,
-                                    std::vector<cmTarget*> &libs) const;
+  std::vector<cmTarget*> const&
+    GetLinkImplementationClosure(const std::string& config) const;
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cbf689c7dd39dc0952361b63e8322a0408b4569b
commit cbf689c7dd39dc0952361b63e8322a0408b4569b
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Jun 11 10:39:51 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:44 2014 -0400

    cmTarget: Rename Get{TransitiveTarget => LinkImplementation}Closure
    
    The method computes the transitive closure of targets starting with
    the current target link implementation libraries.  Clarify the name.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6759a3d..72c46ed 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5207,7 +5207,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
       || (!impliedByUse && !explicitlySet));
 
   std::vector<cmTarget*> deps;
-  tgt->GetTransitiveTargetClosure(config, deps);
+  tgt->GetLinkImplementationClosure(config, deps);
 
   if(deps.empty())
     {
@@ -5423,7 +5423,7 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
                              const std::string& config)
 {
   std::vector<cmTarget*> deps;
-  tgt->GetTransitiveTargetClosure(config, deps);
+  tgt->GetLinkImplementationClosure(config, deps);
 
   if(deps.empty())
     {
@@ -6142,7 +6142,7 @@ void processILibs(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetTransitiveTargetClosure(const std::string& config,
+void cmTarget::GetLinkImplementationClosure(const std::string& config,
                                       std::vector<cmTarget*> &tgts) const
 {
   std::set<cmTarget*> emitted;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 762323f..2211338 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -276,8 +276,8 @@ public:
   void GetTransitivePropertyTargets(const std::string& config,
                                         cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
-  void GetTransitiveTargetClosure(const std::string& config,
-                                        std::vector<cmTarget*> &libs) const;
+  void GetLinkImplementationClosure(const std::string& config,
+                                    std::vector<cmTarget*> &libs) const;
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2f0004c143455387c4b6ecac2458fcec4d57643f
commit 2f0004c143455387c4b6ecac2458fcec4d57643f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Jun 11 10:39:13 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:44 2014 -0400

    cmTarget: Remove 'head' argument from GetTransitiveTargetClosure
    
    The method is never called with any headTarget besides "this".

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index ff4ded1..6759a3d 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -5207,7 +5207,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
       || (!impliedByUse && !explicitlySet));
 
   std::vector<cmTarget*> deps;
-  tgt->GetTransitiveTargetClosure(config, tgt, deps);
+  tgt->GetTransitiveTargetClosure(config, deps);
 
   if(deps.empty())
     {
@@ -5423,7 +5423,7 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
                              const std::string& config)
 {
   std::vector<cmTarget*> deps;
-  tgt->GetTransitiveTargetClosure(config, tgt, deps);
+  tgt->GetTransitiveTargetClosure(config, deps);
 
   if(deps.empty())
     {
@@ -6143,18 +6143,17 @@ void processILibs(const std::string& config,
 
 //----------------------------------------------------------------------------
 void cmTarget::GetTransitiveTargetClosure(const std::string& config,
-                                      cmTarget const* headTarget,
                                       std::vector<cmTarget*> &tgts) const
 {
   std::set<cmTarget*> emitted;
 
   cmTarget::LinkImplementation const* impl
-      = this->GetLinkImplementationLibraries(config, headTarget);
+      = this->GetLinkImplementationLibraries(config, this);
 
   for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
       it != impl->Libraries.end(); ++it)
     {
-      processILibs(config, headTarget, *it, tgts, emitted);
+      processILibs(config, this, *it, tgts, emitted);
     }
 }
 
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ba3077e..762323f 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -277,7 +277,6 @@ public:
                                         cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
   void GetTransitiveTargetClosure(const std::string& config,
-                                        cmTarget const* headTarget,
                                         std::vector<cmTarget*> &libs) const;
 
   /** The link implementation specifies the direct library

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=962f2c3529d39e293549d16963c59f1508c5a81c
commit 962f2c3529d39e293549d16963c59f1508c5a81c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 11:48:31 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:44 2014 -0400

    cmComputeLinkDepends: Simplify CheckWrongConfigItem implementation
    
    Combine the outer two if() conditions into a single one with &&.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 995f191..336097b 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -999,12 +999,9 @@ void cmComputeLinkDepends::CheckWrongConfigItem(int depender_index,
   // For CMake 2.4 bug-compatibility we need to consider the output
   // directories of targets linked in another configuration as link
   // directories.
-  if(cmTarget const* tgt
-                      = this->FindTargetToLink(depender_index, item))
+  cmTarget const* tgt = this->FindTargetToLink(depender_index, item);
+  if(tgt && !tgt->IsImported())
     {
-    if(!tgt->IsImported())
-      {
-      this->OldWrongConfigItems.insert(tgt);
-      }
+    this->OldWrongConfigItems.insert(tgt);
     }
 }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e838e0a977bf3ca07509f4af39d5f93d598f84f4
commit e838e0a977bf3ca07509f4af39d5f93d598f84f4
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 11:44:49 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 09:14:43 2014 -0400

    cmTarget: Simplify processILibs implementation
    
    Combine the outer two if() conditions into a single one with &&.
    Scope inner lookup result inside its condition.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 9d53fc2..ff4ded1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -6123,22 +6123,19 @@ void processILibs(const std::string& config,
                   std::string const& name,
                   std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
 {
-  if (cmTarget* tgt = headTarget->GetMakefile()
-                                ->FindTargetToUse(name))
+  cmTarget* tgt = headTarget->GetMakefile()
+                                  ->FindTargetToUse(name);
+  if (tgt && emitted.insert(tgt).second)
     {
-    if (emitted.insert(tgt).second)
+    tgts.push_back(tgt);
+    if(cmTarget::LinkInterface const* iface =
+       tgt->GetLinkInterfaceLibraries(config, headTarget))
       {
-      tgts.push_back(tgt);
-      cmTarget::LinkInterface const* iface =
-                          tgt->GetLinkInterfaceLibraries(config, headTarget);
-      if (iface)
+      for(std::vector<std::string>::const_iterator
+          it = iface->Libraries.begin();
+          it != iface->Libraries.end(); ++it)
         {
-        for(std::vector<std::string>::const_iterator
-            it = iface->Libraries.begin();
-            it != iface->Libraries.end(); ++it)
-          {
-          processILibs(config, headTarget, *it, tgts, emitted);
-          }
+        processILibs(config, headTarget, *it, tgts, emitted);
         }
       }
     }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7b85938973782ec6d09b1debe6ad48d3ba887683
commit 7b85938973782ec6d09b1debe6ad48d3ba887683
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 09:49:13 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 08:50:08 2014 -0400

    cmComputeTargetDepends: Remove unused 'linking' argument
    
    The AddInterfaceDepends method is never called with a non-true value for
    its 'linking' argument.  Drop it.

diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index f28217f..8e75807 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -261,8 +261,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
       if(emitted.insert(*lib).second)
         {
         this->AddTargetDepend(depender_index, *lib, true);
-        this->AddInterfaceDepends(depender_index, *lib,
-                                  true, emitted);
+        this->AddInterfaceDepends(depender_index, *lib, emitted);
         }
       }
     }
@@ -304,8 +303,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
       if(emitted.insert(*lib).second)
         {
         this->AddTargetDepend(depender_index, *lib, true);
-        this->AddInterfaceDepends(depender_index, *lib,
-                                  true, emitted);
+        this->AddInterfaceDepends(depender_index, *lib, emitted);
         }
       }
     }
@@ -314,7 +312,6 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
 //----------------------------------------------------------------------------
 void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
                                              const std::string& dependee_name,
-                                             bool linking,
                                              std::set<std::string> &emitted)
 {
   cmTarget const* depender = this->Targets[depender_index];
@@ -323,7 +320,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
   // Skip targets that will not really be linked.  This is probably a
   // name conflict between an external library and an executable
   // within the project.
-  if(linking && dependee &&
+  if(dependee &&
      dependee->GetType() == cmTarget::EXECUTABLE &&
      !dependee->IsExecutableWithExports())
     {
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 7553816..b99199f 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -53,7 +53,7 @@ private:
   bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
   void AddInterfaceDepends(int depender_index,
                            const std::string& dependee_name,
-                           bool linking, std::set<std::string> &emitted);
+                           std::set<std::string> &emitted);
   void AddInterfaceDepends(int depender_index, cmTarget const* dependee,
                            const std::string& config,
                            std::set<std::string> &emitted);

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8d15a1bbfbefff919d8a7aa0d04f54d08d1f1a11
commit 8d15a1bbfbefff919d8a7aa0d04f54d08d1f1a11
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 11:31:11 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 08:50:08 2014 -0400

    cmTarget: De-duplicate library list expansion
    
    Create an ExpandLinkItems method to handle evaluation of generator
    expressions in a library list and expansion of the ;-list into a vector.
    Replace some duplicate copies of the implementation with calls to the
    new helper.

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 3b7bfaf..9d53fc2 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -3692,6 +3692,23 @@ void cmTarget::ComputeLinkClosure(const std::string& config, LinkClosure& lc,
 }
 
 //----------------------------------------------------------------------------
+void cmTarget::ExpandLinkItems(std::string const& prop,
+                               std::string const& value,
+                               std::string const& config,
+                               cmTarget const* headTarget,
+                               std::vector<std::string>& libs) const
+{
+  cmGeneratorExpression ge;
+  cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0);
+  cmSystemTools::ExpandListArgument(ge.Parse(value)->Evaluate(
+                                      this->Makefile,
+                                      config,
+                                      false,
+                                      headTarget,
+                                      this, &dagChecker), libs);
+}
+
+//----------------------------------------------------------------------------
 const char* cmTarget::GetSuffixVariableInternal(bool implib) const
 {
   switch(this->GetType())
@@ -5870,19 +5887,8 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
     }
   if(propertyLibs)
     {
-    cmGeneratorExpression ge;
-
-    cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
-                                        linkProp, 0, 0);
-    cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
-                                       ->Evaluate(this->Makefile,
-                                                  desired_config,
-                                                  false,
-                                                  headTarget,
-                                                  this,
-                                                  &dagChecker),
-                                    info.LinkInterface.Libraries);
+    this->ExpandLinkItems(linkProp, propertyLibs, desired_config,
+                          headTarget, info.LinkInterface.Libraries);
     }
   }
   if(this->GetType() == INTERFACE_LIBRARY)
@@ -6302,15 +6308,8 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
   if(explicitLibraries)
     {
     // The interface libraries have been explicitly set.
-    cmGeneratorExpression ge;
-    cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                               linkIfaceProp, 0, 0);
-    cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
-                                        this->Makefile,
-                                        config,
-                                        false,
-                                        headTarget,
-                                        this, &dagChecker), iface.Libraries);
+    this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config,
+                          headTarget, iface.Libraries);
     }
   else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
         || this->PolicyStatusCMP0022 == cmPolicies::OLD)
@@ -6328,19 +6327,13 @@ const char* cmTarget::ComputeLinkInterfaceLibraries(const std::string& config,
       {
       // Compare the link implementation fallback link interface to the
       // preferred new link interface property and warn if different.
-      cmGeneratorExpression ge;
-      cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
-                                      "INTERFACE_LINK_LIBRARIES", 0, 0);
       std::vector<std::string> ifaceLibs;
-      const char* newExplicitLibraries =
-        this->GetProperty("INTERFACE_LINK_LIBRARIES");
-      cmSystemTools::ExpandListArgument(
-        ge.Parse(newExplicitLibraries)->Evaluate(this->Makefile,
-                                                 config,
-                                                 false,
-                                                 headTarget,
-                                                 this, &dagChecker),
-        ifaceLibs);
+      std::string newProp = "INTERFACE_LINK_LIBRARIES";
+      if(const char* newExplicitLibraries = this->GetProperty(newProp))
+        {
+        this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+                              headTarget, ifaceLibs);
+        }
       if (ifaceLibs != impl->Libraries)
         {
         std::string oldLibraries;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3b1b40a..ba3077e 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -764,6 +764,10 @@ private:
   void ComputeLinkClosure(const std::string& config, LinkClosure& lc,
                           cmTarget const* head) const;
 
+  void ExpandLinkItems(std::string const& prop, std::string const& value,
+                       std::string const& config, cmTarget const* headTarget,
+                       std::vector<std::string>& libs) const;
+
   std::string ProcessSourceItemCMP0049(const std::string& s);
 
   void ClearLinkMaps();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6354df92b12746dcb0f6fa263af2adf649cf1f3f
commit 6354df92b12746dcb0f6fa263af2adf649cf1f3f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Jun 16 09:36:24 2014 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Jun 23 08:50:08 2014 -0400

    cmTarget: Remove unused GetInterfaceLinkLibraries method

diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 01edde9..3b7bfaf 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1229,29 +1229,6 @@ void cmTarget::GetDirectLinkLibraries(const std::string& config,
 }
 
 //----------------------------------------------------------------------------
-void cmTarget::GetInterfaceLinkLibraries(const std::string& config,
-                                         std::vector<std::string> &libs,
-                                         cmTarget const* head) const
-{
-  const char *prop = this->GetProperty("INTERFACE_LINK_LIBRARIES");
-  if (prop)
-    {
-    cmGeneratorExpression ge;
-    const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
-
-    cmGeneratorExpressionDAGChecker dagChecker(
-                                        this->GetName(),
-                                        "INTERFACE_LINK_LIBRARIES", 0, 0);
-    cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
-                                        config,
-                                        false,
-                                        head,
-                                        &dagChecker),
-                                      libs);
-    }
-}
-
-//----------------------------------------------------------------------------
 std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
                                   cmTarget::LinkLibraryType llt) const
 {
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 2d51835..3b1b40a 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -162,9 +162,6 @@ public:
   void GetDirectLinkLibraries(const std::string& config,
                               std::vector<std::string> &,
                               cmTarget const* head) const;
-  void GetInterfaceLinkLibraries(const std::string& config,
-                              std::vector<std::string> &,
-                              cmTarget const* head) const;
 
   /** Compute the link type to use for the given configuration.  */
   LinkLibraryType ComputeLinkType(const std::string& config) const;

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

Summary of changes:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list