From a60b09927d4c29756c428d4c38f5ee2810a8f66e Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 31 Oct 2010 17:40:46 +0100 Subject: 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 --- Source/cmake.cxx | 208 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 140 insertions(+), 68 deletions(-) (limited to 'Source/cmake.cxx') diff --git a/Source/cmake.cxx b/Source/cmake.cxx index af01d0d18b..5386fb4f1e 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& targetNamesNodes, + std::set& insertedNodes, + cmGeneratedFileStream& str) +{ + if (insertedNodes.find(targetName) == insertedNodes.end()) + { + insertedNodes.insert(targetName); + std::map::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 targetPtrs; + std::map 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::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 insertedConnections; + std::set 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& localGenerators = - gg->GetLocalGenerators(); + fprintf(stderr, "Writing %s...\n", fileName); + std::set insertedConnections; + std::set insertedNodes; - std::map targetPtrs; - std::map targetNamesNodes; // maps from the actual strings to node names in dot - int cnt = 0; - cnt += getAllTargets(ignoreTargetsSet, targetNamesNodes, targetPtrs, - graphNodePrefix); + for(std::map::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::const_iterator tarIt = - targetPtrs.begin(); tarIt != targetPtrs.end(); ++ tarIt ) +void cmake::writeDotConnections(const char* targetName, + const std::map& targetNamesNodes, + const std::map& targetPtrs, + std::set& insertedNodes, + std::set& insertedConnections, + cmGeneratedFileStream& str) const +{ + std::map::const_iterator targetPtrIt = + targetPtrs.find(targetName); + + if (targetPtrIt == targetPtrs.end()) // not found at all { - const char* newTargetName = tarIt->first.c_str(); - std::map::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::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::const_iterator libNameIt = + targetNamesNodes.find(libName); + + std::string connectionName = myNodeName; + connectionName += "-"; + connectionName += libNameIt->second; + if (insertedConnections.find(connectionName) == insertedConnections.end()) { - std::map::iterator cmakeTarIt - = targetPtrs.find(tit->first.c_str()); - if ( cmakeTarIt == targetPtrs.end() ) // skip ignored targets - { - continue; - } - std::map::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::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& ignoreTargetsSet, int cmake::getAllExternalLibs(const std::set& ignoreTargetsSet, std::map& targetNamesNodes, std::map& targetPtrs, - const char* graphNodePrefix) const + const char* graphNodePrefix, int cnt) const { - int cnt = 0; - const std::vector& localGenerators = this->GetGlobalGenerator()->GetLocalGenerators(); // Ok, now find all the stuff we link to that is not in cmake -- cgit v1.2.1