|
|
@@ -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();
|
|
|
-
|
|
|
- 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 = "";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
-#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());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-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);
|
|
|
- }
|
|
|
- }
|
|
|
+#ifdef CMAKE_BUILD_WITH_CMAKE
|
|
|
+ std::auto_ptr<cmGraphVizWriter> gvWriter(
|
|
|
+ new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators()));
|
|
|
|
|
|
-}
|
|
|
+ std::string settingsFile = this->GetHomeOutputDirectory();
|
|
|
+ settingsFile += "/CMakeGraphVizOptions.cmake";
|
|
|
+ std::string fallbackSettingsFile = this->GetHomeDirectory();
|
|
|
+ fallbackSettingsFile += "/CMakeGraphVizOptions.cmake";
|
|
|
|
|
|
+ gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_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;
|
|
|
- }
|
|
|
- }
|
|
|
+ gvWriter->WritePerTargetFiles(fileName);
|
|
|
+ gvWriter->WriteGlobalFile(fileName);
|
|
|
|
|
|
- return cnt;
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
|
|
|
-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)
|
|
|
{
|