From 5698ad2047002529ff095fb9be2eb5c1d2f7a485 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 5 Feb 2011 18:43:34 +0100 Subject: Make it possible to exlude external libs from dot files Patch from Christian Ehrlicher. By setting GRAPHVIZ_EXTERNAL_LIBS to TRUE in CMakeGraphVizOptions.cmake you can now exclude external libraries from the produced dot file. I.e. then you see only the dependencies within your project. Alex --- Source/cmGraphVizWriter.cxx | 9 +++++++-- Source/cmGraphVizWriter.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index de95aa5..5a08ca6 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -54,6 +54,7 @@ cmGraphVizWriter::cmGraphVizWriter(const std::vector& ,GenerateForStaticLibs(true) ,GenerateForSharedLibs(true) ,GenerateForModuleLibs(true) +,GenerateForExternals(true) ,LocalGenerators(localGenerators) ,HaveTargetsAndLibs(false) { @@ -115,7 +116,8 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, __set_bool_if_set(this->GenerateForExecutables, "GRAPHVIZ_EXECUTABLES"); __set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS"); __set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS"); - __set_bool_if_set(this->GenerateForModuleLibs , "GRAPHVIZ_MODULE_LIBS"); + __set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS"); + __set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS"); cmStdString tmpRegexString; __set_if_set(tmpRegexString, "GRAPHVIZ_TARGET_IGNORE_REGEX"); @@ -321,7 +323,10 @@ void cmGraphVizWriter::CollectTargetsAndLibs() { this->HaveTargetsAndLibs = true; int cnt = this->CollectAllTargets(); - this->CollectAllExternalLibs(cnt); + if (this->GenerateForExternals) + { + this->CollectAllExternalLibs(cnt); + } } } diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index 105eb96..cfe4e36 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -67,6 +67,7 @@ protected: bool GenerateForStaticLibs; bool GenerateForSharedLibs; bool GenerateForModuleLibs; + bool GenerateForExternals; cmsys::RegularExpression TargetIgnoreRegex; -- cgit v0.12 From 4f96a7621fe57cd42dc659572eb2a31c84c65abd Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 5 Feb 2011 19:09:54 +0100 Subject: GRAPHVIZ_IGNORE_TARGETS is now a list of regular expressions This is similar e.g. to CTEST_CUSTOM_WARNING_EXCEPTION from ctest. GRAPHVIZ_TARGET_IGNORE_REGEX is not supported anymore. I hope this is ok, since this was 100% undocumented and can't break a build. Alex --- Source/cmGraphVizWriter.cxx | 52 ++++++++++++++++++++++++++------------------- Source/cmGraphVizWriter.h | 4 +--- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 5a08ca6..079d30e 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -119,28 +119,28 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, __set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS"); __set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS"); - cmStdString tmpRegexString; - __set_if_set(tmpRegexString, "GRAPHVIZ_TARGET_IGNORE_REGEX"); - if (tmpRegexString.size() > 0) - { - if (!this->TargetIgnoreRegex.compile(tmpRegexString.c_str())) - { - std::cerr << "Could not compile bad regex \"" << tmpRegexString << "\"" - << std::endl; - } - } + cmStdString ignoreTargetsRegexes; + __set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS"); - this->TargetsToIgnore.clear(); - const char* ignoreTargets = mf->GetDefinition("GRAPHVIZ_IGNORE_TARGETS"); - if ( ignoreTargets ) + this->TargetsToIgnoreRegex.clear(); + if (ignoreTargetsRegexes.size() > 0) { - std::vector ignoreTargetsVector; - cmSystemTools::ExpandListArgument(ignoreTargets,ignoreTargetsVector); - for(std::vector::iterator itvIt = ignoreTargetsVector.begin(); - itvIt != ignoreTargetsVector.end(); + std::vector ignoreTargetsRegExVector; + cmSystemTools::ExpandListArgument(ignoreTargetsRegexes, + ignoreTargetsRegExVector); + for(std::vector::const_iterator itvIt + = ignoreTargetsRegExVector.begin(); + itvIt != ignoreTargetsRegExVector.end(); ++ itvIt ) { - this->TargetsToIgnore.insert(itvIt->c_str()); + cmStdString currentRegexString(*itvIt); + cmsys::RegularExpression currentRegex; + if (!currentRegex.compile(currentRegexString.c_str())) + { + std::cerr << "Could not compile bad regex \"" << currentRegexString + << "\"" << std::endl; + } + this->TargetsToIgnoreRegex.push_back(currentRegex); } } @@ -415,14 +415,22 @@ int cmGraphVizWriter::CollectAllExternalLibs(int cnt) bool cmGraphVizWriter::IgnoreThisTarget(const char* name) { - if (this->TargetIgnoreRegex.is_valid()) + for(std::vector::iterator itvIt + = this->TargetsToIgnoreRegex.begin(); + itvIt != this->TargetsToIgnoreRegex.end(); + ++ itvIt ) { - if (this->TargetIgnoreRegex.find(name)) + cmsys::RegularExpression& regEx = *itvIt; + if (regEx.is_valid()) { - return true; + if (regEx.find(name)) + { + return true; + } } } - return (this->TargetsToIgnore.find(name) != this->TargetsToIgnore.end()); + + return false; } diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index cfe4e36..cd7a627 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -69,9 +69,7 @@ protected: bool GenerateForModuleLibs; bool GenerateForExternals; - cmsys::RegularExpression TargetIgnoreRegex; - - std::set TargetsToIgnore; + std::vector TargetsToIgnoreRegex; const std::vector& LocalGenerators; -- cgit v0.12 From 08fa5ddb1c0eac593aff143d0d6b00dd284df2a1 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 6 Feb 2011 18:34:48 +0100 Subject: Also generate dependers-graphviz files. With this commit, the --graphviz option now also generates dot files which show which other targets depend on some target. So, now there is * a global dot-file which shows all targets and dependencies * a dot file which shows on what a target Foo depends * a dot file which shows which other targets depend on Foo Alex --- Source/cmGraphVizWriter.cxx | 133 ++++++++++++++++++++++++++++++++++++++++++++ Source/cmGraphVizWriter.h | 6 ++ Source/cmake.cxx | 1 + 3 files changed, 140 insertions(+) diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 079d30e..15bad52 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -147,6 +147,54 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, } +// Iterate over all targets and write for each one a graph which shows +// which other targets depend on it. +void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName) +{ + this->CollectTargetsAndLibs(); + + for(std::map::const_iterator ptrIt = + this->TargetPtrs.begin(); + ptrIt != this->TargetPtrs.end(); + ++ptrIt) + { + if (ptrIt->second == NULL) + { + continue; + } + + if (this->GenerateForTargetType(ptrIt->second->GetType()) == false) + { + continue; + } + + std::string currentFilename = fileName; + currentFilename += "."; + currentFilename += ptrIt->first; + currentFilename += ".dependers"; + + cmGeneratedFileStream str(currentFilename.c_str()); + if ( !str ) + { + return; + } + + std::set insertedConnections; + std::set insertedNodes; + + std::cout << "Writing " << currentFilename << "..." << std::endl; + this->WriteHeader(str); + + this->WriteDependerConnections(ptrIt->first.c_str(), + insertedNodes, insertedConnections, str); + + this->WriteFooter(str); + } +} + + +// Iterate over all targets and write for each one a graph which shows +// on which targets it depends. void cmGraphVizWriter::WritePerTargetFiles(const char* fileName) { this->CollectTargetsAndLibs(); @@ -299,6 +347,91 @@ void cmGraphVizWriter::WriteConnections(const char* targetName, } +void cmGraphVizWriter::WriteDependerConnections(const char* targetName, + std::set& insertedNodes, + std::set& insertedConnections, + cmGeneratedFileStream& str) const +{ + std::map::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; + + // now search who links against me + for(std::map::const_iterator dependerIt = + this->TargetPtrs.begin(); + dependerIt != this->TargetPtrs.end(); + ++dependerIt) + { + if (dependerIt->second == NULL) + { + continue; + } + + if (this->GenerateForTargetType(dependerIt->second->GetType()) == false) + { + continue; + } + + // Now we have a target, check whether it links against targetName. + // If so, draw a connection, and then continue with dependers on that one. + const cmTarget::LinkLibraryVectorType* ll = + &(dependerIt->second->GetOriginalLinkLibraries()); + + for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin(); + llit != ll->end(); + ++ llit ) + { + std::string libName = llit->first.c_str(); + if (libName == targetName) + { + // So this target links against targetName. + std::map::const_iterator dependerNodeNameIt = + this->TargetNamesNodes.find(dependerIt->first); + + if(dependerNodeNameIt != this->TargetNamesNodes.end()) + { + std::string connectionName = dependerNodeNameIt->second; + connectionName += "-"; + connectionName += myNodeName; + + if (insertedConnections.find(connectionName) == + insertedConnections.end()) + { + insertedConnections.insert(connectionName); + this->WriteNode(dependerIt->first.c_str(), dependerIt->second, + insertedNodes, str); + + str << " \"" << dependerNodeNameIt->second << "\" -> \"" + << myNodeName << "\""; + str << " // " < " <first<WriteDependerConnections(dependerIt->first.c_str(), + insertedNodes, insertedConnections, str); + } + + + } + break; + } + } + } + +} + + void cmGraphVizWriter::WriteNode(const char* targetName, const cmTarget* target, std::set& insertedNodes, diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h index cd7a627..f784aa0 100644 --- a/Source/cmGraphVizWriter.h +++ b/Source/cmGraphVizWriter.h @@ -30,6 +30,7 @@ public: const char* fallbackSettingsFileName); void WritePerTargetFiles(const char* fileName); + void WriteTargetDependersFiles(const char* fileName); void WriteGlobalFile(const char* fileName); @@ -48,6 +49,11 @@ protected: std::set& insertedConnections, cmGeneratedFileStream& str) const; + void WriteDependerConnections(const char* targetName, + std::set& insertedNodes, + std::set& insertedConnections, + cmGeneratedFileStream& str) const; + void WriteNode(const char* targetName, const cmTarget* target, std::set& insertedNodes, cmGeneratedFileStream& str) const; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index bab0aaf..c8de913 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2898,6 +2898,7 @@ void cmake::GenerateGraphViz(const char* fileName) const gvWriter->ReadSettings(settingsFile.c_str(), fallbackSettingsFile.c_str()); gvWriter->WritePerTargetFiles(fileName); + gvWriter->WriteTargetDependersFiles(fileName); gvWriter->WriteGlobalFile(fileName); #endif -- cgit v0.12