فهرست منبع

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
Alex Neundorf 15 سال پیش
والد
کامیت
a60b09927d
2فایلهای تغییر یافته به همراه149 افزوده شده و 69 حذف شده
  1. 140 68
      Source/cmake.cxx
  2. 9 1
      Source/cmake.h

+ 140 - 68
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

+ 9 - 1
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;