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  d491ccc926f3fdaf2cef1329cc9bfc77a87568ad (commit)
       via  7af053923fa52575709165b01ed674e0588f11e8 (commit)
       via  6001e674e0eb1e8de7e26c21cc2683f0967f23d8 (commit)
      from  dc40de0fc18c30d271bdca360571f59d724f938f (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=d491ccc926f3fdaf2cef1329cc9bfc77a87568ad
commit d491ccc926f3fdaf2cef1329cc9bfc77a87568ad
Merge: dc40de0 7af0539
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Mon Jan 7 15:11:55 2013 -0500
Commit:     CMake Topic Stage <kwro...@kitware.com>
CommitDate: Mon Jan 7 15:11:55 2013 -0500

    Merge topic 'LINK_LIBRARIES-property' into next
    
    7af0539 Populate the LINK_LIBRARIES property when linking to targets.
    6001e67 Add a HEAD-target to target linking API.


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7af053923fa52575709165b01ed674e0588f11e8
commit 7af053923fa52575709165b01ed674e0588f11e8
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Thu Dec 6 12:14:03 2012 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Jan 7 21:11:12 2013 +0100

    Populate the LINK_LIBRARIES property when linking to targets.
    
    This will be used later to populate the INTERFACE_LINK_LIBRARIES
    property when exporting targets, and will later allow use of
    generator expressions when linking to libraries with
    target_link_libraries.
    
    Also make targets depend on the (config-specific) union of dependencies.
    
    CMake now allows linking to dependencies or not
    depending on the config. However, generated buildsystems are not
    capable of processing config-specific dependencies, so the targets
    depend on the union of dependencies for all configs.

diff --git a/Source/cmComputeTargetDepends.cxx 
b/Source/cmComputeTargetDepends.cxx
index c3a75e4..8fd95b9 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -200,25 +200,51 @@ void cmComputeTargetDepends::CollectTargetDepends(int 
depender_index)
   // Get the depender.
   cmTarget* depender = this->Targets[depender_index];
 
-  // Loop over all targets linked directly.
+  // Loop over all targets linked directly in all configs.
+  // We need to make targets depend on the union of all config-specific
+  // dependencies in all targets, because the generated build-systems can't
+  // deal with config-specific dependencies.
   {
-  cmTarget::LinkLibraryVectorType const& tlibs =
-    depender->GetOriginalLinkLibraries();
   std::set<cmStdString> emitted;
+  {
+  std::vector<std::string> tlibs;
+  depender->GetDirectLinkLibraries(0, tlibs, depender);
   // A target should not depend on itself.
   emitted.insert(depender->GetName());
-  for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
+  for(std::vector<std::string>::const_iterator lib = tlibs.begin();
       lib != tlibs.end(); ++lib)
     {
     // Don't emit the same library twice for this target.
-    if(emitted.insert(lib->first).second)
+    if(emitted.insert(*lib).second)
       {
-      this->AddTargetDepend(depender_index, lib->first.c_str(), true);
-      this->AddInterfaceDepends(depender_index, lib->first.c_str(),
+      this->AddTargetDepend(depender_index, lib->c_str(), true);
+      this->AddInterfaceDepends(depender_index, lib->c_str(),
                                 true, emitted);
       }
     }
   }
+  std::vector<std::string> configs;
+  depender->GetMakefile()->GetConfigurations(configs);
+  for (std::vector<std::string>::const_iterator it = configs.begin();
+    it != configs.end(); ++it)
+    {
+    std::vector<std::string> tlibs;
+    depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
+    // 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)
+      {
+      // Don't emit the same library twice for this target.
+      if(emitted.insert(*lib).second)
+        {
+        this->AddTargetDepend(depender_index, lib->c_str(), true);
+        this->AddInterfaceDepends(depender_index, lib->c_str(),
+                                  true, emitted);
+        }
+      }
+    }
+  }
 
   // Loop over all utility dependencies.
   {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1338ec4..25054c5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -520,6 +520,22 @@ void cmTarget::DefineProperties(cmake *cm)
      "undefined behavior.");
 
   cm->DefineProperty
+    ("LINK_LIBRARIES", cmProperty::TARGET,
+     "List of direct link dependencies.",
+     "This property specifies the list of libraries or targets which will be "
+     "used for linking. "
+     "In addition to accepting values from the target_link_libraries "
+     "command, values may be set directly on any target using the "
+     "set_property command. "
+     "\n"
+     "The target property values are used by the generators to set "
+     "the link libraries for the compiler.  "
+     "See also the target_link_libraries command.\n"
+     "Contents of LINK_LIBRARIES may use \"generator expressions\" with "
+     "the syntax \"$<...>\".  "
+     CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS);
+
+  cm->DefineProperty
     ("INCLUDE_DIRECTORIES", cmProperty::TARGET,
      "List of preprocessor include file search directories.",
      "This property specifies the list of directories given "
@@ -2140,6 +2156,66 @@ bool cmTarget::NameResolvesToFramework(const 
std::string& libname)
 }
 
 //----------------------------------------------------------------------------
+void cmTarget::GetDirectLinkLibraries(const char *config,
+                            std::vector<std::string> &libs, cmTarget *head)
+{
+  const char *prop = this->GetProperty("LINK_LIBRARIES");
+  if (prop)
+    {
+    cmListFileBacktrace lfbt;
+    cmGeneratorExpression ge(lfbt);
+
+    cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+                                        this->GetName(),
+                                        "LINK_LIBRARIES", 0, 0);
+    cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
+                                        config,
+                                        false,
+                                        head,
+                                        &dagChecker),
+                                      libs);
+    }
+}
+
+//----------------------------------------------------------------------------
+std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value,
+                                  cmTarget::LinkLibraryType llt)
+{
+  if (llt == GENERAL)
+    {
+    return value;
+    }
+
+  // Get the list of configurations considered to be DEBUG.
+  std::vector<std::string> const& debugConfigs =
+                      this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+
+  std::string configString = "$<CONFIG:" + debugConfigs[0] + ">";
+
+  if (debugConfigs.size() > 1)
+    {
+    for(std::vector<std::string>::const_iterator
+          li = debugConfigs.begin() + 1; li != debugConfigs.end(); ++li)
+      {
+      configString += ",$<CONFIG:" + *li + ">";
+      }
+    configString = "$<OR:" + configString + ">";
+    }
+
+  if (llt == OPTIMIZED)
+    {
+    configString = "$<NOT:" + configString + ">";
+    }
+  return "$<" + configString + ":" + value + ">";
+}
+
+//----------------------------------------------------------------------------
+static std::string targetNameGenex(const char *lib)
+{
+  return std::string("$<TARGET_NAME:") + lib + ">";
+}
+
+//----------------------------------------------------------------------------
 void cmTarget::AddLinkLibrary(cmMakefile& mf,
                               const char *target, const char* lib,
                               LinkLibraryType llt)
@@ -2149,6 +2225,18 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
     {
     return;
     }
+
+  {
+  cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
+  const bool isNonImportedTarget = tgt && !tgt->IsImported();
+
+  std::string libName = isNonImportedTarget ? targetNameGenex(lib)
+                                          : std::string(lib);
+  this->AppendProperty("LINK_LIBRARIES",
+                       this->GetDebugGeneratorExpressions(libName,
+                                                          llt).c_str());
+  }
+
   cmTarget::LibraryID tmp;
   tmp.first = lib;
   tmp.second = llt;
@@ -4884,26 +4972,23 @@ void cmTarget::ComputeLinkImplementation(const char* 
config,
                                          LinkImplementation& impl,
                                          cmTarget *head)
 {
-  (void)head;
   // Compute which library configuration to link.
   cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
 
   // Collect libraries directly linked in this configuration.
-  LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries();
-  for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin();
+  std::vector<std::string> llibs;
+  this->GetDirectLinkLibraries(config, llibs, head);
+  for(std::vector<std::string>::const_iterator li = llibs.begin();
       li != llibs.end(); ++li)
     {
     // Skip entries that resolve to the target itself or are empty.
-    std::string item = this->CheckCMP0004(li->first);
+    std::string item = this->CheckCMP0004(*li);
     if(item == this->GetName() || item.empty())
       {
       continue;
       }
-    if(li->second == cmTarget::GENERAL || li->second == linkType)
-      {
-      // The entry is meant for this configuration.
-      impl.Libraries.push_back(item);
-      }
+    // The entry is meant for this configuration.
+    impl.Libraries.push_back(item);
     }
 
   LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 29c73b6..d4069fa 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -168,6 +168,9 @@ public:
   return this->LinkLibraries;}
   const LinkLibraryVectorType &GetOriginalLinkLibraries() const
     {return this->OriginalLinkLibraries;}
+  void GetDirectLinkLibraries(const char *config,
+                              std::vector<std::string> &,
+                              cmTarget *head);
 
   /** Compute the link type to use for the given configuration.  */
   LinkLibraryType ComputeLinkType(const char* config);
@@ -622,6 +625,9 @@ private:
 
   void ProcessSourceExpression(std::string const& expr);
 
+  std::string GetDebugGeneratorExpressions(const std::string &value,
+                                  cmTarget::LinkLibraryType llt);
+
   // The cmMakefile instance that owns this target.  This should
   // always be set.
   cmMakefile* Makefile;
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt 
b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 60b36fc..63ae675 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -34,6 +34,13 @@ generate_export_header(depB)
 
 target_link_libraries(depB LINK_PRIVATE depA)
 
+add_library(libgenex SHARED libgenex.cpp)
+generate_export_header(libgenex)
+
+set_property(TARGET depB APPEND PROPERTY
+  LINK_LIBRARIES $<1:libgenex>
+)
+
 add_library(depC SHARED depC.cpp)
 generate_export_header(depC)
 
diff --git a/Tests/CMakeCommands/target_link_libraries/depB.cpp 
b/Tests/CMakeCommands/target_link_libraries/depB.cpp
index 1bbe38b..4f46552 100644
--- a/Tests/CMakeCommands/target_link_libraries/depB.cpp
+++ b/Tests/CMakeCommands/target_link_libraries/depB.cpp
@@ -3,9 +3,13 @@
 
 #include "depA.h"
 
+#include "libgenex.h"
+
 int DepB::foo()
 {
   DepA a;
 
-  return a.foo();
+  LibGenex lg;
+
+  return a.foo() + lg.foo();
 }
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.cpp 
b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp
new file mode 100644
index 0000000..c925c08
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp
@@ -0,0 +1,7 @@
+
+#include "libgenex.h"
+
+int LibGenex::foo()
+{
+  return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.h 
b/Tests/CMakeCommands/target_link_libraries/libgenex.h
new file mode 100644
index 0000000..733f9b6
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/libgenex.h
@@ -0,0 +1,12 @@
+
+#include "libgenex_export.h"
+
+#ifndef LIBGENEX_H
+#define LIBGENEX_H
+
+struct LIBGENEX_EXPORT LibGenex
+{
+  int foo();
+};
+
+#endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6001e674e0eb1e8de7e26c21cc2683f0967f23d8
commit 6001e674e0eb1e8de7e26c21cc2683f0967f23d8
Author:     Stephen Kelly <steve...@gmail.com>
AuthorDate: Fri Jan 4 13:31:01 2013 +0100
Commit:     Stephen Kelly <steve...@gmail.com>
CommitDate: Mon Jan 7 21:11:12 2013 +0100

    Add a HEAD-target to target linking API.
    
    It will be used to evaluate generator expressions with proper
    handling of mapped configurations and is used as the source target
    of properties.
    
    This requires that caching is done with a key of a pair of target
    and config, instead of just config, because now the result also
    depends on the target.
    
    Removing the caching entirely is not an option because it slows cmake
    down considerably.

diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 055aab0..dec2b54 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -172,10 +172,11 @@ satisfy dependencies.
 
 //----------------------------------------------------------------------------
 cmComputeLinkDepends
-::cmComputeLinkDepends(cmTarget* target, const char* config)
+::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head)
 {
   // Store context information.
   this->Target = target;
+  this->HeadTarget = head;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& 
qe)
     {
     // Follow the target dependencies.
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config))
+       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
       {
       // This target provides its own link interface information.
       this->AddLinkEntries(depender_index, iface->Libraries);
@@ -444,7 +445,7 @@ void 
cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
   if(entry.Target)
     {
     if(cmTarget::LinkInterface const* iface =
-       entry.Target->GetLinkInterface(this->Config))
+       entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
       {
       // Follow public and private dependencies transitively.
       this->FollowSharedDeps(index, iface, true);
@@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries()
 {
   // Add direct link dependencies in this configuration.
   cmTarget::LinkImplementation const* impl =
-    this->Target->GetLinkImplementation(this->Config);
+    this->Target->GetLinkImplementation(this->Config, this->HeadTarget);
   this->AddLinkEntries(-1, impl->Libraries);
   for(std::vector<std::string>::const_iterator
         wi = impl->WrongConfigLibraries.begin();
@@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList 
const& nl)
     if(cmTarget* target = this->EntryList[*ni].Target)
       {
       if(cmTarget::LinkInterface const* iface =
-         target->GetLinkInterface(this->Config))
+         target->GetLinkInterface(this->Config, this->HeadTarget))
         {
         if(iface->Multiplicity > count)
           {
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 80a0454..1d5d1b9 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -32,7 +32,7 @@ class cmake;
 class cmComputeLinkDepends
 {
 public:
-  cmComputeLinkDepends(cmTarget* target, const char* config);
+  cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head);
   ~cmComputeLinkDepends();
 
   // Basic information about each link item.
@@ -59,6 +59,7 @@ private:
 
   // Context information.
   cmTarget* Target;
+  cmTarget* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmComputeLinkInformation.cxx 
b/Source/cmComputeLinkInformation.cxx
index d8ffb5e..504c6e7 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -239,10 +239,12 @@ because this need be done only for shared libraries 
without soname-s.
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation
-::cmComputeLinkInformation(cmTarget* target, const char* config)
+::cmComputeLinkInformation(cmTarget* target, const char* config,
+                           cmTarget *headTarget)
 {
   // Store context information.
   this->Target = target;
+  this->HeadTarget = headTarget;
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = this->Makefile->GetLocalGenerator();
   this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
@@ -265,7 +267,7 @@ cmComputeLinkInformation
   this->OrderDependentRPath = 0;
 
   // Get the language used for linking this target.
-  this->LinkLanguage = this->Target->GetLinkerLanguage(config);
+  this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget);
   if(!this->LinkLanguage)
     {
     // The Compute method will do nothing, so skip the rest of the
@@ -503,7 +505,7 @@ bool cmComputeLinkInformation::Compute()
     }
 
   // Compute the ordered link line items.
-  cmComputeLinkDepends cld(this->Target, this->Config);
+  cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget);
   cld.SetOldLinkDirMode(this->OldLinkDirMode);
   cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
 
@@ -569,7 +571,8 @@ 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);
+  cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config,
+                                                          this->HeadTarget);
   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 e0078af..1a76922 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -29,7 +29,8 @@ class cmOrderDirectories;
 class cmComputeLinkInformation
 {
 public:
-  cmComputeLinkInformation(cmTarget* target, const char* config);
+  cmComputeLinkInformation(cmTarget* target, const char* config,
+                           cmTarget* headTarget);
   ~cmComputeLinkInformation();
   bool Compute();
 
@@ -74,6 +75,7 @@ private:
 
   // Context information.
   cmTarget* Target;
+  cmTarget* HeadTarget;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
   cmGlobalGenerator* GlobalGenerator;
diff --git a/Source/cmComputeTargetDepends.cxx 
b/Source/cmComputeTargetDepends.cxx
index 3b15ec1..c3a75e4 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -244,8 +244,9 @@ void cmComputeTargetDepends::AddInterfaceDepends(int 
depender_index,
                                                  const char *config,
                                                std::set<cmStdString> &emitted)
 {
+  cmTarget* depender = this->Targets[depender_index];
   if(cmTarget::LinkInterface const* iface =
-                                dependee->GetLinkInterface(config))
+                                dependee->GetLinkInterface(config, depender))
     {
     for(std::vector<std::string>::const_iterator
         lib = iface->Libraries.begin();
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2b133be..90c0c41 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -357,7 +357,8 @@ cmExportFileGenerator
     }
 
   // Add the transitive link dependencies for this configuration.
-  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
+  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+                                                                     target))
     {
     this->SetImportLinkProperty(suffix, target,
                                 "IMPORTED_LINK_INTERFACE_LANGUAGES",
diff --git a/Source/cmGlobalXCodeGenerator.cxx 
b/Source/cmGlobalXCodeGenerator.cxx
index b2d325c..4c26b82 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1206,7 +1206,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.GetLinkImplementation("NOCONFIG", &cmtarget);
   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 ca53a39..1338ec4 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -72,6 +72,11 @@ struct cmTarget::ImportInfo
   cmTarget::LinkInterface LinkInterface;
 };
 
+struct TargetConfigPair : public std::pair<cmTarget*, std::string> {
+  TargetConfigPair(cmTarget* tgt, const std::string &config)
+    : std::pair<cmTarget*, std::string>(tgt, config) {}
+};
+
 //----------------------------------------------------------------------------
 class cmTargetInternals
 {
@@ -100,20 +105,24 @@ public:
     OptionalLinkInterface(): Exists(false) {}
     bool Exists;
   };
-  typedef std::map<cmStdString, OptionalLinkInterface> LinkInterfaceMapType;
+  typedef std::map<TargetConfigPair, OptionalLinkInterface>
+                                                          LinkInterfaceMapType;
   LinkInterfaceMapType LinkInterfaceMap;
 
   typedef std::map<cmStdString, cmTarget::OutputInfo> OutputInfoMapType;
   OutputInfoMapType OutputInfoMap;
 
-  typedef std::map<cmStdString, cmTarget::ImportInfo> ImportInfoMapType;
+  typedef std::map<TargetConfigPair, cmTarget::ImportInfo>
+                                                            ImportInfoMapType;
   ImportInfoMapType ImportInfoMap;
 
   // Cache link implementation computation from each configuration.
-  typedef std::map<cmStdString, cmTarget::LinkImplementation> LinkImplMapType;
+  typedef std::map<TargetConfigPair,
+                   cmTarget::LinkImplementation> LinkImplMapType;
   LinkImplMapType LinkImplMap;
 
-  typedef std::map<cmStdString, cmTarget::LinkClosure> LinkClosureMapType;
+  typedef std::map<TargetConfigPair, cmTarget::LinkClosure>
+                                                          LinkClosureMapType;
   LinkClosureMapType LinkClosureMap;
 
   struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@@ -3024,8 +3033,11 @@ class cmTargetCollectLinkLanguages
 {
 public:
   cmTargetCollectLinkLanguages(cmTarget* target, const char* config,
-                               std::set<cmStdString>& languages):
-    Config(config), Languages(languages) { this->Visited.insert(target); }
+                               std::set<cmStdString>& languages,
+                               cmTarget* head):
+    Config(config), Languages(languages), HeadTarget(head)
+  { this->Visited.insert(target); }
+
   void Visit(cmTarget* target)
     {
     if(!target || !this->Visited.insert(target).second)
@@ -3034,7 +3046,7 @@ public:
       }
 
     cmTarget::LinkInterface const* iface =
-      target->GetLinkInterface(this->Config);
+      target->GetLinkInterface(this->Config, this->HeadTarget);
     if(!iface) { return; }
 
     for(std::vector<std::string>::const_iterator
@@ -3053,26 +3065,30 @@ public:
 private:
   const char* Config;
   std::set<cmStdString>& Languages;
+  cmTarget* HeadTarget;
   std::set<cmTarget*> Visited;
 };
 
 //----------------------------------------------------------------------------
-const char* cmTarget::GetLinkerLanguage(const char* config)
+const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head)
 {
-  const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str();
+  cmTarget *headTarget = head ? head : this;
+  const char* lang = this->GetLinkClosure(config, headTarget)
+                                                    ->LinkerLanguage.c_str();
   return *lang? lang : 0;
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
+cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config,
+                                                      cmTarget *head)
 {
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : ""));
   cmTargetInternals::LinkClosureMapType::iterator
     i = this->Internal->LinkClosureMap.find(key);
   if(i == this->Internal->LinkClosureMap.end())
     {
     LinkClosure lc;
-    this->ComputeLinkClosure(config, lc);
+    this->ComputeLinkClosure(config, lc, head);
     cmTargetInternals::LinkClosureMapType::value_type entry(key, lc);
     i = this->Internal->LinkClosureMap.insert(entry).first;
     }
@@ -3133,11 +3149,12 @@ public:
 };
 
 //----------------------------------------------------------------------------
-void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
+void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc,
+                                  cmTarget *head)
 {
   // Get languages built in this target.
   std::set<cmStdString> languages;
-  LinkImplementation const* impl = this->GetLinkImplementation(config);
+  LinkImplementation const* impl = this->GetLinkImplementation(config, head);
   for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
       li != impl->Languages.end(); ++li)
     {
@@ -3145,7 +3162,7 @@ void cmTarget::ComputeLinkClosure(const char* config, 
LinkClosure& lc)
     }
 
   // Add interface languages from linked targets.
-  cmTargetCollectLinkLanguages cll(this, config, languages);
+  cmTargetCollectLinkLanguages cll(this, config, languages, head);
   for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
       li != impl->Libraries.end(); ++li)
     {
@@ -3284,7 +3301,8 @@ bool cmTarget::HasSOName(const char* config)
   return ((this->GetType() == cmTarget::SHARED_LIBRARY ||
            this->GetType() == cmTarget::MODULE_LIBRARY) &&
           !this->GetPropertyAsBool("NO_SONAME") &&
-          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
+          this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config,
+                                                                this)));
 }
 
 //----------------------------------------------------------------------------
@@ -3293,7 +3311,7 @@ std::string cmTarget::GetSOName(const char* config)
   if(this->IsImported())
     {
     // Lookup the imported soname.
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
       {
       if(info->NoSOName)
         {
@@ -3330,7 +3348,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const 
char* config)
 {
   if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
       {
       return info->NoSOName;
       }
@@ -3444,7 +3462,7 @@ std::string cmTarget::NormalGetFullPath(const char* 
config, bool implib,
 std::string cmTarget::ImportedGetFullPath(const char* config, bool implib)
 {
   std::string result;
-  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+  if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this))
     {
     result = implib? info->ImportLibrary : info->Location;
     }
@@ -3529,7 +3547,7 @@ void cmTarget::GetFullNameInternal(const char* config,
   const char* suffixVar = this->GetSuffixVariableInternal(implib);
 
   // Check for language-specific default prefix and suffix.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     if(!targetSuffix && suffixVar && *suffixVar)
       {
@@ -3900,7 +3918,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config)
     }
 
   // Check for rpath support on this platform.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
     flagVar += ll;
@@ -4322,7 +4340,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
 
   // Enable if the rpath flag uses a separator and the target uses ELF
   // binaries.
-  if(const char* ll = this->GetLinkerLanguage(config))
+  if(const char* ll = this->GetLinkerLanguage(config, this))
     {
     std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
     sepVar += ll;
@@ -4346,7 +4364,7 @@ bool cmTarget::IsChrpathUsed(const char* config)
 
 //----------------------------------------------------------------------------
 cmTarget::ImportInfo const*
-cmTarget::GetImportInfo(const char* config)
+cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
 {
   // There is no imported information for non-imported targets.
   if(!this->IsImported())
@@ -4365,14 +4383,16 @@ cmTarget::GetImportInfo(const char* config)
     {
     config_upper = "NOCONFIG";
     }
+  TargetConfigPair key(headTarget, config_upper);
   typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType;
+
   ImportInfoMapType::const_iterator i =
-    this->Internal->ImportInfoMap.find(config_upper);
+    this->Internal->ImportInfoMap.find(key);
   if(i == this->Internal->ImportInfoMap.end())
     {
     ImportInfo info;
-    this->ComputeImportInfo(config_upper, info);
-    ImportInfoMapType::value_type entry(config_upper, info);
+    this->ComputeImportInfo(config_upper, info, headTarget);
+    ImportInfoMapType::value_type entry(key, info);
     i = this->Internal->ImportInfoMap.insert(entry).first;
     }
 
@@ -4511,8 +4531,10 @@ bool cmTarget::GetMappedConfig(std::string const& 
desired_config,
 
 //----------------------------------------------------------------------------
 void cmTarget::ComputeImportInfo(std::string const& desired_config,
-                                 ImportInfo& info)
+                                 ImportInfo& info,
+                                 cmTarget *headTarget)
 {
+  (void)headTarget;
   // This method finds information about an imported target from its
   // properties.  The "IMPORTED_" namespace is reserved for properties
   // defined by the project exporting the target.
@@ -4669,12 +4691,13 @@ void cmTarget::ComputeImportInfo(std::string const& 
desired_config,
 }
 
 //----------------------------------------------------------------------------
-cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config)
+cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
+                                                      cmTarget *head)
 {
   // Imported targets have their own link interface.
   if(this->IsImported())
     {
-    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
+    if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
       {
       return &info->LinkInterface;
       }
@@ -4690,14 +4713,15 @@ cmTarget::LinkInterface const* 
cmTarget::GetLinkInterface(const char* config)
     }
 
   // Lookup any existing link interface for this configuration.
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
   cmTargetInternals::LinkInterfaceMapType::iterator
     i = this->Internal->LinkInterfaceMap.find(key);
   if(i == this->Internal->LinkInterfaceMap.end())
     {
     // Compute the link interface for this configuration.
     cmTargetInternals::OptionalLinkInterface iface;
-    iface.Exists = this->ComputeLinkInterface(config, iface);
+    iface.Exists = this->ComputeLinkInterface(config, iface, head);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
@@ -4708,7 +4732,8 @@ cmTarget::LinkInterface const* 
cmTarget::GetLinkInterface(const char* config)
 }
 
 //----------------------------------------------------------------------------
-bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface)
+bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
+                                    cmTarget *headTarget)
 {
   // Construct the property name suffix for this configuration.
   std::string suffix = "_";
@@ -4765,7 +4790,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, 
LinkInterface& iface)
         {
         emitted.insert(*li);
         }
-      LinkImplementation const* impl = this->GetLinkImplementation(config);
+      LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                                headTarget);
       for(std::vector<std::string>::const_iterator
             li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
         {
@@ -4793,7 +4819,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, 
LinkInterface& iface)
   else
     {
     // The link implementation is the default link interface.
-    LinkImplementation const* impl = this->GetLinkImplementation(config);
+    LinkImplementation const* impl = this->GetLinkImplementation(config,
+                                                              headTarget);
     iface.Libraries = impl->Libraries;
     iface.WrongConfigLibraries = impl->WrongConfigLibraries;
     if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -4825,7 +4852,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, 
LinkInterface& iface)
 
 //----------------------------------------------------------------------------
 cmTarget::LinkImplementation const*
-cmTarget::GetLinkImplementation(const char* config)
+cmTarget::GetLinkImplementation(const char* config, cmTarget *head)
 {
   // There is no link implementation for imported targets.
   if(this->IsImported())
@@ -4834,14 +4861,15 @@ cmTarget::GetLinkImplementation(const char* config)
     }
 
   // Lookup any existing link implementation for this configuration.
-  std::string key = cmSystemTools::UpperCase(config? config : "");
+  TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
+
   cmTargetInternals::LinkImplMapType::iterator
     i = this->Internal->LinkImplMap.find(key);
   if(i == this->Internal->LinkImplMap.end())
     {
     // Compute the link implementation for this configuration.
     LinkImplementation impl;
-    this->ComputeLinkImplementation(config, impl);
+    this->ComputeLinkImplementation(config, impl, head);
 
     // Store the information for this configuration.
     cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
@@ -4853,8 +4881,10 @@ cmTarget::GetLinkImplementation(const char* config)
 
 //----------------------------------------------------------------------------
 void cmTarget::ComputeLinkImplementation(const char* config,
-                                         LinkImplementation& impl)
+                                         LinkImplementation& impl,
+                                         cmTarget *head)
 {
+  (void)head;
   // Compute which library configuration to link.
   cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
 
@@ -4977,16 +5007,19 @@ std::string cmTarget::CheckCMP0004(std::string const& 
item)
 
 //----------------------------------------------------------------------------
 cmComputeLinkInformation*
-cmTarget::GetLinkInformation(const char* config)
+cmTarget::GetLinkInformation(const char* config, cmTarget *head)
 {
+  cmTarget *headTarget = head ? head : this;
   // Lookup any existing information for this configuration.
-  std::map<cmStdString, cmComputeLinkInformation*>::iterator
-    i = this->LinkInformation.find(config?config:"");
+  TargetConfigPair key(headTarget,
+                                  cmSystemTools::UpperCase(config?config:""));
+  cmTargetLinkInformationMap::iterator
+    i = this->LinkInformation.find(key);
   if(i == this->LinkInformation.end())
     {
     // Compute information for this configuration.
     cmComputeLinkInformation* info =
-      new cmComputeLinkInformation(this, config);
+      new cmComputeLinkInformation(this, config, headTarget);
     if(!info || !info->Compute())
       {
       delete info;
@@ -4994,8 +5027,7 @@ cmTarget::GetLinkInformation(const char* config)
       }
 
     // Store the information for this configuration.
-    std::map<cmStdString, cmComputeLinkInformation*>::value_type
-      entry(config?config:"", info);
+    cmTargetLinkInformationMap::value_type entry(key, info);
     i = this->LinkInformation.insert(entry).first;
     }
   return i->second;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 52d5ca6..29c73b6 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -25,11 +25,13 @@ class cmSourceFile;
 class cmGlobalGenerator;
 class cmComputeLinkInformation;
 class cmListFileBacktrace;
+class cmTarget;
 
 struct cmTargetLinkInformationMap:
-  public std::map<cmStdString, cmComputeLinkInformation*>
+  public std::map<std::pair<cmTarget*, std::string>, cmComputeLinkInformation*>
 {
-  typedef std::map<cmStdString, cmComputeLinkInformation*> derived;
+  typedef std::map<std::pair<cmTarget*, std::string>,
+                   cmComputeLinkInformation*> derived;
   cmTargetLinkInformationMap() {}
   cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
   ~cmTargetLinkInformationMap();
@@ -258,7 +260,8 @@ public:
 
   /** Get the link interface for the given configuration.  Returns 0
       if the target cannot be linked.  */
-  LinkInterface const* GetLinkInterface(const char* config);
+  LinkInterface const* GetLinkInterface(const char* config,
+                                        cmTarget *headTarget);
 
   /** The link implementation specifies the direct library
       dependencies needed by the object files of the target.  */
@@ -274,7 +277,8 @@ public:
     // Needed only for OLD behavior of CMP0003.
     std::vector<std::string> WrongConfigLibraries;
   };
-  LinkImplementation const* GetLinkImplementation(const char* config);
+  LinkImplementation const* GetLinkImplementation(const char* config,
+                                                  cmTarget *head);
 
   /** Link information from the transitive closure of the link
       implementation and the interfaces of its dependencies.  */
@@ -286,7 +290,7 @@ public:
     // Languages whose runtime libraries must be linked.
     std::vector<std::string> Languages;
   };
-  LinkClosure const* GetLinkClosure(const char* config);
+  LinkClosure const* GetLinkClosure(const char* config, cmTarget *head);
 
   /** Strip off leading and trailing whitespace from an item named in
       the link dependencies of this target.  */
@@ -331,7 +335,7 @@ public:
   bool FindSourceFiles();
 
   ///! Return the preferred linker language for this target
-  const char* GetLinkerLanguage(const char* config = 0);
+  const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0);
 
   /** Get the full name of the target according to the settings in its
       makefile.  */
@@ -399,7 +403,8 @@ public:
   std::string GetInstallNameDirForInstallTree(const char* config,
                                               bool for_xcode = false);
 
-  cmComputeLinkInformation* GetLinkInformation(const char* config);
+  cmComputeLinkInformation* GetLinkInformation(const char* config,
+                                               cmTarget *head = 0);
 
   // Get the properties
   cmPropertyMap &GetProperties() { return this->Properties; };
@@ -597,16 +602,19 @@ private:
 
   // Cache import information from properties for each configuration.
   struct ImportInfo;
-  ImportInfo const* GetImportInfo(const char* config);
-  void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
+  ImportInfo const* GetImportInfo(const char* config,
+                                        cmTarget *workingTarget);
+  void ComputeImportInfo(std::string const& desired_config, ImportInfo& info,
+                                        cmTarget *head);
 
   cmTargetLinkInformationMap LinkInformation;
 
-  bool ComputeLinkInterface(const char* config, LinkInterface& iface);
+  bool ComputeLinkInterface(const char* config, LinkInterface& iface,
+                                        cmTarget *head);
 
   void ComputeLinkImplementation(const char* config,
-                                 LinkImplementation& impl);
-  void ComputeLinkClosure(const char* config, LinkClosure& lc);
+                                 LinkImplementation& impl, cmTarget *head);
+  void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head);
 
   void ClearLinkMaps();
 

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

Summary of changes:


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-commits

Reply via email to