Merge topic 'EXCLUDE_FROM_ALL-genex'

2cdaf43d96 Allow generator expressions in the EXCLUDE_FROM_ALL target property

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5021
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/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index e7ea290..e42b4f0 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -81,8 +81,8 @@
 Next modify ``tutorial.cxx`` to include the configured header file,
 ``TutorialConfig.h``.
 
-Finally, let's print out the version number by updating ``tutorial.cxx`` as
-follows:
+Finally, let's print out the executable name and version number by updating
+``tutorial.cxx`` as follows:
 
 .. literalinclude:: Step2/tutorial.cxx
   :language: c++
@@ -106,7 +106,8 @@
 in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this
 tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the
 ``CMakeLists.txt`` file to 11 and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to
-True:
+True. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the call
+to ``add_executable``.
 
 .. literalinclude:: Step2/CMakeLists.txt
   :language: cmake
@@ -120,18 +121,28 @@
 with your chosen build tool.
 
 For example, from the command line we could navigate to the
-``Help/guide/tutorial`` directory of the CMake source code tree and run the
-following commands:
+``Help/guide/tutorial`` directory of the CMake source code tree and create a
+build directory:
 
 .. code-block:: console
 
   mkdir Step1_build
+
+Next, navigate to the build directory and run CMake to configure the project
+and generate a native build system:
+
+.. code-block:: console
+
   cd Step1_build
   cmake ../Step1
+
+Then call that build system to actually compile/link the project:
+
+.. code-block:: console
+
   cmake --build .
 
-Navigate to the directory where Tutorial was built (likely the make directory
-or a Debug or Release build configuration subdirectory) and run these commands:
+Finally, try to use the newly built ``Tutorial`` with these commands:
 
 .. code-block:: console
 
@@ -212,8 +223,9 @@
 classic approach when dealing with many optional components, we will cover
 the modern approach in the next step.
 
-The corresponding changes to the source code are fairly straightforward. First,
-in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we need it:
+The corresponding changes to the source code are fairly straightforward.
+First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we
+need it:
 
 .. literalinclude:: Step3/tutorial.cxx
   :language: c++
@@ -242,8 +254,17 @@
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
 with your chosen build tool. Then run the built Tutorial executable.
 
-Use the :manual:`ccmake <ccmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>`
-to update the value of ``USE_MYMATH``. Rebuild and run the tutorial again.
+Now let's update the value of ``USE_MYMATH``. The easiest way is to use the
+:manual:`cmake-gui <cmake-gui(1)>` or  :manual:`ccmake <ccmake(1)>` if you're
+in the terminal. Or, alternatively, if you want to change the option from the
+command-line, try:
+
+.. code-block:: console
+
+  cmake ../Step2 -DUSE_MYMATH=OFF
+
+Rebuild and run the tutorial again.
+
 Which function gives better results, sqrt or mysqrt?
 
 Adding Usage Requirements for Library (Step 3)
@@ -320,21 +341,32 @@
 
 That is all that is needed to create a basic local install of the tutorial.
 
-Run the :manual:`cmake  <cmake(1)>` executable or the
+Now run the :manual:`cmake  <cmake(1)>` executable or the
 :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool. Run the install step by using the ``install``
-option of the :manual:`cmake  <cmake(1)>` command (introduced in 3.15, older
-versions of CMake must use ``make install``) from the command line, or build
-the ``INSTALL`` target from an IDE. This will install the appropriate header
-files, libraries, and executables.
+with your chosen build tool.
+
+Then run the install step by using the ``install`` option of the
+:manual:`cmake  <cmake(1)>` command (introduced in 3.15, older versions of
+CMake must use ``make install``) from the command line. For
+multi-configuration tools, don't forget to use the ``--config`` argument to
+specify the configuration. If using an IDE, simply build the ``INSTALL``
+target. This step will install the appropriate header files, libraries, and
+executables. For example:
+
+.. code-block:: console
+
+  cmake --install .
 
 The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
-root of where the files will be installed. If using ``cmake --install`` a
-custom installation directory can be given via the ``--prefix`` argument. For
-multi-configuration tools, use the ``--config`` argument to specify the
-configuration.
+root of where the files will be installed. If using the ``cmake --install``
+command, the installation prefix can be overidden via the ``--prefix``
+argument. For example:
 
-Verify that the installed Tutorial runs.
+.. code-block:: console
+
+  cmake --install . --prefix "/home/myuser/installdir"
+
+Navigate to the install directory and verify that the installed Tutorial runs.
 
 Testing Support
 ---------------
@@ -750,7 +782,7 @@
 :manual:`generator expressions <cmake-generator-expressions(7)>` is to
 conditionally add compiler flags, such as those for language levels or
 warnings. A nice pattern is to associate this information to an ``INTERFACE``
-target allowing this information to propagate. Lets start by constructing an
+target allowing this information to propagate. Let's start by constructing an
 ``INTERFACE`` target and specifying the required C++ standard level of ``11``
 instead of using :variable:`CMAKE_CXX_STANDARD`.
 
diff --git a/Help/prop_tgt/DEBUG_POSTFIX.rst b/Help/prop_tgt/DEBUG_POSTFIX.rst
index 04e312e..eca7cb0 100644
--- a/Help/prop_tgt/DEBUG_POSTFIX.rst
+++ b/Help/prop_tgt/DEBUG_POSTFIX.rst
@@ -1,7 +1,7 @@
 DEBUG_POSTFIX
 -------------
 
-See target property ``<CONFIG>_POSTFIX``.
+See target property :prop_tgt:`<CONFIG>_POSTFIX`.
 
-This property is a special case of the more-general ``<CONFIG>_POSTFIX``
+This property is a special case of the more-general :prop_tgt:`<CONFIG>_POSTFIX`
 property for the ``DEBUG`` configuration.
diff --git a/Help/release/3.18.rst b/Help/release/3.18.rst
index 386b61b..427840e 100644
--- a/Help/release/3.18.rst
+++ b/Help/release/3.18.rst
@@ -318,3 +318,17 @@
 
 * The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object gained
   a new ``precompileHeaders`` field in the ``compileGroups`` objects.
+
+Updates
+=======
+
+Changes made since CMake 3.18.0 include the following.
+
+3.18.1
+------
+
+* The :generator:`Xcode` generator, when :variable:`CMAKE_OSX_ARCHITECTURES`
+  is not defined, now selects ``$(NATIVE_ARCH_ACTUAL)`` as the default
+  architecture (the Xcode ``ARCHS`` setting).  This is needed for Xcode 12
+  to select the host's architecture, which older versions of Xcode did
+  by default.
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index ebfd5a4..8200200 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -490,6 +490,12 @@
         set(id_clang_cxx_library "CLANG_CXX_LIBRARY = \"${CMAKE_MATCH_3}\";")
       endif()
     endif()
+    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_SYSROOT MATCHES "^$|[Mm][Aa][Cc][Oo][Ss]")
+      # When targeting macOS, use only the host architecture.
+      set(id_archs [[ARCHS = "$(NATIVE_ARCH_ACTUAL)";]])
+    else()
+      set(id_archs "")
+    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/CompilerId/Xcode-3.pbxproj.in b/Modules/CompilerId/Xcode-3.pbxproj.in
index 672044e..6fe17e5 100644
--- a/Modules/CompilerId/Xcode-3.pbxproj.in
+++ b/Modules/CompilerId/Xcode-3.pbxproj.in
@@ -84,6 +84,7 @@
 				CODE_SIGNING_REQUIRED = NO;
 				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
 				SYMROOT = .;
+				@id_archs@
 				@id_toolset@
 				@id_lang_version@
 				@id_clang_cxx_library@
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index aa83575..958a22e 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -59,6 +59,7 @@
   X11_XShm_INCLUDE_PATH,         (in X11_Xext_LIB),  X11_XShm_FOUND
   X11_Xshape_INCLUDE_PATH,       (in X11_Xext_LIB),  X11_Xshape_FOUND
   X11_XSync_INCLUDE_PATH,        (in X11_Xext_LIB),  X11_XSync_FOUND
+  X11_Xaw_INCLUDE_PATH,          X11_Xaw_LIB         X11_Xaw_FOUND         X11::Xaw
 #]=======================================================================]
 
 if (UNIX)
@@ -100,6 +101,7 @@
   find_path(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h  ${X11_INC_SEARCH_PATH})
   find_path(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h      ${X11_INC_SEARCH_PATH})
   find_path(X11_Xau_INCLUDE_PATH X11/Xauth.h                         ${X11_INC_SEARCH_PATH})
+  find_path(X11_Xaw_INCLUDE_PATH X11/Xaw/Intrinsic.h                 ${X11_INC_SEARCH_PATH})
   find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h                           ${X11_INC_SEARCH_PATH})
   find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h                  ${X11_INC_SEARCH_PATH})
   find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h               ${X11_INC_SEARCH_PATH})
@@ -134,6 +136,8 @@
   find_path(X11_Xv_INCLUDE_PATH X11/extensions/Xvlib.h               ${X11_INC_SEARCH_PATH})
   find_path(X11_XSync_INCLUDE_PATH X11/extensions/sync.h             ${X11_INC_SEARCH_PATH})
 
+
+
   # Backwards compatibility.
   set(X11_Xinput_INCLUDE_PATH "${X11_Xi_INCLUDE_PATH}")
   set(X11_xf86misc_INCLUDE_PATH "${X11_Xxf86misc_INCLUDE_PATH}")
@@ -148,6 +152,7 @@
   find_library(X11_ICE_LIB ICE               ${X11_LIB_SEARCH_PATH})
   find_library(X11_SM_LIB SM                 ${X11_LIB_SEARCH_PATH})
   find_library(X11_Xau_LIB Xau               ${X11_LIB_SEARCH_PATH})
+  find_library(X11_Xaw_LIB Xaw               ${X11_LIB_SEARCH_PATH})
   find_library(X11_xcb_LIB xcb               ${X11_LIB_SEARCH_PATH})
   find_library(X11_X11_xcb_LIB X11-xcb       ${X11_LIB_SEARCH_PATH})
   find_library(X11_xcb_icccm_LIB xcb-icccm   ${X11_LIB_SEARCH_PATH})
@@ -392,6 +397,10 @@
      set(X11_SM_FOUND TRUE)
   endif()
 
+  if(X11_Xaw_LIB AND X11_Xaw_INCLUDE_PATH)
+      set(X11_Xaw_FOUND TRUE)
+  endif()
+
   # Most of the X11 headers will be in the same directories, avoid
   # creating a huge list of duplicates.
   if (X11_INCLUDE_DIR)
@@ -519,6 +528,14 @@
       INTERFACE_INCLUDE_DIRECTORIES "${X11_Xau_INCLUDE_PATH}")
   endif ()
 
+  if (X11_Xaw_FOUND AND NOT TARGET X11::Xaw)
+    add_library(X11::Xaw UNKNOWN IMPORTED)
+    set_target_properties(X11::Xaw PROPERTIES
+      IMPORTED_LOCATION "${X11_Xaw_LIB}"
+      INTERFACE_INCLUDE_DIRECTORIES "${X11_Xaw_INCLUDE_PATH}"
+      INTERFACE_LINK_LIBRARIES "X11::Xext;X11::Xmu;X11::Xt;X11::Xpm;X11::X11")
+  endif ()
+
   if (X11_xcb_FOUND AND NOT TARGET X11::xcb)
     add_library(X11::xcb UNKNOWN IMPORTED)
     set_target_properties(X11::xcb PROPERTIES
@@ -817,6 +834,8 @@
     X11_SM_LIB
     X11_SM_INCLUDE_PATH
     X11_XSync_INCLUDE_PATH
+    X11_Xaw_LIB
+    X11_Xaw_INCLUDE_PATH
   )
   set(CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK_SAVE})
   set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE})
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 0d7701c..6e7191e 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 20200716)
+set(CMake_VERSION_PATCH 20200722)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
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/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 72dc80b..4fe68d2 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1365,6 +1365,9 @@
 
     for (const cmLinkImplItem& library : libraries->Libraries) {
       if (const cmGeneratorTarget* dependency = library.Target) {
+        if (dependency->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+          continue;
+        }
         if (cm::contains(dependency->GetAllConfigCompileLanguages(),
                          "Swift")) {
           EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 2d47d2c..e54de5d 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -12,6 +12,7 @@
 
 #include <cm/memory>
 #include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
@@ -272,6 +273,13 @@
   return makeProgram;
 }
 
+bool cmGlobalXCodeGenerator::SetSystemName(std::string const& s,
+                                           cmMakefile* mf)
+{
+  this->SystemName = s;
+  return this->cmGlobalGenerator::SetSystemName(s, mf);
+}
+
 bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
                                                  bool build, cmMakefile* mf)
 {
@@ -3375,6 +3383,14 @@
   if (archs.empty()) {
     // Tell Xcode to use NATIVE_ARCH instead of ARCHS.
     buildSettings->AddAttribute("ONLY_ACTIVE_ARCH", this->CreateString("YES"));
+    // When targeting macOS, use only the host architecture.
+    if (this->SystemName == "Darwin"_s &&
+        (!sysroot || !*sysroot ||
+         cmSystemTools::LowerCase(sysroot).find("macos") !=
+           std::string::npos)) {
+      buildSettings->AddAttribute("ARCHS",
+                                  this->CreateString("$(NATIVE_ARCH_ACTUAL)"));
+    }
   } else {
     // Tell Xcode to use ARCHS (ONLY_ACTIVE_ARCH defaults to NO).
     buildSettings->AddAttribute("ARCHS", this->CreateString(archs));
@@ -3406,6 +3422,12 @@
   std::string symroot = cmStrCat(root->GetCurrentBinaryDirectory(), "/build");
   buildSettings->AddAttribute("SYMROOT", this->CreateString(symroot));
 
+  // Inside a try_compile project, do not require signing on any platform.
+  if (this->CMakeInstance->GetIsInTryCompile()) {
+    buildSettings->AddAttribute("CODE_SIGNING_ALLOWED",
+                                this->CreateString("NO"));
+  }
+
   for (auto& config : configs) {
     cmXCodeObject* buildSettingsForCfg = this->CreateFlatClone(buildSettings);
 
@@ -3474,7 +3496,8 @@
   }
 
   if (this->Architectures.empty()) {
-    // With no ARCHS we use ONLY_ACTIVE_ARCH.
+    // With no ARCHS we use ONLY_ACTIVE_ARCH and possibly a
+    // platform-specific default ARCHS placeholder value.
     // Look up the arch that Xcode chooses in this case.
     if (const char* arch = mf->GetDefinition("CMAKE_XCODE_ARCHS")) {
       this->ObjectDirArchDefault = arch;
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 276a9ee..7018de7 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -109,6 +109,7 @@
 
   bool ShouldStripResourcePath(cmMakefile*) const override;
 
+  bool SetSystemName(std::string const& s, cmMakefile* mf) override;
   bool SetGeneratorToolset(std::string const& ts, bool build,
                            cmMakefile* mf) override;
   void AppendFlag(std::string& flags, std::string const& flag) const;
@@ -301,6 +302,7 @@
   std::vector<std::string> Architectures;
   std::string ObjectDirArchDefault;
   std::string ObjectDirArch;
+  std::string SystemName;
   std::string GeneratorToolset;
   std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
   std::vector<std::string> EnabledLangs;
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/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 66e1e40..de68371 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -733,8 +733,13 @@
     static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
     globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
 
-  build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
-                                           genTarget->GetName() + ".rsp");
+  std::string path = localGen.GetHomeRelativeOutputPath();
+  if (!path.empty()) {
+    path += '/';
+  }
+  build.RspFile = this->ConvertToNinjaPath(
+    cmStrCat(path, "CMakeFiles/", genTarget->GetName(),
+             globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
 
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(
@@ -1154,8 +1159,13 @@
       globalGen->GetRuleCmdLength(linkBuild.Rule);
   }
 
-  linkBuild.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
-                                               gt->GetName() + ".rsp");
+  std::string path = localGen.GetHomeRelativeOutputPath();
+  if (!path.empty()) {
+    path += '/';
+  }
+  linkBuild.RspFile = this->ConvertToNinjaPath(
+    cmStrCat(path, "CMakeFiles/", gt->GetName(),
+             globalGen->IsMultiConfig() ? cmStrCat('.', config) : "", ".rsp"));
 
   // Gather order-only dependencies.
   this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index cc67ac2..e0b2116 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -3,6 +3,10 @@
 #ifndef cmStandardLexer_h
 #define cmStandardLexer_h
 
+#if defined(__linux)
+/* Needed for glibc < 2.12 */
+#  define _XOPEN_SOURCE 600
+#endif
 #if !defined(_WIN32) && !defined(__sun)
 /* POSIX APIs are needed */
 #  define _POSIX_C_SOURCE 200809L
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index 5ef67d0..af9fa96 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -24,7 +24,7 @@
 pngtest: main.o
 	@$(CMAKE_FOO) -DMODE=LINK >$(tmp)
 	@foo="`cat $(tmp)`"; \
-	 printf '"%s" %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
+	 printf '"%s" %s %s %s -o pngtest main.o %s\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$(LDFLAGS)" "$$foo" >$(tmp)
 	@cat $(tmp)
 	@sh $(tmp)
 	@rm -f $(tmp)
diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt
index b2adfb2..7325b32 100644
--- a/Tests/FindX11/Test/CMakeLists.txt
+++ b/Tests/FindX11/Test/CMakeLists.txt
@@ -29,6 +29,7 @@
 set(X11_X11_FOUND ${X11_FOUND})
 test_x11_component(x11_components X11)
 test_x11_component(x11_components Xau)
+test_x11_component(x11_components Xaw)
 test_x11_component(x11_components xcb)
 test_x11_component(x11_components X11_xcb)
 test_x11_component(x11_components xcb_icccm)
@@ -67,6 +68,7 @@
 # Not included in X11_LIBRARIES.
 foreach(lib
     Xau
+    Xaw
     xcb
     X11_xcb
     xcb_icccm
diff --git a/Tests/FindX11/Test/main.c b/Tests/FindX11/Test/main.c
index c8144e0..f8c723c 100644
--- a/Tests/FindX11/Test/main.c
+++ b/Tests/FindX11/Test/main.c
@@ -308,6 +308,24 @@
 }
 #endif
 
+#ifdef HAVE_X11_Xaw
+#  include <X11/Intrinsic.h>
+#  include <X11/Xaw/Box.h>
+
+static void test_Xaw(void)
+{
+  XrmOptionDescRec opt_table[] = { { NULL } };
+
+  Widget toplevel;
+  toplevel =
+    XtInitialize("test", "test", opt_table, XtNumber(opt_table), NULL, NULL);
+  Widget box =
+    XtCreateManagedWidget("testbox", boxWidgetClass, toplevel, NULL, 0);
+  return;
+}
+
+#endif
+
 #include <stddef.h>
 
 int main(int argc, char* argv[])
@@ -392,6 +410,9 @@
 #ifdef HAVE_X11_Xv
     test_Xv,
 #endif
+#ifdef HAVE_X11_Xaw
+    test_Xaw,
+#endif
     NULL,
   };
 
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/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/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index cb20fb1..c13c694 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -154,6 +154,7 @@
 
     "|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
     "|[^\n]*is a member of multiple groups"
+    "|[^\n]*offset in archive not a multiple of 8"
     "|[^\n]*from Time Machine by path"
     "|[^\n]*Bullseye Testing Technology"
     ")[^\n]*\n)+"
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index e24279b..41d14ea 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -35,3 +35,4 @@
 
 # Dummy to make sure generation works with such targets.
 add_library(SwiftIface INTERFACE)
+target_link_libraries(SwiftOnly PRIVATE SwiftIface)
diff --git a/Utilities/std/cm/bits/fs_path.cxx b/Utilities/std/cm/bits/fs_path.cxx
index 71386bb..b8c5631 100644
--- a/Utilities/std/cm/bits/fs_path.cxx
+++ b/Utilities/std/cm/bits/fs_path.cxx
@@ -13,8 +13,10 @@
 #  include <string>
 #  include <utility>
 #  include <vector>
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
 #    include <cctype>
+#  endif
+#  if defined(_WIN32) || defined(__CYGWIN__)
 #    include <iterator>
 #  endif
 
@@ -396,7 +398,7 @@
   pointer consume_root_name(pointer ptr, pointer end,
                             bool check_only = false) noexcept
   {
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
     if (ptr < end) {
       if ((end - ptr) >= 2 && this->is_drive_name(ptr)) {
         // Drive letter (X:) is a root name
@@ -409,7 +411,8 @@
           (ptr[1] == '/' || ptr[1] == '\\') &&
           (ptr[2] != '/' && ptr[2] != '\\')) {
         // server name (//server) is a root name
-        auto pos = std::find(ptr + 2, end, '/');
+        auto pos = std::find_if(ptr + 2, end,
+                                [](char c) { return c == '/' || c == '\\'; });
         if (!check_only) {
           this->Entry = cm::string_view(ptr, pos - ptr);
         }
@@ -438,6 +441,31 @@
         }
       }
     }
+#  elif defined(__CYGWIN__)
+    if (ptr < end) {
+      if ((end - ptr) > 2 && ptr[0] == '/' && ptr[1] == '/' && ptr[2] != '/') {
+        // server name (//server) is a root name
+        auto pos = std::find(ptr + 2, end, '/');
+        if (!check_only) {
+          this->Entry = cm::string_view(ptr, pos - ptr);
+        }
+        return pos;
+      }
+    } else {
+      if ((ptr - end) > 2 && ptr[0] != '/') {
+        std::reverse_iterator<pointer> start(ptr);
+        std::reverse_iterator<pointer> stop(end);
+        auto res = std::find(start, stop, '/');
+        pointer pos = res.base() - 1;
+        if ((pos - 1) > end && pos[-1] == '/') {
+          // server name (//server) is a root name
+          if (!check_only) {
+            this->Entry = cm::string_view(pos - 1, ptr - pos + 2);
+          }
+          return pos - 2;
+        }
+      }
+    }
 #  else
     (void)ptr;
     (void)end;
@@ -514,13 +542,25 @@
     this->path_ += static_cast<std::string>(p.get_root_directory());
   } else if (this->has_filename()) {
     this->path_ += this->preferred_separator;
-#  if defined(_WIN32)
+#  if defined(_WIN32) || defined(__CYGWIN__)
     // special case: "//host" / "b" => "//host/b"
   } else if (this->has_root_name() && !this->has_root_directory()) {
     if (this->path_.length() >= 3 &&
-        (this->path_[0] == '/' || this->path_[0] == '\\') &&
-        (this->path_[1] == '/' || this->path_[1] == '\\') &&
-        (this->path_[2] != '/' || this->path_[2] != '\\')) {
+        (this->path_[0] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[0] == '\\'
+#    endif
+         ) &&
+        (this->path_[1] == '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         || this->path_[1] == '\\'
+#    endif
+         ) &&
+        (this->path_[2] != '/'
+#    if defined(_WIN32) && !defined(__CYGWIN__)
+         && this->path_[2] != '\\'
+#    endif
+         )) {
       this->path_ += this->preferred_separator;
     }
 #  endif
@@ -644,7 +684,7 @@
   }
 
   auto is_path_absolute = [](cm::string_view rn, cm::string_view rd) -> bool {
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
     return !rn.empty() && !rd.empty();
 #  else
     (void)rn;
@@ -659,7 +699,7 @@
     return path();
   }
 
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
   // LWG3070 handle special case: filename can also be a root-name
   auto is_drive_name = [](cm::string_view item) -> bool {
     return item.length() == 2 && item[1] == ':';
@@ -724,7 +764,7 @@
 {
   auto gen_path = this->path_;
   auto start = gen_path.begin();
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
   std::replace(gen_path.begin(), gen_path.end(), '\\', '/');
   // preserve special syntax for root_name ('//server' or '//?')
   if (gen_path.length() > 2 && gen_path[2] != '/') {
diff --git a/Utilities/std/cm/filesystem b/Utilities/std/cm/filesystem
index d7ade34..6021712 100644
--- a/Utilities/std/cm/filesystem
+++ b/Utilities/std/cm/filesystem
@@ -27,7 +27,7 @@
 #  include <cm/type_traits>
 #  include <cmext/iterator>
 
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
 #    include <algorithm>
 #  endif
 
@@ -616,7 +616,7 @@
   };
 
 public:
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
   using value_type = wchar_t;
 #  else
   using value_type = char;
@@ -633,7 +633,7 @@
     generic_format
   };
 
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
   static constexpr value_type preferred_separator = L'\\';
 #  else
   static constexpr value_type preferred_separator = '/';
@@ -800,7 +800,7 @@
 
   path& make_preferred()
   {
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
     std::replace(
       this->path_.begin(), this->path_.end(), '/',
       static_cast<path_type::value_type>(this->preferred_separator));
@@ -845,7 +845,7 @@
   // ================
   const string_type& native() const noexcept
   {
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
     this->native_path_ = internals::string_converter<
       path_type::value_type>::to<string_type::value_type>(this->path_);
     return this->native_path_;
@@ -990,9 +990,11 @@
 
   bool is_absolute() const
   {
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
     return this->has_root_name() && this->has_root_directory();
 #  else
+    // For CYGWIN, root_name (i.e. //host or /cygdrive/x) is not considered.
+    // Same as current GNU g++ implementation (9.3).
     return this->has_root_directory();
 #  endif
   }
@@ -1085,7 +1087,7 @@
   int compare_path(cm::string_view str) const;
 
   path_type path_;
-#  if defined(_WIN32)
+#  if defined(_WIN32) && !defined(__CYGWIN__)
   mutable string_type native_path_;
 #  endif
 };
diff --git a/bootstrap b/bootstrap
index 2adb5d9..e6484ce 100755
--- a/bootstrap
+++ b/bootstrap
@@ -625,6 +625,8 @@
   --no-system-bzip2       use cmake-provided bzip2 library (default)
   --system-liblzma        use system-installed liblzma library
   --no-system-liblzma     use cmake-provided liblzma library (default)
+  --system-nghttp2        use system-installed nghttp2 library
+  --no-system-nghttp2     use cmake-provided nghttp2 library (default)
   --system-zstd           use system-installed zstd library
   --no-system-zstd        use cmake-provided zstd library (default)
   --system-libarchive     use system-installed libarchive library
@@ -872,10 +874,10 @@
   --init=*) cmake_init_file=`cmake_arg "$1"` ;;
   --system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
   --no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
-  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-zstd|--system-libuv)
+  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma|--system-nghttp2|--system-zstd|--system-libuv)
     lib=`cmake_arg "$1" "--system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
-  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-zstd|--no-system-libuv)
+  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma|--no-system-nghttp2|--no-system-zstd|--no-system-libuv)
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
   --bootstrap-system-libuv) bootstrap_system_libuv="1" ;;