Move the code for generating dot-files into separate class cmGraphVizWriter
Alex
This commit is contained in:
parent
a60b09927d
commit
84ce612c65
|
@ -183,6 +183,8 @@ SET(SRCS
|
|||
cmGlobalUnixMakefileGenerator3.cxx
|
||||
cmGlobalUnixMakefileGenerator3.h
|
||||
cmGraphAdjacencyList.h
|
||||
cmGraphVizWriter.cxx
|
||||
cmGraphVizWriter.h
|
||||
cmInstallGenerator.h
|
||||
cmInstallGenerator.cxx
|
||||
cmInstallExportGenerator.cxx
|
||||
|
@ -332,7 +334,7 @@ ENDIF (WIN32)
|
|||
|
||||
# create a library used by the command line and the GUI
|
||||
ADD_LIBRARY(CMakeLib ${SRCS})
|
||||
TARGET_LINK_LIBRARIES(CMakeLib cmsys
|
||||
TARGET_LINK_LIBRARIES(CMakeLib cmsys
|
||||
${CMAKE_EXPAT_LIBRARIES} ${CMAKE_ZLIB_LIBRARIES}
|
||||
${CMAKE_TAR_LIBRARIES} ${CMAKE_COMPRESS_LIBRARIES}
|
||||
${CMAKE_CURL_LIBRARIES} )
|
||||
|
@ -432,7 +434,7 @@ IF(CYGWIN)
|
|||
CPack/cmCPackCygwinSourceGenerator.cxx
|
||||
)
|
||||
ENDIF(CYGWIN)
|
||||
|
||||
|
||||
IF(UNIX)
|
||||
SET(CPACK_SRCS ${CPACK_SRCS}
|
||||
CPack/cmCPackDebGenerator.cxx
|
||||
|
|
|
@ -0,0 +1,370 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cmGraphVizWriter.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
static const char* getShapeForTarget(const cmTarget* target)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return "ellipse";
|
||||
}
|
||||
|
||||
switch ( target->GetType() )
|
||||
{
|
||||
case cmTarget::EXECUTABLE:
|
||||
return "house";
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
return "diamond";
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
return "polygon";
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
return "octagon";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "box";
|
||||
}
|
||||
|
||||
|
||||
cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
|
||||
localGenerators)
|
||||
:GraphType("digraph")
|
||||
,GraphName("GG")
|
||||
,GraphHeader("node [\n fontsize = \"12\"\n];")
|
||||
,GraphNodePrefix("node")
|
||||
,LocalGenerators(localGenerators)
|
||||
{
|
||||
int cnt = collectAllTargets();
|
||||
collectAllExternalLibs(cnt);
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
|
||||
const char* fallbackSettingsFileName)
|
||||
{
|
||||
cmake cm;
|
||||
cmGlobalGenerator ggi;
|
||||
ggi.SetCMakeInstance(&cm);
|
||||
std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
|
||||
cmMakefile *mf = lg->GetMakefile();
|
||||
|
||||
const char* inFileName = settingsFileName;
|
||||
|
||||
if ( !cmSystemTools::FileExists(inFileName) )
|
||||
{
|
||||
inFileName = fallbackSettingsFileName;
|
||||
if ( !cmSystemTools::FileExists(inFileName) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !mf->ReadListFile(0, inFileName) )
|
||||
{
|
||||
cmSystemTools::Error("Problem opening GraphViz options file: ",
|
||||
inFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Reading GraphViz options file: " << inFileName << std::endl;
|
||||
|
||||
#define __set_if_set(var, cmakeDefinition) \
|
||||
{ \
|
||||
const char* value = mf->GetDefinition(cmakeDefinition); \
|
||||
if ( value ) \
|
||||
{ \
|
||||
var = value; \
|
||||
} \
|
||||
}
|
||||
|
||||
__set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
|
||||
__set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
|
||||
__set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
|
||||
__set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");
|
||||
|
||||
this->TargetsToIgnore.clear();
|
||||
const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
|
||||
if ( ignoreTargets )
|
||||
{
|
||||
std::vector<std::string> ignoreTargetsVector;
|
||||
cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
|
||||
for(std::vector<std::string>::iterator itvIt = ignoreTargetsVector.begin();
|
||||
itvIt != ignoreTargetsVector.end();
|
||||
++ itvIt )
|
||||
{
|
||||
this->TargetsToIgnore.insert(itvIt->c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
|
||||
{
|
||||
for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
|
||||
this->TargetPtrs.begin();
|
||||
ptrIt != this->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());
|
||||
this->WriteHeader(str);
|
||||
|
||||
this->WriteConnections(ptrIt->first.c_str(),
|
||||
insertedNodes, insertedConnections, str);
|
||||
this->WriteFooter(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
|
||||
{
|
||||
cmGeneratedFileStream str(fileName);
|
||||
if ( !str )
|
||||
{
|
||||
return;
|
||||
}
|
||||
this->WriteHeader(str);
|
||||
|
||||
fprintf(stderr, "Writing %s...\n", fileName);
|
||||
std::set<std::string> insertedConnections;
|
||||
std::set<std::string> insertedNodes;
|
||||
|
||||
for(std::map<cmStdString, const cmTarget*>::const_iterator ptrIt =
|
||||
this->TargetPtrs.begin();
|
||||
ptrIt != this->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;
|
||||
}
|
||||
|
||||
this->WriteConnections(ptrIt->first.c_str(),
|
||||
insertedNodes, insertedConnections, str);
|
||||
}
|
||||
this->WriteFooter(str);
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
|
||||
{
|
||||
str << this->GraphType << " " << this->GraphName << " {" << std::endl;
|
||||
str << this->GraphHeader << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
|
||||
{
|
||||
str << "}" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WriteConnections(const char* targetName,
|
||||
std::set<std::string>& insertedNodes,
|
||||
std::set<std::string>& insertedConnections,
|
||||
cmGeneratedFileStream& str) const
|
||||
{
|
||||
std::map<cmStdString, const cmTarget* >::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;
|
||||
|
||||
const cmTarget::LinkLibraryVectorType* ll =
|
||||
&(targetPtrIt->second->GetOriginalLinkLibraries());
|
||||
|
||||
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 =
|
||||
this->TargetNamesNodes.find(libName);
|
||||
|
||||
std::string connectionName = myNodeName;
|
||||
connectionName += "-";
|
||||
connectionName += libNameIt->second;
|
||||
if (insertedConnections.find(connectionName) == insertedConnections.end())
|
||||
{
|
||||
insertedConnections.insert(connectionName);
|
||||
this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
|
||||
insertedNodes, str);
|
||||
|
||||
str << " \"" << myNodeName.c_str() << "\" -> \""
|
||||
<< libNameIt->second.c_str() << "\"";
|
||||
str << " // " << targetName << " -> " << libName << std::endl;
|
||||
this->WriteConnections(libName, insertedNodes, insertedConnections, str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cmGraphVizWriter::WriteNode(const char* targetName,
|
||||
const cmTarget* target,
|
||||
std::set<std::string>& insertedNodes,
|
||||
cmGeneratedFileStream& str) const
|
||||
{
|
||||
if (insertedNodes.find(targetName) == insertedNodes.end())
|
||||
{
|
||||
insertedNodes.insert(targetName);
|
||||
std::map<cmStdString, cmStdString>::const_iterator nameIt =
|
||||
this->TargetNamesNodes.find(targetName);
|
||||
|
||||
str << " \"" << nameIt->second.c_str() << "\" [ label=\""
|
||||
<< targetName << "\" shape=\"" << getShapeForTarget(target)
|
||||
<< "\"];" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int cmGraphVizWriter::collectAllTargets()
|
||||
{
|
||||
int cnt = 0;
|
||||
// First pass get the list of all cmake targets
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lit =
|
||||
this->LocalGenerators.begin();
|
||||
lit != this->LocalGenerators.end();
|
||||
++ lit )
|
||||
{
|
||||
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
|
||||
for ( cmTargets::const_iterator tit = targets->begin();
|
||||
tit != targets->end();
|
||||
++ tit )
|
||||
{
|
||||
const char* realTargetName = tit->first.c_str();
|
||||
if(this->IgnoreThisTarget(realTargetName))
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
|
||||
cmOStringStream ostr;
|
||||
ostr << this->GraphNodePrefix << cnt++;
|
||||
this->TargetNamesNodes[realTargetName] = ostr.str();
|
||||
this->TargetPtrs[realTargetName] = &tit->second;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
int cmGraphVizWriter::collectAllExternalLibs(int cnt)
|
||||
{
|
||||
// Ok, now find all the stuff we link to that is not in cmake
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lit =
|
||||
this->LocalGenerators.begin();
|
||||
lit != this->LocalGenerators.end();
|
||||
++ lit )
|
||||
{
|
||||
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
|
||||
for ( cmTargets::const_iterator tit = targets->begin();
|
||||
tit != targets->end();
|
||||
++ tit )
|
||||
{
|
||||
const char* realTargetName = tit->first.c_str();
|
||||
if (this->IgnoreThisTarget(realTargetName))
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
const cmTarget::LinkLibraryVectorType* ll =
|
||||
&(tit->second.GetOriginalLinkLibraries());
|
||||
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
|
||||
llit != ll->end();
|
||||
++ llit )
|
||||
{
|
||||
const char* libName = llit->first.c_str();
|
||||
if (this->IgnoreThisTarget(libName))
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
|
||||
std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
|
||||
this->TargetPtrs.find(libName);
|
||||
if ( tarIt == this->TargetPtrs.end() )
|
||||
{
|
||||
cmOStringStream ostr;
|
||||
ostr << this->GraphNodePrefix << cnt++;
|
||||
this->TargetNamesNodes[libName] = ostr.str();
|
||||
this->TargetPtrs[libName] = NULL;
|
||||
//str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
|
||||
//<< "\" shape=\"ellipse\"];" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
bool cmGraphVizWriter::IgnoreThisTarget(const char* name) const
|
||||
{
|
||||
return (this->TargetsToIgnore.find(name) != this->TargetsToIgnore.end());
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#ifndef CMGRAPHVIZWRITER_H
|
||||
#define CMGRAPHVIZWRITER_H
|
||||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
||||
|
||||
Distributed under the OSI-approved BSD License (the "License");
|
||||
see accompanying file Copyright.txt for details.
|
||||
|
||||
This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the License for more information.
|
||||
============================================================================*/
|
||||
#include "cmStandardIncludes.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
|
||||
|
||||
/** This class implements writing files for graphviz (dot) for graphs
|
||||
* representing the dependencies between the targets in the project. */
|
||||
class cmGraphVizWriter
|
||||
{
|
||||
public:
|
||||
|
||||
cmGraphVizWriter(const std::vector<cmLocalGenerator*>& localGenerators);
|
||||
|
||||
void ReadSettings(const char* settingsFileName,
|
||||
const char* fallbackSettingsFileName);
|
||||
|
||||
void WritePerTargetFiles(const char* fileName);
|
||||
|
||||
void WriteGlobalFile(const char* fileName);
|
||||
|
||||
protected:
|
||||
|
||||
int collectAllTargets();
|
||||
|
||||
int collectAllExternalLibs(int cnt);
|
||||
|
||||
void WriteHeader(cmGeneratedFileStream& str) const;
|
||||
|
||||
void WriteConnections(const char* targetName,
|
||||
std::set<std::string>& insertedNodes,
|
||||
std::set<std::string>& insertedConnections,
|
||||
cmGeneratedFileStream& str) const;
|
||||
|
||||
void WriteNode(const char* targetName, const cmTarget* target,
|
||||
std::set<std::string>& insertedNodes,
|
||||
cmGeneratedFileStream& str) const;
|
||||
|
||||
void WriteFooter(cmGeneratedFileStream& str) const;
|
||||
|
||||
bool IgnoreThisTarget(const char* name) const;
|
||||
|
||||
cmStdString GraphType;
|
||||
cmStdString GraphName;
|
||||
cmStdString GraphHeader;
|
||||
cmStdString GraphNodePrefix;
|
||||
|
||||
const std::vector<cmLocalGenerator*>& LocalGenerators;
|
||||
|
||||
std::map<cmStdString, const cmTarget*> TargetPtrs;
|
||||
// maps from the actual target names to node names in dot:
|
||||
std::map<cmStdString, cmStdString> TargetNamesNodes;
|
||||
|
||||
std::set<cmStdString> TargetsToIgnore;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
336
Source/cmake.cxx
336
Source/cmake.cxx
|
@ -26,6 +26,7 @@
|
|||
#include "cmDocumentationFormatterText.h"
|
||||
|
||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||
# include "cmGraphVizWriter.h"
|
||||
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
|
||||
# include "cmVariableWatch.h"
|
||||
# include <cmsys/Terminal.h>
|
||||
|
@ -2836,339 +2837,26 @@ const char* cmake::GetCPackCommand()
|
|||
}
|
||||
|
||||
|
||||
static const char* getShapeForTarget(const cmTarget* target)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return "ellipse";
|
||||
}
|
||||
|
||||
switch ( target->GetType() )
|
||||
{
|
||||
case cmTarget::EXECUTABLE:
|
||||
return "house";
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
return "diamond";
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
return "polygon";
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
return "octagon";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "box";
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
cmake cm;
|
||||
cmGlobalGenerator ggi;
|
||||
ggi.SetCMakeInstance(&cm);
|
||||
std::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator());
|
||||
cmMakefile *mf = lg->GetMakefile();
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
std::auto_ptr<cmGraphVizWriter> gvWriter(
|
||||
new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators()));
|
||||
|
||||
std::string infile = this->GetHomeOutputDirectory();
|
||||
infile += "/CMakeGraphVizOptions.cmake";
|
||||
if ( !cmSystemTools::FileExists(infile.c_str()) )
|
||||
{
|
||||
infile = this->GetHomeDirectory();
|
||||
infile += "/CMakeGraphVizOptions.cmake";
|
||||
if ( !cmSystemTools::FileExists(infile.c_str()) )
|
||||
{
|
||||
infile = "";
|
||||
}
|
||||
}
|
||||
std::string settingsFile = this->GetHomeOutputDirectory();
|
||||
settingsFile += "/CMakeGraphVizOptions.cmake";
|
||||
std::string fallbackSettingsFile = this->GetHomeDirectory();
|
||||
fallbackSettingsFile += "/CMakeGraphVizOptions.cmake";
|
||||
|
||||
if ( !infile.empty() )
|
||||
{
|
||||
if ( !mf->ReadListFile(0, infile.c_str()) )
|
||||
{
|
||||
cmSystemTools::Error("Problem opening GraphViz options file: ",
|
||||
infile.c_str());
|
||||
return;
|
||||
}
|
||||
std::cout << "Read GraphViz options file: " << infile.c_str()
|
||||
<< std::endl;
|
||||
}
|
||||
gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str());
|
||||
|
||||
#define __set_if_not_set(var, value, cmakeDefinition) \
|
||||
const char* var = mf->GetDefinition(cmakeDefinition); \
|
||||
if ( !var ) \
|
||||
{ \
|
||||
var = value; \
|
||||
}
|
||||
__set_if_not_set(graphType, "digraph", "GRAPHVIZ_GRAPH_TYPE");
|
||||
__set_if_not_set(graphName, "GG", "GRAPHVIZ_GRAPH_NAME");
|
||||
__set_if_not_set(graphHeader, "node [\n fontsize = \"12\"\n];",
|
||||
"GRAPHVIZ_GRAPH_HEADER");
|
||||
__set_if_not_set(graphNodePrefix, "node", "GRAPHVIZ_NODE_PREFIX");
|
||||
const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS");
|
||||
std::set<cmStdString> ignoreTargetsSet;
|
||||
if ( ignoreTargets )
|
||||
{
|
||||
std::vector<std::string> ignoreTargetsVector;
|
||||
cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector);
|
||||
std::vector<std::string>::iterator itvIt;
|
||||
for ( itvIt = ignoreTargetsVector.begin();
|
||||
itvIt != ignoreTargetsVector.end();
|
||||
++ itvIt )
|
||||
{
|
||||
ignoreTargetsSet.insert(itvIt->c_str());
|
||||
}
|
||||
}
|
||||
gvWriter->WritePerTargetFiles(fileName);
|
||||
gvWriter->WriteGlobalFile(fileName);
|
||||
|
||||
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;
|
||||
|
||||
fprintf(stderr, "Writing %s...\n", fileName);
|
||||
std::set<std::string> insertedConnections;
|
||||
std::set<std::string> insertedNodes;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
writeDotConnections(ptrIt->first.c_str(), targetNamesNodes, targetPtrs,
|
||||
insertedNodes, insertedConnections, str);
|
||||
}
|
||||
str << "}" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writeNode(targetName, targetPtrIt->second, targetNamesNodes, insertedNodes,
|
||||
str);
|
||||
|
||||
if (targetPtrIt->second == NULL) // it's an external library
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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 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())
|
||||
{
|
||||
insertedConnections.insert(connectionName);
|
||||
writeNode(libName, targetPtrs.find(libName)->second, targetNamesNodes,
|
||||
insertedNodes, str);
|
||||
|
||||
str << " \"" << myNodeName.c_str() << "\" -> \""
|
||||
<< libNameIt->second.c_str() << "\"";
|
||||
str << " // " << targetName << " -> " << libName << std::endl;
|
||||
writeDotConnections(libName, targetNamesNodes, targetPtrs, insertedNodes,
|
||||
insertedConnections, str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
int cmake::getAllTargets(const std::set<cmStdString>& ignoreTargetsSet,
|
||||
std::map<cmStdString, cmStdString>& targetNamesNodes,
|
||||
std::map<cmStdString, const cmTarget*>& targetPtrs,
|
||||
const char* graphNodePrefix) const
|
||||
{
|
||||
int cnt = 0;
|
||||
const std::vector<cmLocalGenerator*>& localGenerators =
|
||||
this->GetGlobalGenerator()->GetLocalGenerators();
|
||||
// First pass get the list of all cmake targets
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lit =
|
||||
localGenerators.begin();
|
||||
lit != localGenerators.end();
|
||||
++ lit )
|
||||
{
|
||||
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
|
||||
for ( cmTargets::const_iterator tit = targets->begin();
|
||||
tit != targets->end();
|
||||
++ tit )
|
||||
{
|
||||
const char* realTargetName = tit->first.c_str();
|
||||
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
//std::cout << "Found target: " << tit->first.c_str() << std::endl;
|
||||
cmOStringStream ostr;
|
||||
ostr << graphNodePrefix << cnt++;
|
||||
targetNamesNodes[realTargetName] = ostr.str();
|
||||
targetPtrs[realTargetName] = &tit->second;
|
||||
}
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
int cmake::getAllExternalLibs(const std::set<cmStdString>& ignoreTargetsSet,
|
||||
std::map<cmStdString, cmStdString>& targetNamesNodes,
|
||||
std::map<cmStdString, const cmTarget*>& targetPtrs,
|
||||
const char* graphNodePrefix, int cnt) const
|
||||
{
|
||||
const std::vector<cmLocalGenerator*>& localGenerators =
|
||||
this->GetGlobalGenerator()->GetLocalGenerators();
|
||||
// Ok, now find all the stuff we link to that is not in cmake
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lit =
|
||||
localGenerators.begin();
|
||||
lit != localGenerators.end();
|
||||
++ lit )
|
||||
{
|
||||
const cmTargets* targets = &((*lit)->GetMakefile()->GetTargets());
|
||||
for ( cmTargets::const_iterator tit = targets->begin();
|
||||
tit != targets->end();
|
||||
++ tit )
|
||||
{
|
||||
const char* realTargetName = tit->first.c_str();
|
||||
if ( ignoreTargetsSet.find(realTargetName) != ignoreTargetsSet.end() )
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
const cmTarget::LinkLibraryVectorType* ll =
|
||||
&(tit->second.GetOriginalLinkLibraries());
|
||||
for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
|
||||
llit != ll->end();
|
||||
++ llit )
|
||||
{
|
||||
const char* libName = llit->first.c_str();
|
||||
if ( ignoreTargetsSet.find(libName) != ignoreTargetsSet.end() )
|
||||
{
|
||||
// Skip ignored targets
|
||||
continue;
|
||||
}
|
||||
|
||||
std::map<cmStdString, const cmTarget*>::const_iterator tarIt =
|
||||
targetPtrs.find(libName);
|
||||
if ( tarIt == targetPtrs.end() )
|
||||
{
|
||||
cmOStringStream ostr;
|
||||
ostr << graphNodePrefix << cnt++;
|
||||
targetNamesNodes[libName] = ostr.str();
|
||||
targetPtrs[libName] = NULL;
|
||||
//str << " \"" << ostr.c_str() << "\" [ label=\"" << libName
|
||||
//<< "\" shape=\"ellipse\"];" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int cmake::SymlinkLibrary(std::vector<std::string>& args)
|
||||
{
|
||||
|
|
|
@ -433,23 +433,6 @@ protected:
|
|||
int* retCodeOut = 0);
|
||||
cmVariableWatch* VariableWatch;
|
||||
|
||||
int getAllTargets(const std::set<cmStdString>& ignoreTargetsSet,
|
||||
std::map<cmStdString, cmStdString>& targetNamesNodes,
|
||||
std::map<cmStdString, const cmTarget*>& targetPtrs,
|
||||
const char* graphNodePrefix) const;
|
||||
|
||||
int getAllExternalLibs(const std::set<cmStdString>& ignoreTargetsSet,
|
||||
std::map<cmStdString, cmStdString>& targetNamesNodes,
|
||||
std::map<cmStdString, const cmTarget*>& targetPtrs,
|
||||
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;
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue