Distinguish "strong" and "weak" target dependency edges

Utility dependencies are "strong" because they must be enforced to
generate a working build.  Link dependencies are "weak" because they can
be broken in the case of a static library cycle.
This commit is contained in:
Brad King 2010-08-25 10:07:25 -04:00
parent 7be2617b5a
commit 681cf011dd
4 changed files with 42 additions and 13 deletions

View File

@ -149,7 +149,10 @@ void cmComputeComponentGraph::TransferEdges()
int j_component = this->TarjanComponents[j]; int j_component = this->TarjanComponents[j];
if(i_component != j_component) if(i_component != j_component)
{ {
this->ComponentGraph[i_component].push_back(j_component); // We do not attempt to combine duplicate edges, but instead
// store the inter-component edges with suitable multiplicity.
this->ComponentGraph[i_component].push_back(
cmGraphEdge(j_component, ni->IsStrong()));
} }
} }
} }

View File

@ -761,7 +761,8 @@ cmComputeLinkDepends::DisplayComponents()
EdgeList const& ol = this->CCG->GetComponentGraphEdges(c); EdgeList const& ol = this->CCG->GetComponentGraphEdges(c);
for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi)
{ {
fprintf(stderr, " followed by Component (%d)\n", *oi); int i = *oi;
fprintf(stderr, " followed by Component (%d)\n", i);
} }
fprintf(stderr, " topo order index %d\n", fprintf(stderr, " topo order index %d\n",
this->ComponentOrder[c]); this->ComponentOrder[c]);

View File

@ -195,15 +195,13 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
// Get the depender. // Get the depender.
cmTarget* depender = this->Targets[depender_index]; cmTarget* depender = this->Targets[depender_index];
// Keep track of dependencies already listed.
std::set<cmStdString> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
// Loop over all targets linked directly. // Loop over all targets linked directly.
{
cmTarget::LinkLibraryVectorType const& tlibs = cmTarget::LinkLibraryVectorType const& tlibs =
depender->GetOriginalLinkLibraries(); depender->GetOriginalLinkLibraries();
std::set<cmStdString> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin(); for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
lib != tlibs.end(); ++lib) lib != tlibs.end(); ++lib)
{ {
@ -213,9 +211,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
this->AddTargetDepend(depender_index, lib->first.c_str(), true); this->AddTargetDepend(depender_index, lib->first.c_str(), true);
} }
} }
}
// Loop over all utility dependencies. // Loop over all utility dependencies.
{
std::set<cmStdString> const& tutils = depender->GetUtilities(); std::set<cmStdString> const& tutils = depender->GetUtilities();
std::set<cmStdString> emitted;
// A target should not depend on itself.
emitted.insert(depender->GetName());
for(std::set<cmStdString>::const_iterator util = tutils.begin(); for(std::set<cmStdString>::const_iterator util = tutils.begin();
util != tutils.end(); ++util) util != tutils.end(); ++util)
{ {
@ -225,6 +228,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
this->AddTargetDepend(depender_index, util->c_str(), false); this->AddTargetDepend(depender_index, util->c_str(), false);
} }
} }
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -272,7 +276,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
int dependee_index = tii->second; int dependee_index = tii->second;
// Add this entry to the dependency graph. // Add this entry to the dependency graph.
this->InitialGraph[depender_index].push_back(dependee_index); this->InitialGraph[depender_index].push_back(
cmGraphEdge(dependee_index, !linking));
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -291,8 +296,8 @@ cmComputeTargetDepends::DisplayGraph(Graph const& graph, const char* name)
{ {
int dependee_index = *ni; int dependee_index = *ni;
cmTarget* dependee = this->Targets[dependee_index]; cmTarget* dependee = this->Targets[dependee_index];
fprintf(stderr, " depends on target %d [%s]\n", dependee_index, fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index,
dependee->GetName()); dependee->GetName(), ni->IsStrong()? "strong" : "weak");
} }
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -390,7 +395,8 @@ cmComputeTargetDepends
if(cmap[j] == c) if(cmap[j] == c)
{ {
cmTarget* dependee = this->Targets[j]; cmTarget* dependee = this->Targets[j];
e << " depends on \"" << dependee->GetName() << "\"\n"; e << " depends on \"" << dependee->GetName() << "\""
<< " (" << (ni->IsStrong()? "strong" : "weak") << ")\n";
} }
} }
} }

View File

@ -14,7 +14,26 @@
#include "cmStandardIncludes.h" #include "cmStandardIncludes.h"
struct cmGraphEdgeList: public std::vector<int> {}; /**
* Graph edge representation. Most use cases just need the
* destination vertex, so we support conversion to/from an int. We
* also store boolean to indicate whether an edge is "strong".
*/
class cmGraphEdge
{
public:
cmGraphEdge(): Dest(0), Strong(true) {}
cmGraphEdge(int n): Dest(n), Strong(true) {}
cmGraphEdge(int n, bool s): Dest(n), Strong(s) {}
cmGraphEdge(cmGraphEdge const& r): Dest(r.Dest), Strong(r.Strong) {}
operator int() const { return this->Dest; }
bool IsStrong() const { return this->Strong; }
private:
int Dest;
bool Strong;
};
struct cmGraphEdgeList: public std::vector<cmGraphEdge> {};
struct cmGraphNodeList: public std::vector<int> {}; struct cmGraphNodeList: public std::vector<int> {};
struct cmGraphAdjacencyList: public std::vector<cmGraphEdgeList> {}; struct cmGraphAdjacencyList: public std::vector<cmGraphEdgeList> {};