summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorAlex Neundorf <neundorf@kde.org>2010-10-31 16:40:46 (GMT)
committerAlex Neundorf <neundorf@kde.org>2010-10-31 16:40:46 (GMT)
commita60b09927d4c29756c428d4c38f5ee2810a8f66e (patch)
tree2486ff42da3095c96333d6f04daf6db5ef9fbbd5 /Source
parent487bd571d56134b15b1060e1921a7e16711f12e6 (diff)
downloadCMake-a60b09927d4c29756c428d4c38f5ee2810a8f66e.zip
CMake-a60b09927d4c29756c428d4c38f5ee2810a8f66e.tar.gz
CMake-a60b09927d4c29756c428d4c38f5ee2810a8f66e.tar.bz2
Generate separate dot files for each target, and a big one with everything.
The big all-in-one file is basically unusable for e.g. kdelibs, it contains around 1000 nodes and the created image is huuuuge ! Too big actually to be displayable or viewable or comprehensable. Alex
Diffstat (limited to 'Source')
-rw-r--r--Source/cmake.cxx208
-rw-r--r--Source/cmake.h10
2 files changed, 149 insertions, 69 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index af01d0d..5386fb4 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2861,13 +2861,26 @@ static const char* getShapeForTarget(const cmTarget* target)
}
+static void writeNode(const char* targetName, const cmTarget* target,
+ const std::map<cmStdString, cmStdString>& targetNamesNodes,
+ std::set<std::string>& insertedNodes,
+ cmGeneratedFileStream& str)
+{
+ if (insertedNodes.find(targetName) == insertedNodes.end())
+ {
+ insertedNodes.insert(targetName);
+ std::map<cmStdString, cmStdString>::const_iterator nameIt =
+ targetNamesNodes.find(targetName);
+
+ str << " \"" << nameIt->second.c_str() << "\" [ label=\""
+ << targetName << "\" shape=\"" << getShapeForTarget(target)
+ << "\"];" << std::endl;
+ }
+}
+
+
void cmake::GenerateGraphViz(const char* fileName) const
{
- cmGeneratedFileStream str(fileName);
- if ( !str )
- {
- return;
- }
cmake cm;
cmGlobalGenerator ggi;
ggi.SetCMakeInstance(&cm);
@@ -2924,83 +2937,144 @@ void cmake::GenerateGraphViz(const char* fileName) const
}
}
+ std::map<cmStdString, const cmTarget*> targetPtrs;
+ std::map<cmStdString, cmStdString> targetNamesNodes; // maps from the actual strings to node names in dot
+ int cnt = getAllTargets(ignoreTargetsSet, targetNamesNodes, targetPtrs,
+ graphNodePrefix);
+
+ cnt = getAllExternalLibs(ignoreTargetsSet, targetNamesNodes, targetPtrs,
+ graphNodePrefix, cnt);
+
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ targetPtrs.begin();
+ ptrIt != targetPtrs.end();
+ ++ptrIt)
+ {
+ if (ptrIt->second == NULL)
+ {
+ continue;
+ }
+
+ if ((ptrIt->second->GetType() != cmTarget::EXECUTABLE)
+ && (ptrIt->second->GetType() != cmTarget::STATIC_LIBRARY)
+ && (ptrIt->second->GetType() != cmTarget::SHARED_LIBRARY)
+ && (ptrIt->second->GetType() != cmTarget::MODULE_LIBRARY))
+ {
+ continue;
+ }
+
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
+
+ std::string currentFilename = fileName;
+ currentFilename += ".";
+ currentFilename += ptrIt->first;
+ cmGeneratedFileStream str(currentFilename.c_str());
+ if ( !str )
+ {
+ return;
+ }
+
+ fprintf(stderr, "Writing %s...\n", currentFilename.c_str());
+ str << graphType << " " << graphName << " {" << std::endl;
+ str << graphHeader << std::endl;
+
+ writeDotConnections(ptrIt->first.c_str(), targetNamesNodes, targetPtrs,
+ insertedNodes, insertedConnections, str);
+ str << "}" << std::endl;
+ }
+
+ cmGeneratedFileStream str(fileName);
+ if ( !str )
+ {
+ return;
+ }
str << graphType << " " << graphName << " {" << std::endl;
str << graphHeader << std::endl;
- const cmGlobalGenerator* gg = this->GetGlobalGenerator();
- const std::vector<cmLocalGenerator*>& localGenerators =
- gg->GetLocalGenerators();
+ fprintf(stderr, "Writing %s...\n", fileName);
+ std::set<std::string> insertedConnections;
+ std::set<std::string> insertedNodes;
- std::map<cmStdString, const cmTarget*> targetPtrs;
- std::map<cmStdString, cmStdString> targetNamesNodes; // maps from the actual strings to node names in dot
- int cnt = 0;
- cnt += getAllTargets(ignoreTargetsSet, targetNamesNodes, targetPtrs,
- graphNodePrefix);
+ for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
+ targetPtrs.begin();
+ ptrIt != targetPtrs.end();
+ ++ptrIt)
+ {
+ if (ptrIt->second == NULL)
+ {
+ continue;
+ }
+
+ if ((ptrIt->second->GetType() != cmTarget::EXECUTABLE)
+ && (ptrIt->second->GetType() != cmTarget::STATIC_LIBRARY)
+ && (ptrIt->second->GetType() != cmTarget::SHARED_LIBRARY)
+ && (ptrIt->second->GetType() != cmTarget::MODULE_LIBRARY))
+ {
+ continue;
+ }
- cnt += getAllExternalLibs(ignoreTargetsSet, targetNamesNodes, targetPtrs,
- graphNodePrefix);
+ writeDotConnections(ptrIt->first.c_str(), targetNamesNodes, targetPtrs,
+ insertedNodes, insertedConnections, str);
+ }
+ str << "}" << std::endl;
+}
- // Write out nodes
- for(std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
- targetPtrs.begin(); tarIt != targetPtrs.end(); ++ tarIt )
+void cmake::writeDotConnections(const char* targetName,
+ const std::map<cmStdString, cmStdString>& targetNamesNodes,
+ const std::map<cmStdString, const cmTarget*>& targetPtrs,
+ std::set<std::string>& insertedNodes,
+ std::set<std::string>& insertedConnections,
+ cmGeneratedFileStream& str) const
+{
+ std::map<cmStdString, const cmTarget* >::const_iterator targetPtrIt =
+ targetPtrs.find(targetName);
+
+ if (targetPtrIt == targetPtrs.end()) // not found at all
{
- const char* newTargetName = tarIt->first.c_str();
- std::map<cmStdString, cmStdString>::const_iterator nameIt =
- targetNamesNodes.find(newTargetName);
+ return;
+ }
- str << " \"" << nameIt->second.c_str() << "\" [ label=\""
- << newTargetName << "\" shape=\"" << getShapeForTarget(tarIt->second)
- << "\"];" << std::endl;
+ writeNode(targetName, targetPtrIt->second, targetNamesNodes, insertedNodes,
+ str);
+
+ if (targetPtrIt->second == NULL) // it's an external library
+ {
+ return;
}
- // Now generate the connectivity
- for ( std::vector<cmLocalGenerator*>::const_iterator lit =
- localGenerators.begin();
- lit != localGenerators.end();
- ++ lit )
+
+ std::string myNodeName = targetNamesNodes.find(targetName)->second;
+
+ const cmTarget::LinkLibraryVectorType* ll =
+ &(targetPtrIt->second->GetOriginalLinkLibraries());
+
+ for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
+ llit != ll->end();
+ ++ llit )
{
- const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
- for (cmTargets::const_iterator tit = targets->begin();
- tit != targets->end();
- ++ tit )
+ const char* libName = llit->first.c_str();
+ std::map<cmStdString, cmStdString>::const_iterator libNameIt =
+ targetNamesNodes.find(libName);
+
+ std::string connectionName = myNodeName;
+ connectionName += "-";
+ connectionName += libNameIt->second;
+ if (insertedConnections.find(connectionName) == insertedConnections.end())
{
- std::map<cmStdString, const cmTarget* >::iterator cmakeTarIt
- = targetPtrs.find(tit->first.c_str());
- if ( cmakeTarIt == targetPtrs.end() ) // skip ignored targets
- {
- continue;
- }
- std::map<cmStdString, cmStdString>::iterator targetNameIt =
- targetNamesNodes.find(tit->first.c_str());
- const cmTarget::LinkLibraryVectorType* ll =
- &(tit->second.GetOriginalLinkLibraries());
+ insertedConnections.insert(connectionName);
+ writeNode(libName, targetPtrs.find(libName)->second, targetNamesNodes,
+ insertedNodes, str);
- for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
- llit != ll->end();
- ++ llit )
- {
- const char* libName = llit->first.c_str();
- std::map<cmStdString, cmStdString>::const_iterator libNameIt =
- targetNamesNodes.find(libName);
- if ( libNameIt == targetNamesNodes.end() )
- {
- // We should not be here.
- std::cout << __LINE__ << " Cannot find library: " << libName
- << " even though it was added in the previous pass" << std::endl;
- abort();
- }
- str << " \"" << targetNameIt->second.c_str() << "\" -> \""
- << libNameIt->second.c_str() << "\"" << std::endl;
- }
+ str << " \"" << myNodeName.c_str() << "\" -> \""
+ << libNameIt->second.c_str() << "\"";
+ str << " // " << targetName << " -> " << libName << std::endl;
+ writeDotConnections(libName, targetNamesNodes, targetPtrs, insertedNodes,
+ insertedConnections, str);
}
}
- // TODO: Use dotted or something for external libraries
- //str << " \"node0\":f4 -> \"node12\"[color=\"#0000ff\" style=dotted]"
- //<< std::endl;
- //
- str << "}" << std::endl;
}
@@ -3044,10 +3118,8 @@ int cmake::getAllTargets(const std::set<cmStdString>& ignoreTargetsSet,
int cmake::getAllExternalLibs(const std::set<cmStdString>& ignoreTargetsSet,
std::map<cmStdString, cmStdString>& targetNamesNodes,
std::map<cmStdString, const cmTarget*>& targetPtrs,
- const char* graphNodePrefix) const
+ const char* graphNodePrefix, int cnt) const
{
- int cnt = 0;
-
const std::vector<cmLocalGenerator*>& localGenerators =
this->GetGlobalGenerator()->GetLocalGenerators();
// Ok, now find all the stuff we link to that is not in cmake
diff --git a/Source/cmake.h b/Source/cmake.h
index b2cc7e7..0de72d9 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -51,6 +51,7 @@ class cmDocumentationSection;
class cmPolicies;
class cmListFileBacktrace;
class cmTarget;
+class cmGeneratedFileStream;
class cmake
{
@@ -440,7 +441,14 @@ protected:
int getAllExternalLibs(const std::set<cmStdString>& ignoreTargetsSet,
std::map<cmStdString, cmStdString>& targetNamesNodes,
std::map<cmStdString, const cmTarget*>& targetPtrs,
- const char* graphNodePrefix) const;
+ const char* graphNodePrefix, int cnt) const;
+
+ void writeDotConnections(const char* targetName,
+ const std::map<cmStdString, cmStdString>& targetNamesNodes,
+ const std::map<cmStdString, const cmTarget*>& targetPtrs,
+ std::set<std::string>& insertedNodes,
+ std::set<std::string>& insertedConnections,
+ cmGeneratedFileStream& str) const;
///! Find the full path to one of the cmake programs like ctest, cpack, etc.
std::string FindCMakeProgram(const char* name) const;