From 08fa5ddb1c0eac593aff143d0d6b00dd284df2a1 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 6 Feb 2011 18:34:48 +0100 Subject: [PATCH] Also generate dependers-graphviz files. With this commit, the --graphviz option now also generates dot files which show which other targets depend on some target. So, now there is * a global dot-file which shows all targets and dependencies * a dot file which shows on what a target Foo depends * a dot file which shows which other targets depend on Foo Alex --- Source/cmGraphVizWriter.cxx | 133 ++++++++++++++++++++++++++++++++++++ Source/cmGraphVizWriter.h | 6 ++ Source/cmake.cxx | 1 + 3 files changed, 140 insertions(+) diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 079d30eff..15bad5265 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -147,6 +147,54 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, } +// Iterate over all targets and write for each one a graph which shows +// which other targets depend on it. +void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName) +{ + this->CollectTargetsAndLibs(); + + for(std::map::const_iterator ptrIt = + this->TargetPtrs.begin(); + ptrIt != this->TargetPtrs.end(); + ++ptrIt) + { + if (ptrIt->second == NULL) + { + continue; + } + + if (this->GenerateForTargetType(ptrIt->second->GetType()) == false) + { + continue; + } + + std::string currentFilename = fileName; + currentFilename += "."; + currentFilename += ptrIt->first; + currentFilename += ".dependers"; + + cmGeneratedFileStream str(currentFilename.c_str()); + if ( !str ) + { + return; + } + + std::set insertedConnections; + std::set insertedNodes; + + std::cout << "Writing " << currentFilename << "..." << std::endl; + this->WriteHeader(str); + + this->WriteDependerConnections(ptrIt->first.c_str(), + insertedNodes, insertedConnections, str); + + this->WriteFooter(str); + } +} + + +// Iterate over all targets and write for each one a graph which shows +// on which targets it depends. void cmGraphVizWriter::WritePerTargetFiles(const char* fileName) { this->CollectTargetsAndLibs(); @@ -299,6 +347,91 @@ void cmGraphVizWriter::WriteConnections(const char* targetName, } +void cmGraphVizWriter::WriteDependerConnections(const char* targetName, + std::set& insertedNodes, + std::set& insertedConnections, + cmGeneratedFileStream& str) const +{ + std::map::const_iterator targetPtrIt = + this->TargetPtrs.find(targetName); + + if (targetPtrIt == this->TargetPtrs.end()) // not found at all + { + return; + } + + this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str); + + if (targetPtrIt->second == NULL) // it's an external library + { + return; + } + + + std::string myNodeName = this->TargetNamesNodes.find(targetName)->second; + + // now search who links against me + for(std::map::const_iterator dependerIt = + this->TargetPtrs.begin(); + dependerIt != this->TargetPtrs.end(); + ++dependerIt) + { + if (dependerIt->second == NULL) + { + continue; + } + + if (this->GenerateForTargetType(dependerIt->second->GetType()) == false) + { + continue; + } + + // Now we have a target, check whether it links against targetName. + // If so, draw a connection, and then continue with dependers on that one. + const cmTarget::LinkLibraryVectorType* ll = + &(dependerIt->second->GetOriginalLinkLibraries()); + + for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin(); + llit != ll->end(); + ++ llit ) + { + std::string libName = llit->first.c_str(); + if (libName == targetName) + { + // So this target links against targetName. + std::map::const_iterator dependerNodeNameIt = + this->TargetNamesNodes.find(dependerIt->first); + + if(dependerNodeNameIt != this->TargetNamesNodes.end()) + { + std::string connectionName = dependerNodeNameIt->second; + connectionName += "-"; + connectionName += myNodeName; + + if (insertedConnections.find(connectionName) == + insertedConnections.end()) + { + insertedConnections.insert(connectionName); + this->WriteNode(dependerIt->first.c_str(), dependerIt->second, + insertedNodes, str); + + str << " \"" << dependerNodeNameIt->second << "\" -> \"" + << myNodeName << "\""; + str << " // " < " <first<WriteDependerConnections(dependerIt->first.c_str(), + insertedNodes, insertedConnections, str); + } + + + } + break; + } + } + } + +} + + void cmGraphVizWriter::WriteNode(const char* targetName, const cmTarget* target, std::set& insertedNodes, diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index cd7a62784..f784aa0a1 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -30,6 +30,7 @@ public: const char* fallbackSettingsFileName); void WritePerTargetFiles(const char* fileName); + void WriteTargetDependersFiles(const char* fileName); void WriteGlobalFile(const char* fileName); @@ -48,6 +49,11 @@ protected: std::set& insertedConnections, cmGeneratedFileStream& str) const; + void WriteDependerConnections(const char* targetName, + std::set& insertedNodes, + std::set& insertedConnections, + cmGeneratedFileStream& str) const; + void WriteNode(const char* targetName, const cmTarget* target, std::set& insertedNodes, cmGeneratedFileStream& str) const; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index bab0aaf83..c8de91309 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2898,6 +2898,7 @@ void cmake::GenerateGraphViz(const char* fileName) const gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str()); gvWriter->WritePerTargetFiles(fileName); + gvWriter->WriteTargetDependersFiles(fileName); gvWriter->WriteGlobalFile(fileName); #endif