BUG: Fix cmComputeLinkInformation cycle detection.

This commit is contained in:
Brad King 2008-01-23 15:56:17 -05:00
parent f27379e3f7
commit 48fddd602d
2 changed files with 15 additions and 12 deletions

View File

@ -1025,7 +1025,7 @@ void cmComputeLinkInformation::CollectRuntimeDirectories()
} }
// Add link directories specified for the target. // Add link directories specified for the target.
std::vector<std::string> const& dirs = this->GetDirectories(); std::vector<std::string> const& dirs = this->Target->GetLinkDirectories();
for(std::vector<std::string>::const_iterator di = dirs.begin(); for(std::vector<std::string>::const_iterator di = dirs.begin();
di != dirs.end(); ++di) di != dirs.end(); ++di)
{ {
@ -1168,39 +1168,41 @@ void cmComputeLinkInformation::OrderRuntimeSearchPath()
{ {
// Allow a cycle to be diagnosed once. // Allow a cycle to be diagnosed once.
this->CycleDiagnosed = false; this->CycleDiagnosed = false;
this->WalkId = 0;
// Iterate through the directories in the original order. // Iterate through the directories in the original order.
for(unsigned int i=0; i < this->RuntimeDirectories.size(); ++i) for(unsigned int i=0; i < this->RuntimeDirectories.size(); ++i)
{ {
this->VisitRuntimeDirectory(i, true); // Start a new DFS from this node.
++this->WalkId;
this->VisitRuntimeDirectory(i);
} }
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmComputeLinkInformation::VisitRuntimeDirectory(unsigned int i, void cmComputeLinkInformation::VisitRuntimeDirectory(unsigned int i)
bool top)
{ {
// Skip nodes already visited. // Skip nodes already visited.
if(this->RuntimeDirectoryVisited[i]) if(this->RuntimeDirectoryVisited[i])
{ {
if(!top) if(this->RuntimeDirectoryVisited[i] == this->WalkId)
{ {
// We have reached a previously visited node but were not called // We have reached a node previously visited on this DFS.
// to start a new section of the graph. There is a cycle. // There is a cycle.
this->DiagnoseCycle(); this->DiagnoseCycle();
} }
return; return;
} }
// We are not visiting this node so mark it. // We are now visiting this node so mark it.
this->RuntimeDirectoryVisited[i] = 1; this->RuntimeDirectoryVisited[i] = this->WalkId;
// Visit the neighbors of the node first. // Visit the neighbors of the node first.
RuntimeConflictList const& clist = this->RuntimeConflictGraph[i]; RuntimeConflictList const& clist = this->RuntimeConflictGraph[i];
for(RuntimeConflictList::const_iterator j = clist.begin(); for(RuntimeConflictList::const_iterator j = clist.begin();
j != clist.end(); ++j) j != clist.end(); ++j)
{ {
this->VisitRuntimeDirectory(j->first, false); this->VisitRuntimeDirectory(j->first);
} }
// Now that all directories required to come before this one have // Now that all directories required to come before this one have

View File

@ -146,7 +146,7 @@ private:
std::set<cmStdString> LibraryRuntimeInfoEmmitted; std::set<cmStdString> LibraryRuntimeInfoEmmitted;
std::vector<std::string> RuntimeDirectories; std::vector<std::string> RuntimeDirectories;
std::map<cmStdString, int> RuntimeDirectoryIndex; std::map<cmStdString, int> RuntimeDirectoryIndex;
std::vector<char> RuntimeDirectoryVisited; std::vector<int> RuntimeDirectoryVisited;
void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target); void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target);
void AddLibraryRuntimeInfo(std::string const& fullPath, void AddLibraryRuntimeInfo(std::string const& fullPath,
const char* soname = 0); const char* soname = 0);
@ -155,9 +155,10 @@ private:
void FindConflictingLibraries(); void FindConflictingLibraries();
void FindDirectoriesForLib(unsigned int lri); void FindDirectoriesForLib(unsigned int lri);
void OrderRuntimeSearchPath(); void OrderRuntimeSearchPath();
void VisitRuntimeDirectory(unsigned int i, bool top); void VisitRuntimeDirectory(unsigned int i);
void DiagnoseCycle(); void DiagnoseCycle();
bool CycleDiagnosed; bool CycleDiagnosed;
int WalkId;
// Adjacency-list representation of runtime path ordering graph. // Adjacency-list representation of runtime path ordering graph.
// This maps from directory to those that must come *before* it. // This maps from directory to those that must come *before* it.