summaryrefslogtreecommitdiffstats
path: root/Source/cmGraphVizWriter.cxx
diff options
context:
space:
mode:
authorNico Müller <nico.mueller@mni.thm.de>2017-09-18 17:22:59 (GMT)
committerNico Müller <nico.mueller@mni.thm.de>2017-09-21 18:49:44 (GMT)
commit5b46cc91d93fe52be614e75e9a08a00f121e8aa7 (patch)
tree8da51681a8bae1d76d68eff35b7b47ee433220a7 /Source/cmGraphVizWriter.cxx
parentdb86cf4e7ebc3a3cb9bf29d2d39986601e6edf90 (diff)
downloadCMake-5b46cc91d93fe52be614e75e9a08a00f121e8aa7.zip
CMake-5b46cc91d93fe52be614e75e9a08a00f121e8aa7.tar.gz
CMake-5b46cc91d93fe52be614e75e9a08a00f121e8aa7.tar.bz2
graphviz: distinguish target dependency types
- The output graph of graphviz differs now between target link types - Updated documentation - Fixes: #17192
Diffstat (limited to 'Source/cmGraphVizWriter.cxx')
-rw-r--r--Source/cmGraphVizWriter.cxx103
1 files changed, 98 insertions, 5 deletions
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 967fd2e..ca87cbf 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGraphVizWriter.h"
+#include <cstddef>
#include <iostream>
#include <sstream>
#include <utility>
@@ -17,7 +18,18 @@
#include "cm_auto_ptr.hxx"
#include "cmake.h"
-static const char* getShapeForTarget(const cmGeneratorTarget* target)
+namespace {
+enum LinkLibraryScopeType
+{
+ LLT_SCOPE_PUBLIC,
+ LLT_SCOPE_PRIVATE,
+ LLT_SCOPE_INTERFACE
+};
+
+const char* const GRAPHVIZ_PRIVATE_EDEGE_STYLE = "dashed";
+const char* const GRAPHVIZ_INTERFACE_EDEGE_STYLE = "dotted";
+
+const char* getShapeForTarget(const cmGeneratorTarget* target)
{
if (!target) {
return "ellipse";
@@ -39,6 +51,76 @@ static const char* getShapeForTarget(const cmGeneratorTarget* target)
return "box";
}
+std::map<std::string, LinkLibraryScopeType> getScopedLinkLibrariesFromTarget(
+ cmTarget* Target)
+{
+ char sep = ';';
+ std::map<std::string, LinkLibraryScopeType> tokens;
+ size_t start = 0, end = 0;
+
+ const char* pInterfaceLinkLibraries =
+ Target->GetProperty("INTERFACE_LINK_LIBRARIES");
+ const char* pLinkLibraries = Target->GetProperty("LINK_LIBRARIES");
+
+ if (!pInterfaceLinkLibraries && !pLinkLibraries) {
+ return tokens; // target is not linked against any other libraries
+ }
+
+ // make sure we don't touch a null-ptr
+ auto interfaceLinkLibraries =
+ std::string(pInterfaceLinkLibraries ? pInterfaceLinkLibraries : "");
+ auto linkLibraries = std::string(pLinkLibraries ? pLinkLibraries : "");
+
+ // first extract interfaceLinkLibraries
+ while (start < interfaceLinkLibraries.length()) {
+
+ if ((end = interfaceLinkLibraries.find(sep, start)) == std::string::npos) {
+ end = interfaceLinkLibraries.length();
+ }
+
+ std::string element = interfaceLinkLibraries.substr(start, end - start);
+ if (std::string::npos == element.find("$<LINK_ONLY:", 0)) {
+ // we assume first, that this library is an interface library.
+ // if we find it again in the linklibraries property, we promote it to an
+ // public library.
+ tokens[element] = LLT_SCOPE_INTERFACE;
+ } else {
+ // this is an private linked static library.
+ // we take care of this case in the second iterator.
+ }
+ start = end + 1;
+ }
+
+ // second extract linkLibraries
+ start = 0;
+ while (start < linkLibraries.length()) {
+
+ if ((end = linkLibraries.find(sep, start)) == std::string::npos) {
+ end = linkLibraries.length();
+ }
+
+ std::string element = linkLibraries.substr(start, end - start);
+
+ if (tokens.find(element) == tokens.end()) {
+ // this library is not found in interfaceLinkLibraries but in
+ // linkLibraries.
+ // this results in a private linked library.
+ tokens[element] = LLT_SCOPE_PRIVATE;
+ } else if (LLT_SCOPE_INTERFACE == tokens[element]) {
+ // this library is found in interfaceLinkLibraries and linkLibraries.
+ // this results in a public linked library.
+ tokens[element] = LLT_SCOPE_PUBLIC;
+ } else {
+ // private and public linked libraries should not be changed anymore.
+ }
+
+ start = end + 1;
+ }
+
+ return tokens;
+}
+}
+
cmGraphVizWriter::cmGraphVizWriter(
const std::vector<cmLocalGenerator*>& localGenerators)
: GraphType("digraph")
@@ -273,11 +355,10 @@ void cmGraphVizWriter::WriteConnections(
}
std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
+ std::map<std::string, LinkLibraryScopeType> ll =
+ getScopedLinkLibrariesFromTarget(targetPtrIt->second->Target);
- const cmTarget::LinkLibraryVectorType* ll =
- &(targetPtrIt->second->Target->GetOriginalLinkLibraries());
-
- for (auto const& llit : *ll) {
+ for (auto const& llit : ll) {
const char* libName = llit.first.c_str();
std::map<std::string, std::string>::const_iterator libNameIt =
this->TargetNamesNodes.find(libName);
@@ -297,6 +378,18 @@ void cmGraphVizWriter::WriteConnections(
insertedNodes, str);
str << " \"" << myNodeName << "\" -> \"" << libNameIt->second << "\"";
+
+ switch (llit.second) {
+ case LLT_SCOPE_PRIVATE:
+ str << "[style = " << GRAPHVIZ_PRIVATE_EDEGE_STYLE << "]";
+ break;
+ case LLT_SCOPE_INTERFACE:
+ str << "[style = " << GRAPHVIZ_INTERFACE_EDEGE_STYLE << "]";
+ break;
+ default:
+ break;
+ }
+
str << " // " << targetName << " -> " << libName << std::endl;
this->WriteConnections(libName, insertedNodes, insertedConnections, str);
}