Merge topic 'fix-typos-identified-using-codespell'

207373802e Fix typos identified using codespell

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5040
diff --git a/Auxiliary/CMakeLists.txt b/Auxiliary/CMakeLists.txt
index a833c79..c0aebef 100644
--- a/Auxiliary/CMakeLists.txt
+++ b/Auxiliary/CMakeLists.txt
@@ -1,4 +1,16 @@
-install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMAKE_XDGDATA_DIR}/vim/vimfiles)
-install(FILES cmake-mode.el DESTINATION ${CMAKE_XDGDATA_DIR}/emacs/site-lisp)
+# Install Vim files to a typical system integration directory.
+# Packagers can set CMake_INSTALL_VIMFILES_DIR to control this.
+if(NOT CMake_INSTALL_VIMFILES_DIR)
+  set(CMake_INSTALL_VIMFILES_DIR ${CMAKE_XDGDATA_DIR}/vim/vimfiles)
+endif()
+install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMake_INSTALL_VIMFILES_DIR})
+
+# Install Emacs files to a typical system integration directory.
+# Packagers can set CMake_INSTALL_EMACS_DIR to control this.
+if(NOT CMake_INSTALL_EMACS_DIR)
+  set(CMake_INSTALL_EMACS_DIR ${CMAKE_XDGDATA_DIR}/emacs/site-lisp)
+endif()
+install(FILES cmake-mode.el DESTINATION ${CMake_INSTALL_EMACS_DIR})
+
 install(FILES cmake.m4 DESTINATION ${CMAKE_XDGDATA_DIR}/aclocal)
 add_subdirectory (bash-completion)
diff --git a/Auxiliary/bash-completion/CMakeLists.txt b/Auxiliary/bash-completion/CMakeLists.txt
index 06d22c2..93b6ffd 100644
--- a/Auxiliary/bash-completion/CMakeLists.txt
+++ b/Auxiliary/bash-completion/CMakeLists.txt
@@ -6,11 +6,16 @@
 # with) as well as a simple installation by a local user into their home
 # directory *if* the prefix is `$HOME/.local` since `.local/share/` is part of
 # the bash-completion search path too.
-# For more complex installations, packagers can set CMAKE_BASH_COMP_DIR to
-# another system location.
+# For more complex installations, packagers can set CMake_INSTALL_BASH_COMP_DIR
+# to another system location.
 
-set(CMAKE_BASH_COMP_DIR_DEFAULT ${CMAKE_XDGDATA_DIR}/bash-completion/completions)
-if (NOT CMAKE_BASH_COMP_DIR)
-  set(CMAKE_BASH_COMP_DIR "${CMAKE_BASH_COMP_DIR_DEFAULT}")
+if(NOT CMake_INSTALL_BASH_COMP_DIR)
+  if(CMAKE_BASH_COMP_DIR)
+    # Honor previous customization option.
+    set(CMake_INSTALL_BASH_COMP_DIR "${CMAKE_BASH_COMP_DIR}")
+  else()
+    # Default.
+    set(CMake_INSTALL_BASH_COMP_DIR ${CMAKE_XDGDATA_DIR}/bash-completion/completions)
+  endif()
 endif()
-install(FILES cmake cpack ctest DESTINATION ${CMAKE_BASH_COMP_DIR})
+install(FILES cmake cpack ctest DESTINATION ${CMake_INSTALL_BASH_COMP_DIR})
diff --git a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
index c9ece22..f0200f3 100644
--- a/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
+++ b/Help/prop_tgt/EXCLUDE_FROM_ALL.rst
@@ -19,3 +19,10 @@
 in an :command:`install(TARGETS)` command, but the user is responsible for
 ensuring that the target's build artifacts are not missing or outdated when
 an install is performed.
+
+This property may use "generator expressions" with the syntax ``$<...>``. See
+the :manual:`cmake-generator-expressions(7)` manual for available expressions.
+
+Only the "Ninja Multi-Config" generator supports a property value that varies by
+configuration.  For all other generators the value of this property must be the
+same for all configurations.
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 2b07b7c..17beadc 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -89,25 +89,7 @@
     message(CHECK_START "Check size of ${type}")
   endif()
 
-  # Include header files.
-  set(headers)
-  if(builtin)
-    if(HAVE_SYS_TYPES_H)
-      string(APPEND headers "#include <sys/types.h>\n")
-    endif()
-    if(HAVE_STDINT_H)
-      string(APPEND headers "#include <stdint.h>\n")
-    endif()
-    if(HAVE_STDDEF_H)
-      string(APPEND headers "#include <stddef.h>\n")
-    endif()
-  endif()
-  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
-    string(APPEND headers "#include \"${h}\"\n")
-  endforeach()
-
-  # Perform the check.
-
+  # Perform language check
   if(language STREQUAL "C")
     set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
   elseif(language STREQUAL "CXX")
@@ -115,6 +97,37 @@
   else()
     message(FATAL_ERROR "Unknown language:\n  ${language}\nSupported languages: C, CXX.\n")
   endif()
+
+  # Include header files.
+  set(headers)
+  if(builtin)
+    if(language STREQUAL "CXX" AND type MATCHES "^std::")
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_CSTDINT)
+        string(APPEND headers "#include <cstdint>\n")
+      endif()
+      if(HAVE_CSTDDEF)
+        string(APPEND headers "#include <cstddef>\n")
+      endif()
+    else()
+      if(HAVE_SYS_TYPES_H)
+        string(APPEND headers "#include <sys/types.h>\n")
+      endif()
+      if(HAVE_STDINT_H)
+        string(APPEND headers "#include <stdint.h>\n")
+      endif()
+      if(HAVE_STDDEF_H)
+        string(APPEND headers "#include <stddef.h>\n")
+      endif()
+    endif()
+  endif()
+  foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
+    string(APPEND headers "#include \"${h}\"\n")
+  endforeach()
+
+  # Perform the check.
   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
   configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
   try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
@@ -232,8 +245,13 @@
       check_include_file(stddef.h HAVE_STDDEF_H)
     elseif(_language STREQUAL "CXX")
       check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
-      check_include_file_cxx(stdint.h HAVE_STDINT_H)
-      check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      if("${TYPE}" MATCHES "^std::")
+        check_include_file_cxx(cstdint HAVE_CSTDINT)
+        check_include_file_cxx(cstddef HAVE_CSTDDEF)
+      else()
+        check_include_file_cxx(stdint.h HAVE_STDINT_H)
+        check_include_file_cxx(stddef.h HAVE_STDDEF_H)
+      endif()
     endif()
   endif()
   unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index a015db9..871da4f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 18)
-set(CMake_VERSION_PATCH 20200721)
+set(CMake_VERSION_PATCH 20200723)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 659a512..3bf4409 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -220,8 +220,9 @@
 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
     QSet<QCMakeProperty> oldProps = this->properties().toSet();
 #else
-    QSet<QCMakeProperty> oldProps = QSet<QCMakeProperty>(
-      this->properties().begin(), this->properties().end());
+    QCMakePropertyList const& oldPropsList = this->properties();
+    QSet<QCMakeProperty> oldProps =
+      QSet<QCMakeProperty>(oldPropsList.begin(), oldPropsList.end());
 #endif
     oldProps.intersect(newProps);
     newProps.subtract(oldProps);
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index a1a0ae8..fdc8f29 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1476,8 +1476,9 @@
     }
 
     if (isInterfaceProperty) {
-      return target->EvaluateInterfaceProperty(propertyName, context,
-                                               dagCheckerParent);
+      return cmGeneratorExpression::StripEmptyListElements(
+        target->EvaluateInterfaceProperty(propertyName, context,
+                                          dagCheckerParent));
     }
 
     cmGeneratorExpressionDAGChecker dagChecker(
@@ -1563,8 +1564,9 @@
     }
 
     if (!interfacePropertyName.empty()) {
-      result = this->EvaluateDependentExpression(result, context->LG, context,
-                                                 target, &dagChecker, target);
+      result = cmGeneratorExpression::StripEmptyListElements(
+        this->EvaluateDependentExpression(result, context->LG, context, target,
+                                          &dagChecker, target));
       std::string linkedTargetsContent = getLinkedTargetsContent(
         target, interfacePropertyName, context, &dagChecker);
       if (!linkedTargetsContent.empty()) {
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9dc86f4..5eff3b8 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -5,8 +5,12 @@
 #include <memory>
 #include <utility>
 
+#include <cmext/algorithm>
+
+#include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
+#include "cmMakefile.h"
 #include "cmProperty.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
@@ -31,6 +35,8 @@
       lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
     DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
     dirTarget.LG = lg.get();
+    const std::vector<std::string>& configs =
+      lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
     // The directory-level rule should depend on the target-level rules
     // for all targets in the directory.
@@ -46,11 +52,18 @@
       }
       DirectoryTarget::Target t;
       t.GT = gt.get();
-      if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
-        if (cmIsOn(*exclude)) {
-          // This target has been explicitly excluded.
-          t.ExcludeFromAll = true;
-        } else {
+      const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL");
+      if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) {
+        for (const std::string& config : configs) {
+          cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config,
+                                                            gt.get());
+          if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+            // This target has been explicitly excluded.
+            t.ExcludedFromAllInConfigs.push_back(config);
+          }
+        }
+
+        if (t.ExcludedFromAllInConfigs.empty()) {
           // This target has been explicitly un-excluded.  The directory-level
           // rule for every directory between this and the root should depend
           // on the target-level rule for this target.
@@ -78,3 +91,12 @@
 
   return dirTargets;
 }
+
+bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
+  const DirectoryTarget::Target& t, const std::string& config)
+{
+  if (this->IsMultiConfig()) {
+    return cm::contains(t.ExcludedFromAllInConfigs, config);
+  }
+  return !t.ExcludedFromAllInConfigs.empty();
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index 7d16dac..f97b5f4 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -30,7 +30,7 @@
     struct Target
     {
       cmGeneratorTarget const* GT = nullptr;
-      bool ExcludeFromAll = false;
+      std::vector<std::string> ExcludedFromAllInConfigs;
     };
     std::vector<Target> Targets;
     struct Dir
@@ -41,6 +41,8 @@
     std::vector<Dir> Children;
   };
   std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
+  bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t,
+                                 const std::string& config);
 };
 
 #endif
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 49b73a8..5c07e31 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -309,17 +309,7 @@
         continue;
       }
 
-      std::vector<std::string> configs =
-        target->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
-      std::vector<cmSourceFile*> srcs;
-      for (std::string const& config : configs) {
-        target->GetSourceFiles(srcs, config);
-        if (!srcs.empty()) {
-          break;
-        }
-      }
-
-      if (srcs.empty()) {
+      if (target->GetAllConfigSources().empty()) {
         std::ostringstream e;
         e << "No SOURCES given to target: " << target->GetName();
         this->GetCMakeInstance()->IssueMessage(
@@ -2173,13 +2163,38 @@
 }
 
 bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
-                                   cmGeneratorTarget* target) const
+                                   const cmGeneratorTarget* target) const
 {
   if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
     return true;
   }
-  if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
-    return cmIsOn(*exclude);
+  cmMakefile* mf = root->GetMakefile();
+  const std::string EXCLUDE_FROM_ALL = "EXCLUDE_FROM_ALL";
+  if (cmProp exclude = target->GetProperty(EXCLUDE_FROM_ALL)) {
+    // Expand the property value per configuration.
+    unsigned int trueCount = 0;
+    unsigned int falseCount = 0;
+    const std::vector<std::string>& configs =
+      mf->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+    for (const std::string& config : configs) {
+      cmGeneratorExpressionInterpreter genexInterpreter(root, config, target);
+      if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
+        ++trueCount;
+      } else {
+        ++falseCount;
+      }
+    }
+
+    // Check whether the genex expansion of the property agrees in all
+    // configurations.
+    if (trueCount && falseCount) {
+      std::ostringstream e;
+      e << "The EXCLUDED_FROM_ALL property of target \"" << target->GetName()
+        << "\" varies by configuration. This is not supported by the \""
+        << root->GetGlobalGenerator()->GetName() << "\" generator.";
+      mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    }
+    return trueCount;
   }
   // This target is included in its directory.  Check whether the
   // directory is excluded.
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 57c7808..c2c80c2 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -542,7 +542,8 @@
   bool IsExcluded(cmStateSnapshot const& root,
                   cmStateSnapshot const& snp) const;
   bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen) const;
-  bool IsExcluded(cmLocalGenerator* root, cmGeneratorTarget* target) const;
+  bool IsExcluded(cmLocalGenerator* root,
+                  const cmGeneratorTarget* target) const;
   virtual void InitializeProgressMarks() {}
 
   struct GlobalTargetInfo
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 2fcba9a..1664dd0 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -470,7 +470,7 @@
     if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+    if (!IsExcluded(t->GetLocalGenerator(), t)) {
       defaultTargets.push_back(t);
     }
   }
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 48eb405..786cde7 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1357,7 +1357,7 @@
       build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
       configDeps.emplace_back(build.Outputs.front());
       for (DirectoryTarget::Target const& t : dt.Targets) {
-        if (!t.ExcludeFromAll) {
+        if (!IsExcludedFromAllInConfig(t, config)) {
           this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
         }
       }
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 23588d8..1764429 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -416,7 +416,7 @@
   std::vector<std::string> depends;
   for (DirectoryTarget::Target const& t : dt.Targets) {
     // Add this to the list of depends rules in this directory.
-    if ((!check_all || !t.ExcludeFromAll) &&
+    if ((!check_all || t.ExcludedFromAllInConfigs.empty()) &&
         (!check_relink ||
          t.GT->NeedRelinkBeforeInstall(lg->GetConfigName()))) {
       // The target may be from a different directory; use its local gen.
@@ -846,7 +846,7 @@
       cmLocalGenerator* tlg = gt->GetLocalGenerator();
 
       if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
-          gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
+          IsExcluded(lg.get(), gt.get())) {
         continue;
       }
 
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 0fcda4e..c23156d 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -67,6 +67,36 @@
       return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
   }
 }
+
+struct DependeesDir
+{
+  template <typename T>
+  static const cmLinkItem& src(const T& con)
+  {
+    return con.src;
+  }
+
+  template <typename T>
+  static const cmLinkItem& dst(const T& con)
+  {
+    return con.dst;
+  }
+};
+
+struct DependersDir
+{
+  template <typename T>
+  static const cmLinkItem& src(const T& con)
+  {
+    return con.dst;
+  }
+
+  template <typename T>
+  static const cmLinkItem& dst(const T& con)
+  {
+    return con.src;
+  }
+};
 }
 
 cmGraphVizWriter::cmGraphVizWriter(std::string const& fileName,
@@ -173,18 +203,16 @@
     return;
   }
 
+  // write global data directly
   this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
 
   if (this->GeneratePerTarget) {
-    auto fileStream = PerTargetFileStreams[depender.AsStr()].get();
-    this->WriteNode(*fileStream, dependee);
-    this->WriteConnection(*fileStream, depender, dependee, scopeType);
+    PerTargetConnections[depender].emplace_back(depender, dependee, scopeType);
   }
 
   if (this->GenerateDependers) {
-    auto fileStream = TargetDependersFileStreams[dependee.AsStr()].get();
-    this->WriteNode(*fileStream, depender);
-    this->WriteConnection(*fileStream, depender, dependee, scopeType);
+    TargetDependersConnections[dependee].emplace_back(dependee, depender,
+                                                      scopeType);
   }
 }
 
@@ -288,10 +316,86 @@
     }
   }
 
+  // write global data and collect all connection data for per target graphs
   for (auto const gt : sortedGeneratorTargets) {
     auto item = cmLinkItem(gt, false, gt->GetBacktrace());
     this->VisitItem(item);
   }
+
+  if (this->GeneratePerTarget) {
+    WritePerTargetConnections<DependeesDir>(PerTargetConnections,
+                                            PerTargetFileStreams);
+  }
+
+  if (this->GenerateDependers) {
+    WritePerTargetConnections<DependersDir>(TargetDependersConnections,
+                                            TargetDependersFileStreams);
+  }
+}
+
+void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
+                                          const cmLinkItem& rootItem,
+                                          Connections& extendedCons,
+                                          std::set<cmLinkItem>& visitedItems)
+{
+  // some "targets" are not in map, e.g. linker flags as -lm or
+  // targets without dependency.
+  // in both cases we are finished with traversing the graph
+  if (connectionMap.find(rootItem) == connectionMap.cend()) {
+    return;
+  }
+
+  const Connections& origCons = connectionMap.at(rootItem);
+
+  for (const Connection& con : origCons) {
+    extendedCons.emplace_back(con);
+    const cmLinkItem& dstItem = con.dst;
+    bool const visited = visitedItems.find(dstItem) != visitedItems.cend();
+    if (!visited) {
+      visitedItems.insert(dstItem);
+      FindAllConnections(connectionMap, dstItem, extendedCons, visitedItems);
+    }
+  }
+}
+
+void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap,
+                                          const cmLinkItem& rootItem,
+                                          Connections& extendedCons)
+{
+  std::set<cmLinkItem> visitedItems = { rootItem };
+  FindAllConnections(connectionMap, rootItem, extendedCons, visitedItems);
+}
+
+template <typename DirFunc>
+void cmGraphVizWriter::WritePerTargetConnections(
+  const ConnectionsMap& connections, const FileStreamMap& streams)
+{
+  // the per target connections must be extended by indirect dependencies
+  ConnectionsMap extendedConnections;
+  for (auto const& conPerTarget : connections) {
+    const cmLinkItem& rootItem = conPerTarget.first;
+    Connections& extendedCons = extendedConnections[conPerTarget.first];
+    FindAllConnections(connections, rootItem, extendedCons);
+  }
+
+  for (auto const& conPerTarget : extendedConnections) {
+    const cmLinkItem& rootItem = conPerTarget.first;
+
+    // some of the nodes are excluded completely and are not written
+    if (this->ItemExcluded(rootItem)) {
+      continue;
+    }
+
+    const Connections& cons = conPerTarget.second;
+    auto fileStream = streams.at(rootItem.AsStr()).get();
+
+    for (const Connection& con : cons) {
+      const cmLinkItem& src = DirFunc::src(con);
+      const cmLinkItem& dst = DirFunc::dst(con);
+      this->WriteNode(*fileStream, con.dst);
+      this->WriteConnection(*fileStream, src, dst, con.scopeType);
+    }
+  }
 }
 
 void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& fs,
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 578660d..9766068 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -7,16 +7,18 @@
 
 #include <map>
 #include <memory>
+#include <set>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "cmsys/RegularExpression.hxx"
 
 #include "cmGeneratedFileStream.h"
+#include "cmLinkItem.h"
 #include "cmLinkItemGraphVisitor.h"
 #include "cmStateTypes.h"
 
-class cmLinkItem;
 class cmGlobalGenerator;
 
 /** This class implements writing files for graphviz (dot) for graphs
@@ -47,6 +49,22 @@
   using FileStreamMap =
     std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
 
+  struct Connection
+  {
+    Connection(cmLinkItem s, cmLinkItem d, std::string scope)
+      : src(std::move(s))
+      , dst(std::move(d))
+      , scopeType(std::move(scope))
+    {
+    }
+
+    cmLinkItem src;
+    cmLinkItem dst;
+    std::string scopeType;
+  };
+  using Connections = std::vector<Connection>;
+  using ConnectionsMap = std::map<cmLinkItem, Connections>;
+
   void VisitLink(cmLinkItem const& depender, cmLinkItem const& dependee,
                  bool isDirectLink, std::string const& scopeType = "");
 
@@ -66,6 +84,19 @@
                        cmLinkItem const& dependeeTargetName,
                        std::string const& edgeStyle);
 
+  void FindAllConnections(const ConnectionsMap& connectionMap,
+                          const cmLinkItem& rootItem,
+                          Connections& extendedCons,
+                          std::set<cmLinkItem>& visitedItems);
+
+  void FindAllConnections(const ConnectionsMap& connectionMap,
+                          const cmLinkItem& rootItem,
+                          Connections& extendedCons);
+
+  template <typename DirFunc>
+  void WritePerTargetConnections(const ConnectionsMap& connections,
+                                 const FileStreamMap& streams);
+
   bool ItemExcluded(cmLinkItem const& item);
   bool ItemNameFilteredOut(std::string const& itemName);
   bool TargetTypeEnabled(cmStateEnums::TargetType targetType) const;
@@ -83,6 +114,9 @@
   FileStreamMap PerTargetFileStreams;
   FileStreamMap TargetDependersFileStreams;
 
+  ConnectionsMap PerTargetConnections;
+  ConnectionsMap TargetDependersConnections;
+
   std::string GraphName;
   std::string GraphHeader;
   std::string GraphNodePrefix;
diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake
index b5eafa6..5571c3d 100644
--- a/Tests/GeneratorExpression/check-part3.cmake
+++ b/Tests/GeneratorExpression/check-part3.cmake
@@ -9,11 +9,11 @@
 check(test_version_equal_2 "1")
 
 if(config AND NOT config STREQUAL NoConfig)
-  if(NOT "${test_imported_includes}" MATCHES "^;*/imported[12]/include/with space;*$")
+  if(NOT "${test_imported_includes}" MATCHES "^[^;]*/imported[12]/include/with space$")
     message(SEND_ERROR "test_imported_includes is not correct: ${test_imported_includes}")
   endif()
 else()
-  if(NOT "${test_imported_includes}" MATCHES "^;;$")
+  if(NOT "${test_imported_includes}" MATCHES "^$")
     message(SEND_ERROR "test_imported_includes is not an empty list: ${test_imported_includes}")
   endif()
 endif()
diff --git a/Tests/Module/CheckTypeSize/CMakeLists.txt b/Tests/Module/CheckTypeSize/CMakeLists.txt
index 16989fe2..102cf0c 100644
--- a/Tests/Module/CheckTypeSize/CMakeLists.txt
+++ b/Tests/Module/CheckTypeSize/CMakeLists.txt
@@ -21,6 +21,8 @@
 
 # Check CXX types
 check_type_size(bool        SIZEOF_BOOL LANGUAGE CXX)
+check_type_size(uint8_t     SIZEOF_UINT8_T LANGUAGE CXX)
+check_type_size(std::uint8_t SIZEOF_STD_UINT8_T LANGUAGE CXX)
 
 set(CMAKE_EXTRA_INCLUDE_FILES someclass.hxx)
 check_type_size("((ns::someclass*)0)->someint" SIZEOF_NS_CLASSMEMBER_INT LANGUAGE CXX)
diff --git a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
index 15dc890..45cd393 100644
--- a/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
+++ b/Tests/Module/CheckTypeSize/CheckTypeSize.cxx
@@ -11,6 +11,12 @@
 #ifdef HAVE_STDDEF_H
 #  include <stddef.h>
 #endif
+#ifdef HAVE_CSTDINT
+#  include <cstdint>
+#endif
+#ifdef HAVE_CSTDDEF
+#  include <cstddef>
+#endif
 
 #include <stdio.h>
 
@@ -122,6 +128,26 @@
   NODEF(SIZEOF_SSIZE_T);
 #endif
 
+/* uint8_t */
+#if defined(SIZEOF_UINT8_T)
+  CHECK(uint8_t, SIZEOF_UINT8_T);
+#  if !defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(HAVE_SIZEOF_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_UINT8_T)
+  NODEF(SIZEOF_UINT8_T);
+#endif
+
+/* std::uint8_t */
+#if defined(SIZEOF_STD_UINT8_T)
+  CHECK(std::uint8_t, SIZEOF_STD_UINT8_T);
+#  if !defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(HAVE_SIZEOF_STD_UINT8_T);
+#  endif
+#elif defined(HAVE_SIZEOF_STD_UINT8_T)
+  NODEF(SIZEOF_STD_UINT8_T);
+#endif
+
 /* ns::someclass::someint */
 #if defined(SIZEOF_NS_CLASSMEMBER_INT)
   CHECK(y.someint, SIZEOF_NS_CLASSMEMBER_INT);
diff --git a/Tests/Module/CheckTypeSize/config.hxx.in b/Tests/Module/CheckTypeSize/config.hxx.in
index 8c66ade..9a80689 100644
--- a/Tests/Module/CheckTypeSize/config.hxx.in
+++ b/Tests/Module/CheckTypeSize/config.hxx.in
@@ -1,11 +1,21 @@
 #cmakedefine HAVE_SYS_TYPES_H
 #cmakedefine HAVE_STDINT_H
 #cmakedefine HAVE_STDDEF_H
+#cmakedefine HAVE_CSTDINT
+#cmakedefine HAVE_CSTDDEF
 
 /* bool */
 #cmakedefine HAVE_SIZEOF_BOOL
 @SIZEOF_BOOL_CODE@
 
+/* uint8_t */
+#cmakedefine HAVE_SIZEOF_UINT8_T
+@SIZEOF_UINT8_T_CODE@
+
+/* std::uint8_t */
+#cmakedefine HAVE_SIZEOF_STD_UINT8_T
+@SIZEOF_STD_UINT8_T_CODE@
+
 /* struct ns::somestruct::someint */
 #cmakedefine HAVE_SIZEOF_NS_STRUCTMEMBER_INT
 @SIZEOF_NS_STRUCTMEMBER_INT_CODE@
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index b037a6d..36b016f 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -207,6 +207,7 @@
 if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(ExportCompileCommands)
 endif()
+add_RunCMake_test(ExcludeFromAll)
 add_RunCMake_test(ExternalData)
 add_RunCMake_test(FeatureSummary)
 add_RunCMake_test(FPHSA)
@@ -393,7 +394,7 @@
 add_RunCMake_test(CMP0004)
 add_RunCMake_test(TargetPolicies)
 add_RunCMake_test(alias_targets)
-add_RunCMake_test(interface_library)
+add_RunCMake_test(InterfaceLibrary)
 add_RunCMake_test(no_install_prefix)
 add_RunCMake_test(configure_file)
 add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME})
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/CMakeLists.txt
copy to Tests/RunCMake/ExcludeFromAll/CMakeLists.txt
diff --git a/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
new file mode 100644
index 0000000..25201e4
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/RunCMakeTest.cmake
@@ -0,0 +1,26 @@
+include(RunCMake)
+
+function(run_single_config_test label config exclude_from_all_value expectation)
+    set(case single-config)
+    message("-- Starting ${case} test: ${label}")
+    set(full_case_name "${case}-build-${config}")
+    set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${full_case_name}/")
+    run_cmake_with_options(${case}
+        -DCMAKE_BUILD_TYPE=${config}
+        -DTOOL_EXCLUDE_FROM_ALL=${exclude_from_all_value})
+    set(RunCMake_TEST_NO_CLEAN 1)
+    include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+    run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config ${config})
+endfunction()
+
+run_single_config_test("explictly not excluded" Debug 0 "should_exist")
+run_single_config_test("excluded" Debug 1 "should_not_exist")
+
+if(RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio)")
+    run_cmake(error-on-mixed-config)
+else()
+    run_single_config_test("explicitly not excluded with genex"
+        Release $<CONFIG:Debug> "should_exist")
+    run_single_config_test("excluded with genex"
+        Debug $<CONFIG:Debug> "should_not_exist")
+endif()
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
similarity index 100%
copy from Tests/RunCMake/interface_library/global-interface-result.txt
copy to Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-result.txt
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
new file mode 100644
index 0000000..eee5278
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error in CMakeLists.txt:
+  The EXCLUDED_FROM_ALL property of target "release_only_tool" varies by
+  configuration.  This is not supported by the "[^"]+"
diff --git a/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
new file mode 100644
index 0000000..6c0ed1d
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/error-on-mixed-config.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
diff --git a/Tests/RunCMake/ExcludeFromAll/main.c b/Tests/RunCMake/ExcludeFromAll/main.c
new file mode 100644
index 0000000..5047a34
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/main.c
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
new file mode 100644
index 0000000..1c455f2
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config-build-check.cmake
@@ -0,0 +1,17 @@
+if(expectation STREQUAL "should_not_exist")
+    set(should_exist FALSE)
+elseif(expectation STREQUAL "should_exist")
+    set(should_exist TRUE)
+else()
+    message(FATAL_ERROR "Encountered unknown expectation: ${expectation}")
+endif()
+
+if(EXISTS "${TARGET_FILE_tool_${config}}")
+    if(NOT should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should not exist.")
+    endif()
+else()
+    if(should_exist)
+        message(FATAL_ERROR "${TARGET_FILE_tool_${config}} should exist.")
+    endif()
+endif()
diff --git a/Tests/RunCMake/ExcludeFromAll/single-config.cmake b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
new file mode 100644
index 0000000..71a9f06
--- /dev/null
+++ b/Tests/RunCMake/ExcludeFromAll/single-config.cmake
@@ -0,0 +1,11 @@
+enable_language(C)
+add_executable(tool main.c)
+set_property(TARGET tool PROPERTY EXCLUDE_FROM_ALL "${TOOL_EXCLUDE_FROM_ALL}")
+
+include(../NinjaMultiConfig/Common.cmake)
+set(orig_CMAKE_CONFIGURATION_TYPES ${CMAKE_CONFIGURATION_TYPES})
+if("${CMAKE_CONFIGURATION_TYPES}" STREQUAL "")
+    set(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE})
+endif()
+generate_output_files(tool)
+set(CMAKE_CONFIGURATION_TYPES ${orig_CMAKE_CONFIGURATION_TYPES})
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
new file mode 100644
index 0000000..ecf7bfe
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES-check.cmake
@@ -0,0 +1,17 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/out.txt" content)
+
+unset(RunCMake_TEST_FAILED)
+
+if (NOT content MATCHES "(INCLUDES1:${RunCMake_TEST_SOURCE_DIR}/include)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES1: \"${CMAKE_MATCH_1}\"\n")
+endif()
+
+if (NOT content MATCHES "(INCLUDES2:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES2: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(INCLUDES3:><)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for INCLUDES3: \"${CMAKE_MATCH_1}\"\n")
+endif()
+if (NOT content MATCHES "(CUSTOM:>;;<)")
+  string(APPEND RunCMake_TEST_FAILED "wrong content for CUSTOM: \"${CMAKE_MATCH_1}\"\n")
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
index cb6f4d8..e9855be 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_PROPERTY-INCLUDE_DIRECTORIES.cmake
@@ -14,5 +14,10 @@
 add_library(foo4 STATIC empty.c)
 target_include_directories(foo4 PUBLIC $<TARGET_PROPERTY:foo3,INCLUDE_DIRECTORIES>)
 
+add_library (foo5 SHARED empty.c)
+set_property(TARGET foo5 PROPERTY INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CUDA>:/include/CUDA>" "$<$<COMPILE_LANGUAGE:Fortran>:/include/Fortran>")
+set_property(TARGET foo5 PROPERTY CUSTOM ";;")
+
 # Evaluate a genex that looks up INCLUDE_DIRECTORIES on multiple targets.
-file(GENERATE OUTPUT out.txt CONTENT "$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>")
+file(GENERATE OUTPUT out.txt CONTENT "INCLUDES1:$<TARGET_PROPERTY:foo4,INCLUDE_DIRECTORIES>\nINCLUDES2:>$<TARGET_PROPERTY:foo5,INTERFACE_INCLUDE_DIRECTORIES><\nINCLUDES3:>$<TARGET_PROPERTY:foo5,INCLUDE_DIRECTORIES><\nCUSTOM:>$<TARGET_PROPERTY:foo5,CUSTOM><\n")
diff --git a/Tests/RunCMake/Graphviz/default_options-check.cmake b/Tests/RunCMake/Graphviz/default_options-check.cmake
index c9a7562..584e276 100644
--- a/Tests/RunCMake/Graphviz/default_options-check.cmake
+++ b/Tests/RunCMake/Graphviz/default_options-check.cmake
@@ -3,3 +3,11 @@
 ensure_files_match(
         ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_default_options.dot
         ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
+
+ensure_files_match(
+        ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
+        ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot.GraphicApplication)
+
+ensure_files_match(
+        ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
+        ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot.CompilerFlags.dependers)
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
new file mode 100644
index 0000000..92fe609
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependencies.dot.GraphicApplication
@@ -0,0 +1,26 @@
+digraph "GraphicApplication" {
+node [
+  fontsize = "12"
+];
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node0" [ label = "CompilerFlags", shape = pentagon ];
+    "node2" -> "node0"  // CoreLibrary -> CompilerFlags
+    "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+    "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node8" [ label = "\"-lm\"", shape = septagon ];
+    "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+    "node0" [ label = "CompilerFlags", shape = pentagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+    "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
new file mode 100644
index 0000000..82a2efe
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_target_dependers.dot.CompilerFlags.dependers
@@ -0,0 +1,30 @@
+digraph "CompilerFlags" {
+node [
+  fontsize = "12"
+];
+    "node0" [ label = "CompilerFlags", shape = pentagon ];
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node2" -> "node0"  // CoreLibrary -> CompilerFlags
+    "node4" [ label = "SystemLibrary", shape = octagon ];
+    "node4" -> "node2" [ style = dotted ] // SystemLibrary -> CoreLibrary
+    "node2" [ label = "CoreLibrary", shape = octagon ];
+    "node2" -> "node4" [ style = dotted ] // CoreLibrary -> SystemLibrary
+    "node1" [ label = "ConsoleApplication", shape = egg ];
+    "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+    "node6" [ label = "GraphicApplication", shape = egg ];
+    "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+    "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+    "node7" -> "node0"  // GraphicLibrary -> CompilerFlags
+    "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+    "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+    "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+    "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+}
diff --git a/Tests/RunCMake/interface_library/CMakeLists.txt b/Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/CMakeLists.txt
rename to Tests/RunCMake/InterfaceLibrary/CMakeLists.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-bad-value.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-bad-value.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-iface.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-iface.cmake
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-result.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-result.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported-stderr.txt
diff --git a/Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake b/Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/IMPORTED_LIBNAME-non-imported.cmake
rename to Tests/RunCMake/InterfaceLibrary/IMPORTED_LIBNAME-non-imported.cmake
diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/RunCMakeTest.cmake
rename to Tests/RunCMake/InterfaceLibrary/RunCMakeTest.cmake
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-result.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-result.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET-stderr.txt
diff --git a/Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake b/Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/add_custom_command-TARGET.cmake
rename to Tests/RunCMake/InterfaceLibrary/add_custom_command-TARGET.cmake
diff --git a/Tests/RunCMake/interface_library/genex_link-result.txt b/Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link-result.txt
rename to Tests/RunCMake/InterfaceLibrary/genex_link-result.txt
diff --git a/Tests/RunCMake/interface_library/genex_link.cmake b/Tests/RunCMake/InterfaceLibrary/genex_link.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/genex_link.cmake
rename to Tests/RunCMake/InterfaceLibrary/genex_link.cmake
diff --git a/Tests/RunCMake/interface_library/global-interface-result.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface-result.txt
rename to Tests/RunCMake/InterfaceLibrary/global-interface-result.txt
diff --git a/Tests/RunCMake/interface_library/global-interface-stderr.txt b/Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/global-interface-stderr.txt
diff --git a/Tests/RunCMake/interface_library/global-interface.cmake b/Tests/RunCMake/InterfaceLibrary/global-interface.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/global-interface.cmake
rename to Tests/RunCMake/InterfaceLibrary/global-interface.cmake
diff --git a/Tests/RunCMake/interface_library/invalid_name-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-result.txt
diff --git a/Tests/RunCMake/interface_library/invalid_name-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_name-stderr.txt
diff --git a/Tests/RunCMake/interface_library/invalid_name.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_name.cmake
rename to Tests/RunCMake/InterfaceLibrary/invalid_name.cmake
diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_signature-result.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature-result.txt
diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_signature-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature-stderr.txt
diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/invalid_signature.cmake
rename to Tests/RunCMake/InterfaceLibrary/invalid_signature.cmake
diff --git a/Tests/RunCMake/interface_library/no_shared_libs.cmake b/Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/no_shared_libs.cmake
rename to Tests/RunCMake/InterfaceLibrary/no_shared_libs.cmake
diff --git a/Tests/RunCMake/interface_library/target_commands-result.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-result.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-result.txt
diff --git a/Tests/RunCMake/interface_library/target_commands-stderr.txt b/Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/target_commands-stderr.txt
diff --git a/Tests/RunCMake/interface_library/target_commands.cmake b/Tests/RunCMake/InterfaceLibrary/target_commands.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/target_commands.cmake
rename to Tests/RunCMake/InterfaceLibrary/target_commands.cmake
diff --git a/Tests/RunCMake/interface_library/whitelist-result.txt b/Tests/RunCMake/InterfaceLibrary/whitelist-result.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/whitelist-result.txt
rename to Tests/RunCMake/InterfaceLibrary/whitelist-result.txt
diff --git a/Tests/RunCMake/interface_library/whitelist-stderr.txt b/Tests/RunCMake/InterfaceLibrary/whitelist-stderr.txt
similarity index 100%
rename from Tests/RunCMake/interface_library/whitelist-stderr.txt
rename to Tests/RunCMake/InterfaceLibrary/whitelist-stderr.txt
diff --git a/Tests/RunCMake/interface_library/whitelist.cmake b/Tests/RunCMake/InterfaceLibrary/whitelist.cmake
similarity index 100%
rename from Tests/RunCMake/interface_library/whitelist.cmake
rename to Tests/RunCMake/InterfaceLibrary/whitelist.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
new file mode 100644
index 0000000..a4d2758
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll-all-build-check.cmake
@@ -0,0 +1,9 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+  INCLUDE
+    ${TARGET_FILE_release_only_tool_Release}
+    ${TARGET_EXE_FILE_release_only_tool_Release}
+
+  EXCLUDE
+    ${TARGET_FILE_release_only_tool_Debug}
+    ${TARGET_EXE_FILE_release_only_tool_Debug}
+  )
diff --git a/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
new file mode 100644
index 0000000..52f84ea
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/ExcludeFromAll.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "")
+set(CMAKE_DEFAULT_BUILD_TYPE "Release" CACHE STRING "")
+set(CMAKE_CROSS_CONFIGS "all" CACHE STRING "")
+set(CMAKE_DEFAULT_CONFIGS "all" CACHE STRING "")
+
+add_executable(release_only_tool main.c)
+set_property(TARGET release_only_tool PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:Release>>")
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(release_only_tool)
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index 76b488e..9249724 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -274,6 +274,11 @@
 file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/install")
 run_ninja(Install all-install build.ninja install:all)
 
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExcludeFromAll-build)
+run_cmake_configure(ExcludeFromAll)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(ExcludeFromAll all "" all:all)
+
 # FIXME Get this working
 #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
 #run_cmake_configure(AutoMocExecutable)