[Cmake-commits] CMake branch, next, updated. v2.8.3-653-ga82616e

Brad King brad.king at kitware.com
Thu Nov 18 11:05:05 EST 2010


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  a82616e2abec51b9f30e53b7c2b32de17488467e (commit)
       via  fd614e60b51e11ac8a99c19d541be9a8e5c141dc (commit)
       via  605f4bc0978fd3c84bc06875aef500e62b0f41c7 (commit)
       via  82596fcffcdf3e536fb0def67f6d4d1d1a3e5207 (commit)
      from  417739a991351c2e0b3138ee9a756e95865bd2ce (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=a82616e2abec51b9f30e53b7c2b32de17488467e
commit a82616e2abec51b9f30e53b7c2b32de17488467e
Merge: 417739a fd614e6
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 18 11:05:00 2010 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Nov 18 11:05:00 2010 -0500

    Merge topic 'vs-target-dependencies' into next
    
    fd614e6 Use modern global dependency graph for VS < 8 deps
    605f4bc Record edge type in global dependency graph
    82596fc Merge branch 'vs8-direct-depends' into vs-target-dependencies


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=fd614e60b51e11ac8a99c19d541be9a8e5c141dc
commit fd614e60b51e11ac8a99c19d541be9a8e5c141dc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Aug 25 10:26:25 2010 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 18 10:51:34 2010 -0500

    Use modern global dependency graph for VS < 8 deps
    
    VS 7.1 and below have 2 behaviors that make the cmComputeTargetDepends
    result difficult to use for solution-level dependencies.  Update the
    method cmGlobalVisualStudioGenerator::ComputeTargetDepends to document
    the behaviors and work around them.  Commit 1a0c166a (Store direct
    dependencies in solutions for VS >= 8, 2010-08-20) isolated VS >= 8 from
    this computation so those versions should be unaffected.
    
    This change removes the last use of cmTarget::GetLinkLibraries for
    purposes other than backward compatibility with legacy interfaces
    (export_library_dependencies, VS 6 custom .dsp templates).  Now the
    cmComputeTargetDepends results are used for all generators so global
    target dependency computation is fully centralized.

diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index bae18a3..7696e6c 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -237,6 +237,59 @@ std::string cmGlobalVisualStudioGenerator::GetUserMacrosRegKeyBase()
 }
 
 //----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::FillLinkClosure(cmTarget* target,
+                                                    TargetSet& linked)
+{
+  if(linked.insert(target).second)
+    {
+    TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+    for(TargetDependSet::const_iterator di = depends.begin();
+        di != depends.end(); ++di)
+      {
+      if(di->IsLink())
+        {
+        this->FillLinkClosure(*di, linked);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::TargetSet const&
+cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target)
+{
+  TargetSetMap::iterator i = this->TargetLinkClosure.find(target);
+  if(i == this->TargetLinkClosure.end())
+    {
+    TargetSetMap::value_type entry(target, TargetSet());
+    i = this->TargetLinkClosure.insert(entry).first;
+    this->FillLinkClosure(target, i->second);
+    }
+  return i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudioGenerator::FollowLinkDepends(
+  cmTarget* target, std::set<cmTarget*>& linked)
+{
+  if(linked.insert(target).second &&
+     target->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    // Static library targets do not list their link dependencies so
+    // we must follow them transitively now.
+    TargetDependSet const& depends = this->GetTargetDirectDepends(*target);
+    for(TargetDependSet::const_iterator di = depends.begin();
+        di != depends.end(); ++di)
+      {
+      if(di->IsLink())
+        {
+        this->FollowLinkDepends(*di, linked);
+        }
+      }
+    }
+}
+
+//----------------------------------------------------------------------------
 bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
 {
   if(!this->cmGlobalGenerator::ComputeTargetDepends())
@@ -269,51 +322,94 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
     return;
     }
   VSDependSet& vsTargetDepend = this->VSTargetDepends[&target];
+  // VS <= 7.1 has two behaviors that affect solution dependencies.
+  //
+  // (1) Solution-level dependencies between a linkable target and a
+  // library cause that library to be linked.  We use an intermedite
+  // empty utility target to express the dependency.  (VS 8 and above
+  // provide a project file "LinkLibraryDependencies" setting to
+  // choose whether to activate this behavior.  We disable it except
+  // when linking external project files.)
+  //
+  // (2) We cannot let static libraries depend directly on targets to
+  // which they "link" because the librarian tool will copy the
+  // targets into the static library.  While the work-around for
+  // behavior (1) would also avoid this, it would create a large
+  // number of extra utility targets for little gain.  Instead, use
+  // the above work-around only for dependencies explicitly added by
+  // the add_dependencies() command.  Approximate link dependencies by
+  // leaving them out for the static library itself but following them
+  // transitively for other targets.
+
+  bool allowLinkable = (target.GetType() != cmTarget::STATIC_LIBRARY &&
+                        target.GetType() != cmTarget::SHARED_LIBRARY &&
+                        target.GetType() != cmTarget::MODULE_LIBRARY &&
+                        target.GetType() != cmTarget::EXECUTABLE);
+
+  TargetDependSet const& depends = this->GetTargetDirectDepends(target);
+
+  // Collect implicit link dependencies (target_link_libraries).
+  // Static libraries cannot depend on their link implementation
+  // due to behavior (2), but they do not really need to.
+  std::set<cmTarget*> linkDepends;
   if(target.GetType() != cmTarget::STATIC_LIBRARY)
     {
-    cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
-    for(cmTarget::LinkLibraryVectorType::const_iterator j = libs.begin();
-        j != libs.end(); ++j)
+    for(TargetDependSet::const_iterator di = depends.begin();
+        di != depends.end(); ++di)
       {
-      if(j->first != target.GetName() &&
-         this->FindTarget(0, j->first.c_str()))
+      cmTargetDepend dep = *di;
+      if(dep.IsLink())
         {
-        vsTargetDepend.insert(j->first);
+        this->FollowLinkDepends(dep, linkDepends);
         }
       }
     }
-  std::set<cmStdString> const& utils = target.GetUtilities();
-  for(std::set<cmStdString>::const_iterator i = utils.begin();
-      i != utils.end(); ++i)
+
+  // Collext explicit util dependencies (add_dependencies).
+  std::set<cmTarget*> utilDepends;
+  for(TargetDependSet::const_iterator di = depends.begin();
+      di != depends.end(); ++di)
     {
-    if(*i != target.GetName())
+    cmTargetDepend dep = *di;
+    if(dep.IsUtil())
       {
-      std::string name = this->GetUtilityForTarget(target, i->c_str());
-      vsTargetDepend.insert(name);
+      this->FollowLinkDepends(dep, utilDepends);
       }
     }
-}
 
-//----------------------------------------------------------------------------
-bool cmGlobalVisualStudioGenerator::CheckTargetLinks(cmTarget& target,
-                                                     const char* name)
-{
-  // Return whether the given target links to a target with the given name.
-  if(target.GetType() == cmTarget::STATIC_LIBRARY)
+  // Collect all targets linked by this target so we can avoid
+  // intermediate targets below.
+  TargetSet linked;
+  if(target.GetType() != cmTarget::STATIC_LIBRARY)
     {
-    // Static libraries never link to anything.
-    return false;
+    linked = this->GetTargetLinkClosure(&target);
     }
-  cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
-  for(cmTarget::LinkLibraryVectorType::const_iterator i = libs.begin();
-      i != libs.end(); ++i)
+
+  // Emit link dependencies.
+  for(std::set<cmTarget*>::iterator di = linkDepends.begin();
+      di != linkDepends.end(); ++di)
+    {
+    cmTarget* dep = *di;
+    vsTargetDepend.insert(dep->GetName());
+    }
+
+  // Emit util dependencies.  Possibly use intermediate targets.
+  for(std::set<cmTarget*>::iterator di = utilDepends.begin();
+      di != utilDepends.end(); ++di)
     {
-    if(i->first == name)
+    cmTarget* dep = *di;
+    if(allowLinkable || !dep->IsLinkable() || linked.count(dep))
       {
-      return true;
+      // Direct dependency allowed.
+      vsTargetDepend.insert(dep->GetName());
+      }
+    else
+      {
+      // Direct dependency on linkable target not allowed.
+      // Use an intermediate utility target.
+      vsTargetDepend.insert(this->GetUtilityDepend(dep));
       }
     }
-  return false;
 }
 
 //----------------------------------------------------------------------------
@@ -330,45 +426,6 @@ std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(cmTarget* target)
 }
 
 //----------------------------------------------------------------------------
-std::string
-cmGlobalVisualStudioGenerator::GetUtilityForTarget(cmTarget& target,
-                                                   const char* name)
-{
-  if(!this->VSLinksDependencies())
-    {
-    return name;
-    }
-
-  // Possibly depend on an intermediate utility target to avoid
-  // linking.
-  if(target.GetType() == cmTarget::STATIC_LIBRARY ||
-     target.GetType() == cmTarget::SHARED_LIBRARY ||
-     target.GetType() == cmTarget::MODULE_LIBRARY ||
-     target.GetType() == cmTarget::EXECUTABLE)
-    {
-    // The depender is a target that links.
-    if(cmTarget* depTarget = this->FindTarget(0, name))
-      {
-      if(depTarget->GetType() == cmTarget::STATIC_LIBRARY ||
-         depTarget->GetType() == cmTarget::SHARED_LIBRARY ||
-         depTarget->GetType() == cmTarget::MODULE_LIBRARY)
-        {
-        // This utility dependency will cause an attempt to link.  If
-        // the depender does not already link the dependee we need an
-        // intermediate target.
-        if(!this->CheckTargetLinks(target, name))
-          {
-          return this->GetUtilityDepend(depTarget);
-          }
-        }
-      }
-    }
-
-  // No special case.  Just use the original dependency name.
-  return name;
-}
-
-//----------------------------------------------------------------------------
 #include <windows.h>
 
 //----------------------------------------------------------------------------
@@ -706,11 +763,22 @@ cmGlobalVisualStudioGenerator::TargetCompare
 
 //----------------------------------------------------------------------------
 cmGlobalVisualStudioGenerator::OrderedTargetDependSet
-::OrderedTargetDependSet(cmGlobalGenerator::TargetDependSet const& targets)
+::OrderedTargetDependSet(TargetDependSet const& targets)
 {
-  for(cmGlobalGenerator::TargetDependSet::const_iterator ti =
+  for(TargetDependSet::const_iterator ti =
         targets.begin(); ti != targets.end(); ++ti)
     {
     this->insert(*ti);
     }
 }
+
+//----------------------------------------------------------------------------
+cmGlobalVisualStudioGenerator::OrderedTargetDependSet
+::OrderedTargetDependSet(TargetSet const& targets)
+{
+  for(TargetSet::const_iterator ti = targets.begin();
+      ti != targets.end(); ++ti)
+    {
+    this->insert(*ti);
+    }
+}
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index c8ea339..bc96f4e 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -69,15 +69,12 @@ public:
       i.e. "Can I build Debug and Release in the same tree?" */
   virtual bool IsMultiConfig() { return true; }
 
+  class TargetSet: public std::set<cmTarget*> {};
   struct TargetCompare
   {
     bool operator()(cmTarget const* l, cmTarget const* r) const;
   };
-  class OrderedTargetDependSet: public std::multiset<cmTarget*, TargetCompare>
-  {
-  public:
-    OrderedTargetDependSet(cmGlobalGenerator::TargetDependSet const&);
-  };
+  class OrderedTargetDependSet;
 
 protected:
   // Does this VS version link targets to each other if there are
@@ -99,6 +96,24 @@ protected:
   std::string GetUtilityDepend(cmTarget* target);
   typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
   UtilityDependsMap UtilityDepends;
+private:
+  void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
+
+  class TargetSetMap: public std::map<cmTarget*, TargetSet> {};
+  TargetSetMap TargetLinkClosure;
+  void FillLinkClosure(cmTarget* target, TargetSet& linked);
+  TargetSet const& GetTargetLinkClosure(cmTarget* target);
+};
+
+class cmGlobalVisualStudioGenerator::OrderedTargetDependSet:
+  public std::multiset<cmTargetDepend,
+                       cmGlobalVisualStudioGenerator::TargetCompare>
+{
+public:
+  typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
+  typedef cmGlobalVisualStudioGenerator::TargetSet TargetSet;
+  OrderedTargetDependSet(TargetDependSet const&);
+  OrderedTargetDependSet(TargetSet const&);
 };
 
 #endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=605f4bc0978fd3c84bc06875aef500e62b0f41c7
commit 605f4bc0978fd3c84bc06875aef500e62b0f41c7
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Wed Aug 25 10:07:25 2010 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 18 10:51:00 2010 -0500

    Record edge type in global dependency graph
    
    Each inter-target dependency may be a 'link' or 'util' dependency.

diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 313c680..3f9c7ec 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -144,7 +144,7 @@ bool cmComputeTargetDepends::Compute()
 //----------------------------------------------------------------------------
 void
 cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t,
-                                               std::set<cmTarget*>& deps)
+                                               cmTargetDependSet& deps)
 {
   // Lookup the index for this target.  All targets should be known by
   // this point.
@@ -156,7 +156,9 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t,
   EdgeList const& nl = this->FinalGraph[i];
   for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
     {
-    deps.insert(this->Targets[*ni]);
+    cmTarget* dep = this->Targets[*ni];
+    cmTargetDependSet::iterator di = deps.insert(dep).first;
+    di->SetType(ni->IsStrong());
     }
 }
 
@@ -445,7 +447,7 @@ cmComputeTargetDepends
       int j = *ei;
       if(cmap[j] == c && ei->IsStrong())
         {
-        this->FinalGraph[i].push_back(j);
+        this->FinalGraph[i].push_back(cmGraphEdge(j, true));
         if(!this->IntraComponent(cmap, c, j, head, emitted, visited))
           {
           return false;
@@ -456,7 +458,7 @@ cmComputeTargetDepends
     // Prepend to a linear linked-list of intra-component edges.
     if(*head >= 0)
       {
-      this->FinalGraph[i].push_back(*head);
+      this->FinalGraph[i].push_back(cmGraphEdge(*head, false));
       }
     else
       {
@@ -515,7 +517,7 @@ cmComputeTargetDepends
       int dependee_component = *ni;
       int dependee_component_head = this->ComponentHead[dependee_component];
       this->FinalGraph[depender_component_tail]
-        .push_back(dependee_component_head);
+        .push_back(cmGraphEdge(dependee_component_head, ni->IsStrong()));
       }
     }
   return true;
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index 240de76..36e533f 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -21,6 +21,7 @@
 class cmComputeComponentGraph;
 class cmGlobalGenerator;
 class cmTarget;
+class cmTargetDependSet;
 
 /** \class cmComputeTargetDepends
  * \brief Compute global interdependencies among targets.
@@ -38,7 +39,7 @@ public:
   bool Compute();
 
   std::vector<cmTarget*> const& GetTargets() const { return this->Targets; }
-  void GetTargetDirectDepends(cmTarget* t, std::set<cmTarget*>& deps);
+  void GetTargetDirectDepends(cmTarget* t, cmTargetDependSet& deps);
 private:
   void CollectTargets();
   void CollectDepends();
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 2aec19f..e3b2641 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -16,6 +16,7 @@
 #include "cmStandardIncludes.h"
 
 #include "cmTarget.h" // For cmTargets
+#include "cmTargetDepend.h" // For cmTargetDependSet
 
 class cmake;
 class cmMakefile;
@@ -234,7 +235,7 @@ public:
   virtual const char* GetCleanTargetName()        { return 0; }
 
   // Class to track a set of dependencies.
-  class TargetDependSet: public std::set<cmTarget*> {};
+  typedef cmTargetDependSet TargetDependSet;
 
   // what targets does the specified target depend on directly
   // via a target_link_libraries or add_dependencies
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
new file mode 100644
index 0000000..258bacd
--- /dev/null
+++ b/Source/cmTargetDepend.h
@@ -0,0 +1,48 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2000-2010 Kitware, Inc., Insight Software Consortium
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmTargetDepend_h
+#define cmTargetDepend_h
+
+#include "cmStandardIncludes.h"
+
+class cmTarget;
+
+/** One edge in the global target dependency graph.
+    It may be marked as a 'link' or 'util' edge or both.  */
+class cmTargetDepend
+{
+  cmTarget* Target;
+
+  // The set order depends only on the Target, so we use
+  // mutable members to acheive a map with set syntax.
+  mutable bool Link;
+  mutable bool Util;
+public:
+  cmTargetDepend(cmTarget* t): Target(t), Link(false), Util(false) {}
+  operator cmTarget*() const { return this->Target; }
+  cmTarget* operator->() const { return this->Target; }
+  cmTarget& operator*() const { return *this->Target; }
+  friend bool operator < (cmTargetDepend const& l, cmTargetDepend const& r)
+    { return l.Target < r.Target; }
+  void SetType(bool strong) const
+    {
+    if(strong) { this->Util = true; }
+    else { this->Link = true; }
+    }
+  bool IsLink() const { return this->Link; }
+  bool IsUtil() const { return this->Util; }
+};
+
+/** Unordered set of (direct) dependencies of a target. */
+class cmTargetDependSet: public std::set<cmTargetDepend> {};
+
+#endif

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=82596fcffcdf3e536fb0def67f6d4d1d1a3e5207
commit 82596fcffcdf3e536fb0def67f6d4d1d1a3e5207
Merge: e6975fe 1a0c166
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Nov 12 12:42:50 2010 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Nov 12 12:42:50 2010 -0500

    Merge branch 'vs8-direct-depends' into vs-target-dependencies


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

Summary of changes:
 Source/cmComputeTargetDepends.cxx        |   12 +-
 Source/cmComputeTargetDepends.h          |    3 +-
 Source/cmGlobalGenerator.h               |    3 +-
 Source/cmGlobalVisualStudioGenerator.cxx |  204 ++++++++++++++++++++----------
 Source/cmGlobalVisualStudioGenerator.h   |   25 +++-
 Source/cmTargetDepend.h                  |   48 +++++++
 6 files changed, 215 insertions(+), 80 deletions(-)
 create mode 100644 Source/cmTargetDepend.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list