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.k...@kitware.com> AuthorDate: Thu Nov 18 11:05:00 2010 -0500 Commit: CMake Topic Stage <kwro...@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.k...@kitware.com> AuthorDate: Wed Aug 25 10:26:25 2010 -0400 Commit: Brad King <brad.k...@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.k...@kitware.com> AuthorDate: Wed Aug 25 10:07:25 2010 -0400 Commit: Brad King <brad.k...@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.k...@kitware.com> AuthorDate: Fri Nov 12 12:42:50 2010 -0500 Commit: Brad King <brad.k...@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 _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-commits