diff options
-rw-r--r-- | Help/release/dev/graphviz-line-styles.rst | 6 | ||||
-rw-r--r-- | Modules/CMakeDetermineCompilerId.cmake | 9 | ||||
-rw-r--r-- | Modules/CMakeGraphVizOptions.cmake | 3 | ||||
-rw-r--r-- | Modules/CompilerId/Xcode-3.pbxproj.in | 1 | ||||
-rw-r--r-- | Source/CMakeVersion.cmake | 2 | ||||
-rw-r--r-- | Source/cmGraphVizWriter.cxx | 103 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 44 |
7 files changed, 148 insertions, 20 deletions
diff --git a/Help/release/dev/graphviz-line-styles.rst b/Help/release/dev/graphviz-line-styles.rst new file mode 100644 index 0000000..d24f236 --- /dev/null +++ b/Help/release/dev/graphviz-line-styles.rst @@ -0,0 +1,6 @@ +graphviz-line-styles +------------------------- + +* The graphviz output now distinguishes between the different dependency types + ``PUBLIC``, ``PRIVATE`` and ``INTERFACE`` and represents them in the output graph + as solid, dashed and dotted edges. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 0a93e5f..cddc966 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -321,12 +321,19 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} set(id_product_type "com.apple.product-type.tool") if(CMAKE_OSX_SYSROOT) set(id_sdkroot "SDKROOT = \"${CMAKE_OSX_SYSROOT}\";") - if(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ii][Pp][Hh][Oo][Nn][Ee]") + if(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ii][Pp][Hh][Oo][Nn][Ee]" OR + CMAKE_OSX_SYSROOT MATCHES "(^|/)[Aa][Pp][Pp][Ll][Ee][Tt][Vv]") set(id_product_type "com.apple.product-type.bundle.unit-test") endif() else() set(id_sdkroot "") endif() + if(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM) + set(id_development_team + "DEVELOPMENT_TEAM = \"${CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM}\";") + else() + set(id_development_team "") + endif() configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-3.pbxproj.in ${id_dir}/CompilerId${lang}.xcodeproj/project.pbxproj @ONLY) unset(_ENV_MACOSX_DEPLOYMENT_TARGET) diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake index 3976581..0d7f1d9 100644 --- a/Modules/CMakeGraphVizOptions.cmake +++ b/Modules/CMakeGraphVizOptions.cmake @@ -20,6 +20,9 @@ # * a ``foo.dot.<target>`` file for each target, file showing on which other targets the respective target depends # * a ``foo.dot.<target>.dependers`` file, showing which other targets depend on the respective target # +# The different dependency types ``PUBLIC``, ``PRIVATE`` and ``INTERFACE`` +# are represented as solid, dashed and dotted edges. +# # This can result in huge graphs. Using the file # ``CMakeGraphVizOptions.cmake`` the look and content of the generated # graphs can be influenced. This file is searched first in diff --git a/Modules/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in index 84f48ae..1cbaa57 100644 --- a/Modules/CompilerId/Xcode-3.pbxproj.in +++ b/Modules/CompilerId/Xcode-3.pbxproj.in @@ -72,6 +72,7 @@ 1DEB928608733DD80010E9CD = { isa = XCBuildConfiguration; buildSettings = { + @id_development_team@ PRODUCT_NAME = CompilerId@id_lang@; }; name = Debug; diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 666293c..10e0e85 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 9) -set(CMake_VERSION_PATCH 20170922) +set(CMake_VERSION_PATCH 20170925) #set(CMake_VERSION_RC 1) 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); } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 73fa8fb..aa4c5ac 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -227,20 +227,38 @@ add_RunCMake_test(separate_arguments) add_RunCMake_test(set_property) add_RunCMake_test(string) add_RunCMake_test(test_include_dirs) -foreach(var - CMAKE_C_COMPILER_ID - CMAKE_C_COMPILER_VERSION - CMAKE_C_STANDARD_DEFAULT - CMAKE_CXX_COMPILER_ID - CMAKE_CXX_COMPILER_VERSION - CMAKE_CXX_STANDARD_DEFAULT - CMake_TEST_CUDA - ) - if(DEFINED ${var}) - list(APPEND try_compile_ARGS -D${var}=${${var}}) + +function(add_RunCMake_test_try_compile) + if(CMAKE_VERSION VERSION_LESS 3.9.20170907 AND "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") + # Older CMake versions do not know about MSVC language standards. + # Approximate our logic from MSVC-CXX.cmake. + if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) OR + CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.10.25017) + set(CMAKE_CXX_STANDARD_DEFAULT 14) + elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0) + set(CMAKE_CXX_STANDARD_DEFAULT "") + else() + unset(CMAKE_CXX_STANDARD_DEFAULT) + endif() endif() -endforeach() -add_RunCMake_test(try_compile) + foreach(var + CMAKE_C_COMPILER_ID + CMAKE_C_COMPILER_VERSION + CMAKE_C_STANDARD_DEFAULT + CMAKE_CXX_COMPILER_ID + CMAKE_CXX_COMPILER_VERSION + CMAKE_CXX_STANDARD_DEFAULT + CMake_TEST_CUDA + ) + if(DEFINED ${var}) + list(APPEND try_compile_ARGS -D${var}=${${var}}) + endif() + endforeach() + add_RunCMake_test(try_compile) +endfunction() +add_RunCMake_test_try_compile() + add_RunCMake_test(try_run) add_RunCMake_test(set) add_RunCMake_test(variable_watch) |