Merge topic 'dependency-providers'

2aa83fa15b Dependency providers: Add find_package and FetchContent support
8a28368feb FetchContent: Don't discard non-empty SOURCE_DIR and BINARY_DIR
8ce9bb8a0c FetchContent: Don't leak internal variables
74a6ddc339 cmFindPackageCommand: Handle Makefile variable definitions more robustly

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Gerhard Olsson <gerhard.nospam@gmail.com>
Merge-request: !7276
diff --git a/.clang-tidy b/.clang-tidy
index 7b8d200..a86f39a 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -7,7 +7,6 @@
 -bugprone-misplaced-widening-cast,\
 -bugprone-narrowing-conversions,\
 -bugprone-too-small-loop-variable,\
-google-readability-casting,\
 misc-*,\
 -misc-no-recursion,\
 -misc-non-private-member-variables-in-classes,\
@@ -24,6 +23,7 @@
 -readability-convert-member-functions-to-static,\
 -readability-function-cognitive-complexity,\
 -readability-function-size,\
+-readability-identifier-length,\
 -readability-identifier-naming,\
 -readability-implicit-bool-conversion,\
 -readability-inconsistent-declaration-parameter-name,\
diff --git a/.gitignore b/.gitignore
index be848fb..5bd9113 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# Common build directories
+build*/
+
 # Exclude MacOS Finder files.
 .DS_Store
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 09afcb3..2d72170 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,6 +16,7 @@
     - build
     - test
     - test-ext
+    - package
     - upload
 
 ################################################################################
@@ -36,6 +37,7 @@
 
 # Job prefixes:
 #   - `b:` build
+#   - `k:` package
 #   - `l:` lint
 #   - `p:` prep
 #   - `t:` test
@@ -53,7 +55,7 @@
 
 p:doc-package:
     extends:
-        - .fedora35_sphinx_package
+        - .fedora36_sphinx_package
         - .cmake_prep_doc_linux
         - .linux_builder_tags_qt
         - .cmake_doc_artifacts
@@ -101,16 +103,16 @@
         - .linux_builder_tags
         - .run_automatically
 
-l:tidy-fedora35:
+l:tidy-fedora36:
     extends:
-        - .fedora35_tidy
+        - .fedora36_tidy
         - .cmake_build_linux
         - .linux_builder_tags_qt
         - .run_automatically
 
-l:sphinx-fedora35:
+l:sphinx-fedora36:
     extends:
-        - .fedora35_sphinx
+        - .fedora36_sphinx
         - .cmake_build_linux
         - .linux_builder_tags_qt
         - .run_automatically
@@ -118,9 +120,9 @@
         CMAKE_CI_JOB_CONTINUOUS: "true"
         CMAKE_CI_JOB_HELP: "true"
 
-l:clang-analyzer-fedora35:
+l:clang-analyzer-fedora36:
     extends:
-        - .fedora35_clang_analyzer
+        - .fedora36_clang_analyzer
         - .cmake_build_linux
         - .linux_builder_tags_qt
         - .run_automatically
@@ -189,17 +191,17 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora35-makefiles:
+t:fedora36-makefiles:
     extends:
-        - .fedora35_makefiles
+        - .fedora36_makefiles
         - .cmake_test_linux_release
         - .linux_builder_tags_qt
         - .run_dependent
         - .needs_centos6_x86_64
 
-t:fedora35-makefiles-nospace:
+t:fedora36-makefiles-nospace:
     extends:
-        - .fedora35_makefiles
+        - .fedora36_makefiles
         - .cmake_test_linux_release
         - .linux_builder_tags_qt
         - .cmake_junit_artifacts
@@ -207,7 +209,7 @@
         - .needs_centos6_x86_64
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
-        CMAKE_CI_BUILD_NAME: fedora35_makefiles_nospace
+        CMAKE_CI_BUILD_NAME: fedora36_makefiles_nospace
         CMAKE_CI_JOB_NIGHTLY: "true"
 
 t:cuda9.2-nvidia:
@@ -268,9 +270,9 @@
     variables:
         CMAKE_CI_NO_MR: "true"
 
-b:fedora35-ninja:
+b:fedora36-ninja:
     extends:
-        - .fedora35_ninja
+        - .fedora36_ninja
         - .cmake_build_linux
         - .cmake_build_artifacts
         - .linux_builder_tags_qt
@@ -287,31 +289,31 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora35-ninja:
+t:fedora36-ninja:
     extends:
-        - .fedora35_ninja
+        - .fedora36_ninja
         - .cmake_test_linux
         - .linux_builder_tags_x11
         - .cmake_test_artifacts
         - .run_dependent
     dependencies:
-        - b:fedora35-ninja
+        - b:fedora36-ninja
     needs:
-        - b:fedora35-ninja
+        - b:fedora36-ninja
     variables:
         CMAKE_CI_JOB_CONTINUOUS: "true"
 
-t:fedora35-ninja-multi:
+t:fedora36-ninja-multi:
     extends:
-        - .fedora35_ninja_multi
+        - .fedora36_ninja_multi
         - .cmake_test_linux_external
         - .linux_builder_tags_qt
         - .cmake_junit_artifacts
         - .run_dependent
     dependencies:
-        - t:fedora35-ninja
+        - t:fedora36-ninja
     needs:
-        - t:fedora35-ninja
+        - t:fedora36-ninja
 
 t:intel2016-makefiles:
     extends:
@@ -530,6 +532,13 @@
         CMAKE_CI_BUILD_NAME: intel2021.5.0_makefiles
         CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2022.0.2-el8
 
+t:intel2021.6.0-makefiles:
+    extends:
+        - .cmake_test_linux_intelclassic_makefiles
+    variables:
+        CMAKE_CI_BUILD_NAME: intel2021.6.0_makefiles
+        CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2022.1.0-el8
+
 t:oneapi2021.1.1-makefiles:
     extends:
         - .cmake_test_linux_inteloneapi_makefiles
@@ -572,6 +581,13 @@
         CMAKE_CI_BUILD_NAME: oneapi2022.0.2_makefiles
         CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2022.0.2-el8
 
+t:oneapi2022.1.0-makefiles:
+    extends:
+        - .cmake_test_linux_inteloneapi_makefiles
+    variables:
+        CMAKE_CI_BUILD_NAME: oneapi2022.1.0_makefiles
+        CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2022.1.0-el8
+
 b:linux-x86_64-package:
     extends:
         - .linux_package
@@ -618,9 +634,9 @@
 
 ## Sanitizer builds
 
-b:fedora35-asan:
+b:fedora36-asan:
     extends:
-        - .fedora35_asan
+        - .fedora36_asan
         - .cmake_build_linux
         - .cmake_build_artifacts
         - .linux_builder_tags_qt
@@ -628,16 +644,16 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora35-asan:
+t:fedora36-asan:
     extends:
-        - .fedora35_asan
+        - .fedora36_asan
         - .cmake_memcheck_linux
         - .linux_builder_tags_qt
         - .run_dependent
     dependencies:
-        - b:fedora35-asan
+        - b:fedora36-asan
     needs:
-        - b:fedora35-asan
+        - b:fedora36-asan
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -969,3 +985,69 @@
         - t:windows-vs2022-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
+
+b:windows-x86_64-package:
+    extends:
+        - .windows_x86_64_package
+        - .cmake_build_windows
+        - .cmake_build_package_artifacts
+        - .windows_tags_nonconcurrent_vs2022
+        - .run_only_for_package
+    dependencies:
+        - p:doc-package
+    needs:
+        - p:doc-package
+
+k:windows-x86_64-package:
+    extends:
+        - .windows_x86_64_package
+        - .cmake_package_windows
+        - .cmake_release_artifacts
+        - .windows_tags_nonconcurrent_vs2022
+        - .run_only_for_package
+    dependencies:
+        - b:windows-x86_64-package
+    needs:
+        - b:windows-x86_64-package
+
+u:windows-x86_64-package:
+    extends:
+        - .rsync_upload_package
+        - .run_only_for_package
+    dependencies:
+        - k:windows-x86_64-package
+    needs:
+        - k:windows-x86_64-package
+
+b:windows-i386-package:
+    extends:
+        - .windows_i386_package
+        - .cmake_build_windows
+        - .cmake_build_package_artifacts
+        - .windows_tags_nonconcurrent_vs2022
+        - .run_only_for_package
+    dependencies:
+        - p:doc-package
+    needs:
+        - p:doc-package
+
+k:windows-i386-package:
+    extends:
+        - .windows_i386_package
+        - .cmake_package_windows
+        - .cmake_release_artifacts
+        - .windows_tags_nonconcurrent_vs2022
+        - .run_only_for_package
+    dependencies:
+        - b:windows-i386-package
+    needs:
+        - b:windows-i386-package
+
+u:windows-i386-package:
+    extends:
+        - .rsync_upload_package
+        - .run_only_for_package
+    dependencies:
+        - k:windows-i386-package
+    needs:
+        - k:windows-i386-package
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
index 5472c0a..57ae573 100644
--- a/.gitlab/artifacts.yml
+++ b/.gitlab/artifacts.yml
@@ -4,13 +4,8 @@
     artifacts:
         expire_in: 1d
         paths:
-            # XXX(globbing): Can be simplified with support from
-            # https://gitlab.com/gitlab-org/gitlab-runner/issues/4840
-            - build/CTestTestfile.cmake
-            - build/*/CTestTestfile.cmake
-            - build/*/*/CTestTestfile.cmake
-            - build/*/*/*/CTestTestfile.cmake
-            - build/*/*/*/*/CTestTestfile.cmake
+            # Test specifications.
+            - build/**/CTestTestfile.cmake
 
             # Allow CMake to find CMAKE_ROOT.
             - build/CMakeFiles/CMakeSourceDir.txt
@@ -68,6 +63,34 @@
             - build/DartConfiguation.tcl
             - build/CTestCustom.cmake
 
+.cmake_build_package_artifacts:
+    artifacts:
+        expire_in: 1d
+        paths:
+            # Allow CPack to find CMAKE_ROOT.
+            - build/CMakeFiles/CMakeSourceDir.txt
+
+            # Install rules.
+            - build/**/cmake_install.cmake
+
+            # We need the main binaries.
+            - build/bin/
+
+            # Pass through the documentation.
+            - build/install-doc/
+
+            # CPack configuration.
+            - build/CPackConfig.cmake
+            - build/CMakeCPackOptions.cmake
+            - build/Source/QtDialog/QtDialogCPack.cmake
+
+            # CPack/IFW packaging files.
+            - build/CMake*.qs
+
+            # CPack/WIX packaging files.
+            - build/Utilities/Release/WiX/custom_action_dll*.wxs
+            - build/Utilities/Release/WiX/CustomAction/CMakeWiXCustomActions.*
+
 .cmake_release_artifacts:
     artifacts:
         expire_in: 5d
@@ -78,6 +101,8 @@
             - build/cmake-*-linux-x86_64.*
             - build/cmake-*-linux-aarch64.*
             - build/cmake-*-macos*-universal.*
+            - build/cmake-*-windows-x86_64.*
+            - build/cmake-*-windows-i386.*
             # Any source packages made.
             - build/cmake-*.tar.gz
             - build/cmake-*.zip
diff --git a/.gitlab/ci/configure_fedora35_clang_analyzer.cmake b/.gitlab/ci/configure_fedora35_clang_analyzer.cmake
deleted file mode 100644
index 761a323..0000000
--- a/.gitlab/ci/configure_fedora35_clang_analyzer.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake")
diff --git a/.gitlab/ci/configure_fedora35_tidy.cmake b/.gitlab/ci/configure_fedora35_tidy.cmake
deleted file mode 100644
index 752d241..0000000
--- a/.gitlab/ci/configure_fedora35_tidy.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake")
diff --git a/.gitlab/ci/configure_fedora35_asan.cmake b/.gitlab/ci/configure_fedora36_asan.cmake
similarity index 65%
rename from .gitlab/ci/configure_fedora35_asan.cmake
rename to .gitlab/ci/configure_fedora36_asan.cmake
index 84fefad..51977d9 100644
--- a/.gitlab/ci/configure_fedora35_asan.cmake
+++ b/.gitlab/ci/configure_fedora36_asan.cmake
@@ -1,4 +1,4 @@
 set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "")
 set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "")
 
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_clang_analyzer.cmake b/.gitlab/ci/configure_fedora36_clang_analyzer.cmake
new file mode 100644
index 0000000..456936b
--- /dev/null
+++ b/.gitlab/ci/configure_fedora36_clang_analyzer.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_fedora35_common.cmake b/.gitlab/ci/configure_fedora36_common.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora35_common.cmake
rename to .gitlab/ci/configure_fedora36_common.cmake
diff --git a/.gitlab/ci/configure_fedora35_makefiles.cmake b/.gitlab/ci/configure_fedora36_makefiles.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora35_makefiles.cmake
rename to .gitlab/ci/configure_fedora36_makefiles.cmake
diff --git a/.gitlab/ci/configure_fedora35_ninja.cmake b/.gitlab/ci/configure_fedora36_ninja.cmake
similarity index 84%
rename from .gitlab/ci/configure_fedora35_ninja.cmake
rename to .gitlab/ci/configure_fedora36_ninja.cmake
index e6143b7..7e33513 100644
--- a/.gitlab/ci/configure_fedora35_ninja.cmake
+++ b/.gitlab/ci/configure_fedora36_ninja.cmake
@@ -8,4 +8,4 @@
 # Cover compilation with C++11 only and not higher standards.
 set(CMAKE_CXX_STANDARD "11" CACHE STRING "")
 
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora35_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_fedora35_ninja_multi.cmake b/.gitlab/ci/configure_fedora36_ninja_multi.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora35_ninja_multi.cmake
rename to .gitlab/ci/configure_fedora36_ninja_multi.cmake
diff --git a/.gitlab/ci/configure_fedora35_sphinx.cmake b/.gitlab/ci/configure_fedora36_sphinx.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora35_sphinx.cmake
rename to .gitlab/ci/configure_fedora36_sphinx.cmake
diff --git a/.gitlab/ci/configure_fedora35_sphinx_package.cmake b/.gitlab/ci/configure_fedora36_sphinx_package.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora35_sphinx_package.cmake
rename to .gitlab/ci/configure_fedora36_sphinx_package.cmake
diff --git a/.gitlab/ci/configure_fedora36_tidy.cmake b/.gitlab/ci/configure_fedora36_tidy.cmake
new file mode 100644
index 0000000..38414d3
--- /dev/null
+++ b/.gitlab/ci/configure_fedora36_tidy.cmake
@@ -0,0 +1,3 @@
+set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora36_common.cmake")
diff --git a/.gitlab/ci/configure_windows_i386_package.cmake b/.gitlab/ci/configure_windows_i386_package.cmake
new file mode 100644
index 0000000..279f5cf
--- /dev/null
+++ b/.gitlab/ci/configure_windows_i386_package.cmake
@@ -0,0 +1,9 @@
+# CPack package file name component for this platform.
+set(CPACK_SYSTEM_NAME "windows-i386" CACHE STRING "")
+
+# Use APIs from at most Windows 7
+set(CMAKE_C_FLAGS "-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-GR -EHsc -D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000" CACHE STRING "")
+set(CMAKE_EXE_LINKER_FLAGS "-machine:x86 -subsystem:console,6.01" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_package_common.cmake")
diff --git a/.gitlab/ci/configure_windows_package_common.cmake b/.gitlab/ci/configure_windows_package_common.cmake
new file mode 100644
index 0000000..cea0ba0
--- /dev/null
+++ b/.gitlab/ci/configure_windows_package_common.cmake
@@ -0,0 +1,35 @@
+set(CMake_DOC_ARTIFACT_PREFIX "$ENV{CI_PROJECT_DIR}/build/install-doc" CACHE PATH "")
+
+# Set up install destinations as expected by the packaging scripts.
+set(CMAKE_DOC_DIR "doc/cmake" CACHE STRING "")
+
+# Link C/C++ runtime library statically.
+set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING "")
+
+# Enable cmake-gui with static qt plugins
+set(BUILD_QtDialog "TRUE" CACHE BOOL "")
+set(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL "3" CACHE STRING "")
+set(qt "$ENV{CI_PROJECT_DIR}/.gitlab/qt")
+set(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES
+  ${qt}/plugins/platforms/qwindows.lib
+  ${qt}/plugins/styles/qwindowsvistastyle.lib
+  ${qt}/lib/Qt5EventDispatcherSupport.lib
+  ${qt}/lib/Qt5FontDatabaseSupport.lib
+  ${qt}/lib/Qt5ThemeSupport.lib
+  ${qt}/lib/qtfreetype.lib
+  ${qt}/lib/qtlibpng.lib
+  imm32.lib
+  wtsapi32.lib
+  CACHE STRING "")
+set(CMAKE_PREFIX_PATH "${qt}" CACHE STRING "")
+
+# Disable ccmake.
+set(BUILD_CursesDialog "OFF" CACHE BOOL "")
+
+set(CMAKE_SKIP_BOOTSTRAP_TEST "TRUE" CACHE STRING "")
+set(CMake_TEST_Java OFF CACHE BOOL "")
+set(CMake_TEST_Qt5 OFF CACHE BOOL "")
+set(CMake_TEST_Qt6 OFF CACHE BOOL "")
+set(Python_FIND_REGISTRY NEVER CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_windows_x86_64_package.cmake b/.gitlab/ci/configure_windows_x86_64_package.cmake
new file mode 100644
index 0000000..b7bba85
--- /dev/null
+++ b/.gitlab/ci/configure_windows_x86_64_package.cmake
@@ -0,0 +1,9 @@
+# CPack package file name component for this platform.
+set(CPACK_SYSTEM_NAME "windows-x86_64" CACHE STRING "")
+
+# Use APIs from at most Windows 7
+set(CMAKE_C_FLAGS "-D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-GR -EHsc -D_WIN32_WINNT=0x601 -DNTDDI_VERSION=0x06010000" CACHE STRING "")
+set(CMAKE_EXE_LINKER_FLAGS "-machine:x64 -subsystem:console,6.01" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_package_common.cmake")
diff --git a/.gitlab/ci/ctest_memcheck_fedora35_asan.lsan.supp b/.gitlab/ci/ctest_memcheck_fedora36_asan.lsan.supp
similarity index 100%
rename from .gitlab/ci/ctest_memcheck_fedora35_asan.lsan.supp
rename to .gitlab/ci/ctest_memcheck_fedora36_asan.lsan.supp
diff --git a/.gitlab/ci/docker/debian10/install_rvm.sh b/.gitlab/ci/docker/debian10/install_rvm.sh
index 75c5adc..0ebc746 100755
--- a/.gitlab/ci/docker/debian10/install_rvm.sh
+++ b/.gitlab/ci/docker/debian10/install_rvm.sh
@@ -14,6 +14,7 @@
 
 curl -sSL https://get.rvm.io | bash -s stable
 
+# keep version in sync with `env_debian*_ninja.sh`
 /usr/local/rvm/bin/rvm install ruby-2.7.0
 
 tar -C /usr/local -cf /root/rvm.tar rvm
diff --git a/.gitlab/ci/docker/fedora35/Dockerfile b/.gitlab/ci/docker/fedora36/Dockerfile
similarity index 90%
rename from .gitlab/ci/docker/fedora35/Dockerfile
rename to .gitlab/ci/docker/fedora36/Dockerfile
index d1614b4..cf6ded9 100644
--- a/.gitlab/ci/docker/fedora35/Dockerfile
+++ b/.gitlab/ci/docker/fedora36/Dockerfile
@@ -1,10 +1,10 @@
-FROM fedora:35 as rvm-build
+FROM fedora:36 as rvm-build
 MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
 
 COPY install_rvm.sh /root/install_rvm.sh
 RUN sh /root/install_rvm.sh
 
-FROM fedora:35
+FROM fedora:36
 MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
 
 COPY install_deps.sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/fedora35/install_deps.sh b/.gitlab/ci/docker/fedora36/install_deps.sh
similarity index 100%
rename from .gitlab/ci/docker/fedora35/install_deps.sh
rename to .gitlab/ci/docker/fedora36/install_deps.sh
diff --git a/.gitlab/ci/docker/fedora35/install_ispc.sh b/.gitlab/ci/docker/fedora36/install_ispc.sh
similarity index 100%
rename from .gitlab/ci/docker/fedora35/install_ispc.sh
rename to .gitlab/ci/docker/fedora36/install_ispc.sh
diff --git a/.gitlab/ci/docker/fedora35/install_rvm.sh b/.gitlab/ci/docker/fedora36/install_rvm.sh
similarity index 67%
rename from .gitlab/ci/docker/fedora35/install_rvm.sh
rename to .gitlab/ci/docker/fedora36/install_rvm.sh
index fca5104..0011f87 100755
--- a/.gitlab/ci/docker/fedora35/install_rvm.sh
+++ b/.gitlab/ci/docker/fedora36/install_rvm.sh
@@ -13,9 +13,7 @@
 
 curl -sSL https://get.rvm.io | bash -s stable
 
-# This is intentionally an older version.
-# If updating, the associated `env_fedora*_makefiles.cmake` file needs updated
-# as well.
-/usr/local/rvm/bin/rvm install ruby-2.7.0
+# keep version in sync with `env_fedora*_makefiles.cmake`
+/usr/local/rvm/bin/rvm install ruby-3.0.4
 
 tar -C /usr/local -cf /root/rvm.tar rvm
diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake
index 5940a28..90c2187 100644
--- a/.gitlab/ci/download_qt.cmake
+++ b/.gitlab/ci/download_qt.cmake
@@ -11,7 +11,19 @@
 
 # Files needed to download.
 set(qt_files)
-if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows")
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows.*package")
+  if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows_x86_64_package")
+    list(APPEND qt_files "qt-5.12.1-win-x86_64-msvc_v142-1.zip")
+    set(qt_subdir "qt-5.12.1-win-x86_64-msvc_v142-1")
+  elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows_i386_package")
+    list(APPEND qt_files "qt-5.12.1-win-i386-msvc_v142-1.zip")
+    set(qt_subdir "qt-5.12.1-win-i386-msvc_v142-1")
+  else ()
+    message(FATAL_ERROR "Unknown arch to use for Qt")
+  endif()
+  set(qt_url_root "https://cmake.org/files/dependencies")
+  set(qt_url_path "")
+elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "windows")
   # Determine the ABI to fetch for Qt.
   if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2015")
     set(qt_platform "windows_x86")
diff --git a/.gitlab/ci/download_qt_hashes.cmake b/.gitlab/ci/download_qt_hashes.cmake
index afbc081..d19d284 100644
--- a/.gitlab/ci/download_qt_hashes.cmake
+++ b/.gitlab/ci/download_qt_hashes.cmake
@@ -12,3 +12,6 @@
 
 set("qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz_hash" d4449771afa0bc6a809c14f1e6d939e7732494cf059503ae451e2bfe8fc60cc1)
 set("qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz_hash" 7b9463a01c8beeee5bf8d01c70deff2d08561cd20aaf6f7a2f41cf8b68ce8a6b)
+
+set("qt-5.12.1-win-i386-msvc_v142-1.zip_hash" aa78711fdaa5d9b146bf7ddcf15983f9fbb3f995462f2d043f8cca74b40ddd11)
+set("qt-5.12.1-win-x86_64-msvc_v142-1.zip_hash" c2fc068b9dac40bb420e28e1ee15ce4f2ccfc866d767f3b99b6bb435b7c4f44b)
diff --git a/.gitlab/ci/env_fedora35_makefiles.cmake b/.gitlab/ci/env_fedora35_makefiles.cmake
deleted file mode 100644
index aa84e23..0000000
--- a/.gitlab/ci/env_fedora35_makefiles.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-set(ENV{MY_RUBY_HOME} "/usr/local/rvm/rubies/ruby-2.7.0")
-set(ENV{PATH} "/usr/lib64/mpich/bin:$ENV{PATH}")
diff --git a/.gitlab/ci/env_fedora35_asan.sh b/.gitlab/ci/env_fedora36_asan.sh
similarity index 100%
rename from .gitlab/ci/env_fedora35_asan.sh
rename to .gitlab/ci/env_fedora36_asan.sh
diff --git a/.gitlab/ci/env_fedora35_clang_analyzer.sh b/.gitlab/ci/env_fedora36_clang_analyzer.sh
similarity index 100%
rename from .gitlab/ci/env_fedora35_clang_analyzer.sh
rename to .gitlab/ci/env_fedora36_clang_analyzer.sh
diff --git a/.gitlab/ci/env_fedora36_makefiles.cmake b/.gitlab/ci/env_fedora36_makefiles.cmake
new file mode 100644
index 0000000..2bcb6d0
--- /dev/null
+++ b/.gitlab/ci/env_fedora36_makefiles.cmake
@@ -0,0 +1,2 @@
+set(ENV{MY_RUBY_HOME} "/usr/local/rvm/rubies/ruby-3.0.4")
+set(ENV{PATH} "/usr/lib64/mpich/bin:$ENV{PATH}")
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index f9af14f..a822d94 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -5,7 +5,7 @@
 ### Release
 
 .linux_prep_source:
-    image: "fedora:35"
+    image: "fedora:36"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -68,8 +68,8 @@
 
 ### Fedora
 
-.fedora35:
-    image: "kitware/cmake:ci-fedora35-x86_64-2022-04-22"
+.fedora36:
+    image: "kitware/cmake:ci-fedora36-x86_64-2022-05-17"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
@@ -77,37 +77,37 @@
 
 #### Lint builds
 
-.fedora35_tidy:
-    extends: .fedora35
+.fedora36_tidy:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_tidy
+        CMAKE_CONFIGURATION: fedora36_tidy
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora35_clang_analyzer:
-    extends: .fedora35
+.fedora36_clang_analyzer:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_clang_analyzer
+        CMAKE_CONFIGURATION: fedora36_clang_analyzer
         CMAKE_CI_BUILD_TYPE: Debug
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora35_sphinx:
-    extends: .fedora35
+.fedora36_sphinx:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_sphinx
+        CMAKE_CONFIGURATION: fedora36_sphinx
         CTEST_NO_WARNINGS_ALLOWED: 1
         CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora35_sphinx_package:
-    extends: .fedora35
+.fedora36_sphinx_package:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_sphinx_package
+        CMAKE_CONFIGURATION: fedora36_sphinx_package
         CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
 
 #### Build and test
@@ -137,27 +137,27 @@
         CMAKE_CI_NO_INSTALL: 1
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.fedora35_ninja:
-    extends: .fedora35
+.fedora36_ninja:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_ninja
+        CMAKE_CONFIGURATION: fedora36_ninja
         CMAKE_CI_BUILD_TYPE: Release
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.fedora35_ninja_multi:
-    extends: .fedora35
+.fedora36_ninja_multi:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_ninja_multi
+        CMAKE_CONFIGURATION: fedora36_ninja_multi
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "Ninja Multi-Config"
 
-.fedora35_makefiles:
-    extends: .fedora35
+.fedora36_makefiles:
+    extends: .fedora36
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_makefiles
+        CMAKE_CONFIGURATION: fedora36_makefiles
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "Unix Makefiles"
 
@@ -189,13 +189,13 @@
         CTEST_MEMORYCHECK_TYPE: AddressSanitizer
         CTEST_MEMORYCHECK_SANITIZER_OPTIONS: ""
 
-.fedora35_asan:
+.fedora36_asan:
     extends:
-        - .fedora35
+        - .fedora36
         - .fedora_asan_addon
 
     variables:
-        CMAKE_CONFIGURATION: fedora35_asan
+        CMAKE_CONFIGURATION: fedora36_asan
 
 ### Intel Compiler
 
@@ -389,7 +389,7 @@
 
 .cmake_codespell_linux:
     stage: build
-    extends: .fedora35
+    extends: .fedora36
     script:
         - codespell
     interruptible: true
@@ -532,7 +532,7 @@
 .cmake_org_help:
     stage: build
     extends:
-        - .fedora35
+        - .fedora36
         - .linux_builder_tags
         - .cmake_org_help_artifacts
     script:
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index 4b4656a..e5febbe 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -37,6 +37,12 @@
         VCVARSPLATFORM: "x64"
         VCVARSVERSION: "14.32.31326"
 
+.windows_vcvarsall_vs2022_x86:
+    variables:
+        VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSPLATFORM: "x86"
+        VCVARSVERSION: "14.32.31326"
+
 .windows_vs2022_x64_ninja:
     extends:
         - .windows_build_ninja
@@ -45,6 +51,30 @@
     variables:
         CMAKE_CONFIGURATION: windows_vs2022_x64_ninja
 
+.windows_package:
+    extends:
+        - .windows_build_ninja
+
+    variables:
+        CMAKE_CI_BUILD_TYPE: Release
+        CMAKE_CI_NO_INSTALL: 1
+
+.windows_x86_64_package:
+    extends:
+        - .windows_package
+        - .windows_vcvarsall_vs2022_x64
+
+    variables:
+        CMAKE_CONFIGURATION: windows_x86_64_package
+
+.windows_i386_package:
+    extends:
+        - .windows_package
+        - .windows_vcvarsall_vs2022_x86
+
+    variables:
+        CMAKE_CONFIGURATION: windows_i386_package
+
 ### External testing
 
 .windows_vs2022_x64:
@@ -236,6 +266,18 @@
 
     interruptible: true
 
+.cmake_package_windows:
+    stage: package
+
+    script:
+        - *before_script_windows
+        - Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
+        - cd build
+        - cpack -G ZIP
+        - cpack -G WIX
+
+    interruptible: true
+
 .cmake_test_windows:
     stage: test
 
diff --git a/.gitlab/rules.yml b/.gitlab/rules.yml
index 8efa304..8fc40a7f 100644
--- a/.gitlab/rules.yml
+++ b/.gitlab/rules.yml
@@ -70,7 +70,7 @@
           when: on_success
         - if: '$CMAKE_CI_PACKAGE != null && $CI_JOB_STAGE == "prep"'
           when: manual
-        - if: '$CMAKE_CI_PACKAGE != null && $CI_JOB_STAGE != "upload"'
+        - if: '$CMAKE_CI_PACKAGE != null && $CI_JOB_STAGE != "package" && $CI_JOB_STAGE != "upload"'
           when: on_success
         - when: never
 
diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml
index d831c3e..38d40a9 100644
--- a/.gitlab/upload.yml
+++ b/.gitlab/upload.yml
@@ -1,7 +1,7 @@
 # Steps for uploading artifacts
 
 .rsync_upload_package:
-    image: "fedora:35"
+    image: "fedora:36"
     stage: upload
     tags:
         - cmake
@@ -21,7 +21,7 @@
 
 .rsync_upload_help:
     stage: upload
-    image: "fedora:35"
+    image: "fedora:36"
     tags:
         - cmake
         - docker
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in
index 81dfeee..f354362 100644
--- a/CMakeCPackOptions.cmake.in
+++ b/CMakeCPackOptions.cmake.in
@@ -248,6 +248,13 @@
 
   set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high")
 
+  if(NOT "$ENV{CMAKE_CI_PACKAGE}" STREQUAL "")
+    # Suppress validation.  It does not work without
+    # an interactive session or an admin account.
+    # https://github.com/wixtoolset/issues/issues/3968
+    list(APPEND CPACK_WIX_LIGHT_EXTRA_FLAGS "-sval")
+  endif()
+
   set(CPACK_WIX_UI_BANNER
     "@CMake_SOURCE_DIR@/Utilities/Release/WiX/ui_banner.jpg"
   )
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 093c1d8..49026a3 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -98,6 +98,7 @@
   "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Value stored to '[^']+' is never read"
   "zstd/lib/.*:[0-9]+:[0-9]+: warning: Assigned value is garbage or undefined"
   "zstd/lib/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
+  "zstd/lib/.*:[0-9]+:[0-9]+: warning: The right operand of .* is a garbage value due to array index out of bounds"
   )
 
 if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index ab5f860..6683edb 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -54,10 +54,8 @@
 
   .. versionchanged:: 3.24
     On ``Windows`` platform, it is possible to include registry queries as part
-    of the directories. Such specifications will be ignored on all other
-    platforms.
-
-  .. include:: FIND_XXX_REGISTRY_QUERY.txt
+    of the directories, using a :ref:`dedicated syntax <Find Using Windows Registry>`.
+    Such specifications will be ignored on all other platforms.
 
 ``REGISTRY_VIEW``
   .. versionadded:: 3.24
diff --git a/Help/command/FIND_XXX_REGISTRY_QUERY.txt b/Help/command/FIND_XXX_REGISTRY_QUERY.txt
deleted file mode 100644
index 04a087a..0000000
--- a/Help/command/FIND_XXX_REGISTRY_QUERY.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-The formal syntax, as specified using
-`BNF <https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form>`_ notation with
-the regular extensions, for registry query is the following:
-
-.. parsed-literal::
-
-  registry_query  ::= '[' `sep_definition`_? `root_key`_
-                      ((`key_separator`_ `sub_key`_)? (`value_separator`_ `value_name`_)?)? ']'
-  _`sep_definition`  ::= '{' `value_separator`_ '}'
-  _`root_key`        ::= 'HKLM' | 'HKEY_LOCAL_MACHINE' | 'HKCU' | 'HKEY_CURRENT_USER' |
-                      'HKCR' | 'HKEY_CLASSES_ROOT' | 'HKCC' | 'HKEY_CURRENT_CONFIG' |
-                      'HKU' | 'HKEY_USERS'
-  _`sub_key`         ::= `element`_ (`key_separator`_ `element`_)*
-  _`key_separator`   ::= '/' | '\\'
-  _`value_separator` ::= `element`_ | ';'
-  _`value_name`      ::= `element`_ | '(default)'
-  _`element`         ::= `character`_\+
-  _`character`       ::= <any character except `key_separator`_ and `value_separator`_>
-
-The `sep_definition`_ optional item offers the possibility to specify the
-string used to separate the `sub_key`_ from the `value_name`_ item. If
-not specified, the character ``;`` is used.
-
-.. parsed-literal::
-
-  # example using default separator
-  |FIND_XXX| (... **PATHS** "/root/[HKLM/Stuff;InstallDir]/lib[HKLM\\\\Stuff;Architecture]")
-
-  # example using different specified separators
-  |FIND_XXX| (... **HINTS** "/root/[{|}HKCU/Stuff|InstallDir]/lib[{@@}HKCU\\\\Stuff@@Architecture]")
-
-If the `value_name`_ item is not specified or has the special name
-``(default)``, the content of the default value, if any, will be returned. The
-supported types for the `value_name`_ are:
-
-* ``REG_SZ``.
-* ``REG_EXPAND_SZ``. The returned data is expanded.
-* ``REG_DWORD``.
-* ``REG_QWORD``.
-
-When the registry query failed, typically because the key does not exist or
-the data type is not supported, the string ``/REGISTRY-NOTFOUND`` is substituted
-to the ``[]`` query expression.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 8567a00..a4dad21 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -310,10 +310,9 @@
 
 .. versionchanged:: 3.24
   On ``Windows`` platform, it is possible to include registry queries as part
-  of the directories specified through ``HINTS`` and ``PATHS`` keywords. Such
-  specifications will be ignored on all other platforms.
-
-.. include:: FIND_XXX_REGISTRY_QUERY.txt
+  of the directories specified through ``HINTS`` and ``PATHS`` keywords, using
+  a :ref:`dedicated syntax <Find Using Windows Registry>`. Such specifications
+  will be ignored on all other platforms.
 
 .. versionadded:: 3.24
   ``REGISTRY_VIEW`` can be specified to manage ``Windows`` registry queries
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 4b2a631..806a98d 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -7,6 +7,8 @@
 
 Try building some code.
 
+.. _`Try Compiling Whole Projects`:
+
 Try Compiling Whole Projects
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -25,6 +27,15 @@
 build a specific target instead of the ``all`` or ``ALL_BUILD`` target.  See
 below for the meaning of other options.
 
+.. versionchanged:: 3.24
+  CMake variables describing platform settings, and those listed by the
+  :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES` variable, are propagated
+  into the project's build configuration.  See policy :policy:`CMP0137`.
+  Previously this was only done by the
+  :ref:`source file <Try Compiling Source Files>` signature.
+
+.. _`Try Compiling Source Files`:
+
 Try Compiling Source Files
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -205,3 +216,7 @@
 .. versionchanged:: 3.14
   For the :generator:`Green Hills MULTI` generator the GHS toolset and target
   system customization cache variables are also propagated into the test project.
+
+.. versionadded:: 3.24
+  The :variable:`CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES` variable may be
+  set to disable passing platform variables into the test project.
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index fe146de..2c6cd96 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -242,6 +242,69 @@
 Make sure you comment them as deprecated, so that no-one starts using
 them.
 
+.. _`Find Using Windows Registry`:
+
+Find Using Windows Registry
+---------------------------
+
+.. versionchanged:: 3.24
+
+Options ``HINTS`` and ``PATHS`` of :command:`find_file`,
+:command:`find_library`, :command:`find_path`, :command:`find_program`, and
+:command:`find_package` commands offer the possibility, on ``Windows``
+platform, to query the registry.
+
+The formal syntax, as specified using
+`BNF <https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form>`_ notation with
+the regular extensions, for registry query is the following:
+
+.. raw:: latex
+
+   \begin{small}
+
+.. productionlist::
+  registry_query: '[' `sep_definition`? `root_key`
+                :     ((`key_separator` `sub_key`)? (`value_separator` `value_name`_)?)? ']'
+  sep_definition: '{' `value_separator` '}'
+  root_key: 'HKLM' | 'HKEY_LOCAL_MACHINE' | 'HKCU' | 'HKEY_CURRENT_USER' |
+          : 'HKCR' | 'HKEY_CLASSES_ROOT' | 'HKCC' | 'HKEY_CURRENT_CONFIG' |
+          : 'HKU' | 'HKEY_USERS'
+  sub_key: `element` (`key_separator` `element`)*
+  key_separator: '/' | '\\'
+  value_separator: `element` | ';'
+  value_name: `element` | '(default)'
+  element: `character`\+
+  character: <any character except `key_separator` and `value_separator`>
+
+.. raw:: latex
+
+   \end{small}
+
+The :token:`sep_definition` optional item offers the possibility to specify
+the string used to separate the :token:`sub_key` from the :token:`value_name`
+item. If not specified, the character ``;`` is used. Multiple
+:token:`registry_query` items can be specified as part of a path.
+
+.. code-block:: cmake
+
+  # example using default separator
+  find_file(... PATHS "/root/[HKLM/Stuff;InstallDir]/lib[HKLM\\\\Stuff;Architecture]")
+
+  # example using different specified separators
+  find_library(... HINTS "/root/[{|}HKCU/Stuff|InstallDir]/lib[{@@}HKCU\\\\Stuff@@Architecture]")
+
+If the :token:`value_name` item is not specified or has the special name
+``(default)``, the content of the default value, if any, will be returned. The
+supported types for the :token:`value_name` are:
+
+* ``REG_SZ``.
+* ``REG_EXPAND_SZ``. The returned data is expanded.
+* ``REG_DWORD``.
+* ``REG_QWORD``.
+
+When the registry query failed, typically because the key does not exist or
+the data type is not supported, the string ``/REGISTRY-NOTFOUND`` is substituted
+to the ``[]`` query expression.
 
 A Sample Find Module
 --------------------
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 22c14df..848a133 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -197,6 +197,8 @@
 
 .. genex:: $<HIP_COMPILER_ID:compiler_ids>
 
+  .. versionadded:: 3.21
+
   where ``compiler_ids`` is a comma-separated list.
   ``1`` if the CMake's compiler id of the HIP compiler matches any one
   of the entries in ``compiler_ids``, otherwise ``0``.
@@ -249,6 +251,8 @@
 
 .. genex:: $<HIP_COMPILER_VERSION:version>
 
+  .. versionadded:: 3.21
+
   ``1`` if the version of the HIP compiler matches ``version``, otherwise ``0``.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
 
@@ -716,6 +720,8 @@
 
 .. genex:: $<HIP_COMPILER_ID>
 
+  .. versionadded:: 3.21
+
   The CMake's compiler id of the HIP compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
 
@@ -762,6 +768,8 @@
 
 .. genex:: $<HIP_COMPILER_VERSION>
 
+  .. versionadded:: 3.21
+
   The version of the HIP compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
 
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 259cebb..788d086 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -58,6 +58,7 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0137: try_compile() passes platform variables in project mode. </policy/CMP0137>
    CMP0136: Watcom runtime library flags are selected by an abstraction. </policy/CMP0136>
    CMP0135: ExternalProject ignores timestamps in archives by default for the URL download method. </policy/CMP0135>
    CMP0134: Fallback to \"HOST\" Windows registry view when \"TARGET\" view is not usable. </policy/CMP0134>
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 20b62c5..7935ca3 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -381,7 +381,7 @@
    /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
    /prop_tgt/UNITY_BUILD_MODE
    /prop_tgt/UNITY_BUILD_UNIQUE_ID
-   /prop_tgt/VERIFY_HEADER_SETS
+   /prop_tgt/VERIFY_INTERFACE_HEADER_SETS
    /prop_tgt/VERSION
    /prop_tgt/VISIBILITY_INLINES_HIDDEN
    /prop_tgt/VS_CONFIGURATION_TYPE
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 00ea0bc..9fbb146 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -503,13 +503,14 @@
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT
    /variable/CMAKE_STATIC_LINKER_FLAGS_INIT
    /variable/CMAKE_TRY_COMPILE_CONFIGURATION
+   /variable/CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
    /variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
    /variable/CMAKE_TRY_COMPILE_TARGET_TYPE
    /variable/CMAKE_UNITY_BUILD
    /variable/CMAKE_UNITY_BUILD_BATCH_SIZE
    /variable/CMAKE_UNITY_BUILD_UNIQUE_ID
    /variable/CMAKE_USE_RELATIVE_PATHS
-   /variable/CMAKE_VERIFY_HEADER_SETS
+   /variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS
    /variable/CMAKE_VISIBILITY_INLINES_HIDDEN
    /variable/CMAKE_VS_GLOBALS
    /variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index e0cb708..38105dd 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -426,6 +426,11 @@
  in :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`.
  This flag tells CMake to warn about other files as well.
 
+``--compile-no-warning-as-error``
+ Ignore target property :prop_tgt:`COMPILE_WARNING_AS_ERROR` and variable
+ :variable:`CMAKE_COMPILE_WARNING_AS_ERROR`, preventing warnings from being
+ treated as errors on compile.
+
 ``--profiling-output=<path>``
  Used in conjunction with ``--profiling-format`` to output to a given path.
 
diff --git a/Help/policy/CMP0137.rst b/Help/policy/CMP0137.rst
new file mode 100644
index 0000000..ba3cb9c
--- /dev/null
+++ b/Help/policy/CMP0137.rst
@@ -0,0 +1,33 @@
+CMP0137
+-------
+
+.. versionadded:: 3.24
+
+:command:`try_compile` passes platform variables in project mode.
+
+The :command:`try_compile` command :ref:`source file <Try Compiling Source
+Files>` signature propagates CMake variables containing platform settings,
+and those specified by the :variable:`CMAKE_TRY_COMPILE_PLATFORM_VARIABLES`
+variable, into the generated test project.  This helps the test project drive
+the toolchain the same way the calling project will.  In CMake 3.23 and below,
+the :ref:`whole-project <Try Compiling Whole Projects>` signature does not
+propagate platform variables automatically.  CMake 3.24 and above prefer to
+propagate platform variables in the :ref:`whole-project <Try Compiling Whole
+Projects>` signature.  This policy provides compatibility with projects that
+have not been updated to expect the behavior.
+
+The ``OLD`` behavior for this policy is to not pass any additional variables to
+the :ref:`whole-project <Try Compiling Whole Projects>` signature.
+The ``NEW`` behavior for this policy is to pass the same variables that the
+:ref:`source file <Try Compiling Source Files>` signature does.
+
+Regardless of the policy setting, the
+:variable:`CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES` variable may be set
+to suppress passing the platform variables through either signature.
+
+This policy was introduced in CMake version 3.24.  Use the
+:command:`cmake_policy` command to set this policy to ``OLD`` or ``NEW``
+explicitly. Unlike many policies, CMake version |release| does *not* warn
+by default when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/VERIFY_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_HEADER_SETS.rst
deleted file mode 100644
index e151017..0000000
--- a/Help/prop_tgt/VERIFY_HEADER_SETS.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-VERIFY_HEADER_SETS
-------------------
-
-.. versionadded:: 3.24
-
-Used to verify that all headers in a target's header sets can be included on
-their own.
-
-When this property is set to true, and the target is an object library, static
-library, shared library, or executable with exports enabled, and the target
-has one or more ``PUBLIC`` or ``INTERFACE`` header sets, an object library
-target named ``<target_name>_verify_header_sets`` is created. This verification
-target has one source file per header in the ``PUBLIC`` and ``INTERFACE``
-header sets. Each source file only includes its associated header file. The
-verification target links against the original target to get all of its usage
-requirements. The verification target has its :prop_tgt:`EXCLUDE_FROM_ALL` and
-:prop_tgt:`DISABLE_PRECOMPILE_HEADERS` properties set to true, and its
-:prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC`, :prop_tgt:`AUTOUIC`, and
-:prop_tgt:`UNITY_BUILD` properties set to false.
-
-If the header's :prop_sf:`LANGUAGE` property is set, the value of that property
-is used to determine the language with which to compile the header file.
-Otherwise, if the target has any C++ sources, the header is compiled as C++.
-Otherwise, if the target has any C sources, the header is compiled as C.
-Otherwise, the header file is not compiled.
diff --git a/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst
new file mode 100644
index 0000000..d8045c6
--- /dev/null
+++ b/Help/prop_tgt/VERIFY_INTERFACE_HEADER_SETS.rst
@@ -0,0 +1,25 @@
+VERIFY_INTERFACE_HEADER_SETS
+----------------------------
+
+.. versionadded:: 3.24
+
+Used to verify that all headers in a target's ``PUBLIC`` and ``INTERFACE``
+header sets can be included on their own.
+
+When this property is set to true, and the target is an object library, static
+library, shared library, or executable with exports enabled, and the target
+has one or more ``PUBLIC`` or ``INTERFACE`` header sets, an object library
+target named ``<target_name>_verify_interface_header_sets`` is created. This
+verification target has one source file per header in the ``PUBLIC`` and
+``INTERFACE`` header sets. Each source file only includes its associated
+header file. The verification target links against the original target to get
+all of its usage requirements. The verification target has its
+:prop_tgt:`EXCLUDE_FROM_ALL` and :prop_tgt:`DISABLE_PRECOMPILE_HEADERS`
+properties set to true, and its :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTORCC`,
+:prop_tgt:`AUTOUIC`, and :prop_tgt:`UNITY_BUILD` properties set to false.
+
+If the header's :prop_sf:`LANGUAGE` property is set, the value of that property
+is used to determine the language with which to compile the header file.
+Otherwise, if the target has any C++ sources, the header is compiled as C++.
+Otherwise, if the target has any C sources, the header is compiled as C.
+Otherwise, the header file is not compiled.
diff --git a/Help/release/dev/FindGLUT-remove-undocumented-vars.rst b/Help/release/dev/FindGLUT-remove-undocumented-vars.rst
new file mode 100644
index 0000000..6a0c904
--- /dev/null
+++ b/Help/release/dev/FindGLUT-remove-undocumented-vars.rst
@@ -0,0 +1,5 @@
+FindGLUT-remove-undocumented-vars
+---------------------------------
+
+* The :module:`FindGLUT` module no longer provides the undocumented
+  result variables ``GLUT_LIBRARY`` and ``GLUT_INCLUDE_PATH``.
diff --git a/Help/release/dev/pkgconfig-static-libs.rst b/Help/release/dev/pkgconfig-static-libs.rst
new file mode 100644
index 0000000..8f7ab0e
--- /dev/null
+++ b/Help/release/dev/pkgconfig-static-libs.rst
@@ -0,0 +1,7 @@
+pkgconfig-static-libs
+---------------------
+
+* The :module:`FindPkgConfig` module learned to find static libraries
+  in addition to the default search for shared libraries.
+  :command:`pkg_check_modules` gained a ``STATIC_TARGET`` option
+  to make the imported target reference static libraries.
diff --git a/Help/release/dev/try_compile-project-platform-vars.rst b/Help/release/dev/try_compile-project-platform-vars.rst
new file mode 100644
index 0000000..06596d4
--- /dev/null
+++ b/Help/release/dev/try_compile-project-platform-vars.rst
@@ -0,0 +1,10 @@
+try_compile-project-platform-vars
+---------------------------------
+
+* The :command:`try_compile` command
+  :ref:`whole-project <Try Compiling Whole Projects>` signature
+  now propagates platform variables.  See policy :policy:`CMP0137`.
+
+* The :variable:`CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES` variable
+  was added to tell the :command:`try_compile` command not to
+  pass any platform variables to the test project.
diff --git a/Help/release/dev/verify-header-sets.rst b/Help/release/dev/verify-header-sets.rst
deleted file mode 100644
index 7676382..0000000
--- a/Help/release/dev/verify-header-sets.rst
+++ /dev/null
@@ -1,7 +0,0 @@
-verify-header-sets
-------------------
-
-* A new :prop_tgt:`VERIFY_HEADER_SETS` target property was added, which can be
-  used to verify that all headers in header sets can be used on their own.
-* A new :variable:`CMAKE_VERIFY_HEADER_SETS` variable was added, which is used
-  to initialize the :prop_tgt:`VERIFY_HEADER_SETS` target property.
diff --git a/Help/release/dev/verify-interface-header-sets.rst b/Help/release/dev/verify-interface-header-sets.rst
new file mode 100644
index 0000000..fcccb62
--- /dev/null
+++ b/Help/release/dev/verify-interface-header-sets.rst
@@ -0,0 +1,9 @@
+verify-interface-header-sets
+----------------------------
+
+* A new :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` target property was added,
+  which can be used to verify that all headers in header sets can be used on
+  their own.
+* A new :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable was added,
+  which is used to initialize the :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS`
+  target property.
diff --git a/Help/release/dev/vs-system-include.rst b/Help/release/dev/vs-system-include.rst
new file mode 100644
index 0000000..5f42dba
--- /dev/null
+++ b/Help/release/dev/vs-system-include.rst
@@ -0,0 +1,4 @@
+vs-system-include
+-----------------
+
+* :ref:`Visual Studio Generators` now support ``SYSTEM`` headers.
diff --git a/Help/release/dev/werror-property.rst b/Help/release/dev/werror-property.rst
index c337df7..84c825f 100644
--- a/Help/release/dev/werror-property.rst
+++ b/Help/release/dev/werror-property.rst
@@ -6,3 +6,8 @@
   Target Property. If :prop_tgt:`COMPILE_WARNING_AS_ERROR` is true, it expands
   to a different flag depending on the compiler such that any warnings at
   compile will be treated as errors.
+
+* :manual:`cmake(1)` gained the command-line option
+  ``--compile-no-warning-as-error`` which causes the values of
+  the :prop_tgt:`COMPILE_WARNING_AS_ERROR` target property and
+  :variable:`CMAKE_COMPILE_WARNING_AS_ERROR` variable to be ignored.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
index 91cf848..4b799c0 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCC.rst
@@ -1,7 +1,7 @@
 CMAKE_COMPILER_IS_GNUCC
 -----------------------
 
-.. versionadded:: 3.7
-
 True if the ``C`` compiler is GNU.
-Use :variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
+
+This variable is deprecated.  Use
+:variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
index e67718a..29069d2 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUCXX.rst
@@ -1,7 +1,7 @@
 CMAKE_COMPILER_IS_GNUCXX
 ------------------------
 
-.. versionadded:: 3.7
-
 True if the C++ (``CXX``) compiler is GNU.
-Use :variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
+
+This variable is deprecated.  Use
+:variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
index f69c01a..05303dc 100644
--- a/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
+++ b/Help/variable/CMAKE_COMPILER_IS_GNUG77.rst
@@ -1,7 +1,7 @@
 CMAKE_COMPILER_IS_GNUG77
 ------------------------
 
-.. versionadded:: 3.7
-
 True if the ``Fortran`` compiler is GNU.
-Use :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
+
+This variable is deprecated.  Use
+:variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` instead.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES.rst b/Help/variable/CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES.rst
new file mode 100644
index 0000000..944caa5
--- /dev/null
+++ b/Help/variable/CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES.rst
@@ -0,0 +1,10 @@
+CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
+---------------------------------------
+
+Set to a true value to tell the :command:`try_compile` command not
+to propagate any platform variables into the test project.
+
+The :command:`try_compile` command normally passes some CMake variables
+that configure the platform and toolchain behavior into test projects.
+See policy :policy:`CMP0137`.  This variable may be set to disable
+that behavior.
diff --git a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
index d178513..6b26d14 100644
--- a/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
+++ b/Help/variable/CMAKE_TRY_COMPILE_PLATFORM_VARIABLES.rst
@@ -26,3 +26,12 @@
 setting will be made visible to the toolchain file both for the main
 project and for test projects generated by the :command:`try_compile`
 command source file signature.
+
+.. versionchanged:: 3.24
+  Listed variables are propagated to the :command:`try_compile`
+  :ref:`whole-project <Try Compiling Whole Projects>` signature too.
+  See :policy:`CMP0137`.
+
+.. versionadded:: 3.24
+  The :variable:`CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES` variable may be
+  set to disable passing platform variables into the test project.
diff --git a/Help/variable/CMAKE_VERIFY_HEADER_SETS.rst b/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
similarity index 63%
rename from Help/variable/CMAKE_VERIFY_HEADER_SETS.rst
rename to Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
index 8bd618a..6f14e6f 100644
--- a/Help/variable/CMAKE_VERIFY_HEADER_SETS.rst
+++ b/Help/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.rst
@@ -1,11 +1,11 @@
-CMAKE_VERIFY_HEADER_SETS
-------------------------
+CMAKE_VERIFY_INTERFACE_HEADER_SETS
+----------------------------------
 
 .. versionadded:: 3.24
 
-This variable is used to initialize the :prop_tgt:`VERIFY_HEADER_SETS`
-property of targets when they are created.  Setting it to true
-enables header set verification.
+This variable is used to initialize the
+:prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` property of targets when they are
+created.  Setting it to true enables header set verification.
 
 Projects should not set this variable, it is intended as a developer
 control to be set on the :manual:`cmake(1)` command line or other
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
index 84d7212..5c13bb7 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE.rst
@@ -9,4 +9,4 @@
 either the 32-bit or 64-bit host toolchains by specifying a ``host=x86``
 or ``host=x64`` value in the :variable:`CMAKE_GENERATOR_TOOLSET` option.
 CMake provides the selected toolchain architecture preference in this
-variable (``x86``, ``x64``, or empty).
+variable (``x86``, ``x64``, ``ARM64`` or empty).
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index 1f8c38c..8ca9f28 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -327,32 +327,34 @@
 if(NOT CPackComponent_CMake_INCLUDED)
 set(CPackComponent_CMake_INCLUDED 1)
 
-# Macro that appends a SET command for the given variable name (var)
-# to the macro named strvar, but only if the variable named "var"
+# Function that appends a SET command for the given variable name (var)
+# to the string named strvar, but only if the variable named "var"
 # has been defined. The string will eventually be appended to a CPack
 # configuration file.
-macro(cpack_append_variable_set_command var strvar)
+function(cpack_append_variable_set_command var strvar)
   if (DEFINED ${var})
     string(APPEND ${strvar} "set(${var}")
     foreach(APPENDVAL ${${var}})
       string(APPEND ${strvar} " ${APPENDVAL}")
     endforeach()
     string(APPEND ${strvar} ")\n")
+    set(${strvar} "${${strvar}}" PARENT_SCOPE)
   endif ()
-endmacro()
+endfunction()
 
-# Macro that appends a SET command for the given variable name (var)
-# to the macro named strvar, but only if the variable named "var"
+# Function that appends a SET command for the given variable name (var)
+# to the string named strvar, but only if the variable named "var"
 # has been defined and is a string. The string will eventually be
 # appended to a CPack configuration file.
-macro(cpack_append_string_variable_set_command var strvar)
+function(cpack_append_string_variable_set_command var strvar)
   if (DEFINED ${var})
     list(LENGTH ${var} CPACK_APP_VALUE_LEN)
     if(${CPACK_APP_VALUE_LEN} EQUAL 1)
       string(APPEND ${strvar} "set(${var} \"${${var}}\")\n")
     endif()
+    set(${strvar} "${${strvar}}" PARENT_SCOPE)
   endif ()
-endmacro()
+endfunction()
 
 # Macro that appends a SET command for the given list variable name (var)
 # to the macro named strvar, but only if the variable named "var"
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 707de88..e19b7c9 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -244,9 +244,9 @@
         .. versionadded:: 3.11
 
         Specify whether the ``.netrc`` file is to be used for operation.
-        If this option is not specified, the value of the :variable:`CMAKE_NETRC`
-        variable will be used instead (see :command:`file(DOWNLOAD)`)
-        Valid levels are:
+        If this option is not specified, the value of the
+        :variable:`CMAKE_NETRC` variable will be used instead
+        (see :command:`file(DOWNLOAD)`).  Valid levels are:
 
         ``IGNORED``
           The ``.netrc`` file is ignored.
@@ -386,8 +386,9 @@
         override the default strategy.  This variable should not be set by a
         project, it is intended for the user to set.  It is primarily intended
         for use in continuous integration scripts to ensure that when history
-        is rewritten on a remote branch, the build doesn't end up with unintended
-        changes or failed builds resulting from conflicts during rebase operations.
+        is rewritten on a remote branch, the build doesn't end up with
+        unintended changes or failed builds resulting from conflicts during
+        rebase operations.
 
     *Subversion*
       ``SVN_REPOSITORY <url>``
@@ -527,7 +528,8 @@
       :manual:`CMake Options <cmake(1)>`).
 
       .. versionadded:: 3.3
-        Arguments may use :manual:`generator expressions <cmake-generator-expressions(7)>`.
+        Arguments may use
+        :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
     ``CMAKE_CACHE_ARGS <arg>...``
       This is an alternate way of specifying cache variables where command line
@@ -538,7 +540,8 @@
       using the :manual:`cmake -C <cmake(1)>` command line option.
 
       .. versionadded:: 3.3
-        Arguments may use :manual:`generator expressions <cmake-generator-expressions(7)>`.
+        Arguments may use
+        :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
     ``CMAKE_CACHE_DEFAULT_ARGS <arg>...``
       .. versionadded:: 3.2
@@ -551,7 +554,7 @@
       build directory or re-uses previous build contents.
 
       .. versionadded:: 3.15
-        If the CMake generator is the ``Green Hills MULTI`` and not overridden then
+        If the CMake generator is the ``Green Hills MULTI`` and not overridden,
         the original project's settings for the GHS toolset and target system
         customization cache variables are propagated into the external project.
 
@@ -1017,9 +1020,9 @@
 
   .. versionadded:: 3.19
     If :policy:`CMP0114` is set to ``NEW``, step targets are fully responsible
-    for holding the custom commands implementing their steps.  The primary target
-    created by ``ExternalProject_Add`` depends on the step targets, and the
-    step targets depend on each other.  The target-level dependencies match
+    for holding the custom commands implementing their steps.  The primary
+    target created by ``ExternalProject_Add`` depends on the step targets, and
+    the step targets depend on each other.  The target-level dependencies match
     the file-level dependencies used by the custom commands for each step.
     The targets for steps created with :command:`ExternalProject_Add_Step`'s
     ``INDEPENDENT`` option do not depend on the external targets specified
@@ -1031,16 +1034,16 @@
 
   * A deprecated ``NO_DEPENDS`` option may be specified immediately after the
     ``<name>`` and before the first step.
-    If the ``NO_DEPENDS`` option is specified, the step target will not depend on
-    the dependencies of the external project (i.e. on any dependencies of the
+    If the ``NO_DEPENDS`` option is specified, the step target will not depend
+    on the dependencies of the external project (i.e. on any dependencies of the
     ``<name>`` custom target created by :command:`ExternalProject_Add`). This is
-    usually safe for the ``download``, ``update`` and ``patch`` steps, since they
-    do not typically require that the dependencies are updated and built. Using
-    ``NO_DEPENDS`` for any of the other pre-defined steps, however, may break
-    parallel builds. Only use ``NO_DEPENDS`` where it is certain that the named
-    steps genuinely do not have dependencies. For custom steps, consider whether
-    or not the custom commands require the dependencies to be configured, built
-    and installed.
+    usually safe for the ``download``, ``update`` and ``patch`` steps, since
+    they do not typically require that the dependencies are updated and built.
+    Using ``NO_DEPENDS`` for any of the other pre-defined steps, however, may
+    break parallel builds. Only use ``NO_DEPENDS`` where it is certain that the
+    named steps genuinely do not have dependencies. For custom steps, consider
+    whether or not the custom commands require the dependencies to be
+    configured, built and installed.
 
   * The ``INDEPENDENT_STEP_TARGETS`` option for :command:`ExternalProject_Add`,
     or the ``EP_INDEPENDENT_STEP_TARGETS`` directory property, tells the
@@ -1190,7 +1193,13 @@
   set(${out_var} "^(${${out_var}})=([0-9A-Fa-f]+)$")
 endmacro()
 
-function(_ep_parse_arguments f keywords name ns args)
+function(_ep_parse_arguments
+  f
+  keywords
+  name
+  ns
+  args
+)
   # Transfer the arguments to this function into target properties for the
   # new custom target we just added so that we can set up all the build steps
   # correctly based on target properties.
@@ -1206,7 +1215,8 @@
     set(is_value 1)
 
     if(arg MATCHES "^[A-Z][A-Z0-9_][A-Z0-9_]+$" AND
-        NOT (("x${arg}x" STREQUAL "x${key}x") AND ("x${key}x" STREQUAL "xCOMMANDx")) AND
+        NOT (("x${arg}x" STREQUAL "x${key}x") AND
+             ("x${key}x" STREQUAL "xCOMMANDx")) AND
         NOT arg MATCHES "^(TRUE|FALSE)$")
       if(arg IN_LIST keywords)
         set(is_value 0)
@@ -1229,7 +1239,9 @@
         endif()
       else()
         # Missing Keyword
-        message(AUTHOR_WARNING "value '${arg}' with no previous keyword in ${f}")
+        message(AUTHOR_WARNING
+          "value '${arg}' with no previous keyword in ${f}"
+        )
       endif()
     else()
       set(key "${arg}")
@@ -1238,63 +1250,31 @@
 endfunction()
 
 
-define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED
-  BRIEF_DOCS "Base directory for External Project storage."
-  FULL_DOCS
-  "See documentation of the ExternalProject_Add() function in the "
-  "ExternalProject module."
-  )
-
-define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED
-  BRIEF_DOCS "Top prefix for External Project storage."
-  FULL_DOCS
-  "See documentation of the ExternalProject_Add() function in the "
-  "ExternalProject module."
-  )
-
-define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
-  BRIEF_DOCS
-  "List of ExternalProject steps that automatically get corresponding targets"
-  FULL_DOCS
-  "These targets will be dependent on the main target dependencies. "
-  "See documentation of the ExternalProject_Add_StepTargets() function in the "
-  "ExternalProject module."
-  )
-
-define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED
-  BRIEF_DOCS
-  "List of ExternalProject steps that automatically get corresponding targets"
-  FULL_DOCS
-  "These targets will not be dependent on the main target dependencies. "
-  "See documentation of the ExternalProject_Add_StepTargets() function in the "
-  "ExternalProject module."
-  )
-
-define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
-  BRIEF_DOCS "Never update automatically from the remote repo."
-  FULL_DOCS
-  "See documentation of the ExternalProject_Add() function in the "
-  "ExternalProject module."
-  )
+define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED)
+define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED)
+define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED)
+define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED)
+define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED)
 
 function(_ep_write_gitclone_script
-         script_filename
-         source_dir
-         git_EXECUTABLE
-         git_repository
-         git_tag
-         git_remote_name
-         init_submodules
-         git_submodules_recurse
-         git_submodules
-         git_shallow
-         git_progress
-         git_config
-         src_name
-         work_dir
-         gitclone_infofile
-         gitclone_stampfile
-         tls_verify)
+  script_filename
+  source_dir
+  git_EXECUTABLE
+  git_repository
+  git_tag
+  git_remote_name
+  init_submodules
+  git_submodules_recurse
+  git_submodules
+  git_shallow
+  git_progress
+  git_config
+  src_name
+  work_dir
+  gitclone_infofile
+  gitclone_stampfile
+  tls_verify
+)
 
   if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
     # Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
@@ -1309,7 +1289,8 @@
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
 
-  if(GIT_VERSION_STRING VERSION_LESS 2.20 OR 2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING)
+  if(GIT_VERSION_STRING VERSION_LESS 2.20 OR
+     2.21 VERSION_LESS_EQUAL GIT_VERSION_STRING)
     set(git_clone_options "--no-checkout")
   else()
     set(git_clone_options)
@@ -1337,7 +1318,8 @@
   # disable cert checking if explicitly told not to do it
   if(NOT "x${tls_verify}" STREQUAL "x" AND NOT tls_verify)
     set(git_options
-      -c http.sslVerify=false)
+      -c http.sslVerify=false
+    )
   endif()
   string (REPLACE ";" " " git_options "${git_options}")
 
@@ -1349,15 +1331,16 @@
 endfunction()
 
 function(_ep_write_hgclone_script
-         script_filename
-         source_dir
-         hg_EXECUTABLE
-         hg_repository
-         hg_tag
-         src_name
-         work_dir
-         hgclone_infofile
-         hgclone_stampfile)
+  script_filename
+  source_dir
+  hg_EXECUTABLE
+  hg_repository
+  hg_tag
+  src_name
+  work_dir
+  hgclone_infofile
+  hgclone_stampfile
+)
 
   if("${hg_tag}" STREQUAL "")
     message(FATAL_ERROR "Tag for hg checkout should not be empty.")
@@ -1372,16 +1355,17 @@
 
 
 function(_ep_write_gitupdate_script
-         script_filename
-         git_EXECUTABLE
-         git_tag
-         git_remote_name
-         init_submodules
-         git_submodules_recurse
-         git_submodules
-         git_repository
-         work_dir
-         git_update_strategy)
+  script_filename
+  git_EXECUTABLE
+  git_tag
+  git_remote_name
+  init_submodules
+  git_submodules_recurse
+  git_submodules
+  git_repository
+  work_dir
+  git_update_strategy
+)
 
   if("${git_tag}" STREQUAL "")
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
@@ -1403,20 +1387,20 @@
 endfunction()
 
 function(_ep_write_downloadfile_script
-         script_filename
-         REMOTE
-         LOCAL
-         timeout
-         inactivity_timeout
-         no_progress
-         hash
-         tls_verify
-         tls_cainfo
-         userpwd
-         http_headers
-         netrc
-         netrc_file)
-
+  script_filename
+  REMOTE
+  LOCAL
+  timeout
+  inactivity_timeout
+  no_progress
+  hash
+  tls_verify
+  tls_cainfo
+  userpwd
+  http_headers
+  netrc
+  netrc_file
+)
   if(timeout)
     set(TIMEOUT_ARGS TIMEOUT ${timeout})
     set(TIMEOUT_MSG "${timeout} seconds")
@@ -1499,9 +1483,8 @@
   set(HTTP_HEADERS_ARGS "")
   if(NOT http_headers STREQUAL "")
     foreach(header ${http_headers})
-      set(
-          HTTP_HEADERS_ARGS
-          "HTTPHEADER \"${header}\"\n        ${HTTP_HEADERS_ARGS}"
+      string(PREPEND HTTP_HEADERS_ARGS
+        "HTTPHEADER \"${header}\"\n        "
       )
     endforeach()
   endif()
@@ -1519,13 +1502,17 @@
   # * USERPWD_ARGS
   # * HTTP_HEADERS_ARGS
   configure_file(
-      "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/download.cmake.in"
-      "${script_filename}"
-      @ONLY
+    "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/download.cmake.in"
+    "${script_filename}"
+    @ONLY
   )
 endfunction()
 
-function(_ep_write_verifyfile_script script_filename LOCAL hash)
+function(_ep_write_verifyfile_script
+  script_filename
+  LOCAL
+  hash
+)
   _ep_get_hash_regex(_ep_hash_regex)
   if("${hash}" MATCHES "${_ep_hash_regex}")
     set(ALGO "${CMAKE_MATCH_1}")
@@ -1540,17 +1527,23 @@
   # * EXPECT_VALUE
   # * LOCAL
   configure_file(
-      "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/verify.cmake.in"
-      "${script_filename}"
-      @ONLY
+    "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/verify.cmake.in"
+    "${script_filename}"
+    @ONLY
   )
 endfunction()
 
 
-function(_ep_write_extractfile_script script_filename name filename directory options)
+function(_ep_write_extractfile_script
+  script_filename
+  name
+  filename
+  directory options
+)
   set(args "")
 
-  if(filename MATCHES "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
+  if(filename MATCHES
+     "(\\.|=)(7z|tar\\.bz2|tar\\.gz|tar\\.xz|tbz2|tgz|txz|zip)$")
     set(args xfz)
   endif()
 
@@ -1559,8 +1552,10 @@
   endif()
 
   if(args STREQUAL "")
-    message(SEND_ERROR "error: do not know how to extract '${filename}' -- known types are .7z, .tar, .tar.bz2, .tar.gz, .tar.xz, .tbz2, .tgz, .txz and .zip")
-    return()
+    message(FATAL_ERROR
+      "Do not know how to extract '${filename}' -- known types are: "
+      ".7z, .tar, .tar.bz2, .tar.gz, .tar.xz, .tbz2, .tgz, .txz and .zip"
+    )
   endif()
 
   configure_file(
@@ -1604,7 +1599,8 @@
     get_property(have_binary_dir TARGET ${name} PROPERTY _EP_BINARY_DIR SET)
     if(have_binary_dir)
       message(FATAL_ERROR
-        "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!")
+        "External project ${name} has both BINARY_DIR and BUILD_IN_SOURCE!"
+      )
     endif()
   endif()
   set(top "${CMAKE_CURRENT_BINARY_DIR}")
@@ -1640,7 +1636,8 @@
     set_property(TARGET ${name} PROPERTY _EP_SOURCE_SUBDIR "")
   elseif(IS_ABSOLUTE "${source_subdir}")
     message(FATAL_ERROR
-      "External project ${name} has non-relative SOURCE_SUBDIR!")
+      "External project ${name} has non-relative SOURCE_SUBDIR!"
+    )
   else()
     # Prefix with a slash so that when appended to the source directory, it
     # behaves as expected.
@@ -1650,9 +1647,13 @@
   if(build_in_source)
     get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
     if(source_subdir)
-      set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}/${source_subdir}")
+      set_property(TARGET ${name} PROPERTY
+        _EP_BINARY_DIR "${source_dir}/${source_subdir}"
+      )
     else()
-      set_property(TARGET ${name} PROPERTY _EP_BINARY_DIR "${source_dir}")
+      set_property(TARGET ${name} PROPERTY
+        _EP_BINARY_DIR "${source_dir}"
+      )
     endif()
   endif()
 
@@ -1679,7 +1680,16 @@
   set(vars ${ARGN})
   foreach(var ${vars})
     if(${var})
-      foreach(dir SOURCE_DIR SOURCE_SUBDIR BINARY_DIR INSTALL_DIR TMP_DIR DOWNLOAD_DIR DOWNLOADED_FILE LOG_DIR)
+      foreach(dir
+        SOURCE_DIR
+        SOURCE_SUBDIR
+        BINARY_DIR
+        INSTALL_DIR
+        TMP_DIR
+        DOWNLOAD_DIR
+        DOWNLOADED_FILE
+        LOG_DIR
+      )
         get_property(val TARGET ${target_name} PROPERTY _EP_${dir})
         string(REPLACE "<${dir}>" "${val}" ${var} "${${var}}")
       endforeach()
@@ -1688,7 +1698,11 @@
 endmacro()
 
 
-function(_ep_command_line_to_initial_cache var args force)
+function(_ep_command_line_to_initial_cache
+  var
+  args
+  force
+)
   set(script_initial_cache "")
   set(regex "^([^:]+):([^=]+)=(.*)$")
   set(setArg "")
@@ -1701,7 +1715,9 @@
       set(line "${CMAKE_MATCH_1}")
       if(NOT "${setArg}" STREQUAL "")
         # This is required to build up lists in variables, or complete an entry
-        string(APPEND setArg "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})")
+        string(APPEND setArg
+          "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})"
+        )
         string(APPEND script_initial_cache "\n${setArg}")
         set(accumulator "")
         set(setArg "")
@@ -1721,14 +1737,20 @@
   endforeach()
   # Catch the final line of the args
   if(NOT "${setArg}" STREQUAL "")
-    string(APPEND setArg "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})")
+    string(APPEND setArg
+      "${accumulator}\" CACHE ${type} \"Initial cache\" ${forceArg})"
+    )
     string(APPEND script_initial_cache "\n${setArg}")
   endif()
   set(${var} ${script_initial_cache} PARENT_SCOPE)
 endfunction()
 
 
-function(_ep_write_initial_cache target_name script_filename script_initial_cache)
+function(_ep_write_initial_cache
+  target_name
+  script_filename
+  script_initial_cache
+)
   # Write out values into an initial cache, that will be passed to CMake with -C
   # Replace location tags.
   _ep_replace_location_tags(${target_name} script_initial_cache)
@@ -1756,7 +1778,10 @@
 endfunction()
 
 
-function(_ep_get_configure_command_id name cfg_cmd_id_var)
+function(_ep_get_configure_command_id
+  name
+  cfg_cmd_id_var
+)
   get_target_property(cmd ${name} _EP_CONFIGURE_COMMAND)
 
   if(cmd STREQUAL "")
@@ -1782,7 +1807,11 @@
 endfunction()
 
 
-function(_ep_get_build_command name step cmd_var)
+function(_ep_get_build_command
+  name
+  step
+  cmd_var
+)
   set(cmd "")
   set(args)
   _ep_get_configure_command_id(${name} cfg_cmd_id)
@@ -1820,8 +1849,10 @@
           # BUILD_COMMAND to change the default command instead, but for
           # compatibility honor the value.
           set(config ${CMAKE_CFG_INTDIR})
-          message(AUTHOR_WARNING "CMAKE_CFG_INTDIR should not be set by project code.\n"
-            "To get a non-default build command, use the BUILD_COMMAND option.")
+          message(AUTHOR_WARNING
+            "CMAKE_CFG_INTDIR should not be set by project code.\n"
+            "To get a non-default build command, use the BUILD_COMMAND option."
+          )
         else()
           set(config $<CONFIG>)
         endif()
@@ -1869,7 +1900,11 @@
   set(${cmd_var} "${cmd}" PARENT_SCOPE)
 endfunction()
 
-function(_ep_write_log_script name step cmd_var)
+function(_ep_write_log_script
+  name
+  step
+  cmd_var
+)
   ExternalProject_Get_Property(${name} log_dir)
   ExternalProject_Get_Property(${name} stamp_dir)
   set(command "${${cmd_var}}")
@@ -1936,15 +1971,29 @@
       endif()
     endforeach()
     string(APPEND code "set(command \"${cmd}\")${code_execute_process}")
-    file(GENERATE OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake" CONTENT "${code}")
-    set(command ${CMAKE_COMMAND} "-Dmake=\${make}" "-Dconfig=\${config}" -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake)
+    file(GENERATE
+      OUTPUT "${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake"
+      CONTENT "${code}"
+    )
+    set(command
+      ${CMAKE_COMMAND}
+      "-Dmake=\${make}"
+      "-Dconfig=\${config}"
+      -P ${stamp_dir}/${name}-${step}-$<CONFIG>-impl.cmake
+    )
   endif()
 
   # Wrap the command in a script to log output to files.
   set(script ${stamp_dir}/${name}-${step}-$<CONFIG>.cmake)
   set(logbase ${log_dir}/${name}-${step})
-  get_property(log_merged TARGET ${name} PROPERTY _EP_LOG_MERGED_STDOUTERR)
-  get_property(log_output_on_failure TARGET ${name} PROPERTY _EP_LOG_OUTPUT_ON_FAILURE)
+  get_property(log_merged
+    TARGET ${name}
+    PROPERTY _EP_LOG_MERGED_STDOUTERR
+  )
+  get_property(log_output_on_failure
+    TARGET ${name}
+    PROPERTY _EP_LOG_OUTPUT_ON_FAILURE
+  )
   if (log_merged)
     set(stdout_log "${logbase}.log")
     set(stderr_log "${logbase}.log")
@@ -1965,7 +2014,7 @@
   RESULT_VARIABLE result
   OUTPUT_FILE \"\${stdout_log}\"
   ERROR_FILE \"\${stderr_log}\"
-  )
+)
 macro(read_up_to_max_size log_file output_var)
   file(SIZE \${log_file} determined_size)
   set(max_size 10240)
@@ -2032,7 +2081,11 @@
 endfunction()
 
 
-function(_ep_get_step_stampfile name step stampfile_var)
+function(_ep_get_step_stampfile
+  name
+  step
+  stampfile_var
+)
   ExternalProject_Get_Property(${name} stamp_dir)
 
   _ep_get_configuration_subdir_suffix(cfgdir)
@@ -2042,7 +2095,10 @@
 endfunction()
 
 
-function(_ep_get_complete_stampfile name stampfile_var)
+function(_ep_get_complete_stampfile
+  name
+  stampfile_var
+)
   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
   _ep_get_configuration_subdir_suffix(cfgdir)
   set(stampfile "${cmf_dir}${cfgdir}/${name}-complete")
@@ -2051,7 +2107,11 @@
 endfunction()
 
 
-function(_ep_step_add_target name step no_deps)
+function(_ep_step_add_target
+  name
+  step
+  no_deps
+)
   if(TARGET ${name}-${step})
     return()
   endif()
@@ -2063,16 +2123,20 @@
     # we need CMP0113 NEW behavior.
     cmake_policy(SET CMP0113 NEW)
   endif()
-  add_custom_target(${name}-${step}
-    DEPENDS ${stamp_file})
+  add_custom_target(${name}-${step} DEPENDS ${stamp_file})
   cmake_policy(POP)
-  set_property(TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP 1)
-  set_property(TARGET ${name}-${step} PROPERTY LABELS ${name})
-  set_property(TARGET ${name}-${step} PROPERTY FOLDER "ExternalProjectTargets/${name}")
+  set_target_properties(${name}-${step} PROPERTIES
+    _EP_IS_EXTERNAL_PROJECT_STEP 1
+    LABELS "${name}"
+    FOLDER "ExternalProjectTargets/${name}"
+  )
 
   if(cmp0114 STREQUAL "NEW")
     # Add target-level dependencies for the step.
-    get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
+    get_property(exclude_from_main
+      TARGET ${name}
+      PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
+    )
     if(NOT exclude_from_main)
       add_dependencies(${name} ${name}-${step})
     endif()
@@ -2082,7 +2146,9 @@
     get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT)
   else()
     if(no_deps AND "${step}" MATCHES "^(configure|build|install|test)$")
-      message(AUTHOR_WARNING "Using NO_DEPENDS for \"${step}\" step  might break parallel builds")
+      message(AUTHOR_WARNING
+        "Using NO_DEPENDS for \"${step}\" step  might break parallel builds"
+      )
     endif()
     set(independent ${no_deps})
   endif()
@@ -2097,12 +2163,25 @@
 endfunction()
 
 
-function(_ep_step_add_target_dependencies name step node)
-  get_property(dependees TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDEES)
+function(_ep_step_add_target_dependencies
+  name
+  step
+  node
+)
+  get_property(dependees
+    TARGET ${name}
+    PROPERTY _EP_${node}_INTERNAL_DEPENDEES
+  )
   list(REMOVE_DUPLICATES dependees)
   foreach(dependee IN LISTS dependees)
-    get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
-    get_property(dependee_dependers TARGET ${name} PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS)
+    get_property(exclude_from_main
+      TARGET ${name}
+      PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
+    )
+    get_property(dependee_dependers
+      TARGET ${name}
+      PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS
+    )
     if(exclude_from_main OR dependee_dependers MATCHES ";")
       # The step on which our step target depends itself has
       # dependents in multiple targes.  It needs a step target too
@@ -2119,8 +2198,15 @@
 endfunction()
 
 
-function(_ep_step_add_target_dependents name step node)
-  get_property(dependers TARGET ${name} PROPERTY _EP_${node}_INTERNAL_DEPENDERS)
+function(_ep_step_add_target_dependents
+  name
+  step
+  node
+)
+  get_property(dependers
+    TARGET ${name}
+    PROPERTY _EP_${node}_INTERNAL_DEPENDERS
+  )
   list(REMOVE_DUPLICATES dependers)
   foreach(depender IN LISTS dependers)
     if(TARGET ${name}-${depender})
@@ -2147,7 +2233,7 @@
         "The 'NO_DEPENDS' option is no longer allowed.  "
         "It has been superseded by the per-step 'INDEPENDENT' option.  "
         "See policy CMP0114."
-        )
+      )
     endif()
   elseif(cmp0114 STREQUAL "")
     cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
@@ -2155,11 +2241,11 @@
       "ExternalProject target '${name}' would depend on the targets for "
       "step(s) '${steps}' under policy CMP0114, but this is being left out "
       "for compatibility since the policy is not set."
-      )
+    )
     if(no_deps)
-      string(APPEND _cmp0114_warning
-        "  Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114."
-        )
+      string(APPEND _cmp0114_warning "  "
+        "Also, the NO_DEPENDS option is deprecated in favor of policy CMP0114."
+      )
     endif()
     message(AUTHOR_WARNING "${_cmp0114_warning}")
   endif()
@@ -2188,38 +2274,60 @@
     LOG
     USES_TERMINAL
   )
-  _ep_parse_arguments(ExternalProject_Add_Step "${keywords}"
-                      ${name} _EP_${step}_ "${ARGN}")
+  _ep_parse_arguments(
+    ExternalProject_Add_Step
+    "${keywords}"
+    ${name}
+    _EP_${step}_
+    "${ARGN}"
+  )
 
-  get_property(independent TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT)
+  get_property(independent
+    TARGET ${name}
+    PROPERTY _EP_${step}_INDEPENDENT
+  )
   if(independent STREQUAL "")
     set(independent FALSE)
-    set_property(TARGET ${name} PROPERTY _EP_${step}_INDEPENDENT "${independent}")
+    set_property(TARGET ${name} PROPERTY
+      _EP_${step}_INDEPENDENT "${independent}"
+    )
   endif()
 
-  get_property(exclude_from_main TARGET ${name} PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN)
+  get_property(exclude_from_main
+    TARGET ${name}
+    PROPERTY _EP_${step}_EXCLUDE_FROM_MAIN
+  )
   if(NOT exclude_from_main)
     add_custom_command(APPEND
       OUTPUT ${complete_stamp_file}
       DEPENDS ${stamp_file}
-      )
+    )
   endif()
 
   # Steps depending on this step.
   get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
-  set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDERS ${dependers})
+  set_property(TARGET ${name} APPEND PROPERTY
+    _EP_${step}_INTERNAL_DEPENDERS ${dependers}
+  )
   foreach(depender IN LISTS dependers)
-    set_property(TARGET ${name} APPEND PROPERTY _EP_${depender}_INTERNAL_DEPENDEES ${step})
+    set_property(TARGET ${name} APPEND PROPERTY
+      _EP_${depender}_INTERNAL_DEPENDEES ${step}
+    )
     _ep_get_step_stampfile(${name} ${depender} depender_stamp_file)
     add_custom_command(APPEND
       OUTPUT ${depender_stamp_file}
       DEPENDS ${stamp_file}
-      )
+    )
     if(cmp0114 STREQUAL "NEW" AND NOT independent)
-      get_property(dep_independent TARGET ${name} PROPERTY _EP_${depender}_INDEPENDENT)
+      get_property(dep_independent
+        TARGET ${name}
+        PROPERTY _EP_${depender}_INDEPENDENT
+      )
       if(dep_independent)
-        message(FATAL_ERROR "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT "
-          "but depends on step '${step}' that is not marked INDEPENDENT.")
+        message(FATAL_ERROR
+          "ExternalProject '${name}' step '${depender}' is marked INDEPENDENT "
+          "but depends on step '${step}' that is not marked INDEPENDENT."
+        )
       endif()
     endif()
   endforeach()
@@ -2232,16 +2340,25 @@
 
   # Dependencies on steps.
   get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
-  set_property(TARGET ${name} APPEND PROPERTY _EP_${step}_INTERNAL_DEPENDEES ${dependees})
+  set_property(TARGET ${name} APPEND PROPERTY
+    _EP_${step}_INTERNAL_DEPENDEES ${dependees}
+  )
   foreach(dependee IN LISTS dependees)
-    set_property(TARGET ${name} APPEND PROPERTY _EP_${dependee}_INTERNAL_DEPENDERS ${step})
+    set_property(TARGET ${name} APPEND PROPERTY
+      _EP_${dependee}_INTERNAL_DEPENDERS ${step}
+    )
     _ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file)
     list(APPEND depends ${dependee_stamp_file})
     if(cmp0114 STREQUAL "NEW" AND independent)
-      get_property(dep_independent TARGET ${name} PROPERTY _EP_${dependee}_INDEPENDENT)
+      get_property(dep_independent
+        TARGET ${name}
+        PROPERTY _EP_${dependee}_INDEPENDENT
+      )
       if(NOT dep_independent)
-        message(FATAL_ERROR "ExternalProject '${name}' step '${step}' is marked INDEPENDENT "
-          "but depends on step '${dependee}' that is not marked INDEPENDENT.")
+        message(FATAL_ERROR
+          "ExternalProject '${name}' step '${step}' is marked INDEPENDENT "
+          "but depends on step '${dependee}' that is not marked INDEPENDENT."
+        )
       endif()
     endif()
   endforeach()
@@ -2253,25 +2370,47 @@
   else()
     set(comment "No ${step} step for '${name}'")
   endif()
-  get_property(work_dir TARGET ${name} PROPERTY _EP_${step}_WORKING_DIRECTORY)
+  get_property(work_dir
+    TARGET ${name}
+    PROPERTY _EP_${step}_WORKING_DIRECTORY
+  )
 
   # Replace list separators.
-  get_property(sep TARGET ${name} PROPERTY _EP_LIST_SEPARATOR)
+  get_property(sep
+    TARGET ${name}
+    PROPERTY _EP_LIST_SEPARATOR
+  )
   if(sep AND command)
     string(REPLACE "${sep}" "\\;" command "${command}")
   endif()
 
   # Replace location tags.
-  _ep_replace_location_tags(${name} comment command work_dir byproducts)
+  _ep_replace_location_tags(
+    ${name}
+    comment
+    command
+    work_dir
+    byproducts
+  )
 
   # Custom comment?
-  get_property(comment_set TARGET ${name} PROPERTY _EP_${step}_COMMENT SET)
+  get_property(comment_set
+    TARGET ${name}
+    PROPERTY _EP_${step}_COMMENT
+    SET
+  )
   if(comment_set)
-    get_property(comment TARGET ${name} PROPERTY _EP_${step}_COMMENT)
+    get_property(comment
+      TARGET ${name}
+      PROPERTY _EP_${step}_COMMENT
+    )
   endif()
 
   # Uses terminal?
-  get_property(uses_terminal TARGET ${name} PROPERTY _EP_${step}_USES_TERMINAL)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_${step}_USES_TERMINAL
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL)
   else()
@@ -2279,7 +2418,10 @@
   endif()
 
   # Run every time?
-  get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS)
+  get_property(always
+    TARGET ${name}
+    PROPERTY _EP_${step}_ALWAYS
+  )
   if(always)
     set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
     set(touch)
@@ -2287,7 +2429,9 @@
     get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
     if(_isMultiConfig)
       foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
-        string(REPLACE "/${CMAKE_CFG_INTDIR}" "/${cfg}" stamp_file_config "${stamp_file}")
+        string(REPLACE "/${CMAKE_CFG_INTDIR}" "/${cfg}"
+          stamp_file_config "${stamp_file}"
+        )
         file(REMOVE ${stamp_file_config})
       endforeach()
     else()
@@ -2332,9 +2476,15 @@
   set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step})
 
   # Add custom "step target"?
-  get_property(step_targets TARGET ${name} PROPERTY _EP_STEP_TARGETS)
+  get_property(step_targets
+    TARGET ${name}
+    PROPERTY _EP_STEP_TARGETS
+  )
   if(NOT step_targets)
-    get_property(step_targets DIRECTORY PROPERTY EP_STEP_TARGETS)
+    get_property(step_targets
+      DIRECTORY
+      PROPERTY EP_STEP_TARGETS
+    )
   endif()
   foreach(st ${step_targets})
     if("${st}" STREQUAL "${step}")
@@ -2343,31 +2493,43 @@
     endif()
   endforeach()
 
-  get_property(independent_step_targets TARGET ${name} PROPERTY _EP_INDEPENDENT_STEP_TARGETS)
+  get_property(independent_step_targets
+    TARGET ${name} PROPERTY
+    _EP_INDEPENDENT_STEP_TARGETS
+  )
   if(NOT independent_step_targets)
-    get_property(independent_step_targets DIRECTORY PROPERTY EP_INDEPENDENT_STEP_TARGETS)
+    get_property(independent_step_targets
+      DIRECTORY
+      PROPERTY EP_INDEPENDENT_STEP_TARGETS
+    )
   endif()
   if(cmp0114 STREQUAL "NEW")
     if(independent_step_targets)
       message(FATAL_ERROR
-        "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to\n"
-        "  ${independent_step_targets}\n"
+        "ExternalProject '${name}' option 'INDEPENDENT_STEP_TARGETS' is set to"
+        "\n  ${independent_step_targets}\n"
         "but the option is no longer allowed.  "
         "It has been superseded by the per-step 'INDEPENDENT' option.  "
         "See policy CMP0114."
-        )
+      )
     endif()
   else()
     if(independent_step_targets AND cmp0114 STREQUAL "")
-      get_property(warned TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS)
+      get_property(warned
+        TARGET ${name}
+        PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS
+      )
       if(NOT warned)
-        set_property(TARGET ${name} PROPERTY _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1)
+        set_property(TARGET ${name} PROPERTY
+          _EP_CMP0114_WARNED_INDEPENDENT_STEP_TARGETS 1
+        )
         cmake_policy(GET_WARNING CMP0114 _cmp0114_warning)
-        string(APPEND _cmp0114_warning "\n"
-          "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to\n"
-          "  ${independent_step_targets}\n"
+        string(APPEND _cmp0114_warning
+          "\n"
+          "ExternalProject '${name}' option INDEPENDENT_STEP_TARGETS is set to"
+          "\n  ${independent_step_targets}\n"
           "but the option is deprecated in favor of policy CMP0114."
-          )
+        )
         message(AUTHOR_WARNING "${_cmp0114_warning}")
       endif()
     endif()
@@ -2386,33 +2548,51 @@
 
   # Sanity checks on "name" and "step".
   if(NOT TARGET ${name})
-    message(FATAL_ERROR "Cannot find target \"${name}\". Perhaps it has not yet been created using ExternalProject_Add.")
+    message(FATAL_ERROR
+      "Cannot find target \"${name}\". Perhaps it has not yet been created "
+      "using ExternalProject_Add."
+    )
   endif()
 
   get_property(type TARGET ${name} PROPERTY TYPE)
   if(NOT type STREQUAL "UTILITY")
-    message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.")
+    message(FATAL_ERROR
+      "Target \"${name}\" was not generated by ExternalProject_Add."
+    )
   endif()
 
   get_property(is_ep TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT)
   if(NOT is_ep)
-    message(FATAL_ERROR "Target \"${name}\" was not generated by ExternalProject_Add.")
+    message(FATAL_ERROR
+      "Target \"${name}\" was not generated by ExternalProject_Add."
+    )
   endif()
 
   get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
   list(FIND steps ${step} is_step)
   if(is_step LESS 0)
-    message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".")
+    message(FATAL_ERROR
+      "External project \"${name}\" does not have a step \"${step}\"."
+    )
   endif()
 
   if(TARGET ${name}-${step})
     get_property(type TARGET ${name}-${step} PROPERTY TYPE)
     if(NOT type STREQUAL "UTILITY")
-      message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.")
+      message(FATAL_ERROR
+        "Target \"${name}-${step}\" was not generated by "
+        "ExternalProject_Add_StepTargets."
+      )
     endif()
-    get_property(is_ep_step TARGET ${name}-${step} PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP)
+    get_property(is_ep_step
+      TARGET ${name}-${step}
+      PROPERTY _EP_IS_EXTERNAL_PROJECT_STEP
+    )
     if(NOT is_ep_step)
-      message(FATAL_ERROR "Target \"${name}-${step}\" was not generated by ExternalProject_Add_StepTargets.")
+      message(FATAL_ERROR
+        "Target \"${name}-${step}\" was not generated by "
+        "ExternalProject_Add_StepTargets."
+      )
     endif()
   endif()
 
@@ -2422,7 +2602,8 @@
   foreach(dep ${dependencies})
     add_custom_command(APPEND
       OUTPUT ${stamp_file}
-      DEPENDS ${dep})
+      DEPENDS ${dep}
+    )
     if(TARGET ${name}-${step})
       foreach(dep ${dependencies})
         add_dependencies(${name}-${step} ${dep})
@@ -2455,14 +2636,21 @@
 endfunction()
 
 function(_ep_get_git_submodules_recurse git_submodules_recurse)
-  # Checks for GIT_SUBMODULES_RECURSE property
-  # Default is ON, which sets git_submodules_recurse output variable to "--recursive"
-  # Otherwise, the output variable is set to an empty value ""
-  get_property(git_submodules_recurse_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE SET)
+  # Checks for GIT_SUBMODULES_RECURSE property. Default is ON, which sets
+  # git_submodules_recurse output variable to "--recursive". Otherwise, the
+  # output variable is set to an empty value "".
+  get_property(git_submodules_recurse_set
+    TARGET ${name}
+    PROPERTY _EP_GIT_SUBMODULES_RECURSE
+    SET
+  )
   if(NOT git_submodules_recurse_set)
     set(recurseFlag "--recursive")
   else()
-    get_property(git_submodules_recurse_value TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE)
+    get_property(git_submodules_recurse_value
+      TARGET ${name}
+      PROPERTY _EP_GIT_SUBMODULES_RECURSE
+    )
     if(git_submodules_recurse_value)
       set(recurseFlag "--recursive")
     else()
@@ -2473,13 +2661,21 @@
 
   # The git submodule update '--recursive' flag requires git >= v1.6.5
   if(recurseFlag AND GIT_VERSION_STRING VERSION_LESS 1.6.5)
-    message(FATAL_ERROR "error: git version 1.6.5 or later required for --recursive flag with 'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
+    message(FATAL_ERROR
+      "git version 1.6.5 or later required for --recursive flag with "
+      "'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'"
+    )
   endif()
 endfunction()
 
 
 function(_ep_add_download_command name)
-  ExternalProject_Get_Property(${name} source_dir stamp_dir download_dir tmp_dir)
+  ExternalProject_Get_Property(${name}
+    source_dir
+    stamp_dir
+    download_dir
+    tmp_dir
+  )
 
   get_property(cmd_set TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND SET)
   get_property(cmd TARGET ${name} PROPERTY _EP_DOWNLOAD_COMMAND)
@@ -2517,7 +2713,14 @@
     get_filename_component(src_name "${source_dir}" NAME)
     get_filename_component(work_dir "${source_dir}" PATH)
     set(comment "Performing download step (CVS checkout) for '${name}'")
-    set(cmd ${CVS_EXECUTABLE} -d ${cvs_repository} -q co ${cvs_tag} -d ${src_name} ${cvs_module})
+    set(cmd
+      ${CVS_EXECUTABLE}
+      -d ${cvs_repository}
+      -q
+      co ${cvs_tag}
+      -d ${src_name}
+      ${cvs_module}
+    )
 
   elseif(svn_repository)
     set(method svn)
@@ -2530,7 +2733,10 @@
     get_property(svn_username TARGET ${name} PROPERTY _EP_SVN_USERNAME)
     get_property(svn_password TARGET ${name} PROPERTY _EP_SVN_PASSWORD)
     get_property(svn_trust_cert TARGET ${name} PROPERTY _EP_SVN_TRUST_CERT)
-    get_property(uses_terminal TARGET ${name} PROPERTY _EP_USES_TERMINAL_DOWNLOAD)
+    get_property(uses_terminal
+      TARGET ${name}
+      PROPERTY _EP_USES_TERMINAL_DOWNLOAD
+    )
     if(uses_terminal)
       set(svn_interactive_args "")
     else()
@@ -2550,9 +2756,16 @@
     if(svn_trust_cert)
       set(svn_trust_cert_args --trust-server-cert)
     endif()
-    set(cmd ${Subversion_SVN_EXECUTABLE} co ${svn_repository} ${svn_revision}
-      ${svn_interactive_args} ${svn_trust_cert_args} ${svn_user_pw_args}
-      ${src_name})
+    set(cmd
+      ${Subversion_SVN_EXECUTABLE}
+      co
+      ${svn_repository}
+      ${svn_revision}
+      ${svn_interactive_args}
+      ${svn_trust_cert_args}
+      ${svn_user_pw_args}
+      ${src_name}
+    )
 
   elseif(git_repository)
     set(method git)
@@ -2573,7 +2786,10 @@
     endif()
 
     set(git_init_submodules TRUE)
-    get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET)
+    get_property(git_submodules_set
+      TARGET ${name}
+      PROPERTY _EP_GIT_SUBMODULES SET
+    )
     if(git_submodules_set)
       get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
       if(git_submodules  STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW")
@@ -2622,10 +2838,25 @@
     # create a cmake script to invoke as download command.
     # The script will delete the source directory and then call git clone.
     #
-    _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
-      ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
-      ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}"
-      )
+    _ep_write_gitclone_script(
+      ${tmp_dir}/${name}-gitclone.cmake
+      ${source_dir}
+      ${GIT_EXECUTABLE}
+      ${git_repository}
+      ${git_tag}
+      ${git_remote_name}
+      ${git_init_submodules}
+      "${git_submodules_recurse}"
+      "${git_submodules}"
+      "${git_shallow}"
+      "${git_progress}"
+      "${git_config}"
+      ${src_name}
+      ${work_dir}
+      ${stamp_dir}/${name}-gitinfo.txt
+      ${stamp_dir}/${name}-gitclone-lastrun.txt
+      "${tls_verify}"
+    )
     set(comment "Performing download step (git clone) for '${name}'")
     set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake)
 
@@ -2656,10 +2887,17 @@
     # create a cmake script to invoke as download command.
     # The script will delete the source directory and then call hg clone.
     #
-    _ep_write_hgclone_script(${tmp_dir}/${name}-hgclone.cmake ${source_dir}
-      ${HG_EXECUTABLE} ${hg_repository} ${hg_tag} ${src_name} ${work_dir}
-      ${stamp_dir}/${name}-hginfo.txt ${stamp_dir}/${name}-hgclone-lastrun.txt
-      )
+    _ep_write_hgclone_script(
+      ${tmp_dir}/${name}-hgclone.cmake
+      ${source_dir}
+      ${HG_EXECUTABLE}
+      ${hg_repository}
+      ${hg_tag}
+      ${src_name}
+      ${work_dir}
+      ${stamp_dir}/${name}-hginfo.txt
+      ${stamp_dir}/${name}-hgclone-lastrun.txt
+    )
     set(comment "Performing download step (hg clone) for '${name}'")
     set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-hgclone.cmake)
 
@@ -2671,13 +2909,21 @@
     if(hash AND NOT "${hash}" MATCHES "${_ep_hash_regex}")
       _ep_get_hash_algos(_ep_hash_algos)
       list(JOIN _ep_hash_algos "|" _ep_hash_algos)
-      message(FATAL_ERROR "URL_HASH is set to\n  ${hash}\n"
-        "but must be ALGO=value where ALGO is\n  ${_ep_hash_algos}\n"
-        "and value is a hex string.")
+      message(FATAL_ERROR
+        "URL_HASH is set to\n"
+        "  ${hash}\n"
+        "but must be ALGO=value where ALGO is\n"
+        "  ${_ep_hash_algos}\n"
+        "and value is a hex string."
+      )
     endif()
     get_property(md5 TARGET ${name} PROPERTY _EP_URL_MD5)
     if(md5 AND NOT "MD5=${md5}" MATCHES "${_ep_hash_regex}")
-      message(FATAL_ERROR "URL_MD5 is set to\n  ${md5}\nbut must be a hex string.")
+      message(FATAL_ERROR
+        "URL_MD5 is set to\n"
+        "  ${md5}\n"
+        "but must be a hex string."
+      )
     endif()
     if(md5 AND NOT hash)
       set(hash "MD5=${md5}")
@@ -2691,7 +2937,9 @@
     if(NOT "${url_list_length}" STREQUAL "1")
       foreach(entry ${url})
         if(NOT "${entry}" MATCHES "^[a-z]+://")
-          message(FATAL_ERROR "At least one entry of URL is a path (invalid in a list)")
+          message(FATAL_ERROR
+            "At least one entry of URL is a path (invalid in a list)"
+          )
         endif()
       endforeach()
       if("x${fname}" STREQUAL "x")
@@ -2702,17 +2950,23 @@
     if(IS_DIRECTORY "${url}")
       get_filename_component(abs_dir "${url}" ABSOLUTE)
       set(comment "Performing download step (DIR copy) for '${name}'")
-      set(cmd   ${CMAKE_COMMAND} -E rm -rf ${source_dir}
-        COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir})
+      set(cmd
+        ${CMAKE_COMMAND} -E rm -rf ${source_dir}
+        COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir}
+      )
     else()
-      get_property(no_extract TARGET "${name}" PROPERTY _EP_DOWNLOAD_NO_EXTRACT)
+      get_property(no_extract
+        TARGET "${name}"
+        PROPERTY _EP_DOWNLOAD_NO_EXTRACT
+      )
       string(APPEND extra_repo_info "no_extract=${no_extract}\n")
       if("${url}" MATCHES "^[a-z]+://")
         # TODO: Should download and extraction be different steps?
         if("x${fname}" STREQUAL "x")
           set(fname "${url}")
         endif()
-        if("${fname}" MATCHES [[([^/\?#]+(\.|=)(7z|tar|tar\.bz2|tar\.gz|tar\.xz|tbz2|tgz|txz|zip))([/?#].*)?$]])
+        set(ext_regex [[7z|tar|tar\.bz2|tar\.gz|tar\.xz|tbz2|tgz|txz|zip]])
+        if("${fname}" MATCHES "([^/\\?#]+(\\.|=)(${ext_regex}))([/?#].*)?$")
           set(fname "${CMAKE_MATCH_1}")
         elseif(no_extract)
           get_filename_component(fname "${fname}" NAME)
@@ -2727,8 +2981,14 @@
         string(REPLACE ";" "-" fname "${fname}")
         set(file ${download_dir}/${fname})
         get_property(timeout TARGET ${name} PROPERTY _EP_TIMEOUT)
-        get_property(inactivity_timeout TARGET ${name} PROPERTY _EP_INACTIVITY_TIMEOUT)
-        get_property(no_progress TARGET ${name} PROPERTY _EP_DOWNLOAD_NO_PROGRESS)
+        get_property(inactivity_timeout
+          TARGET ${name}
+          PROPERTY _EP_INACTIVITY_TIMEOUT
+        )
+        get_property(no_progress
+          TARGET ${name}
+          PROPERTY _EP_DOWNLOAD_NO_PROGRESS
+        )
         get_property(tls_verify TARGET ${name} PROPERTY _EP_TLS_VERIFY)
         get_property(tls_cainfo TARGET ${name} PROPERTY _EP_TLS_CAINFO)
         get_property(netrc TARGET ${name} PROPERTY _EP_NETRC)
@@ -2752,15 +3012,18 @@
           "${netrc}"
           "${netrc_file}"
         )
-        set(cmd ${CMAKE_COMMAND} -P "${download_script}"
-          COMMAND)
+        set(cmd
+          ${CMAKE_COMMAND} -P "${download_script}"
+          COMMAND
+        )
         if (no_extract)
           set(steps "download and verify")
         else ()
           set(steps "download, verify and extract")
         endif ()
         set(comment "Performing download step (${steps}) for '${name}'")
-        file(WRITE "${stamp_dir}/verify-${name}.cmake" "") # already verified by 'download_script'
+        # already verified by 'download_script'
+        file(WRITE "${stamp_dir}/verify-${name}.cmake" "")
 
         # Rather than adding everything to the RepositoryInfo.txt file, it is
         # more robust to just depend on the download script. That way, we will
@@ -2781,7 +3044,9 @@
         )
       endif()
       list(APPEND cmd ${CMAKE_COMMAND} -P ${stamp_dir}/verify-${name}.cmake)
-      get_target_property(extract_timestamp ${name} _EP_DOWNLOAD_EXTRACT_TIMESTAMP)
+      get_target_property(extract_timestamp ${name}
+        _EP_DOWNLOAD_EXTRACT_TIMESTAMP
+      )
       if(no_extract)
         if(NOT extract_timestamp STREQUAL "extract_timestamp-NOTFOUND")
           message(FATAL_ERROR
@@ -2825,14 +3090,16 @@
           "${source_dir}"
           "${options}"
         )
-        list(APPEND cmd COMMAND ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake)
+        list(APPEND cmd
+          COMMAND ${CMAKE_COMMAND} -P ${stamp_dir}/extract-${name}.cmake
+        )
       endif ()
     endif()
   else()
     set(method source_dir)
     _ep_is_dir_empty("${source_dir}" empty)
     if(${empty})
-      message(SEND_ERROR
+      message(FATAL_ERROR
         "No download info given for '${name}' and its source directory:\n"
         " ${source_dir}\n"
         "is not an existing non-empty directory.  Please specify one of:\n"
@@ -2843,7 +3110,7 @@
         " * SVN_REPOSITORY\n"
         " * HG_REPOSITORY\n"
         " * CVS_REPOSITORY and CVS_MODULE"
-        )
+      )
     endif()
   endif()
 
@@ -2858,15 +3125,20 @@
     @ONLY
   )
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_DOWNLOAD)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_DOWNLOAD
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY
-    _EP_USES_TERMINAL_DOWNLOAD)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_DOWNLOAD
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
@@ -2887,16 +3159,26 @@
       DEPENDEES mkdir
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 endfunction()
 
 function(_ep_get_update_disconnected var name)
-  get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
+  get_property(update_disconnected_set
+    TARGET ${name}
+    PROPERTY _EP_UPDATE_DISCONNECTED
+    SET
+  )
   if(update_disconnected_set)
-    get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
+    get_property(update_disconnected
+      TARGET ${name}
+      PROPERTY _EP_UPDATE_DISCONNECTED
+    )
   else()
-    get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
+    get_property(update_disconnected
+      DIRECTORY
+      PROPERTY EP_UPDATE_DISCONNECTED
+    )
   endif()
   set(${var} "${update_disconnected}" PARENT_SCOPE)
 endfunction()
@@ -2957,8 +3239,14 @@
     if(svn_trust_cert)
       set(svn_trust_cert_args --trust-server-cert)
     endif()
-    set(cmd ${Subversion_SVN_EXECUTABLE} up ${svn_revision}
-      ${svn_interactive_args} ${svn_trust_cert_args} ${svn_user_pw_args})
+    set(cmd
+      ${Subversion_SVN_EXECUTABLE}
+      up
+      ${svn_revision}
+      ${svn_interactive_args}
+      ${svn_trust_cert_args}
+      ${svn_user_pw_args}
+    )
     set(always 1)
   elseif(git_repository)
     # FetchContent gives us these directly, so don't try to recompute them
@@ -2971,25 +3259,43 @@
     endif()
     set(work_dir ${source_dir})
     set(comment "Performing update step for '${name}'")
-    get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
+
+    get_property(git_tag
+      TARGET ${name}
+      PROPERTY _EP_GIT_TAG
+    )
     if(NOT git_tag)
       set(git_tag "master")
     endif()
-    get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME)
+
+    get_property(git_remote_name
+      TARGET ${name}
+      PROPERTY _EP_GIT_REMOTE_NAME
+    )
     if(NOT git_remote_name)
       set(git_remote_name "origin")
     endif()
 
     set(git_init_submodules TRUE)
-    get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET)
+    get_property(git_submodules_set
+      TARGET ${name}
+      PROPERTY _EP_GIT_SUBMODULES
+      SET
+    )
     if(git_submodules_set)
-      get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+      get_property(git_submodules
+        TARGET ${name}
+        PROPERTY _EP_GIT_SUBMODULES
+      )
       if(git_submodules  STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW")
         set(git_init_submodules FALSE)
       endif()
     endif()
 
-    get_property(git_update_strategy TARGET ${name} PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY)
+    get_property(git_update_strategy
+      TARGET ${name}
+      PROPERTY _EP_GIT_REMOTE_UPDATE_STRATEGY
+    )
     if(NOT git_update_strategy)
       set(git_update_strategy "${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}")
     endif()
@@ -2998,7 +3304,10 @@
     endif()
     set(strategies CHECKOUT REBASE REBASE_CHECKOUT)
     if(NOT git_update_strategy IN_LIST strategies)
-      message(FATAL_ERROR "'${git_update_strategy}' is not one of the supported strategies: ${strategies}")
+      message(FATAL_ERROR
+        "'${git_update_strategy}' is not one of the supported strategies: "
+        "${strategies}"
+      )
     endif()
 
     _ep_get_git_submodules_recurse(git_submodules_recurse)
@@ -3023,32 +3332,48 @@
     endif()
     set(work_dir ${source_dir})
     set(comment "Performing update step (hg pull) for '${name}'")
-    get_property(hg_tag TARGET ${name} PROPERTY _EP_HG_TAG)
+
+    get_property(hg_tag
+      TARGET ${name}
+      PROPERTY _EP_HG_TAG
+    )
     if(NOT hg_tag)
       set(hg_tag "tip")
     endif()
+
     if("${HG_VERSION_STRING}" STREQUAL "2.1")
-      message(WARNING "Mercurial 2.1 does not distinguish an empty pull from a failed pull:
- http://mercurial.selenic.com/wiki/UpgradeNotes#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X
+      set(notesAnchor
+        "#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X"
+      )
+      message(WARNING
+"Mercurial 2.1 does not distinguish an empty pull from a failed pull:
+ http://mercurial.selenic.com/wiki/UpgradeNotes${notesAnchor}
  http://thread.gmane.org/gmane.comp.version-control.mercurial.devel/47656
 Update to Mercurial >= 2.1.1.
 ")
     endif()
-    set(cmd ${HG_EXECUTABLE} pull
+
+    set(cmd
+      ${HG_EXECUTABLE} pull
       COMMAND ${HG_EXECUTABLE} update ${hg_tag}
-      )
+    )
     set(always 1)
   endif()
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_UPDATE)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_UPDATE
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY
-    _EP_USES_TERMINAL_UPDATE)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_UPDATE
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
@@ -3070,7 +3395,7 @@
       DEPENDEES download
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 
 endfunction()
@@ -3088,14 +3413,20 @@
     set(work_dir ${source_dir})
   endif()
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_PATCH)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_PATCH
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY _EP_USES_TERMINAL_PATCH)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_PATCH
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
@@ -3121,18 +3452,27 @@
       DEPENDEES \${patch_dep}
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 endfunction()
 
 function(_ep_get_file_deps var name)
   set(file_deps)
 
-  get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
+  get_property(deps
+    TARGET ${name}
+    PROPERTY _EP_DEPENDS
+  )
   foreach(dep IN LISTS deps)
-    get_property(dep_type TARGET ${dep} PROPERTY TYPE)
+    get_property(dep_type
+      TARGET ${dep}
+      PROPERTY TYPE
+    )
     if(dep_type STREQUAL "UTILITY")
-      get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
+      get_property(is_ep
+        TARGET ${dep}
+        PROPERTY _EP_IS_EXTERNAL_PROJECT
+      )
       if(is_ep)
         _ep_get_step_stampfile(${dep} "done" done_stamp_file)
         list(APPEND file_deps ${done_stamp_file})
@@ -3144,9 +3484,16 @@
 endfunction()
 
 function(_ep_extract_configure_command var name)
-  get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
+  get_property(cmd_set
+    TARGET ${name}
+    PROPERTY _EP_CONFIGURE_COMMAND
+    SET
+  )
   if(cmd_set)
-    get_property(cmd TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND)
+    get_property(cmd
+      TARGET ${name}
+      PROPERTY _EP_CONFIGURE_COMMAND
+    )
   else()
     get_target_property(cmake_command ${name} _EP_CMAKE_COMMAND)
     if(cmake_command)
@@ -3155,13 +3502,22 @@
       set(cmd "${CMAKE_COMMAND}")
     endif()
 
-    get_property(cmake_args TARGET ${name} PROPERTY _EP_CMAKE_ARGS)
+    get_property(cmake_args
+      TARGET ${name}
+      PROPERTY _EP_CMAKE_ARGS
+    )
     list(APPEND cmd ${cmake_args})
 
     # If there are any CMAKE_CACHE_ARGS or CMAKE_CACHE_DEFAULT_ARGS,
     # write an initial cache and use it
-    get_property(cmake_cache_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_ARGS)
-    get_property(cmake_cache_default_args TARGET ${name} PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS)
+    get_property(cmake_cache_args
+      TARGET ${name}
+      PROPERTY _EP_CMAKE_CACHE_ARGS
+    )
+    get_property(cmake_cache_default_args
+      TARGET ${name}
+      PROPERTY _EP_CMAKE_CACHE_DEFAULT_ARGS
+    )
 
     set(has_cmake_cache_args 0)
     if(NOT "${cmake_cache_args}" STREQUAL "")
@@ -3173,10 +3529,18 @@
       set(has_cmake_cache_default_args 1)
     endif()
 
-    get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
-    get_target_property(cmake_generator_instance ${name} _EP_CMAKE_GENERATOR_INSTANCE)
-    get_target_property(cmake_generator_platform ${name} _EP_CMAKE_GENERATOR_PLATFORM)
-    get_target_property(cmake_generator_toolset ${name} _EP_CMAKE_GENERATOR_TOOLSET)
+    get_target_property(cmake_generator ${name}
+      _EP_CMAKE_GENERATOR
+    )
+    get_target_property(cmake_generator_instance ${name}
+      _EP_CMAKE_GENERATOR_INSTANCE
+    )
+    get_target_property(cmake_generator_platform ${name}
+      _EP_CMAKE_GENERATOR_PLATFORM
+    )
+    get_target_property(cmake_generator_toolset ${name}
+      _EP_CMAKE_GENERATOR_TOOLSET
+    )
     if(cmake_generator)
       list(APPEND cmd "-G${cmake_generator}")
       if(cmake_generator_platform)
@@ -3186,7 +3550,9 @@
         list(APPEND cmd "-T${cmake_generator_toolset}")
       endif()
       if(cmake_generator_instance)
-        list(APPEND cmd "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${cmake_generator_instance}")
+        list(APPEND cmd
+          "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${cmake_generator_instance}"
+        )
       endif()
     else()
       if(CMAKE_EXTRA_GENERATOR)
@@ -3195,49 +3561,72 @@
         list(APPEND cmd "-G${CMAKE_GENERATOR}")
         if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
           set(has_cmake_cache_default_args 1)
-          set(cmake_cache_default_args ${cmake_cache_default_args}
+          list(APPEND cmake_cache_default_args
             "-DGHS_TARGET_PLATFORM:STRING=${GHS_TARGET_PLATFORM}"
             "-DGHS_PRIMARY_TARGET:STRING=${GHS_PRIMARY_TARGET}"
             "-DGHS_TOOLSET_ROOT:STRING=${GHS_TOOLSET_ROOT}"
             "-DGHS_OS_ROOT:STRING=${GHS_OS_ROOT}"
             "-DGHS_OS_DIR:STRING=${GHS_OS_DIR}"
-            "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}")
+            "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}"
+          )
         endif()
       endif()
       if(cmake_generator_platform)
-        message(FATAL_ERROR "Option CMAKE_GENERATOR_PLATFORM not allowed without CMAKE_GENERATOR.")
+        message(FATAL_ERROR
+          "Option CMAKE_GENERATOR_PLATFORM not allowed without "
+          "CMAKE_GENERATOR."
+        )
       endif()
       if(CMAKE_GENERATOR_PLATFORM)
         list(APPEND cmd "-A${CMAKE_GENERATOR_PLATFORM}")
       endif()
       if(cmake_generator_toolset)
-        message(FATAL_ERROR "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR.")
+        message(FATAL_ERROR
+          "Option CMAKE_GENERATOR_TOOLSET not allowed without CMAKE_GENERATOR."
+        )
       endif()
       if(CMAKE_GENERATOR_TOOLSET)
         list(APPEND cmd "-T${CMAKE_GENERATOR_TOOLSET}")
       endif()
       if(cmake_generator_instance)
-        message(FATAL_ERROR "Option CMAKE_GENERATOR_INSTANCE not allowed without CMAKE_GENERATOR.")
+        message(FATAL_ERROR
+          "Option CMAKE_GENERATOR_INSTANCE not allowed without CMAKE_GENERATOR."
+        )
       endif()
       if(CMAKE_GENERATOR_INSTANCE)
-        list(APPEND cmd "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
+        list(APPEND cmd
+          "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}"
+        )
       endif()
     endif()
 
     if(has_cmake_cache_args OR has_cmake_cache_default_args)
       set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake")
       if(has_cmake_cache_args)
-        _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1)
+        _ep_command_line_to_initial_cache(
+          script_initial_cache_force
+          "${cmake_cache_args}"
+          1
+        )
       endif()
       if(has_cmake_cache_default_args)
-        _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0)
+        _ep_command_line_to_initial_cache(
+          script_initial_cache_default
+          "${cmake_cache_default_args}"
+          0
+        )
       endif()
-      _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}")
+      _ep_write_initial_cache(
+        ${name}
+        "${_ep_cache_args_script}"
+        "${script_initial_cache_force}${script_initial_cache_default}"
+      )
       list(APPEND cmd "-C${_ep_cache_args_script}")
       _ep_replace_location_tags(${name} _ep_cache_args_script)
       set(_ep_cache_args_script
         "${_ep_cache_args_script}"
-        PARENT_SCOPE)
+        PARENT_SCOPE
+      )
     endif()
 
     list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>")
@@ -3251,8 +3640,10 @@
   ExternalProject_Get_Property(${name} binary_dir tmp_dir)
 
   set(file_deps)
-  get_property(configure_handled_by_build TARGET ${name}
-               PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD)
+  get_property(configure_handled_by_build
+    TARGET ${name}
+    PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD
+  )
   if(NOT configure_handled_by_build)
     # Depend on other external projects (file-level)
     _ep_get_file_deps(file_deps ${name})
@@ -3272,15 +3663,20 @@
   list(APPEND file_deps ${tmp_dir}/${name}-cfgcmd.txt)
   list(APPEND file_deps ${_ep_cache_args_script})
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_CONFIGURE)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_CONFIGURE
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY
-    _EP_USES_TERMINAL_CONFIGURE)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_CONFIGURE
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
@@ -3300,7 +3696,7 @@
       DEPENDS \${file_deps}
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 endfunction()
 
@@ -3309,43 +3705,63 @@
   ExternalProject_Get_Property(${name} binary_dir)
 
   set(file_deps)
-  get_property(configure_handled_by_build TARGET ${name}
-               PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD)
+  get_property(configure_handled_by_build
+    TARGET ${name}
+    PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD
+  )
   if(configure_handled_by_build)
     # Depend on other external projects (file-level)
     _ep_get_file_deps(file_deps ${name})
   endif()
 
-  get_property(cmd_set TARGET ${name} PROPERTY _EP_BUILD_COMMAND SET)
+  get_property(cmd_set
+    TARGET ${name}
+    PROPERTY _EP_BUILD_COMMAND
+    SET
+  )
   if(cmd_set)
-    get_property(cmd TARGET ${name} PROPERTY _EP_BUILD_COMMAND)
+    get_property(cmd
+      TARGET ${name}
+      PROPERTY _EP_BUILD_COMMAND
+    )
   else()
     _ep_get_build_command(${name} BUILD cmd)
   endif()
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_BUILD)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_BUILD
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY
-    _EP_USES_TERMINAL_BUILD)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_BUILD
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
     set(uses_terminal "")
   endif()
 
-  get_property(build_always TARGET ${name} PROPERTY _EP_BUILD_ALWAYS)
+  get_property(build_always
+    TARGET ${name}
+    PROPERTY _EP_BUILD_ALWAYS
+  )
   if(build_always)
     set(always 1)
   else()
     set(always 0)
   endif()
 
-  get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS)
+  get_property(build_byproducts
+    TARGET ${name}
+    PROPERTY _EP_BUILD_BYPRODUCTS
+  )
 
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
@@ -3362,7 +3778,7 @@
       ALWAYS \${always}
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 endfunction()
 
@@ -3370,22 +3786,34 @@
 function(_ep_add_install_command name)
   ExternalProject_Get_Property(${name} binary_dir)
 
-  get_property(cmd_set TARGET ${name} PROPERTY _EP_INSTALL_COMMAND SET)
+  get_property(cmd_set
+    TARGET ${name}
+    PROPERTY _EP_INSTALL_COMMAND
+    SET
+  )
   if(cmd_set)
-    get_property(cmd TARGET ${name} PROPERTY _EP_INSTALL_COMMAND)
+    get_property(cmd
+      TARGET ${name}
+      PROPERTY _EP_INSTALL_COMMAND
+    )
   else()
     _ep_get_build_command(${name} INSTALL cmd)
   endif()
 
-  get_property(log TARGET ${name} PROPERTY _EP_LOG_INSTALL)
+  get_property(log
+    TARGET ${name}
+    PROPERTY _EP_LOG_INSTALL
+  )
   if(log)
     set(log LOG 1)
   else()
     set(log "")
   endif()
 
-  get_property(uses_terminal TARGET ${name} PROPERTY
-    _EP_USES_TERMINAL_INSTALL)
+  get_property(uses_terminal
+    TARGET ${name}
+    PROPERTY _EP_USES_TERMINAL_INSTALL
+  )
   if(uses_terminal)
     set(uses_terminal USES_TERMINAL 1)
   else()
@@ -3404,7 +3832,7 @@
       DEPENDEES build
       ${log}
       ${uses_terminal}
-      )"
+    )"
   )
 endfunction()
 
@@ -3422,7 +3850,10 @@
   #
   if(cmd_set OR before OR after OR exclude)
     if(cmd_set)
-      get_property(cmd TARGET ${name} PROPERTY _EP_TEST_COMMAND)
+      get_property(cmd
+        TARGET ${name}
+        PROPERTY _EP_TEST_COMMAND
+      )
     else()
       _ep_get_build_command(${name} TEST cmd)
     endif()
@@ -3445,15 +3876,20 @@
       set(exclude_args "")
     endif()
 
-    get_property(log TARGET ${name} PROPERTY _EP_LOG_TEST)
+    get_property(log
+      TARGET ${name}
+      PROPERTY _EP_LOG_TEST
+    )
     if(log)
       set(log LOG 1)
     else()
       set(log "")
     endif()
 
-    get_property(uses_terminal TARGET ${name} PROPERTY
-      _EP_USES_TERMINAL_TEST)
+    get_property(uses_terminal
+      TARGET ${name}
+      PROPERTY _EP_USES_TERMINAL_TEST
+    )
     if(uses_terminal)
       set(uses_terminal USES_TERMINAL 1)
     else()
@@ -3474,7 +3910,7 @@
         ${exclude_args}
         ${log}
         ${uses_terminal}
-        )"
+      )"
     )
   endif()
 endfunction()
@@ -3483,11 +3919,12 @@
 function(ExternalProject_Add name)
   cmake_policy(GET CMP0097 _EP_CMP0097
     PARENT_SCOPE # undocumented, do not use outside of CMake
-    )
+  )
   cmake_policy(GET CMP0114 cmp0114
     PARENT_SCOPE # undocumented, do not use outside of CMake
-    )
-  if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12 AND NOT cmp0114 STREQUAL "NEW")
+  )
+  if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12 AND
+     NOT cmp0114 STREQUAL "NEW")
     message(AUTHOR_WARNING
       "Policy CMP0114 is not set to NEW.  "
       "In order to support the Xcode \"new build system\", "
@@ -3496,12 +3933,12 @@
       "Since CMake is generating for the Xcode \"new build system\", "
       "ExternalProject_Add will use policy CMP0114's NEW behavior anyway, "
       "but the generated build system may not match what the project intends."
-      )
+    )
     set(cmp0114 "NEW")
   endif()
   cmake_policy(GET CMP0135 _EP_CMP0135
     PARENT_SCOPE # undocumented, do not use outside of CMake
-    )
+  )
 
   _ep_get_configuration_subdir_suffix(cfgdir)
 
@@ -3520,11 +3957,12 @@
   # argument was passed, we explicitly set it for the target.
   add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
   cmake_policy(POP)
-  set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1)
-  set_property(TARGET ${name} PROPERTY LABELS ${name})
-  set_property(TARGET ${name} PROPERTY FOLDER "ExternalProjectTargets/${name}")
-
-  set_property(TARGET ${name} PROPERTY _EP_CMP0114 "${cmp0114}")
+  set_target_properties(${name} PROPERTIES
+    _EP_IS_EXTERNAL_PROJECT 1
+    LABELS ${name}
+    FOLDER "ExternalProjectTargets/${name}"
+    _EP_CMP0114 "${cmp0114}"
+  )
 
   set(keywords
     #
@@ -3657,13 +4095,22 @@
     #
     LIST_SEPARATOR
   )
-  _ep_parse_arguments(ExternalProject_Add "${keywords}" ${name} _EP_ "${ARGN}")
+  _ep_parse_arguments(
+    ExternalProject_Add
+    "${keywords}"
+    ${name}
+    _EP_
+    "${ARGN}"
+  )
   _ep_set_directories(${name})
   _ep_get_step_stampfile(${name} "done" done_stamp_file)
   _ep_get_step_stampfile(${name} "install" install_stamp_file)
 
   # Set the EXCLUDE_FROM_ALL target property if required.
-  get_property(exclude_from_all TARGET ${name} PROPERTY _EP_EXCLUDE_FROM_ALL)
+  get_property(exclude_from_all
+    TARGET ${name}
+    PROPERTY _EP_EXCLUDE_FROM_ALL
+  )
   if(exclude_from_all)
     set_property(TARGET ${name} PROPERTY EXCLUDE_FROM_ALL TRUE)
   endif()
@@ -3690,11 +4137,13 @@
     COMMAND ${CMAKE_COMMAND} -E touch ${done_stamp_file}
     DEPENDS ${install_stamp_file}
     VERBATIM
-    )
-
+  )
 
   # Depend on other external projects (target-level).
-  get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
+  get_property(deps
+    TARGET ${name}
+    PROPERTY _EP_DEPENDS
+  )
   foreach(arg IN LISTS deps)
     add_dependencies(${name} ${arg})
   endforeach()
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index e1cc843..5ca296e 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1431,7 +1431,7 @@
     # and can always request a known configuration further below.
     get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
     if(is_multi_config)
-      list(APPEND subCMakeOpts "-DCMAKE_CONFIGURATION_TYPES:STRING=Release")
+      list(APPEND subCMakeOpts "-DCMAKE_CONFIGURATION_TYPES:STRING=Debug")
     endif()
 
   else()
@@ -1479,7 +1479,7 @@
   # anything to be updated, so extra rebuilds of the project won't occur.
   # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
   # has this set to something not findable on the PATH. We also ensured above
-  # that the Release config will be defined for multi-config generators.
+  # that the Debug config will be defined for multi-config generators.
   configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
                  "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
   execute_process(
@@ -1495,7 +1495,7 @@
     message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
   endif()
   execute_process(
-    COMMAND ${CMAKE_COMMAND} --build . --config Release
+    COMMAND ${CMAKE_COMMAND} --build . --config Debug
     RESULT_VARIABLE result
     ${outputOptions}
     WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
index 72d4db5..320ddad 100644
--- a/Modules/FindGLUT.cmake
+++ b/Modules/FindGLUT.cmake
@@ -275,8 +275,4 @@
         PROPERTY INTERFACE_LINK_LIBRARIES GLUT::Cocoa)
     endif()
   endif()
-
-  #The following deprecated settings are for backwards compatibility with CMake1.4
-  set (GLUT_LIBRARY ${GLUT_LIBRARIES})
-  set (GLUT_INCLUDE_PATH ${GLUT_INCLUDE_DIRS})
 endif()
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index ab8af3e..854e0e1 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -143,7 +143,9 @@
       string(REGEX REPLACE "${_regexp}" " " _pkgconfig_invoke_result "${_pkgconfig_invoke_result}")
     endif()
 
-    separate_arguments(_pkgconfig_invoke_result)
+    # pkg-config can represent "spaces within an argument" by backslash-escaping the space.
+    # UNIX_COMMAND mode treats backslash-escaped spaces as "not a space that delimits arguments".
+    separate_arguments(_pkgconfig_invoke_result UNIX_COMMAND "${_pkgconfig_invoke_result}")
 
     #message(STATUS "  ${_varname} ... ${_pkgconfig_invoke_result}")
     set(_pkgconfig_${_varname} ${_pkgconfig_invoke_result})
@@ -167,13 +169,14 @@
 endmacro()
 
 # Splits given arguments into options and a package list
-macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global)
+macro(_pkgconfig_parse_options _result _is_req _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _static_target)
   set(${_is_req} 0)
   set(${_is_silent} 0)
   set(${_no_cmake_path} 0)
   set(${_no_cmake_environment_path} 0)
   set(${_imp_target} 0)
   set(${_imp_target_global} 0)
+  set(${_static_target} 0)
   if(DEFINED PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
     if(NOT PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
       set(${_no_cmake_path} 1)
@@ -203,6 +206,9 @@
     if (_pkg STREQUAL "GLOBAL")
       set(${_imp_target_global} 1)
     endif()
+    if (_pkg STREQUAL "STATIC_TARGET")
+      set(${_static_target} 1)
+    endif()
   endforeach()
 
   if (${_imp_target_global} AND NOT ${_imp_target})
@@ -215,6 +221,7 @@
   list(REMOVE_ITEM ${_result} "NO_CMAKE_PATH")
   list(REMOVE_ITEM ${_result} "NO_CMAKE_ENVIRONMENT_PATH")
   list(REMOVE_ITEM ${_result} "IMPORTED_TARGET")
+  list(REMOVE_ITEM ${_result} "STATIC_TARGET")
   list(REMOVE_ITEM ${_result} "GLOBAL")
 endmacro()
 
@@ -246,7 +253,7 @@
 # scan the LDFLAGS returned by pkg-config for library directories and
 # libraries, figure out the absolute paths of that libraries in the
 # given directories
-function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
+function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path _static)
   unset(_libs)
   unset(_find_opts)
 
@@ -259,9 +266,23 @@
     list(APPEND _find_opts "NO_CMAKE_ENVIRONMENT_PATH")
   endif()
 
+  if(_static)
+    set(var_prefix ${_prefix}_STATIC)
+    set(pkgcfg_lib_prefix pkgcfg_static_lib_${_prefix})
+    # reconfigure library prefixes/suffixes so that only static libraries can be found
+    set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_STATIC_LIBRARY_PREFIX}")
+    set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+  else()
+    set(var_prefix ${_prefix})
+    set(pkgcfg_lib_prefix pkgcfg_lib_${_prefix})
+    # reconfigure library prefixes/suffixes so that only dynamic libraries can be found
+    set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_SHARED_LIBRARY_PREFIX}")
+    set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX}")
+  endif()
+
   unset(_search_paths)
   unset(_next_is_framework)
-  foreach (flag IN LISTS ${_prefix}_LDFLAGS)
+  foreach (flag IN LISTS ${var_prefix}_LDFLAGS)
     if (_next_is_framework)
       list(APPEND _libs "-framework ${flag}")
       unset(_next_is_framework)
@@ -280,61 +301,78 @@
       continue()
     endif()
 
+    set(lib_var_name ${pkgcfg_lib_prefix}_${_pkg_search})
+
     if(_search_paths)
         # Firstly search in -L paths
-        find_library(pkgcfg_lib_${_prefix}_${_pkg_search}
+        find_library(${lib_var_name}
                      NAMES ${_pkg_search}
                      HINTS ${_search_paths} NO_DEFAULT_PATH)
     endif()
-    find_library(pkgcfg_lib_${_prefix}_${_pkg_search}
+    find_library(${lib_var_name}
                  NAMES ${_pkg_search}
                  ${_find_opts})
-    mark_as_advanced(pkgcfg_lib_${_prefix}_${_pkg_search})
-    if(pkgcfg_lib_${_prefix}_${_pkg_search})
-      list(APPEND _libs "${pkgcfg_lib_${_prefix}_${_pkg_search}}")
+
+    mark_as_advanced(${lib_var_name})
+    if(${lib_var_name})
+      list(APPEND _libs "${${lib_var_name}}")
     else()
       list(APPEND _libs ${_pkg_search})
     endif()
   endforeach()
 
-  set(${_prefix}_LINK_LIBRARIES "${_libs}" PARENT_SCOPE)
+  set(${var_prefix}_LINK_LIBRARIES "${_libs}" PARENT_SCOPE)
 endfunction()
 
 # create an imported target from all the information returned by pkg-config
-function(_pkg_create_imp_target _prefix _imp_target_global)
-  if (NOT TARGET PkgConfig::${_prefix})
+function(_pkg_create_imp_target _prefix _imp_target_global _var_qualifier)
+  set(tgt PkgConfig::${_prefix})
+  set(var_prefix ${_prefix}${_var_qualifier})
+
+  if (NOT TARGET ${tgt})
     if(${_imp_target_global})
       set(_global_opt "GLOBAL")
     else()
       unset(_global_opt)
     endif()
-    add_library(PkgConfig::${_prefix} INTERFACE IMPORTED ${_global_opt})
+    add_library(${tgt} INTERFACE IMPORTED ${_global_opt})
 
-    if(${_prefix}_INCLUDE_DIRS)
-      set_property(TARGET PkgConfig::${_prefix} PROPERTY
-                   INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}")
+    if(${var_prefix}_INCLUDE_DIRS)
+      set_property(TARGET ${tgt} PROPERTY
+                   INTERFACE_INCLUDE_DIRECTORIES "${${var_prefix}_INCLUDE_DIRS}")
     endif()
-    if(${_prefix}_LINK_LIBRARIES)
-      set_property(TARGET PkgConfig::${_prefix} PROPERTY
-                   INTERFACE_LINK_LIBRARIES "${${_prefix}_LINK_LIBRARIES}")
+    if(${var_prefix}_LINK_LIBRARIES)
+      set_property(TARGET ${tgt} PROPERTY
+                   INTERFACE_LINK_LIBRARIES "${${var_prefix}_LINK_LIBRARIES}")
     endif()
-    if(${_prefix}_LDFLAGS_OTHER)
-      set_property(TARGET PkgConfig::${_prefix} PROPERTY
-                   INTERFACE_LINK_OPTIONS "${${_prefix}_LDFLAGS_OTHER}")
+    if(${var_prefix}_LDFLAGS_OTHER)
+      set_property(TARGET ${tgt} PROPERTY
+                   INTERFACE_LINK_OPTIONS "${${var_prefix}_LDFLAGS_OTHER}")
     endif()
-    if(${_prefix}_CFLAGS_OTHER)
-      set_property(TARGET PkgConfig::${_prefix} PROPERTY
-                   INTERFACE_COMPILE_OPTIONS "${${_prefix}_CFLAGS_OTHER}")
+    if(${var_prefix}_CFLAGS_OTHER)
+      set_property(TARGET ${tgt} PROPERTY
+                   INTERFACE_COMPILE_OPTIONS "${${var_prefix}_CFLAGS_OTHER}")
     endif()
   endif()
 endfunction()
 
 # recalculate the dynamic output
 # this is a macro and not a function so the result of _pkg_find_libs is automatically propagated
-macro(_pkg_recalculate _prefix _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global)
-  _pkg_find_libs(${_prefix} ${_no_cmake_path} ${_no_cmake_environment_path})
+macro(_pkg_recalculate _prefix _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _static_target)
+  # populate unqualified (shared) series of variables
+  _pkg_find_libs("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} FALSE)
+  # populate STATIC_ series of variables
+  _pkg_find_libs("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} TRUE)
+
   if(${_imp_target})
-    _pkg_create_imp_target(${_prefix} ${_imp_target_global})
+    if (${_static_target})
+      set(var_qualifier "_STATIC")
+    else()
+      set(var_qualifier "")
+    endif()
+    # create unqualified target, sourced from whichever series of variables is preferred.
+    # default: source target from unqualified (shared) variables. otherwise STATIC_ variables
+    _pkg_create_imp_target("${_prefix}" ${_imp_target_global} "${var_qualifier}")
   endif()
 endmacro()
 
@@ -503,7 +541,7 @@
 endfunction()
 
 ###
-macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _prefix)
+macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _static_target _prefix)
   _pkgconfig_unset(${_prefix}_FOUND)
   _pkgconfig_unset(${_prefix}_VERSION)
   _pkgconfig_unset(${_prefix}_PREFIX)
@@ -639,20 +677,21 @@
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LIBRARY_DIRS  "(^| )-L"             --libs-only-L )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS       ""                    --libs )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER ""                    --libs-only-other )
-
-      if (APPLE AND "-framework" IN_LIST ${_prefix}_LDFLAGS_OTHER)
-        _pkgconfig_extract_frameworks("${_prefix}")
-      endif()
-
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS  "(^| )(-I|-isystem ?)" --cflags-only-I )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS        ""                    --cflags )
       _pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER  ""                    --cflags-only-other )
 
-      if (${_prefix}_CFLAGS_OTHER MATCHES "-isystem")
-        _pkgconfig_extract_isystem("${_prefix}")
-      endif ()
+      foreach (qualifier IN ITEMS "" "_STATIC")
+        set(qual_prefix ${_prefix}${qualifier})
+        if (APPLE AND "-framework" IN_LIST ${qual_prefix}_LDFLAGS_OTHER)
+          _pkgconfig_extract_frameworks("${qual_prefix}")
+        endif()
+        if (${qual_prefix}_CFLAGS_OTHER MATCHES "-isystem")
+          _pkgconfig_extract_isystem("${qual_prefix}")
+        endif ()
+      endforeach()
 
-      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
+      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} ${_static_target})
     endif()
 
     _pkg_restore_path_internal()
@@ -676,7 +715,7 @@
                       [REQUIRED] [QUIET]
                       [NO_CMAKE_PATH]
                       [NO_CMAKE_ENVIRONMENT_PATH]
-                      [IMPORTED_TARGET [GLOBAL]]
+                      [IMPORTED_TARGET [GLOBAL] [STATIC_TARGET]]
                       <moduleSpec> [<moduleSpec>...])
 
   When the ``REQUIRED`` argument is given, the command will fail with an error
@@ -707,6 +746,13 @@
     The ``GLOBAL`` argument will make the
     imported target available in global scope.
 
+  .. versionadded:: 3.24
+    The ``STATIC_TARGET`` argument will make the
+    imported target reference the static libraries
+    reported in ``<XXX>_STATIC_LINK_LIBRARIES``.
+    Without this option, the imported target
+    references the ``<XXX>_LINK_LIBRARIES``.
+
   .. versionadded:: 3.15
     Non-library linker options reported by ``pkg-config`` are stored in the
     :prop_tgt:`INTERFACE_LINK_OPTIONS` target property.
@@ -738,6 +784,10 @@
     only the libraries (without the '-l')
   ``<XXX>_LINK_LIBRARIES``
     the libraries and their absolute paths
+  ``<XXX>_STATIC_LINK_LIBRARIES``
+    .. versionadded:: 3.24
+
+    static libraries and their absolute paths
   ``<XXX>_LIBRARY_DIRS``
     the paths of the libraries (without the '-L')
   ``<XXX>_LDFLAGS``
@@ -819,12 +869,12 @@
     XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
 #]========================================]
 macro(pkg_check_modules _prefix _module0)
-  _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN})
+  _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _static_target "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND OR
       (NOT "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0};${ARGN}") OR
       (    "${ARGN}" STREQUAL "" AND NOT "${__pkg_config_arguments_${_prefix}}" STREQUAL "${_module0}"))
-    _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} "${_prefix}" ${_pkg_modules})
+    _pkg_check_modules_internal("${_pkg_is_required}" "${_pkg_is_silent}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} ${_static_target} "${_prefix}" ${_pkg_modules})
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
     if (${_prefix}_FOUND)
@@ -832,7 +882,7 @@
     endif()
   else()
     if (${_prefix}_FOUND)
-      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
+      _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} ${_static_target})
     endif()
   endif()
 endmacro()
@@ -866,7 +916,7 @@
     pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2)
 #]========================================]
 macro(pkg_search_module _prefix _module0)
-  _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN})
+  _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global _static_target "${_module0}" ${ARGN})
   # check cached value
   if (NOT DEFINED __pkg_config_checked_${_prefix} OR __pkg_config_checked_${_prefix} LESS ${PKG_CONFIG_VERSION} OR NOT ${_prefix}_FOUND)
     set(_pkg_modules_found 0)
@@ -878,7 +928,7 @@
     # iterate through all modules and stop at the first working one.
     foreach(_pkg_alt ${_pkg_modules_alt})
       if(NOT _pkg_modules_found)
-        _pkg_check_modules_internal(0 1 ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} "${_prefix}" "${_pkg_alt}")
+        _pkg_check_modules_internal(0 1 ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} ${_static_target} "${_prefix}" "${_pkg_alt}")
       endif()
 
       if (${_prefix}_FOUND)
@@ -895,7 +945,7 @@
 
     _pkgconfig_set(__pkg_config_checked_${_prefix} ${PKG_CONFIG_VERSION})
   elseif (${_prefix}_FOUND)
-    _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global})
+    _pkg_recalculate("${_prefix}" ${_no_cmake_path} ${_no_cmake_environment_path} ${_imp_target} ${_imp_target_global} ${_static_target})
   endif()
 endmacro()
 
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 527ca8b..8b322ed 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -10,6 +10,16 @@
 Find Vulkan, which is a low-overhead, cross-platform 3D graphics
 and computing API.
 
+Optional COMPONENTS
+^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.24
+
+This module respects several optional COMPONENTS: ``glslc``,
+``glslangValidator``, ``glslang``, ``shaderc_combined`` and ``SPIRV-Tools``.
+On macOS, an additional component ``MoltenVK`` is available.
+There are corresponding import targets for each of these flags.
+
 IMPORTED Targets
 ^^^^^^^^^^^^^^^^
 
@@ -36,6 +46,30 @@
   The glslangValidator tool, if found.  It is used to compile GLSL and
   HLSL shaders into SPIR-V.
 
+``Vulkan::glslang``
+  .. versionadded:: 3.24
+
+  Defined if SDK has the Khronos-reference front-end shader parser and SPIR-V
+  generator library (glslang).
+
+``Vulkan::shaderc_combined``
+  .. versionadded:: 3.24
+
+  Defined if SDK has the Google static library for Vulkan shader compilation
+  (shaderc_combined).
+
+``Vulkan::SPIRV-Tools``
+  .. versionadded:: 3.24
+
+  Defined if SDK has the Khronos library to process SPIR-V modules
+  (SPIRV-Tools).
+
+``Vulkan::MoltenVK``
+  .. versionadded:: 3.24
+
+  Defined if SDK has the Khronos library which implement a subset of Vulkan API
+  over Apple Metal graphics framework. (MoltenVK).
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
@@ -51,6 +85,30 @@
   .. versionadded:: 3.23
 
   value from ``vulkan/vulkan_core.h``
+``Vulkan_glslc_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the glslc executable.
+``Vulkan_glslangValidator_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the glslangValidator executable.
+``Vulkan_glslang_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the glslang library.
+``Vulkan_shaderc_combined_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the shaderc_combined library.
+``Vulkan_SPIRV-Tools_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the SPIRV-Tools library.
+``Vulkan_MoltenVK_FOUND``
+  .. versionadded:: 3.24
+
+  True, if the SDK has the MoltenVK library.
 
 The module will also defines these cache variables:
 
@@ -62,6 +120,22 @@
   the path to the GLSL SPIR-V compiler
 ``Vulkan_GLSLANG_VALIDATOR_EXECUTABLE``
   the path to the glslangValidator tool
+``Vulkan_glslang_LIBRARY``
+  .. versionadded:: 3.24
+
+  Path to the glslang library.
+``Vulkan_shaderc_combined_LIBRARY``
+  .. versionadded:: 3.24
+
+  Path to the shaderc_combined library.
+``Vulkan_SPIRV-Tools_LIBRARY``
+  .. versionadded:: 3.24
+
+  Path to the SPIRV-Tools library.
+``Vulkan_MoltenVK_LIBRARY``
+  .. versionadded:: 3.24
+
+  Path to the MoltenVK library.
 
 Hints
 ^^^^^
@@ -76,61 +150,298 @@
 
 #]=======================================================================]
 
-if(WIN32)
-  find_path(Vulkan_INCLUDE_DIR
-    NAMES vulkan/vulkan.h
-    HINTS
-      "$ENV{VULKAN_SDK}/Include"
-    )
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW)
 
+# For backward compatibility as `FindVulkan` in previous CMake versions allow to retrieve `glslc`
+# and `glslangValidator` without requesting the corresponding component.
+if(NOT glslc IN_LIST Vulkan_FIND_COMPONENTS)
+  list(APPEND Vulkan_FIND_COMPONENTS glslc)
+endif()
+if(NOT glslangValidator IN_LIST Vulkan_FIND_COMPONENTS)
+  list(APPEND Vulkan_FIND_COMPONENTS glslangValidator)
+endif()
+
+if(WIN32)
+  set(_Vulkan_library_name vulkan-1)
+  set(_Vulkan_hint_include_search_paths
+    "$ENV{VULKAN_SDK}/Include"
+  )
   if(CMAKE_SIZEOF_VOID_P EQUAL 8)
-    find_library(Vulkan_LIBRARY
-      NAMES vulkan-1
-      HINTS
-        "$ENV{VULKAN_SDK}/Lib"
-        "$ENV{VULKAN_SDK}/Bin"
-      )
-    find_program(Vulkan_GLSLC_EXECUTABLE
-      NAMES glslc
-      HINTS
-        "$ENV{VULKAN_SDK}/Bin"
-      )
-    find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE
-      NAMES glslangValidator
-      HINTS
-        "$ENV{VULKAN_SDK}/Bin"
-      )
-  elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
-    find_library(Vulkan_LIBRARY
-      NAMES vulkan-1
-      HINTS
-        "$ENV{VULKAN_SDK}/Lib32"
-        "$ENV{VULKAN_SDK}/Bin32"
-      )
-    find_program(Vulkan_GLSLC_EXECUTABLE
-      NAMES glslc
-      HINTS
-        "$ENV{VULKAN_SDK}/Bin32"
-      )
-    find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE
-      NAMES glslangValidator
-      HINTS
-        "$ENV{VULKAN_SDK}/Bin32"
-      )
+    set(_Vulkan_hint_executable_search_paths
+      "$ENV{VULKAN_SDK}/Bin"
+    )
+    set(_Vulkan_hint_library_search_paths
+      "$ENV{VULKAN_SDK}/Lib"
+      "$ENV{VULKAN_SDK}/Bin"
+    )
+  else()
+    set(_Vulkan_hint_executable_search_paths
+      "$ENV{VULKAN_SDK}/Bin32"
+    )
+    set(_Vulkan_hint_library_search_paths
+      "$ENV{VULKAN_SDK}/Lib32"
+      "$ENV{VULKAN_SDK}/Bin32"
+    )
   endif()
 else()
-  find_path(Vulkan_INCLUDE_DIR
-    NAMES vulkan/vulkan.h
-    HINTS "$ENV{VULKAN_SDK}/include")
-  find_library(Vulkan_LIBRARY
-    NAMES vulkan
-    HINTS "$ENV{VULKAN_SDK}/lib")
+  set(_Vulkan_library_name vulkan)
+  set(_Vulkan_hint_include_search_paths
+    "$ENV{VULKAN_SDK}/include"
+  )
+  set(_Vulkan_hint_executable_search_paths
+    "$ENV{VULKAN_SDK}/bin"
+  )
+  set(_Vulkan_hint_library_search_paths
+    "$ENV{VULKAN_SDK}/lib"
+  )
+endif()
+if(APPLE AND DEFINED ENV{VULKAN_SDK})
+  cmake_path(SET _MoltenVK_path NORMALIZE "$ENV{VULKAN_SDK}/../MoltenVK")
+  if(EXISTS "${_MoltenVK_path}")
+    list(APPEND _Vulkan_hint_include_search_paths
+      "${_MoltenVK_path}/include"
+    )
+    if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
+      list(APPEND _Vulkan_hint_library_search_paths
+        "${_MoltenVK_path}/dylib/iOS"
+      )
+    elseif(CMAKE_SYSTEM_NAME STREQUAL "tvOS")
+      list(APPEND _Vulkan_hint_library_search_paths
+        "${_MoltenVK_path}/dylib/tvOS"
+      )
+    else()
+      list(APPEND _Vulkan_hint_library_search_paths
+        "${_MoltenVK_path}/dylib/macOS"
+      )
+    endif()
+  endif()
+  unset(_MoltenVK_path)
+endif()
+
+find_path(Vulkan_INCLUDE_DIR
+  NAMES vulkan/vulkan.h
+  HINTS
+    ${_Vulkan_hint_include_search_paths}
+  )
+mark_as_advanced(Vulkan_INCLUDE_DIR)
+
+find_library(Vulkan_LIBRARY
+  NAMES ${_Vulkan_library_name}
+  HINTS
+    ${_Vulkan_hint_library_search_paths}
+  )
+mark_as_advanced(Vulkan_LIBRARY)
+
+if(glslc IN_LIST Vulkan_FIND_COMPONENTS)
   find_program(Vulkan_GLSLC_EXECUTABLE
     NAMES glslc
-    HINTS "$ENV{VULKAN_SDK}/bin")
+    HINTS
+      ${_Vulkan_hint_executable_search_paths}
+    )
+  mark_as_advanced(Vulkan_GLSLC_EXECUTABLE)
+endif()
+if(glslangValidator IN_LIST Vulkan_FIND_COMPONENTS)
   find_program(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE
     NAMES glslangValidator
-    HINTS "$ENV{VULKAN_SDK}/bin")
+    HINTS
+      ${_Vulkan_hint_executable_search_paths}
+    )
+  mark_as_advanced(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE)
+endif()
+if(glslang IN_LIST Vulkan_FIND_COMPONENTS)
+  find_library(Vulkan_glslang-spirv_LIBRARY
+    NAMES SPIRV
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-spirv_LIBRARY)
+
+  find_library(Vulkan_glslang-spirv_DEBUG_LIBRARY
+    NAMES SPIRVd
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-spirv_DEBUG_LIBRARY)
+
+  find_library(Vulkan_glslang-oglcompiler_LIBRARY
+    NAMES OGLCompiler
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-oglcompiler_LIBRARY)
+
+  find_library(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY
+    NAMES OGLCompilerd
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY)
+
+  find_library(Vulkan_glslang-osdependent_LIBRARY
+    NAMES OSDependent
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-osdependent_LIBRARY)
+
+  find_library(Vulkan_glslang-osdependent_DEBUG_LIBRARY
+    NAMES OSDependentd
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-osdependent_DEBUG_LIBRARY)
+
+  find_library(Vulkan_glslang-machineindependent_LIBRARY
+    NAMES MachineIndependent
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-machineindependent_LIBRARY)
+
+  find_library(Vulkan_glslang-machineindependent_DEBUG_LIBRARY
+    NAMES MachineIndependentd
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-machineindependent_DEBUG_LIBRARY)
+
+  find_library(Vulkan_glslang-genericcodegen_LIBRARY
+    NAMES GenericCodeGen
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-genericcodegen_LIBRARY)
+
+  find_library(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY
+    NAMES GenericCodeGend
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY)
+
+  find_library(Vulkan_glslang_LIBRARY
+    NAMES glslang
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang_LIBRARY)
+
+  find_library(Vulkan_glslang_DEBUG_LIBRARY
+    NAMES glslangd
+    HINTS
+      ${_Vulkan_hint_library_search_paths}
+    )
+  mark_as_advanced(Vulkan_glslang_DEBUG_LIBRARY)
+endif()
+if(shaderc_combined IN_LIST Vulkan_FIND_COMPONENTS)
+  find_library(Vulkan_shaderc_combined_LIBRARY
+    NAMES shaderc_combined
+    HINTS
+    ${_Vulkan_hint_library_search_paths})
+  mark_as_advanced(Vulkan_shaderc_combined_LIBRARY)
+
+  find_library(Vulkan_shaderc_combined_DEBUG_LIBRARY
+    NAMES shaderc_combinedd
+    HINTS
+    ${_Vulkan_hint_library_search_paths})
+  mark_as_advanced(Vulkan_shaderc_combined_DEBUG_LIBRARY)
+endif()
+if(SPIRV-Tools IN_LIST Vulkan_FIND_COMPONENTS)
+  find_library(Vulkan_SPIRV-Tools_LIBRARY
+    NAMES SPIRV-Tools
+    HINTS
+      ${_Vulkan_hint_library_search_paths})
+  mark_as_advanced(Vulkan_SPIRV-Tools_LIBRARY)
+
+  find_library(Vulkan_SPIRV-Tools_DEBUG_LIBRARY
+    NAMES SPIRV-Toolsd
+    HINTS
+      ${_Vulkan_hint_library_search_paths})
+  mark_as_advanced(Vulkan_SPIRV-Tools_DEBUG_LIBRARY)
+endif()
+if(MoltenVK IN_LIST Vulkan_FIND_COMPONENTS)
+  find_library(Vulkan_MoltenVK_LIBRARY
+    NAMES MoltenVK
+    HINTS
+      ${_Vulkan_hint_library_search_paths})
+  mark_as_advanced(Vulkan_MoltenVK_LIBRARY)
+
+  find_path(Vulkan_MoltenVK_INCLUDE_DIR
+    NAMES MoltenVK/mvk_vulkan.h
+    HINTS
+      ${_Vulkan_hint_include_search_paths}
+    )
+  mark_as_advanced(Vulkan_MoltenVK_INCLUDE_DIR)
+endif()
+
+if(Vulkan_GLSLC_EXECUTABLE)
+  set(Vulkan_glslc_FOUND TRUE)
+else()
+  set(Vulkan_glslc_FOUND FALSE)
+endif()
+
+if(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE)
+  set(Vulkan_glslangValidator_FOUND TRUE)
+else()
+  set(Vulkan_glslangValidator_FOUND FALSE)
+endif()
+
+function(_Vulkan_set_library_component_found component)
+  cmake_parse_arguments(PARSE_ARGV 1 _ARG
+    "NO_WARNING"
+    ""
+    "DEPENDENT_COMPONENTS")
+
+  set(all_dependent_component_found TRUE)
+  foreach(dependent_component IN LISTS _ARG_DEPENDENT_COMPONENTS)
+    if(NOT Vulkan_${dependent_component}_FOUND)
+      set(all_dependent_component_found FALSE)
+      break()
+    endif()
+  endforeach()
+
+  if(all_dependent_component_found AND (Vulkan_${component}_LIBRARY OR Vulkan_${component}_DEBUG_LIBRARY))
+    set(Vulkan_${component}_FOUND TRUE PARENT_SCOPE)
+
+    # For Windows Vulkan SDK, third party tools binaries are provided with different MSVC ABI:
+    #   - Release binaries uses a runtime library
+    #   - Debug binaries uses a debug runtime library
+    # This lead to incompatibilities in linking for some configuration types due to CMake-default or project-configured selected MSVC ABI.
+    if(WIN32 AND NOT _ARG_NO_WARNING)
+      if(NOT Vulkan_${component}_LIBRARY)
+        message(WARNING
+"Library ${component} for Release configuration is missing, imported target Vulkan::${component} may not be able to link when targeting this build configuration due to incompatible MSVC ABI.")
+      endif()
+      if(NOT Vulkan_${component}_DEBUG_LIBRARY)
+        message(WARNING
+"Library ${component} for Debug configuration is missing, imported target Vulkan::${component} may not be able to link when targeting this build configuration due to incompatible MSVC ABI. Consider re-installing the Vulkan SDK and request debug libraries to fix this warning.")
+      endif()
+    endif()
+  else()
+    set(Vulkan_${component}_FOUND FALSE PARENT_SCOPE)
+  endif()
+endfunction()
+
+_Vulkan_set_library_component_found(glslang-spirv NO_WARNING)
+_Vulkan_set_library_component_found(glslang-oglcompiler NO_WARNING)
+_Vulkan_set_library_component_found(glslang-osdependent NO_WARNING)
+_Vulkan_set_library_component_found(glslang-machineindependent NO_WARNING)
+_Vulkan_set_library_component_found(glslang-genericcodegen NO_WARNING)
+_Vulkan_set_library_component_found(glslang
+  DEPENDENT_COMPONENTS
+    glslang-spirv
+    glslang-oglcompiler
+    glslang-osdependent
+    glslang-machineindependent
+    glslang-genericcodegen)
+_Vulkan_set_library_component_found(shaderc_combined)
+_Vulkan_set_library_component_found(SPIRV-Tools)
+
+if(Vulkan_MoltenVK_INCLUDE_DIR AND Vulkan_MoltenVK_LIBRARY)
+  set(Vulkan_MoltenVK_FOUND TRUE)
+else()
+  set(Vulkan_MoltenVK_FOUND FALSE)
 endif()
 
 set(Vulkan_LIBRARIES ${Vulkan_LIBRARY})
@@ -155,6 +466,25 @@
   endif()
 endif()
 
+if(Vulkan_MoltenVK_FOUND)
+  set(Vulkan_MoltenVK_VERSION "")
+  if(Vulkan_MoltenVK_INCLUDE_DIR)
+    set(VK_MVK_MOLTENVK_H ${Vulkan_MoltenVK_INCLUDE_DIR}/MoltenVK/vk_mvk_moltenvk.h)
+    if(EXISTS ${VK_MVK_MOLTENVK_H})
+      file(STRINGS  ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_MAJOR REGEX "^#define MVK_VERSION_MAJOR ")
+      string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_MAJOR "${_Vulkan_MoltenVK_VERSION_MAJOR}")
+      file(STRINGS  ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_MINOR REGEX "^#define MVK_VERSION_MINOR ")
+      string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_MINOR "${_Vulkan_MoltenVK_VERSION_MINOR}")
+      file(STRINGS  ${VK_MVK_MOLTENVK_H} _Vulkan_MoltenVK_VERSION_PATCH REGEX "^#define MVK_VERSION_PATCH ")
+      string(REGEX MATCHALL "[0-9]+" _Vulkan_MoltenVK_VERSION_PATCH "${_Vulkan_MoltenVK_VERSION_PATCH}")
+      set(Vulkan_MoltenVK_VERSION "${_Vulkan_MoltenVK_VERSION_MAJOR}.${_Vulkan_MoltenVK_VERSION_MINOR}.${_Vulkan_MoltenVK_VERSION_PATCH}")
+      unset(_Vulkan_MoltenVK_VERSION_MAJOR)
+      unset(_Vulkan_MoltenVK_VERSION_MINOR)
+      unset(_Vulkan_MoltenVK_VERSION_PATCH)
+    endif()
+  endif()
+endif()
+
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
 find_package_handle_standard_args(Vulkan
   REQUIRED_VARS
@@ -162,11 +492,9 @@
     Vulkan_INCLUDE_DIR
   VERSION_VAR
     Vulkan_VERSION
+  HANDLE_COMPONENTS
 )
 
-mark_as_advanced(Vulkan_INCLUDE_DIR Vulkan_LIBRARY Vulkan_GLSLC_EXECUTABLE
-                 Vulkan_GLSLANG_VALIDATOR_EXECUTABLE)
-
 if(Vulkan_FOUND AND NOT TARGET Vulkan::Vulkan)
   add_library(Vulkan::Vulkan UNKNOWN IMPORTED)
   set_target_properties(Vulkan::Vulkan PROPERTIES
@@ -189,3 +517,228 @@
   add_executable(Vulkan::glslangValidator IMPORTED)
   set_property(TARGET Vulkan::glslangValidator PROPERTY IMPORTED_LOCATION "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}")
 endif()
+
+if(Vulkan_FOUND)
+  if((Vulkan_glslang-spirv_LIBRARY OR Vulkan_glslang-spirv_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-spirv)
+    add_library(Vulkan::glslang-spirv STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang-spirv
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang-spirv_LIBRARY)
+      set_property(TARGET Vulkan::glslang-spirv APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang-spirv
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-spirv_LIBRARY}")
+    endif()
+    if(Vulkan_glslang-spirv_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang-spirv APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang-spirv
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-spirv_DEBUG_LIBRARY}")
+    endif()
+  endif()
+
+  if((Vulkan_glslang-oglcompiler_LIBRARY OR Vulkan_glslang-oglcompiler_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-oglcompiler)
+    add_library(Vulkan::glslang-oglcompiler STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang-oglcompiler
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang-oglcompiler_LIBRARY)
+      set_property(TARGET Vulkan::glslang-oglcompiler APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang-oglcompiler
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-oglcompiler_LIBRARY}")
+    endif()
+    if(Vulkan_glslang-oglcompiler_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang-oglcompiler APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang-oglcompiler
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-oglcompiler_DEBUG_LIBRARY}")
+    endif()
+  endif()
+
+  if((Vulkan_glslang-osdependent_LIBRARY OR Vulkan_glslang-osdependent_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-osdependent)
+    add_library(Vulkan::glslang-osdependent STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang-osdependent
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang-osdependent_LIBRARY)
+      set_property(TARGET Vulkan::glslang-osdependent APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang-osdependent
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-osdependent_LIBRARY}")
+    endif()
+    if(Vulkan_glslang-osdependent_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang-osdependent APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang-osdependent
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-osdependent_DEBUG_LIBRARY}")
+    endif()
+  endif()
+
+  if((Vulkan_glslang-machineindependent_LIBRARY OR Vulkan_glslang-machineindependent_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-machineindependent)
+    add_library(Vulkan::glslang-machineindependent STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang-machineindependent
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang-machineindependent_LIBRARY)
+      set_property(TARGET Vulkan::glslang-machineindependent APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang-machineindependent
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-machineindependent_LIBRARY}")
+    endif()
+    if(Vulkan_glslang-machineindependent_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang-machineindependent APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang-machineindependent
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-machineindependent_DEBUG_LIBRARY}")
+    endif()
+  endif()
+
+  if((Vulkan_glslang-genericcodegen_LIBRARY OR Vulkan_glslang-genericcodegen_DEBUG_LIBRARY) AND NOT TARGET Vulkan::glslang-genericcodegen)
+    add_library(Vulkan::glslang-genericcodegen STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang-genericcodegen
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang-genericcodegen_LIBRARY)
+      set_property(TARGET Vulkan::glslang-genericcodegen APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang-genericcodegen
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang-genericcodegen_LIBRARY}")
+    endif()
+    if(Vulkan_glslang-genericcodegen_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang-genericcodegen APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang-genericcodegen
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang-genericcodegen_DEBUG_LIBRARY}")
+    endif()
+  endif()
+
+  if((Vulkan_glslang_LIBRARY OR Vulkan_glslang_DEBUG_LIBRARY)
+      AND TARGET Vulkan::glslang-spirv
+      AND TARGET Vulkan::glslang-oglcompiler
+      AND TARGET Vulkan::glslang-osdependent
+      AND TARGET Vulkan::glslang-machineindependent
+      AND TARGET Vulkan::glslang-genericcodegen
+      AND NOT TARGET Vulkan::glslang)
+    add_library(Vulkan::glslang STATIC IMPORTED)
+    set_property(TARGET Vulkan::glslang
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_glslang_LIBRARY)
+      set_property(TARGET Vulkan::glslang APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::glslang
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_glslang_LIBRARY}")
+    endif()
+    if(Vulkan_glslang_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::glslang APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::glslang
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_glslang_DEBUG_LIBRARY}")
+    endif()
+    target_link_libraries(Vulkan::glslang
+      INTERFACE
+        Vulkan::glslang-spirv
+        Vulkan::glslang-oglcompiler
+        Vulkan::glslang-osdependent
+        Vulkan::glslang-machineindependent
+        Vulkan::glslang-genericcodegen
+    )
+  endif()
+
+  if((Vulkan_shaderc_combined_LIBRARY OR Vulkan_shaderc_combined_DEBUG_LIBRARY) AND NOT TARGET Vulkan::shaderc_combined)
+    add_library(Vulkan::shaderc_combined STATIC IMPORTED)
+    set_property(TARGET Vulkan::shaderc_combined
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_shaderc_combined_LIBRARY)
+      set_property(TARGET Vulkan::shaderc_combined APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::shaderc_combined
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_shaderc_combined_LIBRARY}")
+    endif()
+    if(Vulkan_shaderc_combined_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::shaderc_combined APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::shaderc_combined
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_shaderc_combined_DEBUG_LIBRARY}")
+    endif()
+
+    if(UNIX)
+      find_package(Threads REQUIRED)
+      target_link_libraries(Vulkan::shaderc_combined
+        INTERFACE
+          Threads::Threads)
+    endif()
+  endif()
+
+  if((Vulkan_SPIRV-Tools_LIBRARY OR Vulkan_SPIRV-Tools_DEBUG_LIBRARY) AND NOT TARGET Vulkan::SPIRV-Tools)
+    add_library(Vulkan::SPIRV-Tools STATIC IMPORTED)
+    set_property(TARGET Vulkan::SPIRV-Tools
+      PROPERTY
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+    if(Vulkan_SPIRV-Tools_LIBRARY)
+      set_property(TARGET Vulkan::SPIRV-Tools APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Release)
+      set_property(TARGET Vulkan::SPIRV-Tools
+        PROPERTY
+          IMPORTED_LOCATION_RELEASE "${Vulkan_SPIRV-Tools_LIBRARY}")
+    endif()
+    if(Vulkan_SPIRV-Tools_DEBUG_LIBRARY)
+      set_property(TARGET Vulkan::SPIRV-Tools APPEND
+        PROPERTY
+          IMPORTED_CONFIGURATIONS Debug)
+      set_property(TARGET Vulkan::SPIRV-Tools
+        PROPERTY
+          IMPORTED_LOCATION_DEBUG "${Vulkan_SPIRV-Tools_DEBUG_LIBRARY}")
+    endif()
+  endif()
+endif()
+
+if(Vulkan_MoltenVK_FOUND)
+  if(Vulkan_MoltenVK_LIBRARY AND NOT TARGET Vulkan::MoltenVK)
+    add_library(Vulkan::MoltenVK SHARED IMPORTED)
+    set_target_properties(Vulkan::MoltenVK
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_MoltenVK_INCLUDE_DIR}"
+        IMPORTED_LOCATION "${Vulkan_MoltenVK_LIBRARY}"
+    )
+  endif()
+endif()
+
+unset(_Vulkan_library_name)
+unset(_Vulkan_hint_include_search_paths)
+unset(_Vulkan_hint_executable_search_paths)
+unset(_Vulkan_hint_library_search_paths)
+
+cmake_policy(POP)
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
index 4af842a..f50116f 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -77,8 +77,13 @@
 unset(_ZLIB_x86)
 list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
 
-set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic zlibstat zlibvc)
-set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibstatd zlibvcd)
+if(ZLIB_USE_STATIC_LIBS)
+  set(ZLIB_NAMES zlibstatic zlibstat zlib z)
+  set(ZLIB_NAMES_DEBUG zlibstaticd zlibstatd zlibd zd)
+else()
+  set(ZLIB_NAMES z zlib zdll zlib1 zlibstatic zlibwapi zlibvc zlibstat)
+  set(ZLIB_NAMES_DEBUG zd zlibd zdlld zlibd1 zlib1d zlibstaticd zlibwapid zlibvcd zlibstatd)
+endif()
 
 # Try each search configuration.
 foreach(search ${_ZLIB_SEARCHES})
@@ -87,9 +92,15 @@
 
 # Allow ZLIB_LIBRARY to be set manually, as the location of the zlib library
 if(NOT ZLIB_LIBRARY)
+  set(_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES})
+  set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+  # Prefix/suffix of the win32/Makefile.gcc build
+  if(WIN32)
+    list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib")
+    list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a")
+  endif()
   # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
   if(ZLIB_USE_STATIC_LIBS)
-    set(_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
     if(WIN32)
       set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
     else()
@@ -103,9 +114,8 @@
   endforeach()
 
   # Restore the original find library ordering
-  if(ZLIB_USE_STATIC_LIBS)
-    set(CMAKE_FIND_LIBRARY_SUFFIXES ${_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
-  endif()
+  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_zlib_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+  set(CMAKE_FIND_LIBRARY_PREFIXES ${_zlib_ORIG_CMAKE_FIND_LIBRARY_PREFIXES})
 
   include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
   select_library_configurations(ZLIB)
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
index ce0bc10..fb35ff0 100644
--- a/Modules/FortranCInterface/CMakeLists.txt
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -112,6 +112,9 @@
   CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
   target_compile_options(FortranCInterface PRIVATE "-fno-lto")
   target_compile_options(myfort PRIVATE "-flto=auto" "-ffat-lto-objects")
+endif()
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
+  CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
   target_compile_options(symbols PRIVATE "-flto=auto" "-ffat-lto-objects")
 endif()
 
diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake
index fb363f4..056d025 100644
--- a/Modules/Internal/CPack/CPackNuGet.cmake
+++ b/Modules/Internal/CPack/CPackNuGet.cmake
@@ -332,7 +332,9 @@
 function(_cpack_nuget_make_files_tag)
     set(_files)
     foreach(_comp IN LISTS ARGN)
-        string(APPEND _files "        <file src=\"${_comp}/**\" target=\".\" />\n")
+        cmake_path(APPEND _comp "**")
+        cmake_path(NATIVE_PATH _comp _comp)
+        string(APPEND _files "        <file src=\"${_comp}\" target=\".\" />\n")
     endforeach()
     set(_CPACK_NUGET_FILES_TAG "<files>\n${_files}    </files>" PARENT_SCOPE)
 endfunction()
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 82c4383..3941311 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -191,7 +191,7 @@
       set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}")
       __windows_compiler_msvc(${lang})
       set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX")
-      set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-imsvc ")
+      set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-imsvc")
     endmacro()
   else()
     cmake_policy(GET CMP0091 __WINDOWS_CLANG_CMP0091)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 66590af..17ef046 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 23)
-set(CMake_VERSION_PATCH 20220517)
+set(CMake_VERSION_PATCH 20220525)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 9ca7a69..9dd8fe3 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -468,7 +468,7 @@
   const std::string suffix = "/data";
 
   if (this->componentPackageMethod == this->ONE_PACKAGE) {
-    return std::string(prefix + this->GetRootPackageName() + suffix);
+    return cmStrCat(prefix, this->GetRootPackageName(), suffix);
   }
 
   return prefix +
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index f25d2d2..46fc57f 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -116,13 +116,12 @@
   cmCPackeIFWUpdatesPatcher(cmCPackIFWRepository* r, cmXMLWriter& x)
     : repository(r)
     , xout(x)
-    , patched(false)
   {
   }
 
   cmCPackIFWRepository* repository;
   cmXMLWriter& xout;
-  bool patched;
+  bool patched = false;
 
 protected:
   void StartElement(const std::string& name, const char** atts) override
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 8e5e637..a3b9434 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -707,7 +707,7 @@
                           &cmCPackDebGenerator::createDbgsymDDeb) &&
       retval;
   }
-  return int(retval);
+  return static_cast<int>(retval);
 }
 
 bool cmCPackDebGenerator::createDeb()
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 0fe4ff4..81a866a 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -88,7 +88,6 @@
 public:
   InfoParser(cmCTestBZR* bzr, const char* prefix)
     : BZR(bzr)
-    , CheckOutFound(false)
   {
     this->SetLog(&bzr->Log, prefix);
     this->RegexCheckOut.compile("checkout of branch: *([^\t\r\n]+)$");
@@ -97,7 +96,7 @@
 
 private:
   cmCTestBZR* BZR;
-  bool CheckOutFound;
+  bool CheckOutFound = false;
   cmsys::RegularExpression RegexCheckOut;
   cmsys::RegularExpression RegexParent;
   bool ProcessLine() override
@@ -255,26 +254,26 @@
       this->BZR->DoRevision(this->Rev, this->Changes);
     } else if (!this->CData.empty() &&
                (name == "file" || name == "directory")) {
-      this->CurChange.Path.assign(&this->CData[0], this->CData.size());
+      this->CurChange.Path.assign(this->CData.data(), this->CData.size());
       cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
       this->Changes.push_back(this->CurChange);
     } else if (!this->CData.empty() && name == "symlink") {
       // symlinks have an arobase at the end in the log
-      this->CurChange.Path.assign(&this->CData[0], this->CData.size() - 1);
+      this->CurChange.Path.assign(this->CData.data(), this->CData.size() - 1);
       cmSystemTools::ConvertToUnixSlashes(this->CurChange.Path);
       this->Changes.push_back(this->CurChange);
     } else if (!this->CData.empty() && name == "committer") {
-      this->Rev.Author.assign(&this->CData[0], this->CData.size());
+      this->Rev.Author.assign(this->CData.data(), this->CData.size());
       if (this->EmailRegex.find(this->Rev.Author)) {
         this->Rev.Author = this->EmailRegex.match(1);
         this->Rev.EMail = this->EmailRegex.match(2);
       }
     } else if (!this->CData.empty() && name == "timestamp") {
-      this->Rev.Date.assign(&this->CData[0], this->CData.size());
+      this->Rev.Date.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "message") {
-      this->Rev.Log.assign(&this->CData[0], this->CData.size());
+      this->Rev.Log.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "revno") {
-      this->Rev.Rev.assign(&this->CData[0], this->CData.size());
+      this->Rev.Rev.assign(this->CData.data(), this->CData.size());
     }
     this->CData.clear();
   }
@@ -389,7 +388,7 @@
   // For some reason bzr uses stderr to display the update status.
   OutputLogger out(this->Log, "pull-out> ");
   UpdateParser err(this, "pull-err> ");
-  return this->RunUpdateCommand(&bzr_update[0], &out, &err);
+  return this->RunUpdateCommand(bzr_update.data(), &out, &err);
 }
 
 bool cmCTestBZR::LoadRevisions()
diff --git a/Source/CTest/cmCTestBinPacker.cxx b/Source/CTest/cmCTestBinPacker.cxx
index e21b14d..6eb45fa 100644
--- a/Source/CTest/cmCTestBinPacker.cxx
+++ b/Source/CTest/cmCTestBinPacker.cxx
@@ -34,7 +34,7 @@
  * more combinations can be tried.
  */
 template <typename AllocationStrategy>
-static bool AllocateCTestResources(
+bool AllocateCTestResources(
   const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
   const std::vector<std::string>& resourcesSorted, std::size_t currentIndex,
   std::vector<cmCTestBinPackerAllocation*>& allocations)
@@ -82,7 +82,7 @@
 }
 
 template <typename AllocationStrategy>
-static bool AllocateCTestResources(
+bool AllocateCTestResources(
   const std::map<std::string, cmCTestResourceAllocator::Resource>& resources,
   std::vector<cmCTestBinPackerAllocation>& allocations)
 {
@@ -108,7 +108,7 @@
 
   // Do the actual allocation
   return AllocateCTestResources<AllocationStrategy>(
-    resources, resourcesSorted, std::size_t(0), allocationsPtr);
+    resources, resourcesSorted, static_cast<std::size_t>(0), allocationsPtr);
 }
 
 class RoundRobinAllocationStrategy
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 1209e06..87ab762 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -101,7 +101,7 @@
 
   UpdateParser out(this, "up-out> ");
   UpdateParser err(this, "up-err> ");
-  return this->RunUpdateCommand(&cvs_update[0], &out, &err);
+  return this->RunUpdateCommand(cvs_update.data(), &out, &err);
 }
 
 class cmCTestCVS::LogParser : public cmCTestVC::LineParser
@@ -111,7 +111,6 @@
   LogParser(cmCTestCVS* cvs, const char* prefix, std::vector<Revision>& revs)
     : CVS(cvs)
     , Revisions(revs)
-    , Section(SectionHeader)
   {
     this->SetLog(&cvs->Log, prefix);
     this->RegexRevision.compile("^revision +([^ ]*) *$");
@@ -131,7 +130,7 @@
     SectionRevisions,
     SectionEnd
   };
-  SectionType Section;
+  SectionType Section = SectionHeader;
   Revision Rev;
 
   bool ProcessLine() override
@@ -259,7 +258,7 @@
     revisions.resize(2, this->Unknown);
 
     // Write the entry for this file with these revisions.
-    File f(fi.second, &revisions[0], &revisions[1]);
+    File f(fi.second, revisions.data(), revisions.data() + 1);
     this->WriteXMLEntry(xml, path, fi.first, full, f);
   }
   xml.EndElement(); // Directory
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index aef58c5..f7c6a9c 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -2210,7 +2210,7 @@
 {
   auto i = this->LabelIdMap.find(label);
   if (i == this->LabelIdMap.end()) {
-    int n = int(this->Labels.size());
+    int n = static_cast<int>(this->Labels.size());
     this->Labels.push_back(label);
     LabelIdMapType::value_type entry(label, n);
     i = this->LabelIdMap.insert(entry).first;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 56f805c..b2fb069 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -176,7 +176,7 @@
   // Fetch upstream refs.
   OutputLogger fetch_out(this->Log, "fetch-out> ");
   OutputLogger fetch_err(this->Log, "fetch-err> ");
-  if (!this->RunUpdateCommand(&git_fetch[0], &fetch_out, &fetch_err)) {
+  if (!this->RunUpdateCommand(git_fetch.data(), &fetch_out, &fetch_err)) {
     return false;
   }
 
@@ -225,7 +225,7 @@
 
   OutputLogger custom_out(this->Log, "custom-out> ");
   OutputLogger custom_err(this->Log, "custom-err> ");
-  return this->RunUpdateCommand(&git_custom[0], &custom_out, &custom_err);
+  return this->RunUpdateCommand(git_custom.data(), &custom_out, &custom_err);
 }
 
 bool cmCTestGIT::UpdateInternal()
@@ -332,7 +332,6 @@
   DiffParser(cmCTestGIT* git, const char* prefix)
     : LineParser('\0', false)
     , GIT(git)
-    , DiffField(DiffFieldNone)
   {
     this->SetLog(&git->Log, prefix);
   }
@@ -349,7 +348,7 @@
     DiffFieldSrc,
     DiffFieldDst
   };
-  DiffFieldType DiffField;
+  DiffFieldType DiffField = DiffFieldNone;
   Change CurChange;
 
   void DiffReset()
@@ -454,7 +453,6 @@
 public:
   CommitParser(cmCTestGIT* git, const char* prefix)
     : DiffParser(git, prefix)
-    , Section(SectionHeader)
   {
     this->Separator = SectionSep[this->Section];
   }
@@ -469,7 +467,7 @@
     SectionCount
   };
   static char const SectionSep[SectionCount];
-  SectionType Section;
+  SectionType Section = SectionHeader;
   Revision Rev;
 
   struct Person
@@ -537,7 +535,8 @@
 
   void NextSection()
   {
-    this->Section = SectionType((this->Section + 1) % SectionCount);
+    this->Section =
+      static_cast<SectionType>((this->Section + 1) % SectionCount);
     this->Separator = SectionSep[this->Section];
     if (this->Section == SectionHeader) {
       this->GIT->DoRevision(this->Rev, this->Changes);
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 5f4581e..97b01ba 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -157,7 +157,7 @@
 
   OutputLogger out(this->Log, "update-out> ");
   OutputLogger err(this->Log, "update-err> ");
-  return this->RunUpdateCommand(&hg_update[0], &out, &err);
+  return this->RunUpdateCommand(hg_update.data(), &out, &err);
 }
 
 class cmCTestHG::LogParser
@@ -213,13 +213,13 @@
     if (name == "logentry") {
       this->HG->DoRevision(this->Rev, this->Changes);
     } else if (!this->CData.empty() && name == "author") {
-      this->Rev.Author.assign(&this->CData[0], this->CData.size());
+      this->Rev.Author.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "email") {
-      this->Rev.EMail.assign(&this->CData[0], this->CData.size());
+      this->Rev.EMail.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "date") {
-      this->Rev.Date.assign(&this->CData[0], this->CData.size());
+      this->Rev.Date.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "msg") {
-      this->Rev.Log.assign(&this->CData[0], this->CData.size());
+      this->Rev.Log.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "files") {
       std::vector<std::string> paths = this->SplitCData();
       for (std::string const& path : paths) {
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 2d8276a..788845b 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -1207,7 +1207,8 @@
 
       if (failure >= 0) {
         ostr << "<b>" << this->ResultStrings[failure] << "</b> ";
-        if (results.empty() || unsigned(failure) > results.size() - 1) {
+        if (results.empty() ||
+            static_cast<unsigned>(failure) > results.size() - 1) {
           results.push_back(1);
         } else {
           results[failure]++;
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 50c9c16..0e67c41 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -118,7 +118,6 @@
 public:
   DiffParser(cmCTestP4* p4, const char* prefix)
     : P4(p4)
-    , AlreadyNotified(false)
   {
     this->SetLog(&this->P4->Log, prefix);
     this->RegexDiff.compile("^==== (.*)#[0-9]+ - (.*)");
@@ -126,7 +125,7 @@
 
 private:
   cmCTestP4* P4;
-  bool AlreadyNotified;
+  bool AlreadyNotified = false;
   std::string CurrentPath;
   cmsys::RegularExpression RegexDiff;
 
@@ -161,7 +160,7 @@
 
     UserParser out(this, "users-out> ");
     OutputLogger err(this->Log, "users-err> ");
-    this->RunChild(&p4_users[0], &out, &err);
+    this->RunChild(p4_users.data(), &out, &err);
 
     // The user should now be added to the map. Search again.
     it = this->Users.find(username);
@@ -193,7 +192,6 @@
   DescribeParser(cmCTestP4* p4, const char* prefix)
     : LineParser('\n', false)
     , P4(p4)
-    , Section(SectionHeader)
   {
     this->SetLog(&this->P4->Log, prefix);
     this->RegexHeader.compile("^Change ([0-9]+) by (.+)@(.+) on (.*)$");
@@ -216,7 +214,7 @@
     SectionDiff,
     SectionCount
   };
-  SectionType Section;
+  SectionType Section = SectionHeader;
   Revision Rev;
 
   bool ProcessLine() override
@@ -250,7 +248,8 @@
       this->Rev = Revision();
     }
 
-    this->Section = SectionType((this->Section + 1) % SectionCount);
+    this->Section =
+      static_cast<SectionType>((this->Section + 1) % SectionCount);
   }
 
   void DoHeaderLine()
@@ -354,7 +353,7 @@
   IdentifyParser out(this, "p4_changes-out> ", rev);
   OutputLogger err(this->Log, "p4_changes-err> ");
 
-  bool result = this->RunChild(&p4_identify[0], &out, &err);
+  bool result = this->RunChild(p4_identify.data(), &out, &err);
 
   // If there was a problem contacting the server return "<unknown>"
   if (!result) {
@@ -418,7 +417,7 @@
   OutputLogger err(this->Log, "p4_changes-err> ");
 
   this->ChangeLists.clear();
-  this->RunChild(&p4_changes[0], &out, &err);
+  this->RunChild(p4_changes.data(), &out, &err);
 
   if (this->ChangeLists.empty()) {
     return true;
@@ -435,7 +434,7 @@
 
     DescribeParser outDescribe(this, "p4_describe-out> ");
     OutputLogger errDescribe(this->Log, "p4_describe-err> ");
-    this->RunChild(&p4_describe[0], &outDescribe, &errDescribe);
+    this->RunChild(p4_describe.data(), &outDescribe, &errDescribe);
   }
   return true;
 }
@@ -455,7 +454,7 @@
 
   DiffParser out(this, "p4_diff-out> ");
   OutputLogger err(this->Log, "p4_diff-err> ");
-  this->RunChild(&p4_diff[0], &out, &err);
+  this->RunChild(p4_diff.data(), &out, &err);
   return true;
 }
 
@@ -473,7 +472,7 @@
   OutputLogger custom_out(this->Log, "p4_customsync-out> ");
   OutputLogger custom_err(this->Log, "p4_customsync-err> ");
 
-  return this->RunUpdateCommand(&p4_custom[0], &custom_out, &custom_err);
+  return this->RunUpdateCommand(p4_custom.data(), &custom_out, &custom_err);
 }
 
 bool cmCTestP4::UpdateImpl()
@@ -523,5 +522,5 @@
   OutputLogger out(this->Log, "p4_sync-out> ");
   OutputLogger err(this->Log, "p4_sync-err> ");
 
-  return this->RunUpdateCommand(&p4_sync[0], &out, &err);
+  return this->RunUpdateCommand(p4_sync.data(), &out, &err);
 }
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 4692dbd..4c98fdf 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -286,9 +286,9 @@
   args.push_back(nullptr);
 
   if (strcmp(parameters[0], "update") == 0) {
-    return this->RunUpdateCommand(&args[0], out, err);
+    return this->RunUpdateCommand(args.data(), out, err);
   }
-  return this->RunChild(&args[0], out, err);
+  return this->RunChild(args.data(), out, err);
 }
 
 class cmCTestSVN::LogParser
@@ -353,16 +353,16 @@
     if (name == "logentry") {
       this->SVN->DoRevisionSVN(this->Rev, this->Changes);
     } else if (!this->CData.empty() && name == "path") {
-      std::string orig_path(&this->CData[0], this->CData.size());
+      std::string orig_path(this->CData.data(), this->CData.size());
       std::string new_path = this->SVNRepo.BuildLocalPath(orig_path);
       this->CurChange.Path.assign(new_path);
       this->Changes.push_back(this->CurChange);
     } else if (!this->CData.empty() && name == "author") {
-      this->Rev.Author.assign(&this->CData[0], this->CData.size());
+      this->Rev.Author.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "date") {
-      this->Rev.Date.assign(&this->CData[0], this->CData.size());
+      this->Rev.Date.assign(this->CData.data(), this->CData.size());
     } else if (!this->CData.empty() && name == "msg") {
-      this->Rev.Log.assign(&this->CData[0], this->CData.size());
+      this->Rev.Log.assign(this->CData.data(), this->CData.size());
     }
     this->CData.clear();
   }
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index fae5e30..da085a6 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -56,7 +56,7 @@
   {
     std::string val;
     if (!this->CurrentValue.empty()) {
-      val.assign(&this->CurrentValue[0], this->CurrentValue.size());
+      val.assign(this->CurrentValue.data(), this->CurrentValue.size());
     }
     return val;
   }
@@ -124,7 +124,7 @@
 {
   // We submit all available parts by default.
   for (cmCTest::Part p = cmCTest::PartStart; p != cmCTest::PartCount;
-       p = cmCTest::Part(p + 1)) {
+       p = static_cast<cmCTest::Part>(p + 1)) {
     this->SubmitPart[p] = true;
   }
   this->HasWarnings = false;
@@ -730,15 +730,15 @@
     return -1;
   }
 
-  if (getenv("HTTP_PROXY")) {
+  if (char const* proxy = getenv("HTTP_PROXY")) {
     this->HTTPProxyType = 1;
-    this->HTTPProxy = getenv("HTTP_PROXY");
+    this->HTTPProxy = proxy;
     if (getenv("HTTP_PROXY_PORT")) {
       this->HTTPProxy += ":";
       this->HTTPProxy += getenv("HTTP_PROXY_PORT");
     }
-    if (getenv("HTTP_PROXY_TYPE")) {
-      std::string type = getenv("HTTP_PROXY_TYPE");
+    if (char const* proxy_type = getenv("HTTP_PROXY_TYPE")) {
+      std::string type = proxy_type;
       // HTTP/SOCKS4/SOCKS5
       if (type == "HTTP") {
         this->HTTPProxyType = 1;
@@ -810,7 +810,7 @@
 
   // Query parts for files to submit.
   for (cmCTest::Part p = cmCTest::PartStart; p != cmCTest::PartCount;
-       p = cmCTest::Part(p + 1)) {
+       p = static_cast<cmCTest::Part>(p + 1)) {
     // Skip parts we are not submitting.
     if (!this->SubmitPart[p]) {
       continue;
@@ -894,9 +894,8 @@
 {
   // Check whether each part is selected.
   for (cmCTest::Part p = cmCTest::PartStart; p != cmCTest::PartCount;
-       p = cmCTest::Part(p + 1)) {
-    this->SubmitPart[p] =
-      (std::set<cmCTest::Part>::const_iterator(parts.find(p)) != parts.end());
+       p = static_cast<cmCTest::Part>(p + 1)) {
+    this->SubmitPart[p] = parts.find(p) != parts.end();
   }
 }
 
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 696a5ea..248533a 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -586,7 +586,8 @@
 {
   std::size_t total = passed.size() + failed.size();
 
-  float percent = float(passed.size()) * 100.0f / float(total);
+  float percent =
+    static_cast<float>(passed.size()) * 100.0f / static_cast<float>(total);
   if (!failed.empty() && percent > 99) {
     percent = 99;
   }
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index d5711c5..609ccba 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -66,7 +66,7 @@
   this->Log << "--- Begin Initial Checkout ---\n";
   OutputLogger out(this->Log, "co-out> ");
   OutputLogger err(this->Log, "co-err> ");
-  bool result = this->RunChild(&vc_co[0], &out, &err, parent.c_str());
+  bool result = this->RunChild(vc_co.data(), &out, &err, parent.c_str());
   this->Log << "--- End Initial Checkout ---\n";
   if (!result) {
     cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 3e254e0..5a8e40f 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -95,9 +95,10 @@
 
   // Add a label to display when cache is empty
   // dummy entry widget (does not respond to input)
-  cmCursesCacheEntryComposite comp("EMPTY CACHE", 30, 30);
-  comp.Entry = cm::make_unique<cmCursesDummyWidget>(1, 1, 1, 1);
-  newEntries.emplace_back(std::move(comp));
+  this->EmptyCacheEntry =
+    cm::make_unique<cmCursesCacheEntryComposite>("EMPTY CACHE", 30, 30);
+  this->EmptyCacheEntry->Entry =
+    cm::make_unique<cmCursesDummyWidget>(1, 1, 1, 1);
 
   if (count > 0) {
     // Create the composites.
@@ -192,10 +193,9 @@
   // if no cache entries there should still be one dummy field
   this->IsEmpty = this->Fields.empty();
   if (this->IsEmpty) {
-    const auto& front = this->Entries.front();
-    this->Fields.push_back(front.Label->Field);
-    this->Fields.push_back(front.IsNewLabel->Field);
-    this->Fields.push_back(front.Entry->Field);
+    this->Fields.push_back(this->EmptyCacheEntry->Label->Field);
+    this->Fields.push_back(this->EmptyCacheEntry->IsNewLabel->Field);
+    this->Fields.push_back(this->EmptyCacheEntry->Entry->Field);
     this->NumberOfVisibleEntries = 1;
   }
   // Has to be null terminated.
@@ -617,7 +617,7 @@
     cmValue existingValue =
       this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey);
     if (existingValue) {
-      std::string oldValue = *existingValue;
+      std::string const& oldValue = *existingValue;
       std::string newValue = entry.Entry->GetValue();
       std::string fixedOldValue;
       std::string fixedNewValue;
@@ -973,7 +973,7 @@
         }
       }
     }
-    if (size_t(findex) >= 3 * this->NumberOfVisibleEntries - 1) {
+    if (static_cast<size_t>(findex) >= 3 * this->NumberOfVisibleEntries - 1) {
       set_current_field(this->Form, this->Fields[2]);
     } else if (new_page(this->Fields[findex + 1])) {
       form_driver(this->Form, REQ_NEXT_PAGE);
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index fb44a45..112b7e8 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -162,6 +162,7 @@
   // Number of pages displayed
   int NumberOfPages = 0;
   bool IsEmpty = false;
+  std::unique_ptr<cmCursesCacheEntryComposite> EmptyCacheEntry;
 
   int InitialWidth;
   std::unique_ptr<cmake> CMakeInstance;
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 994df78..f79d6fc 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -66,7 +66,6 @@
 public:
   QCMakeAdvancedFilter(QObject* o)
     : QSortFilterProxyModel(o)
-    , ShowAdvanced(false)
   {
   }
 
@@ -78,7 +77,7 @@
   bool showAdvanced() const { return this->ShowAdvanced; }
 
 protected:
-  bool ShowAdvanced;
+  bool ShowAdvanced = false;
 
   bool filterAcceptsRow(int row, const QModelIndex& p) const override
   {
@@ -304,7 +303,7 @@
 
       int num = props2.size();
       for (int i = 0; i < num; i++) {
-        QCMakeProperty prop = props2[i];
+        QCMakeProperty const& prop = props2[i];
         QList<QStandardItem*> items;
         items.append(new QStandardItem());
         items.append(new QStandardItem());
@@ -326,7 +325,7 @@
 
       int num = props2.size();
       for (int i = 0; i < num; i++) {
-        QCMakeProperty prop = props2[i];
+        QCMakeProperty const& prop = props2[i];
         QList<QStandardItem*> items;
         items.append(new QStandardItem());
         items.append(new QStandardItem());
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index cfde37c..f29983c 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -92,7 +92,6 @@
   : Stream(os)
   , Archive(archive_write_new())
   , Disk(archive_read_disk_new())
-  , Verbose(false)
   , Format(format)
 {
   // Upstream fixed an issue with their integer parsing in 3.4.0
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 260bd20..b9fa3d7 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -156,7 +156,7 @@
   std::ostream& Stream;
   struct archive* Archive;
   struct archive* Disk;
-  bool Verbose;
+  bool Verbose = false;
   std::string Format;
   std::string Error;
   std::string MTime;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 710b4d7..9638a72 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -322,7 +322,7 @@
   for (const char* c = in.c_str(); *c; ++c) {
     if (*c == '%' && isxdigit(*(c + 1)) && isxdigit(*(c + 2))) {
       char buf[3] = { *(c + 1), *(c + 2), 0 };
-      out.append(1, char(strtoul(buf, nullptr, 16)));
+      out.append(1, static_cast<char>(strtoul(buf, nullptr, 16)));
       c += 2;
     } else {
       out.append(1, *c);
@@ -357,7 +357,7 @@
   this->Impl->Parts[PartDone].SetName("Done");
 
   // Fill the part name-to-id map.
-  for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
+  for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) {
     this->Impl
       ->PartMap[cmSystemTools::LowerCase(this->Impl->Parts[p].GetName())] = p;
   }
@@ -643,7 +643,7 @@
   std::string src_dir = this->GetCTestConfiguration("SourceDirectory");
   std::string bld_dir = this->GetCTestConfiguration("BuildDirectory");
   this->Impl->BuildID = "";
-  for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
+  for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) {
     this->Impl->Parts[p].SubmitFiles.clear();
   }
 
@@ -797,7 +797,7 @@
 bool cmCTest::SetTest(const std::string& ttype, bool report)
 {
   if (cmSystemTools::LowerCase(ttype) == "all") {
-    for (Part p = PartStart; p != PartCount; p = Part(p + 1)) {
+    for (Part p = PartStart; p != PartCount; p = static_cast<Part>(p + 1)) {
       this->Impl->Parts[p].Enable();
     }
     return true;
@@ -935,7 +935,8 @@
   bool notest = true;
   int update_count = 0;
 
-  for (Part p = PartStart; notest && p != PartCount; p = Part(p + 1)) {
+  for (Part p = PartStart; notest && p != PartCount;
+       p = static_cast<Part>(p + 1)) {
     notest = !this->Impl->Parts[p];
   }
   if (this->Impl->Parts[PartUpdate] &&
@@ -1672,16 +1673,16 @@
 #endif
   );
   std::vector<char> file_buffer(len + 1);
-  ifs.read(&file_buffer[0], len);
+  ifs.read(file_buffer.data(), len);
   ifs.close();
 
   std::vector<char> encoded_buffer((len * 3) / 2 + 5);
 
   size_t const rlen = cmsysBase64_Encode(
-    reinterpret_cast<unsigned char*>(&file_buffer[0]), len,
-    reinterpret_cast<unsigned char*>(&encoded_buffer[0]), 1);
+    reinterpret_cast<unsigned char*>(file_buffer.data()), len,
+    reinterpret_cast<unsigned char*>(encoded_buffer.data()), 1);
 
-  return std::string(&encoded_buffer[0], rlen);
+  return std::string(encoded_buffer.data(), rlen);
 }
 
 bool cmCTest::SubmitExtraFiles(std::vector<std::string> const& files)
@@ -2019,7 +2020,8 @@
     i++;
     long outputSize;
     if (cmStrToLong(args[i], &outputSize)) {
-      this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize));
+      this->Impl->TestHandler.SetTestOutputSizePassed(
+        static_cast<int>(outputSize));
     } else {
       cmCTestLog(this, WARNING,
                  "Invalid value for '--test-output-size-passed': " << args[i]
@@ -2030,7 +2032,8 @@
     i++;
     long outputSize;
     if (cmStrToLong(args[i], &outputSize)) {
-      this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize));
+      this->Impl->TestHandler.SetTestOutputSizeFailed(
+        static_cast<int>(outputSize));
     } else {
       cmCTestLog(this, WARNING,
                  "Invalid value for '--test-output-size-failed': " << args[i]
@@ -2801,7 +2804,7 @@
                                        const std::vector<std::string>& args)
 {
   bool success = true;
-  std::string arg = args[i];
+  std::string const& arg = args[i];
   if (this->CheckArgument(arg, "-T"_s, "--test-action") &&
       (i < args.size() - 1)) {
     this->Impl->ProduceXML = true;
@@ -2833,7 +2836,7 @@
                                       const std::vector<std::string>& args)
 {
   bool success = true;
-  std::string arg = args[i];
+  std::string const& arg = args[i];
   if (this->CheckArgument(arg, "-M"_s, "--test-model") &&
       (i < args.size() - 1)) {
     i++;
@@ -3729,7 +3732,7 @@
   strm.avail_in = static_cast<uInt>(str.size());
   strm.next_in = in;
   strm.avail_out = outSize;
-  strm.next_out = &out[0];
+  strm.next_out = out.data();
   ret = deflate(&strm, Z_FINISH);
 
   if (ret != Z_STREAM_END) {
@@ -3743,10 +3746,10 @@
   // Now base64 encode the resulting binary string
   std::vector<unsigned char> base64EncodedBuffer((outSize * 3) / 2);
 
-  size_t rlen =
-    cmsysBase64_Encode(&out[0], strm.total_out, &base64EncodedBuffer[0], 1);
+  size_t rlen = cmsysBase64_Encode(out.data(), strm.total_out,
+                                   base64EncodedBuffer.data(), 1);
 
-  str.assign(reinterpret_cast<char*>(&base64EncodedBuffer[0]), rlen);
+  str.assign(reinterpret_cast<char*>(base64EncodedBuffer.data()), rlen);
 
   return true;
 }
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 8e479c5..141c4eb 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -95,7 +95,8 @@
 
 std::string bool2string(bool const value)
 {
-  return std::string(std::size_t(1), static_cast<char>('0' + int(value)));
+  return std::string(static_cast<std::size_t>(1),
+                     static_cast<char>('0' + static_cast<int>(value)));
 }
 
 bool looksLikeSpecialVariable(const std::string& var,
@@ -141,15 +142,17 @@
     {
       this->current = std::next(this->current);
       this->next =
-        std::next(this->current, difference_type(this->current != args.end()));
+        std::next(this->current,
+                  static_cast<difference_type>(this->current != args.end()));
       return *this;
     }
 
   private:
     CurrentAndNextIter(base_t& args)
       : current(args.begin())
-      , next(std::next(this->current,
-                       difference_type(this->current != args.end())))
+      , next(
+          std::next(this->current,
+                    static_cast<difference_type>(this->current != args.end())))
     {
     }
   };
@@ -167,19 +170,21 @@
     {
       this->current = std::next(this->current);
       this->next =
-        std::next(this->current, difference_type(this->current != args.end()));
-      this->nextnext =
-        std::next(this->next, difference_type(this->next != args.end()));
+        std::next(this->current,
+                  static_cast<difference_type>(this->current != args.end()));
+      this->nextnext = std::next(
+        this->next, static_cast<difference_type>(this->next != args.end()));
       return *this;
     }
 
   private:
     CurrentAndTwoMoreIter(base_t& args)
       : current(args.begin())
-      , next(std::next(this->current,
-                       difference_type(this->current != args.end())))
-      , nextnext(
-          std::next(this->next, difference_type(this->next != args.end())))
+      , next(
+          std::next(this->current,
+                    static_cast<difference_type>(this->current != args.end())))
+      , nextnext(std::next(
+          this->next, static_cast<difference_type>(this->next != args.end())))
     {
     }
   };
@@ -526,9 +531,6 @@
 bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
                                         MessageType&)
 {
-  const auto policy64IsOld = this->Policy64Status == cmPolicies::OLD ||
-    this->Policy64Status == cmPolicies::WARN;
-
   for (auto args = newArgs.make2ArgsIterator(); args.current != newArgs.end();
        args.advance(newArgs)) {
 
@@ -580,7 +582,8 @@
     // does a command exist
     else if (this->IsKeyword(keyCOMMAND, *args.current)) {
       newArgs.ReduceOneArg(
-        bool(this->Makefile.GetState()->GetCommand(args.next->GetValue())),
+        static_cast<bool>(
+          this->Makefile.GetState()->GetCommand(args.next->GetValue())),
         args);
     }
     // does a policy exist
@@ -591,8 +594,9 @@
     }
     // does a target exist
     else if (this->IsKeyword(keyTARGET, *args.current)) {
-      newArgs.ReduceOneArg(
-        bool(this->Makefile.FindTargetToUse(args.next->GetValue())), args);
+      newArgs.ReduceOneArg(static_cast<bool>(this->Makefile.FindTargetToUse(
+                             args.next->GetValue())),
+                           args);
     }
     // is a variable defined
     else if (this->IsKeyword(keyDEFINED, *args.current)) {
@@ -607,7 +611,8 @@
 
       else if (looksLikeSpecialVariable(var, "CACHE"_s, varNameLen)) {
         const auto cache = args.next->GetValue().substr(6, varNameLen - 7);
-        result = bool(this->Makefile.GetState()->GetCacheEntryValue(cache));
+        result = static_cast<bool>(
+          this->Makefile.GetState()->GetCacheEntryValue(cache));
       }
 
       else {
@@ -617,11 +622,13 @@
     }
     // does a test exist
     else if (this->IsKeyword(keyTEST, *args.current)) {
-      if (policy64IsOld) {
+      if (this->Policy64Status == cmPolicies::OLD ||
+          this->Policy64Status == cmPolicies::WARN) {
         continue;
       }
-      newArgs.ReduceOneArg(bool(this->Makefile.GetTest(args.next->GetValue())),
-                           args);
+      newArgs.ReduceOneArg(
+        static_cast<bool>(this->Makefile.GetTest(args.next->GetValue())),
+        args);
     }
   }
   return true;
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 4909948..1e84a0b 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -32,11 +32,7 @@
 {
 public:
   LanguageStandardState(std::string&& lang)
-    : IsEnabled(false)
-    , DidStandard(false)
-    , DidStandardRequired(false)
-    , DidExtensions(false)
-    , StandardFlag(lang + "_STANDARD")
+    : StandardFlag(lang + "_STANDARD")
     , RequiredFlag(lang + "_STANDARD_REQUIRED")
     , ExtensionFlag(lang + "_EXTENSIONS")
   {
@@ -154,10 +150,10 @@
   }
 
 private:
-  bool IsEnabled;
-  bool DidStandard;
-  bool DidStandardRequired;
-  bool DidExtensions;
+  bool IsEnabled = false;
+  bool DidStandard = false;
+  bool DidStandardRequired = false;
+  bool DidExtensions = false;
 
   std::string StandardFlag;
   std::string RequiredFlag;
@@ -872,7 +868,10 @@
   }
 
   // Forward a set of variables to the inner project cache.
-  if (this->SrcFileSignature) {
+  if ((this->SrcFileSignature ||
+       this->Makefile->GetPolicyStatus(cmPolicies::CMP0137) ==
+         cmPolicies::NEW) &&
+      !this->Makefile->IsOn("CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES")) {
     std::set<std::string> vars;
     vars.insert(&c_properties[lang_property_start],
                 &c_properties[lang_property_start + lang_property_size]);
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index b331862..ff9ab0f 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -83,15 +83,15 @@
 bool cmCryptoHash::IntFromHexDigit(char input, char& output)
 {
   if (input >= '0' && input <= '9') {
-    output = char(input - '0');
+    output = static_cast<char>(input - '0');
     return true;
   }
   if (input >= 'a' && input <= 'f') {
-    output = char(input - 'a' + 0xA);
+    output = static_cast<char>(input - 'a' + 0xA);
     return true;
   }
   if (input >= 'A' && input <= 'F') {
-    output = char(input - 'A' + 0xA);
+    output = static_cast<char>(input - 'A' + 0xA);
     return true;
   }
   return false;
@@ -182,7 +182,7 @@
 std::vector<unsigned char> cmCryptoHash::Finalize()
 {
   std::vector<unsigned char> hash(rhash_get_digest_size(this->Id), 0);
-  rhash_final(this->CTX, &hash[0]);
+  rhash_final(this->CTX, hash.data());
   return hash;
 }
 
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index d5e54ae..ac93c90 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -478,7 +478,7 @@
   // when the interface described in the module does not.
 
   std::string mod = args[2];
-  std::string stamp = args[3];
+  std::string const& stamp = args[3];
   std::string compilerId;
   if (args.size() >= 5) {
     compilerId = args[4];
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 66f1733..8aea753 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -83,7 +83,6 @@
     : External(external)
     , Stream(std::move(fin))
     , ByteOrder(order)
-    , ELFType(cmELF::FileTypeInvalid)
   {
 // In most cases the processor-specific byte order will match that
 // of the target execution environment.  If we choose wrong here
@@ -150,7 +149,7 @@
   ByteOrderType ByteOrder;
 
   // The ELF file type.
-  cmELF::FileType ELFType;
+  cmELF::FileType ELFType = cmELF::FileTypeInvalid;
 
   // The ELF architecture.
   std::uint16_t Machine;
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index d9d5a4b..ba4b326 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -737,7 +737,7 @@
     // exclude source directory from output search path
     // - only if not named the same as an output directory
     if (!cmSystemTools::FileIsDirectory(
-          std::string(this->HomeOutputDirectory + "/" + p))) {
+          cmStrCat(this->HomeOutputDirectory, '/', p))) {
       excludeFromOut += p + "/|";
     }
   }
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index c1df992..7f8374d 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -417,7 +417,7 @@
     "toolchains", //
     "__test"      //
   };
-  return objectKindNames[size_t(kind)];
+  return objectKindNames[static_cast<size_t>(kind)];
 }
 
 std::string cmFileAPI::ObjectName(Object const& o)
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index e4728ac..26006d8 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -285,7 +285,7 @@
   }
 
   // Get the variable in which to store the results.
-  std::string outVar = args[2];
+  std::string const& outVar = args[2];
 
   // Parse the options.
   enum
@@ -1610,8 +1610,8 @@
   return realsize;
 }
 
-size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
-                                      size_t size, void* data)
+int cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
+                                   size_t size, void* data)
 {
   cmFileCommandVectorOfChar& vec =
     *static_cast<cmFileCommandVectorOfChar*>(data);
@@ -1870,7 +1870,7 @@
       }
       std::string algo = i->substr(0, pos);
       expectedHash = cmSystemTools::LowerCase(i->substr(pos + 1));
-      hash = std::unique_ptr<cmCryptoHash>(cmCryptoHash::New(algo));
+      hash = cmCryptoHash::New(algo);
       if (!hash) {
         std::string err =
           cmStrCat("DOWNLOAD EXPECTED_HASH given unknown ALGO: ", algo);
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 63a4274..1667807 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -27,16 +27,6 @@
   : Status(status)
   , Makefile(&status.GetMakefile())
   , Name(name)
-  , Always(false)
-  , MatchlessFiles(true)
-  , FilePermissions(0)
-  , DirPermissions(0)
-  , CurrentMatchRule(nullptr)
-  , UseGivenPermissionsFile(false)
-  , UseGivenPermissionsDir(false)
-  , UseSourcePermissions(true)
-  , FollowSymlinkChain(false)
-  , Doing(DoingNone)
 {
 }
 
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index ee9872d..1fd2062 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -28,15 +28,15 @@
   cmExecutionStatus& Status;
   cmMakefile* Makefile;
   const char* Name;
-  bool Always;
+  bool Always = false;
   cmFileTimeCache FileTimes;
 
   // Whether to install a file not matching any expression.
-  bool MatchlessFiles;
+  bool MatchlessFiles = true;
 
   // Permissions for files and directories installed by this object.
-  mode_t FilePermissions;
-  mode_t DirPermissions;
+  mode_t FilePermissions = 0;
+  mode_t DirPermissions = 0;
 
   // Properties set by pattern and regex match rules.
   struct MatchProperties
@@ -85,17 +85,15 @@
   virtual void ReportCopy(const std::string&, Type, bool) {}
   virtual bool ReportMissing(const std::string& fromFile);
 
-  MatchRule* CurrentMatchRule;
-  bool UseGivenPermissionsFile;
-  bool UseGivenPermissionsDir;
-  bool UseSourcePermissions;
-  bool FollowSymlinkChain;
+  MatchRule* CurrentMatchRule = nullptr;
+  bool UseGivenPermissionsFile = false;
+  bool UseGivenPermissionsDir = false;
+  bool UseSourcePermissions = true;
+  bool FollowSymlinkChain = false;
   std::string Destination;
   std::string FilesFromDir;
   std::vector<std::string> Files;
-  int Doing;
 
-  virtual bool Parse(std::vector<std::string> const& args);
   enum
   {
     DoingNone,
@@ -110,6 +108,9 @@
     DoingPermissionsMatch,
     DoingLast1
   };
+  int Doing = DoingNone;
+
+  virtual bool Parse(std::vector<std::string> const& args);
   virtual bool CheckKeyword(std::string const& arg);
   virtual bool CheckValue(std::string const& arg);
 
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index 9bfbd13..5cfb2cf 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -23,13 +23,6 @@
 
 cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
   : cmFileCopier(status, "INSTALL")
-  , InstallType(cmInstallType_FILES)
-  , InstallMode(cmInstallMode::COPY)
-  , Optional(false)
-  , MessageAlways(false)
-  , MessageLazy(false)
-  , MessageNever(false)
-  , DestDirLength(0)
 {
   // Installation does not use source permissions by default.
   this->UseSourcePermissions = false;
@@ -440,7 +433,7 @@
       }
     }
     destination = sdestdir + destination.substr(skip);
-    this->DestDirLength = int(sdestdir.size());
+    this->DestDirLength = static_cast<int>(sdestdir.size());
   }
 
   // check if default dir creation permissions were set
diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h
index 3f6bd45..0b6f15d 100644
--- a/Source/cmFileInstaller.h
+++ b/Source/cmFileInstaller.h
@@ -19,13 +19,13 @@
   ~cmFileInstaller() override;
 
 protected:
-  cmInstallType InstallType;
-  cmInstallMode InstallMode;
-  bool Optional;
-  bool MessageAlways;
-  bool MessageLazy;
-  bool MessageNever;
-  int DestDirLength;
+  cmInstallType InstallType = cmInstallType_FILES;
+  cmInstallMode InstallMode = cmInstallMode::COPY;
+  bool Optional = false;
+  bool MessageAlways = false;
+  bool MessageLazy = false;
+  bool MessageNever = false;
+  int DestDirLength = 0;
   std::string Rename;
 
   std::string Manifest;
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index dcb3626..da82675 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -460,8 +460,8 @@
       // in the `fb->Args` vector. The first item is the iteration variable
       // name...
       const std::size_t iter_cnt = 2u +
-        int(start < stop) * (stop - start) / std::abs(step) +
-        int(start > stop) * (start - stop) / std::abs(step);
+        static_cast<int>(start < stop) * (stop - start) / std::abs(step) +
+        static_cast<int>(start > stop) * (start - stop) / std::abs(step);
       fb->Args.resize(iter_cnt);
       fb->Args.front() = args.front();
       auto cc = start;
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 70fe537..542b98c 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -123,13 +123,12 @@
     : File(file)
     , Buffer(buffer)
     , Directory(std::move(dir))
-    , LastCharWasNewline(false)
   {
   }
   FILE* File;
   YY_BUFFER_STATE Buffer;
   std::string Directory;
-  bool LastCharWasNewline;
+  bool LastCharWasNewline = false;
 };
 
 struct cmFortranCompiler
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index a52e66a..b529b8f 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -44,7 +44,8 @@
 #endif
   if (encoding == codecvt::UTF8_WITH_BOM) {
     // Write the BOM encoding header into the file
-    char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
+    char magic[] = { static_cast<char>(0xEF), static_cast<char>(0xBB),
+                     static_cast<char>(0xBF) };
     this->write(magic, 3);
   }
 }
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 840f511..f988e54 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -100,11 +100,6 @@
   cmListFileBacktrace backtrace, std::string input)
   : Backtrace(std::move(backtrace))
   , Input(std::move(input))
-  , EvaluateForBuildsystem(false)
-  , Quiet(false)
-  , HadContextSensitiveCondition(false)
-  , HadHeadSensitiveCondition(false)
-  , HadLinkLanguageSensitiveCondition(false)
 {
   cmGeneratorExpressionLexer l;
   std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 03be782..188993f 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -161,8 +161,8 @@
   std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators;
   const std::string Input;
   bool NeedsEvaluation;
-  bool EvaluateForBuildsystem;
-  bool Quiet;
+  bool EvaluateForBuildsystem = false;
+  bool Quiet = false;
 
   mutable std::set<cmGeneratorTarget*> DependTargets;
   mutable std::set<cmGeneratorTarget const*> AllTargetsSeen;
@@ -171,9 +171,9 @@
                    std::map<std::string, std::string>>
     MaxLanguageStandard;
   mutable std::string Output;
-  mutable bool HadContextSensitiveCondition;
-  mutable bool HadHeadSensitiveCondition;
-  mutable bool HadLinkLanguageSensitiveCondition;
+  mutable bool HadContextSensitiveCondition = false;
+  mutable bool HadHeadSensitiveCondition = false;
+  mutable bool HadLinkLanguageSensitiveCondition = false;
   mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
 };
 
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
index 42cbe2a..8076887 100644
--- a/Source/cmGeneratorExpressionContext.cxx
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -16,10 +16,6 @@
   , HeadTarget(headTarget)
   , CurrentTarget(currentTarget)
   , Quiet(quiet)
-  , HadError(false)
-  , HadContextSensitiveCondition(false)
-  , HadHeadSensitiveCondition(false)
-  , HadLinkLanguageSensitiveCondition(false)
   , EvaluateForBuildsystem(evaluateForBuildsystem)
 {
 }
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 22e7463..21e3961 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -36,9 +36,9 @@
   // directly or indirectly in the property.
   cmGeneratorTarget const* CurrentTarget;
   bool Quiet;
-  bool HadError;
-  bool HadContextSensitiveCondition;
-  bool HadHeadSensitiveCondition;
-  bool HadLinkLanguageSensitiveCondition;
+  bool HadError = false;
+  bool HadContextSensitiveCondition = false;
+  bool HadHeadSensitiveCondition = false;
+  bool HadLinkLanguageSensitiveCondition = false;
   bool EvaluateForBuildsystem;
 };
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 26ffd4b..beb623f 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -413,7 +413,7 @@
       return std::string();
     }
 
-    std::string targetName = parameters.front();
+    std::string const& targetName = parameters.front();
     if (targetName.empty() ||
         !cmGeneratorExpression::IsValidTargetName(targetName)) {
       reportError(context, content->GetOriginalExpression(),
@@ -445,7 +445,7 @@
       return std::string();
     }
 
-    std::string targetName = parameters.front();
+    std::string const& targetName = parameters.front();
     if (targetName.empty() ||
         !cmGeneratorExpression::IsValidTargetName(targetName)) {
       reportError(context, content->GetOriginalExpression(),
@@ -1759,7 +1759,7 @@
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    std::string tgtName = parameters.front();
+    std::string const& tgtName = parameters.front();
     cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
     if (!gt) {
       std::ostringstream e;
@@ -1847,7 +1847,7 @@
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    std::string tgtName = parameters.front();
+    std::string const& tgtName = parameters.front();
     cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
     if (!gt) {
       std::ostringstream e;
@@ -2396,7 +2396,7 @@
     cmGeneratorExpressionDAGChecker* dagChecker) const
   {
     // Lookup the referenced target.
-    std::string name = parameters.front();
+    std::string const& name = parameters.front();
 
     if (!cmGeneratorExpression::IsValidTargetName(name)) {
       ::reportError(context, content->GetOriginalExpression(),
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index 794c1a1..bbee4d5 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -15,7 +15,6 @@
 cmGeneratorExpressionParser::cmGeneratorExpressionParser(
   std::vector<cmGeneratorExpressionToken> tokens)
   : Tokens(std::move(tokens))
-  , NestingLevel(0)
 {
 }
 
diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h
index efaef3e..63273e4 100644
--- a/Source/cmGeneratorExpressionParser.h
+++ b/Source/cmGeneratorExpressionParser.h
@@ -26,5 +26,5 @@
 
   std::vector<cmGeneratorExpressionToken>::const_iterator it;
   const std::vector<cmGeneratorExpressionToken> Tokens;
-  unsigned int NestingLevel;
+  unsigned int NestingLevel = 0;
 };
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index d8a7c39..8ed7f10 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -335,20 +335,6 @@
 
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   : Target(t)
-  , FortranModuleDirectoryCreated(false)
-  , SourceFileFlagsConstructed(false)
-  , PolicyWarnedCMP0022(false)
-  , PolicyReportedCMP0069(false)
-  , DebugIncludesDone(false)
-  , DebugCompileOptionsDone(false)
-  , DebugCompileFeaturesDone(false)
-  , DebugCompileDefinitionsDone(false)
-  , DebugLinkOptionsDone(false)
-  , DebugLinkDirectoriesDone(false)
-  , DebugPrecompileHeadersDone(false)
-  , DebugSourcesDone(false)
-  , UtilityItemsDone(false)
-  , SourcesAreContextDependent(Tribool::Indeterminate)
 {
   this->Makefile = this->Target->GetMakefile();
   this->LocalGenerator = lg;
@@ -2775,15 +2761,14 @@
 
 class cmTargetSelectLinker
 {
-  int Preference;
+  int Preference = 0;
   cmGeneratorTarget const* Target;
   cmGlobalGenerator* GG;
   std::set<std::string> Preferred;
 
 public:
   cmTargetSelectLinker(cmGeneratorTarget const* target)
-    : Preference(0)
-    , Target(target)
+    : Target(target)
   {
     this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
   }
@@ -8527,7 +8512,7 @@
 
 bool cmGeneratorTarget::AddHeaderSetVerification()
 {
-  if (!this->GetPropertyAsBool("VERIFY_HEADER_SETS")) {
+  if (!this->GetPropertyAsBool("VERIFY_INTERFACE_HEADER_SETS")) {
     return true;
   }
 
@@ -8601,7 +8586,7 @@
               cmMakefile::PolicyPushPop polScope(this->Makefile);
               this->Makefile->SetPolicy(cmPolicies::CMP0119, cmPolicies::NEW);
               verifyTarget = this->Makefile->AddLibrary(
-                cmStrCat(this->GetName(), "_verify_header_sets"),
+                cmStrCat(this->GetName(), "_verify_interface_header_sets"),
                 cmStateEnums::OBJECT_LIBRARY, {}, true);
             }
 
@@ -8682,9 +8667,9 @@
   }
   headerFilename += source.GetLocation().GetName();
 
-  auto filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
-                           '/', this->GetName(), "_verify_header_sets/",
-                           headerFilename, extension);
+  auto filename = cmStrCat(
+    this->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->GetName(),
+    "_verify_interface_header_sets/", headerFilename, extension);
   auto* verificationSource = this->Makefile->GetOrCreateSource(filename);
   verificationSource->SetProperty("LANGUAGE", language);
 
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index b927848..6bce7d2 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -881,7 +881,7 @@
 
   std::string CreateFortranModuleDirectory(
     std::string const& working_dir) const;
-  mutable bool FortranModuleDirectoryCreated;
+  mutable bool FortranModuleDirectoryCreated = false;
   mutable std::string FortranModuleDirectory;
 
   friend class cmTargetTraceDependencies;
@@ -906,7 +906,7 @@
   mutable std::string ExportMacro;
 
   void ConstructSourceFileFlags() const;
-  mutable bool SourceFileFlagsConstructed;
+  mutable bool SourceFileFlagsConstructed = false;
   mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
 
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
@@ -1143,24 +1143,24 @@
   mutable OutputNameMapType OutputNameMap;
   mutable std::set<cmLinkItem> UtilityItems;
   cmPolicies::PolicyMap PolicyMap;
-  mutable bool PolicyWarnedCMP0022;
-  mutable bool PolicyReportedCMP0069;
-  mutable bool DebugIncludesDone;
-  mutable bool DebugCompileOptionsDone;
-  mutable bool DebugCompileFeaturesDone;
-  mutable bool DebugCompileDefinitionsDone;
-  mutable bool DebugLinkOptionsDone;
-  mutable bool DebugLinkDirectoriesDone;
-  mutable bool DebugPrecompileHeadersDone;
-  mutable bool DebugSourcesDone;
-  mutable bool UtilityItemsDone;
+  mutable bool PolicyWarnedCMP0022 = false;
+  mutable bool PolicyReportedCMP0069 = false;
+  mutable bool DebugIncludesDone = false;
+  mutable bool DebugCompileOptionsDone = false;
+  mutable bool DebugCompileFeaturesDone = false;
+  mutable bool DebugCompileDefinitionsDone = false;
+  mutable bool DebugLinkOptionsDone = false;
+  mutable bool DebugLinkDirectoriesDone = false;
+  mutable bool DebugPrecompileHeadersDone = false;
+  mutable bool DebugSourcesDone = false;
+  mutable bool UtilityItemsDone = false;
   enum class Tribool
   {
     False = 0x0,
     True = 0x1,
     Indeterminate = 0x2
   };
-  mutable Tribool SourcesAreContextDependent;
+  mutable Tribool SourcesAreContextDependent = Tribool::Indeterminate;
 
   bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
                            std::string& out) const;
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 4a25311..943ce1d 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -71,7 +71,7 @@
   }
 
   // The cmake variable in which to store the result.
-  const std::string variable = args[0];
+  std::string const& variable = args[0];
 
   std::string name;
   std::string propertyName;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 12ae983..9d61de9 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1157,7 +1157,10 @@
 {
   // if there is an extension and it starts with . then move past the
   // . because the extensions are not stored with a .  in the map
-  if (ext && *ext == '.') {
+  if (!ext) {
+    return "";
+  }
+  if (*ext == '.') {
     ++ext;
   }
   auto const it = this->ExtensionToLanguage.find(ext);
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index 12ffa5b..600ee0a 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -138,7 +138,8 @@
 bool cmGlobalVisualStudio12Generator::ProcessGeneratorToolsetField(
   std::string const& key, std::string const& value)
 {
-  if (key == "host" && (value == "x64" || value == "x86")) {
+  if (key == "host" &&
+      (value == "x64" || value == "x86" || value == "ARM64")) {
     this->GeneratorToolsetHostArchitecture = value;
     return true;
   }
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index bc38335..1c05d36 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -27,16 +27,17 @@
 
 #if defined(_M_ARM64)
 #  define HOST_PLATFORM_NAME "ARM64"
-#  define HOST_TOOLS_ARCH ""
+#  define HOST_TOOLS_ARCH(v)                                                  \
+    (v >= cmGlobalVisualStudioGenerator::VSVersion::VS17) ? "ARM64" : ""
 #elif defined(_M_ARM)
 #  define HOST_PLATFORM_NAME "ARM"
-#  define HOST_TOOLS_ARCH ""
+#  define HOST_TOOLS_ARCH(v) ""
 #elif defined(_M_IA64)
 #  define HOST_PLATFORM_NAME "Itanium"
-#  define HOST_TOOLS_ARCH ""
+#  define HOST_TOOLS_ARCH(v) ""
 #elif defined(_WIN64)
 #  define HOST_PLATFORM_NAME "x64"
-#  define HOST_TOOLS_ARCH "x64"
+#  define HOST_TOOLS_ARCH(v) "x64"
 #else
 static bool VSIsWow64()
 {
@@ -58,10 +59,12 @@
 #endif
 }
 
-static std::string VSHostArchitecture()
+static std::string VSHostArchitecture(
+  cmGlobalVisualStudioGenerator::VSVersion v)
 {
+  static_cast<void>(v);
 #ifdef HOST_TOOLS_ARCH
-  return HOST_TOOLS_ARCH;
+  return HOST_TOOLS_ARCH(v);
 #else
   if (VSIsWow64()) {
     return "x64";
@@ -433,7 +436,8 @@
   this->DefaultLinkFlagTableName = VSVersionToToolset(this->Version);
   if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16) {
     this->DefaultPlatformName = VSHostPlatformName();
-    this->DefaultPlatformToolsetHostArchitecture = VSHostArchitecture();
+    this->DefaultPlatformToolsetHostArchitecture =
+      VSHostArchitecture(this->Version);
   }
   if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS17) {
     // FIXME: Search for an existing framework?  Under '%ProgramFiles(x86)%',
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index ab18e2a..2bb438d 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -109,18 +109,6 @@
   , GraphHeader("node [\n  fontsize = \"12\"\n];")
   , GraphNodePrefix("node")
   , GlobalGenerator(globalGenerator)
-  , NextNodeId(0)
-  , GenerateForExecutables(true)
-  , GenerateForStaticLibs(true)
-  , GenerateForSharedLibs(true)
-  , GenerateForModuleLibs(true)
-  , GenerateForInterfaceLibs(true)
-  , GenerateForObjectLibs(true)
-  , GenerateForUnknownLibs(true)
-  , GenerateForCustomTargets(false)
-  , GenerateForExternals(true)
-  , GeneratePerTarget(true)
-  , GenerateDependers(true)
 {
 }
 
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 0912fc8..24dbe52 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -119,19 +119,19 @@
 
   cmGlobalGenerator const* GlobalGenerator;
 
-  int NextNodeId;
+  int NextNodeId = 0;
   // maps from the actual item names to node names in dot:
   std::map<std::string, std::string> NodeNames;
 
-  bool GenerateForExecutables;
-  bool GenerateForStaticLibs;
-  bool GenerateForSharedLibs;
-  bool GenerateForModuleLibs;
-  bool GenerateForInterfaceLibs;
-  bool GenerateForObjectLibs;
-  bool GenerateForUnknownLibs;
-  bool GenerateForCustomTargets;
-  bool GenerateForExternals;
-  bool GeneratePerTarget;
-  bool GenerateDependers;
+  bool GenerateForExecutables = true;
+  bool GenerateForStaticLibs = true;
+  bool GenerateForSharedLibs = true;
+  bool GenerateForModuleLibs = true;
+  bool GenerateForInterfaceLibs = true;
+  bool GenerateForObjectLibs = true;
+  bool GenerateForUnknownLibs = true;
+  bool GenerateForCustomTargets = false;
+  bool GenerateForExternals = true;
+  bool GeneratePerTarget = true;
+  bool GenerateDependers = true;
 };
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 8462b99..d358763 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -20,7 +20,6 @@
   bool optional, cmListFileBacktrace backtrace)
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all, false, std::move(backtrace))
-  , LocalGenerator(nullptr)
   , Directories(dirs)
   , FilePermissions(std::move(file_permissions))
   , DirPermissions(std::move(dir_permissions))
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 419fd8c..7deb9ba 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -42,7 +42,7 @@
   void AddDirectoryInstallRule(std::ostream& os, const std::string& config,
                                Indent indent,
                                std::vector<std::string> const& dirs);
-  cmLocalGenerator* LocalGenerator;
+  cmLocalGenerator* LocalGenerator = nullptr;
   std::vector<std::string> const Directories;
   std::string const FilePermissions;
   std::string const DirPermissions;
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index f1ac656..8a48aa2 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -32,7 +32,6 @@
   , FileName(std::move(filename))
   , Namespace(std::move(name_space))
   , ExportOld(exportOld)
-  , LocalGenerator(nullptr)
 {
   if (android) {
 #ifndef CMAKE_BOOTSTRAP
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index dc07d36..02fe1fa 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -65,7 +65,7 @@
   std::string const FileName;
   std::string const Namespace;
   bool const ExportOld;
-  cmLocalGenerator* LocalGenerator;
+  cmLocalGenerator* LocalGenerator = nullptr;
 
   std::string TempDir;
   std::string MainImportFile;
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 378b9fc..18a852b 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -19,7 +19,6 @@
   bool optional, cmListFileBacktrace backtrace)
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all, false, std::move(backtrace))
-  , LocalGenerator(nullptr)
   , Files(files)
   , FilePermissions(std::move(file_permissions))
   , Rename(std::move(rename))
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index 2276ab8..53076b3 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -44,7 +44,7 @@
                            Indent indent,
                            std::vector<std::string> const& files);
 
-  cmLocalGenerator* LocalGenerator;
+  cmLocalGenerator* LocalGenerator = nullptr;
   std::vector<std::string> const Files;
   std::string const FilePermissions;
   std::string const Rename;
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index 87110a9..93abd45 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -165,14 +165,22 @@
 }
 
 std::string cmInstallGenerator::CreateComponentTest(
-  const std::string& component, bool exclude_from_all)
+  const std::string& component, bool exclude_from_all, bool all_components)
 {
+  if (all_components) {
+    if (exclude_from_all) {
+      return "CMAKE_INSTALL_COMPONENT";
+    }
+    return {};
+  }
+
   std::string result = "CMAKE_INSTALL_COMPONENT STREQUAL \"";
   result += component;
   result += "\"";
   if (!exclude_from_all) {
     result += " OR NOT CMAKE_INSTALL_COMPONENT";
   }
+
   return result;
 }
 
@@ -181,10 +189,11 @@
   // Track indentation.
   Indent indent;
 
+  std::string component_test = this->CreateComponentTest(
+    this->Component, this->ExcludeFromAll, this->AllComponents);
+
   // Begin this block of installation.
-  if (!this->AllComponents) {
-    std::string component_test =
-      this->CreateComponentTest(this->Component, this->ExcludeFromAll);
+  if (!component_test.empty()) {
     os << indent << "if(" << component_test << ")\n";
   }
 
@@ -193,7 +202,7 @@
                               this->AllComponents ? indent : indent.Next());
 
   // End this block of installation.
-  if (!this->AllComponents) {
+  if (!component_test.empty()) {
     os << indent << "endif()\n\n";
   }
 }
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index d342c99..9fcd284 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -78,7 +78,8 @@
   void GenerateScript(std::ostream& os) override;
 
   std::string CreateComponentTest(const std::string& component,
-                                  bool exclude_from_all);
+                                  bool exclude_from_all,
+                                  bool all_components = false);
 
   using TweakMethod =
     std::function<void(std::ostream& os, Indent indent,
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index bec98b6..a5625fe 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -20,7 +20,6 @@
                        std::move(backtrace))
   , Script(std::move(script))
   , Code(code)
-  , AllowGenex(false)
 {
   // We need per-config actions if the script has generator expressions.
   if (cmGeneratorExpression::Find(this->Script) != std::string::npos) {
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 2cf6a4b..c3a7058 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -41,5 +41,5 @@
   std::string const Script;
   bool const Code;
   cmLocalGenerator* LocalGenerator;
-  bool AllowGenex;
+  bool AllowGenex = false;
 };
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index ae11afc..16c5002 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -50,7 +50,6 @@
   : cmInstallGenerator(dest, configurations, component, message,
                        exclude_from_all, false, std::move(backtrace))
   , TargetName(std::move(targetName))
-  , Target(nullptr)
   , FilePermissions(std::move(file_permissions))
   , ImportLibrary(implib)
   , Optional(optional)
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 6173f2c..3fc4b59 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -118,7 +118,7 @@
   void IssueCMP0095Warning(const std::string& unescapedRpath);
 
   std::string const TargetName;
-  cmGeneratorTarget* Target;
+  cmGeneratorTarget* Target = nullptr;
   std::string const FilePermissions;
   NamelinkModeType NamelinkMode;
   bool const ImportLibrary;
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 290642b..b1e9e56 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -18,10 +18,6 @@
                                        cmStateDirectory const& stateDir)
   : StateDir(stateDir)
   , OutputConverter(outputConverter)
-  , ForResponse(false)
-  , UseWatcomQuote(false)
-  , UseNinjaMulti(false)
-  , Relink(false)
 {
 }
 
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index a1dafc4..9fb222c 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -67,8 +67,8 @@
   cmStateDirectory StateDir;
   cmOutputConverter* OutputConverter;
 
-  bool ForResponse;
-  bool UseWatcomQuote;
-  bool UseNinjaMulti;
-  bool Relink;
+  bool ForResponse = false;
+  bool UseWatcomQuote = false;
+  bool UseNinjaMulti = false;
+  bool Relink = false;
 };
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 56345df..d412534 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -229,7 +229,7 @@
   // If `listString` or `args` is empty, no need to append `;`,
   // then index is going to be `1` and points to the end-of-string ";"
   auto const offset =
-    std::string::size_type(listString.empty() || args.empty());
+    static_cast<std::string::size_type>(listString.empty() || args.empty());
   listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";");
 
   makefile.AddDefinition(listName, listString);
@@ -255,7 +255,7 @@
   // If `listString` or `args` is empty, no need to append `;`,
   // then `offset` is going to be `1` and points to the end-of-string ";"
   auto const offset =
-    std::string::size_type(listString.empty() || args.empty());
+    static_cast<std::string::size_type>(listString.empty() || args.empty());
   listString.insert(0,
                     cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]);
 
@@ -1199,7 +1199,7 @@
   const std::string messageHint = "sub-command SORT ";
 
   while (argumentIndex < args.size()) {
-    const std::string option = args[argumentIndex++];
+    std::string const& option = args[argumentIndex++];
     if (option == "COMPARE") {
       if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) {
         std::string error = cmStrCat(messageHint, "option \"", option,
@@ -1208,7 +1208,7 @@
         return false;
       }
       if (argumentIndex < args.size()) {
-        const std::string argument = args[argumentIndex++];
+        std::string const& argument = args[argumentIndex++];
         if (argument == "STRING") {
           sortCompare = cmStringSorter::Compare::STRING;
         } else if (argument == "FILE_BASENAME") {
@@ -1235,7 +1235,7 @@
         return false;
       }
       if (argumentIndex < args.size()) {
-        const std::string argument = args[argumentIndex++];
+        std::string const& argument = args[argumentIndex++];
         if (argument == "SENSITIVE") {
           sortCaseSensitivity = cmStringSorter::CaseSensitivity::SENSITIVE;
         } else if (argument == "INSENSITIVE") {
@@ -1259,7 +1259,7 @@
         return false;
       }
       if (argumentIndex < args.size()) {
-        const std::string argument = args[argumentIndex++];
+        std::string const& argument = args[argumentIndex++];
         if (argument == "ASCENDING") {
           sortOrder = cmStringSorter::Order::ASCENDING;
         } else if (argument == "DESCENDING") {
@@ -1346,7 +1346,7 @@
 
   using size_type = decltype(varArgsExpanded)::size_type;
 
-  if (start < 0 || size_type(start) >= varArgsExpanded.size()) {
+  if (start < 0 || static_cast<size_type>(start) >= varArgsExpanded.size()) {
     status.SetError(cmStrCat("begin index: ", start, " is out of range 0 - ",
                              varArgsExpanded.size() - 1));
     return false;
@@ -1357,9 +1357,10 @@
   }
 
   const size_type end =
-    (length == -1 || size_type(start + length) > varArgsExpanded.size())
+    (length == -1 ||
+     static_cast<size_type>(start + length) > varArgsExpanded.size())
     ? varArgsExpanded.size()
-    : size_type(start + length);
+    : static_cast<size_type>(start + length);
   std::vector<std::string> sublist(varArgsExpanded.begin() + start,
                                    varArgsExpanded.begin() + end);
   status.GetMakefile().AddDefinition(variableName, cmJoin(sublist, ";"));
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 5133521..4485ac6 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -36,7 +36,7 @@
   cmListFile* ListFile;
   cmListFileBacktrace Backtrace;
   cmMessenger* Messenger;
-  const char* FileName;
+  const char* FileName = nullptr;
   cmListFileLexer* Lexer;
   std::string FunctionName;
   long FunctionLine;
@@ -55,7 +55,6 @@
   : ListFile(lf)
   , Backtrace(std::move(lfbt))
   , Messenger(messenger)
-  , FileName(nullptr)
   , Lexer(cmListFileLexer_New())
 {
 }
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index f7c2509..0553989 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -110,16 +110,22 @@
   cm::optional<std::string> DeferId;
 
   cmListFileContext() = default;
-  cmListFileContext(cmListFileContext&& /*other*/) = default;
+  // This move constructor is marked `noexcept` yet `clang-tidy` 14 reports it
+  // as being able to throw an exception. Suppress the warning as there doesn't
+  // seem to be any way for this to happen given the member types.
+  // NOLINTNEXTLINE(bugprone-exception-escape)
+  cmListFileContext(cmListFileContext&& /*other*/) noexcept = default;
   cmListFileContext(const cmListFileContext& /*other*/) = default;
   cmListFileContext& operator=(const cmListFileContext& /*other*/) = default;
 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-  cmListFileContext& operator=(cmListFileContext&& /*other*/) = default;
+  cmListFileContext& operator=(cmListFileContext&& /*other*/) noexcept =
+    default;
 #else
   // The move assignment operators for several STL classes did not become
   // noexcept until C++17, which causes some tools to warn about this move
   // assignment operator throwing an exception when it shouldn't.
-  cmListFileContext& operator=(cmListFileContext&& /*other*/) = delete;
+  cmListFileContext& operator=(cmListFileContext&& /*other*/) noexcept =
+    delete;
 #endif
 
   cmListFileContext(std::string name, std::string filePath, long line)
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index d49e711..9981c05 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -106,7 +106,7 @@
   }
 
   // Prepare the table of variables to read.
-  std::string const prefix = args[2];
+  std::string const& prefix = args[2];
   std::set<std::string> const variablesToRead(args.begin() + 3, args.end());
 
   // Read the cache file.
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index e2bcea8..d2c81ae 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1026,11 +1026,13 @@
   }
 
   // Add Warning as errors flags
-  const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
-  const cmValue wErrorFlag = this->Makefile->GetDefinition(
-    cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_WARNING_AS_ERROR"));
-  if (wError.IsOn() && wErrorFlag.IsSet()) {
-    flags.emplace_back(wErrorFlag);
+  if (!this->GetCMakeInstance()->GetIgnoreWarningAsError()) {
+    const cmValue wError = target->GetProperty("COMPILE_WARNING_AS_ERROR");
+    const cmValue wErrorFlag = this->Makefile->GetDefinition(
+      cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_WARNING_AS_ERROR"));
+    if (wError.IsOn() && wErrorFlag.IsSet()) {
+      flags.emplace_back(wErrorFlag);
+    }
   }
 
   // Add compile flag for the MSVC compiler only.
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 91d7ac5..b5df459 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -478,8 +478,8 @@
 private:
   cmMakefile* Makefile;
   bool NoPolicyScope;
-  bool CheckCMP0011;
-  bool ReportError;
+  bool CheckCMP0011 = false;
+  bool ReportError = true;
   void EnforceCMP0011();
 };
 
@@ -488,8 +488,6 @@
                                        bool noPolicyScope)
   : Makefile(mf)
   , NoPolicyScope(noPolicyScope)
-  , CheckCMP0011(false)
-  , ReportError(true)
 {
   this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
     cmListFileContext::FromListFilePath(filenametoread));
@@ -623,7 +621,6 @@
 public:
   ListFileScope(cmMakefile* mf, std::string const& filenametoread)
     : Makefile(mf)
-    , ReportError(true)
   {
     this->Makefile->Backtrace = this->Makefile->Backtrace.Push(
       cmListFileContext::FromListFilePath(filenametoread));
@@ -650,7 +647,7 @@
 
 private:
   cmMakefile* Makefile;
-  bool ReportError;
+  bool ReportError = true;
 };
 
 class cmMakefile::DeferScope
@@ -1536,7 +1533,6 @@
 public:
   BuildsystemFileScope(cmMakefile* mf)
     : Makefile(mf)
-    , ReportError(true)
   {
     std::string currentStart =
       cmStrCat(this->Makefile->StateSnapshot.GetDirectory().GetCurrentSource(),
@@ -1578,7 +1574,7 @@
   cmGlobalGenerator* GG;
   cmMakefile* CurrentMakefile;
   cmStateSnapshot Snapshot;
-  bool ReportError;
+  bool ReportError = true;
 };
 
 void cmMakefile::Configure()
@@ -4511,7 +4507,7 @@
   /* Record the setting of every policy.  */
   using PolicyID = cmPolicies::PolicyID;
   for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
-       pid = PolicyID(pid + 1)) {
+       pid = static_cast<PolicyID>(pid + 1)) {
     pm.Set(pid, this->GetPolicyStatus(pid));
   }
 }
@@ -4538,7 +4534,6 @@
                                              const std::string& fileName,
                                              cmPolicies::PolicyMap const& pm)
   : Makefile(mf)
-  , ReportError(true)
 {
   this->Makefile->PushFunctionScope(fileName, pm);
 }
@@ -4552,7 +4547,6 @@
                                        const std::string& fileName,
                                        const cmPolicies::PolicyMap& pm)
   : Makefile(mf)
-  , ReportError(true)
 {
   this->Makefile->PushMacroScope(fileName, pm);
 }
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index c8e1e83..e7b9716 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -833,7 +833,7 @@
 
   private:
     cmMakefile* Makefile;
-    bool ReportError;
+    bool ReportError = true;
   };
 
   class MacroPushPop
@@ -850,7 +850,7 @@
 
   private:
     cmMakefile* Makefile;
-    bool ReportError;
+    bool ReportError = true;
   };
 
   void PushFunctionScope(std::string const& fileName,
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 66031db..21b91e0 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -929,7 +929,9 @@
   }
 
   // Compute the list of outputs.
-  std::vector<std::string> outputs(1, targetFullPathReal);
+  std::vector<std::string> outputs;
+  outputs.reserve(3);
+  outputs.push_back(targetFullPathReal);
   if (this->TargetNames.SharedObject != this->TargetNames.Real) {
     outputs.push_back(targetFullPathSO);
   }
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
index 337f78b..1cd97c9 100644
--- a/Source/cmMakefileProfilingData.cxx
+++ b/Source/cmMakefileProfilingData.cxx
@@ -60,7 +60,7 @@
     v["ph"] = "B";
     v["name"] = lff.LowerCaseName();
     v["cat"] = "cmake";
-    v["ts"] = Json::Value::UInt64(
+    v["ts"] = static_cast<Json::Value::UInt64>(
       std::chrono::duration_cast<std::chrono::microseconds>(
         std::chrono::steady_clock::now().time_since_epoch())
         .count());
@@ -98,7 +98,7 @@
     cmsys::SystemInformation info;
     Json::Value v;
     v["ph"] = "E";
-    v["ts"] = Json::Value::UInt64(
+    v["ts"] = static_cast<Json::Value::UInt64>(
       std::chrono::duration_cast<std::chrono::microseconds>(
         std::chrono::steady_clock::now().time_since_epoch())
         .count());
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index df9ebcf..1c0ff13 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -57,10 +57,10 @@
 
   if (argumentIndex < args.size()) {
     const std::string messageHint = "sub-command EXPR ";
-    const std::string option = args[argumentIndex++];
+    std::string const& option = args[argumentIndex++];
     if (option == "OUTPUT_FORMAT") {
       if (argumentIndex < args.size()) {
-        const std::string argument = args[argumentIndex++];
+        std::string const& argument = args[argumentIndex++];
         if (argument == "DECIMAL") {
           outputFormat = NumericFormat::DECIMAL;
         } else if (argument == "HEXADECIMAL") {
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 7eea4b2..674735b 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -18,7 +18,6 @@
   : GT(target)
   , Makefile(target->Target->GetMakefile())
   , LocalGenerator(target->GetLocalGenerator())
-  , MacContentFolders(nullptr)
 {
   if (this->MustSkip()) {
     return;
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index a3b6f98..c33b087 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -65,5 +65,5 @@
   cmGeneratorTarget* GT;
   cmMakefile* Makefile;
   cmLocalGenerator* LocalGenerator;
-  std::set<std::string>* MacContentFolders;
+  std::set<std::string>* MacContentFolders = nullptr;
 };
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index e62e0cd..6883535 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -29,7 +29,6 @@
 
 cmOutputConverter::cmOutputConverter(cmStateSnapshot const& snapshot)
   : StateSnapshot(snapshot)
-  , LinkScriptShell(false)
 {
   assert(this->StateSnapshot.IsValid());
   this->ComputeRelativePathTopSource();
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index d19bccc..6e1bfe3 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -138,7 +138,7 @@
   static bool Shell_ArgumentNeedsQuotes(cm::string_view in, int flags);
   static std::string Shell_GetArgument(cm::string_view in, int flags);
 
-  bool LinkScriptShell;
+  bool LinkScriptShell = false;
 
   // The top-most directories for relative path conversion.  Both the
   // source and destination location of a relative path conversion
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index e31de1c..03ae44e 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -43,7 +43,7 @@
   if (id >= cmPolicies::CMPCOUNT) {
     return false;
   }
-  pid = cmPolicies::PolicyID(id);
+  pid = static_cast<cmPolicies::PolicyID>(id);
   return true;
 }
 
@@ -279,7 +279,7 @@
   // now loop over all the policies and set them as appropriate
   std::vector<cmPolicies::PolicyID> ancientPolicies;
   for (PolicyID pid = cmPolicies::CMP0000; pid != cmPolicies::CMPCOUNT;
-       pid = PolicyID(pid + 1)) {
+       pid = static_cast<PolicyID>(pid + 1)) {
     if (isPolicyNewerThan(pid, majorVer, minorVer, patchVer)) {
       if (cmPolicies::GetPolicyStatus(pid) == cmPolicies::REQUIRED_ALWAYS) {
         ancientPolicies.push_back(pid);
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 4977083..c8b037e 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -411,7 +411,10 @@
          3, 24, 0, cmPolicies::WARN)                                          \
   SELECT(POLICY, CMP0136,                                                     \
          "Watcom runtime library flags are selected by an abstraction.", 3,   \
-         24, 0, cmPolicies::WARN)
+         24, 0, cmPolicies::WARN)                                             \
+  SELECT(POLICY, CMP0137,                                                     \
+         "try_compile() passes platform variables in project mode", 3, 24, 0, \
+         cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
 #define CM_FOR_EACH_POLICY_ID(POLICY)                                         \
diff --git a/Source/cmProcessTools.cxx b/Source/cmProcessTools.cxx
index 9ebf5b7..9e7854b 100644
--- a/Source/cmProcessTools.cxx
+++ b/Source/cmProcessTools.cxx
@@ -21,12 +21,12 @@
          (p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
     if (out && p == cmsysProcess_Pipe_STDOUT) {
       processOutput.DecodeText(data, length, strdata, 1);
-      if (!out->Process(strdata.c_str(), int(strdata.size()))) {
+      if (!out->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
         out = nullptr;
       }
     } else if (err && p == cmsysProcess_Pipe_STDERR) {
       processOutput.DecodeText(data, length, strdata, 2);
-      if (!err->Process(strdata.c_str(), int(strdata.size()))) {
+      if (!err->Process(strdata.c_str(), static_cast<int>(strdata.size()))) {
         err = nullptr;
       }
     }
@@ -34,13 +34,13 @@
   if (out) {
     processOutput.DecodeText(std::string(), strdata, 1);
     if (!strdata.empty()) {
-      out->Process(strdata.c_str(), int(strdata.size()));
+      out->Process(strdata.c_str(), static_cast<int>(strdata.size()));
     }
   }
   if (err) {
     processOutput.DecodeText(std::string(), strdata, 2);
     if (!strdata.empty()) {
-      err->Process(strdata.c_str(), int(strdata.size()));
+      err->Process(strdata.c_str(), static_cast<int>(strdata.size()));
     }
   }
   cmsysProcess_WaitForExit(cp, nullptr);
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 04d99c9..4b65fb9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -242,9 +242,9 @@
       const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
                                  &v[2], &v[3]);
       for (auto i = 0u; i < MAX_VERSION_COMPONENTS; ++i) {
-        if (int(i) < vc) {
+        if (static_cast<int>(i) < vc) {
           std::snprintf(vb[i], maxIntLength, "%u", v[i]);
-          version_string += &"."[std::size_t(i == 0)];
+          version_string += &"."[static_cast<std::size_t>(i == 0)];
           version_string += vb[i];
           version_components[i] = vb[i];
         } else {
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 1e4dedd..fa9d4cc 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -19,11 +19,6 @@
 cmRST::cmRST(std::ostream& os, std::string docroot)
   : OS(os)
   , DocRoot(std::move(docroot))
-  , IncludeDepth(0)
-  , OutputLinePending(false)
-  , LastLineEndedInColonColon(false)
-  , Markup(MarkupNone)
-  , Directive(DirectiveNone)
   , CMakeDirective("^.. (cmake:)?("
                    "command|envvar|genex|variable"
                    ")::[ \t]+([^ \t\n]+)$")
diff --git a/Source/cmRST.h b/Source/cmRST.h
index 156b20a..ea4ef22 100644
--- a/Source/cmRST.h
+++ b/Source/cmRST.h
@@ -69,11 +69,11 @@
 
   std::ostream& OS;
   std::string DocRoot;
-  int IncludeDepth;
-  bool OutputLinePending;
-  bool LastLineEndedInColonColon;
-  MarkupType Markup;
-  DirectiveType Directive;
+  int IncludeDepth = 0;
+  bool OutputLinePending = false;
+  bool LastLineEndedInColonColon = false;
+  MarkupType Markup = MarkupNone;
+  DirectiveType Directive = DirectiveNone;
   cmsys::RegularExpression CMakeDirective;
   cmsys::RegularExpression CMakeModuleDirective;
   cmsys::RegularExpression ParsedLiteralDirective;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 26f255d..4dfdfae 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -236,6 +236,7 @@
   cmGlobalGenerator* gg = this->GetMakefile()->GetGlobalGenerator();
 
   // Add newer Visual Studio paths
+  AddVisualStudioPath(paths, "Visual Studio 17 ", 17, gg);
   AddVisualStudioPath(paths, "Visual Studio 16 ", 16, gg);
   AddVisualStudioPath(paths, "Visual Studio 15 ", 15, gg);
 
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 437b938..166ee56 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -12,8 +12,6 @@
                                      std::vector<std::string> configurations)
   : RuntimeConfigVariable(std::move(config_var))
   , Configurations(std::move(configurations))
-  , ConfigurationTypes(nullptr)
-  , ActionsPerConfig(false)
 {
 }
 
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index 46d794c..3d7b350 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -78,12 +78,12 @@
 
   // Information used during generation.
   std::string ConfigurationName;
-  std::vector<std::string> const* ConfigurationTypes;
+  std::vector<std::string> const* ConfigurationTypes = nullptr;
 
   // True if the subclass needs to generate an explicit rule for each
   // configuration.  False if the subclass only generates one rule for
   // all enabled configurations.
-  bool ActionsPerConfig;
+  bool ActionsPerConfig = false;
 
 private:
   void GenerateScriptActionsOnce(std::ostream& os, Indent indent);
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 527175d..512a5fa 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1995,7 +1995,7 @@
           --length;
         }
         if (length > 0) {
-          line.append(&out[0], length);
+          line.append(out.data(), length);
         }
         out.erase(out.begin(), outiter + 1);
         return cmsysProcess_Pipe_STDOUT;
@@ -2013,7 +2013,7 @@
           --length;
         }
         if (length > 0) {
-          line.append(&err[0], length);
+          line.append(err.data(), length);
         }
         err.erase(err.begin(), erriter + 1);
         return cmsysProcess_Pipe_STDERR;
@@ -2057,12 +2057,12 @@
         erriter = err.begin() + size;
       }
       if (!out.empty()) {
-        line.append(&out[0], outiter - out.begin());
+        line.append(out.data(), outiter - out.begin());
         out.erase(out.begin(), out.end());
         return cmsysProcess_Pipe_STDOUT;
       }
       if (!err.empty()) {
-        line.append(&err[0], erriter - err.begin());
+        line.append(err.data(), erriter - err.begin());
         err.erase(err.begin(), err.end());
         return cmsysProcess_Pipe_STDERR;
       }
@@ -3149,7 +3149,7 @@
     }
     return false;
   }
-  if (!f.write(&bytes[0], bytes.size())) {
+  if (!f.write(bytes.data(), bytes.size())) {
     if (emsg) {
       *emsg = "Error replacing DYNAMIC table header.";
     }
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 80d1940..83dc1c2 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -621,7 +621,7 @@
   }
 
   initProp("FOLDER");
-  initProp("VERIFY_HEADER_SETS");
+  initProp("VERIFY_INTERFACE_HEADER_SETS");
 
   if (this->GetGlobalGenerator()->IsXcode()) {
     initProp("XCODE_GENERATE_SCHEME");
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 9027409..4ff5eb4 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -18,17 +18,14 @@
 
   // The set order depends only on the Target, so we use
   // mutable members to achieve a map with set syntax.
-  mutable bool Link;
-  mutable bool Util;
-  mutable bool Cross;
+  mutable bool Link = false;
+  mutable bool Util = false;
+  mutable bool Cross = false;
   mutable cmListFileBacktrace Backtrace;
 
 public:
   cmTargetDepend(cmGeneratorTarget const* t)
     : Target(t)
-    , Link(false)
-    , Util(false)
-    , Cross(false)
   {
   }
   operator cmGeneratorTarget const*() const { return this->Target; }
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index f31501e..b4b4319 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -99,7 +99,7 @@
 {
   return TargetIncludeDirectoriesImpl(status).HandleArguments(
     args, "INCLUDE_DIRECTORIES",
-    TargetIncludeDirectoriesImpl::ArgumentFlags(
+    static_cast<TargetIncludeDirectoriesImpl::ArgumentFlags>(
       TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
       TargetIncludeDirectoriesImpl::PROCESS_AFTER |
       TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index 7c0f9e7..e6ed01b 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -8,8 +8,7 @@
 #include "cmValue.h"
 
 cmTest::cmTest(cmMakefile* mf)
-  : CommandExpandLists(false)
-  , Backtrace(mf->GetBacktrace())
+  : Backtrace(mf->GetBacktrace())
 {
   this->Makefile = mf;
   this->OldStyle = true;
diff --git a/Source/cmTest.h b/Source/cmTest.h
index 85978da..1c14310 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -64,7 +64,7 @@
   cmPropertyMap Properties;
   std::string Name;
   std::vector<std::string> Command;
-  bool CommandExpandLists;
+  bool CommandExpandLists = false;
 
   bool OldStyle;
 
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index e2b6c20..677fdb6 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -50,7 +50,7 @@
     // SOURCE_DATE_EPOCH has only a resolution in the seconds range
     microseconds = 0;
   }
-  if (currentTimeT == time_t(-1)) {
+  if (currentTimeT == static_cast<time_t>(-1)) {
     return std::string();
   }
 
diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx
index 81a6507..12c121f 100644
--- a/Source/cmTransformDepfile.cxx
+++ b/Source/cmTransformDepfile.cxx
@@ -89,7 +89,9 @@
   }
 
   // Write a UTF-8 BOM so MSBuild knows the encoding when reading the file.
-  static const char utf8bom[] = { char(0xEF), char(0xBB), char(0xBF) };
+  static const char utf8bom[] = { static_cast<char>(0xEF),
+                                  static_cast<char>(0xBB),
+                                  static_cast<char>(0xBF) };
   fout.write(utf8bom, sizeof(utf8bom));
 
   // Write the format expected by MSBuild CustomBuild AdditionalInputs.
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 2513303..6688668 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -17,10 +17,10 @@
 
   cmCryptoHash md5(cmCryptoHash::AlgoMD5);
   md5.Initialize();
-  md5.Append(&hashInput[0], hashInput.size());
+  md5.Append(hashInput.data(), hashInput.size());
   std::vector<unsigned char> digest = md5.Finalize();
 
-  return this->FromDigest(&digest[0], 3);
+  return this->FromDigest(digest.data(), 3);
 }
 
 std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
@@ -31,10 +31,10 @@
 
   cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
   sha1.Initialize();
-  sha1.Append(&hashInput[0], hashInput.size());
+  sha1.Append(hashInput.data(), hashInput.size());
   std::vector<unsigned char> digest = sha1.Finalize();
 
-  return this->FromDigest(&digest[0], 5);
+  return this->FromDigest(digest.data(), 5);
 }
 
 void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,
@@ -46,7 +46,7 @@
   if (!name.empty()) {
     output.resize(output.size() + name.size());
 
-    memcpy(&output[0] + uuidNamespace.size(), name.c_str(), name.size());
+    memcpy(output.data() + uuidNamespace.size(), name.c_str(), name.size());
   }
 }
 
@@ -59,7 +59,7 @@
   memcpy(uuid, digest, 16);
 
   uuid[6] &= 0xF;
-  uuid[6] |= byte_t(version << 4);
+  uuid[6] |= static_cast<byte_t>(version << 4);
 
   uuid[8] &= 0x3F;
   uuid[8] |= 0x80;
@@ -118,7 +118,8 @@
   for (int i = 0; i < 2; ++i) {
     unsigned char rest = byte % 16;
     byte /= 16;
-    char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA));
+    char c = (rest < 0xA) ? static_cast<char>('0' + rest)
+                          : static_cast<char>('a' + (rest - 0xA));
     result.at(1 - i) = c;
   }
 
@@ -143,7 +144,7 @@
       return false;
     }
 
-    output.push_back(char(c1 << 4 | c2));
+    output.push_back(static_cast<char>(c1 << 4 | c2));
   }
 
   return true;
@@ -152,15 +153,15 @@
 bool cmUuid::IntFromHexDigit(char input, char& output) const
 {
   if (input >= '0' && input <= '9') {
-    output = char(input - '0');
+    output = static_cast<char>(input - '0');
     return true;
   }
   if (input >= 'a' && input <= 'f') {
-    output = char(input - 'a' + 0xA);
+    output = static_cast<char>(input - 'a' + 0xA);
     return true;
   }
   if (input >= 'A' && input <= 'F') {
-    output = char(input - 'A' + 0xA);
+    output = static_cast<char>(input - 'A' + 0xA);
     return true;
   }
   return false;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 1739b5a..60b89df 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3356,6 +3356,43 @@
     }
   }
 
+  // Get includes for this target
+  if (!this->LangForClCompile.empty()) {
+    auto includeList = this->GetIncludes(configName, this->LangForClCompile);
+
+    auto sysIncludeFlag = this->Makefile->GetDefinition(
+      cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", this->LangForClCompile));
+
+    if (sysIncludeFlag) {
+      bool gotOneSys = false;
+      for (auto i : includeList) {
+        cmSystemTools::ConvertToUnixSlashes(i);
+        if (this->GeneratorTarget->IsSystemIncludeDirectory(
+              i, configName, this->LangForClCompile)) {
+          auto flag = cmTrimWhitespace(*sysIncludeFlag);
+          if (this->MSTools) {
+            cmSystemTools::ReplaceString(flag, "-external:I", "/external:I");
+          }
+          clOptions.AppendFlagString("AdditionalOptions",
+                                     cmStrCat(flag, " \"", i, '"'));
+          gotOneSys = true;
+        } else {
+          clOptions.AddInclude(i);
+        }
+      }
+
+      if (gotOneSys) {
+        if (auto sysIncludeFlagWarning = this->Makefile->GetDefinition(
+              cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", this->LangForClCompile,
+                       "_WARNING"))) {
+          flags = cmStrCat(flags, ' ', *sysIncludeFlagWarning);
+        }
+      }
+    } else {
+      clOptions.AddIncludes(includeList);
+    }
+  }
+
   clOptions.Parse(flags);
   clOptions.Parse(defineFlags);
   std::vector<std::string> targetDefines;
@@ -3382,12 +3419,6 @@
     clOptions.AppendFlag("DefineConstants", targetDefines);
   }
 
-  // Get includes for this target
-  if (!this->LangForClCompile.empty()) {
-    clOptions.AddIncludes(
-      this->GetIncludes(configName, this->LangForClCompile));
-  }
-
   if (this->MSTools) {
     clOptions.SetVerboseMakefile(
       this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx
index 0811bd0..e4ad9b4 100644
--- a/Source/cmXMLWriter.cxx
+++ b/Source/cmXMLWriter.cxx
@@ -10,10 +10,6 @@
   : Output(output)
   , IndentationElement(1, '\t')
   , Level(level)
-  , Indent(0)
-  , ElementOpen(false)
-  , BreakAttrib(false)
-  , IsContent(false)
 {
 }
 
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index 6e8eeb7..49fc864 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -124,10 +124,10 @@
   std::stack<std::string, std::vector<std::string>> Elements;
   std::string IndentationElement;
   std::size_t Level;
-  std::size_t Indent;
-  bool ElementOpen;
-  bool BreakAttrib;
-  bool IsContent;
+  std::size_t Indent = 0;
+  bool ElementOpen = false;
+  bool BreakAttrib = false;
+  bool IsContent = false;
 };
 
 class cmXMLElement; // IWYU pragma: keep
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index a8dc963..d9ae75a 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1086,6 +1086,14 @@
                   << "uninitialized variables.\n";
         state->SetCheckSystemVars(true);
         return true;
+      } },
+    CommandArgument{
+      "--compile-no-warning-as-error", CommandArgument::Values::Zero,
+      [](std::string const&, cmake* state) -> bool {
+        std::cout << "Ignoring COMPILE_WARNING_AS_ERROR target property and "
+                  << "CMAKE_COMPILE_WARNING_AS_ERROR variable.\n";
+        state->SetIgnoreWarningAsError(true);
+        return true;
       } }
   };
 
@@ -2543,7 +2551,7 @@
                           const char* helpString, int type)
 {
   this->State->AddCacheEntry(key, value, helpString,
-                             cmStateEnums::CacheEntryType(type));
+                             static_cast<cmStateEnums::CacheEntryType>(type));
   this->UnwatchUnusedCli(key);
 
   if (key == "CMAKE_WARN_DEPRECATED"_s) {
diff --git a/Source/cmake.h b/Source/cmake.h
index c2bbff7..3c6af17 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -534,6 +534,8 @@
   void SetWarnUnusedCli(bool b) { this->WarnUnusedCli = b; }
   bool GetCheckSystemVars() const { return this->CheckSystemVars; }
   void SetCheckSystemVars(bool b) { this->CheckSystemVars = b; }
+  bool GetIgnoreWarningAsError() const { return this->IgnoreWarningAsError; }
+  void SetIgnoreWarningAsError(bool b) { this->IgnoreWarningAsError = b; }
 
   void MarkCliAsUsed(const std::string& variable);
 
@@ -686,6 +688,7 @@
   bool WarnUninitialized = false;
   bool WarnUnusedCli = true;
   bool CheckSystemVars = false;
+  bool IgnoreWarningAsError = false;
   std::map<std::string, bool> UsedCliVariables;
   std::string CMakeEditCommand;
   std::string CXXEnvironment;
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 41c6c12..97c275e 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -111,6 +111,9 @@
   { "--check-system-vars",
     "Find problems with variable usage in system "
     "files." },
+  { "--compile-no-warning-as-error",
+    "Ignore COMPILE_WARNING_AS_ERROR property and "
+    "CMAKE_COMPILE_WARNING_AS_ERROR variable." },
 #  if !defined(CMAKE_BOOTSTRAP)
   { "--profiling-format=<fmt>",
     "Output data for profiling CMake scripts. Supported formats: "
@@ -406,7 +409,7 @@
     } else if (numJobs > INT_MAX) {
       std::cerr << "The <jobs> value is too large.\n\n";
     } else {
-      jobs = int(numJobs);
+      jobs = static_cast<int>(numJobs);
     }
   } else {
     std::cerr << "'" << command << "' invalid number '" << jobString
@@ -591,7 +594,7 @@
                          "is too large.\n\n";
             dir.clear();
           } else {
-            jobs = int(numJobs);
+            jobs = static_cast<int>(numJobs);
           }
         } else {
           std::cerr << "'CMAKE_BUILD_PARALLEL_LEVEL' environment variable\n"
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index df740c9..9ab39f1 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2069,8 +2069,8 @@
 {
   int Type;
   bool Verbose;
-  bool Incremental;
-  bool LinkGeneratesManifest;
+  bool Incremental = false;
+  bool LinkGeneratesManifest = true;
   std::vector<std::string> LinkCommand;
   std::vector<std::string> UserManifests;
   std::string LinkerManifestFile;
@@ -2085,8 +2085,6 @@
   cmVSLink(int type, bool verbose)
     : Type(type)
     , Verbose(verbose)
-    , Incremental(false)
-    , LinkGeneratesManifest(true)
   {
   }
   bool Parse(std::vector<std::string>::const_iterator argBeg,
diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx
index 0ebe00e..0585774 100644
--- a/Tests/CMakeLib/run_compile_commands.cxx
+++ b/Tests/CMakeLib/run_compile_commands.cxx
@@ -115,7 +115,7 @@
 
   void Next()
   {
-    this->C = char(this->Input.get());
+    this->C = static_cast<char>(this->Input.get());
     if (this->Input.bad()) {
       this->ErrorExit("Unexpected end of file.");
     }
diff --git a/Tests/FindVulkan/Test/CMakeLists.txt b/Tests/FindVulkan/Test/CMakeLists.txt
index 7ae8a11..42543ac 100644
--- a/Tests/FindVulkan/Test/CMakeLists.txt
+++ b/Tests/FindVulkan/Test/CMakeLists.txt
@@ -1,28 +1,80 @@
 cmake_minimum_required(VERSION 3.4)
+cmake_policy(SET CMP0091 NEW)
 project(TestFindVulkan C CXX)
 include(CTest)
 
-SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../)
-find_package(Vulkan REQUIRED)
+set(components
+  glslang
+  shaderc_combined
+  SPIRV-Tools
+)
+if(APPLE)
+  list(APPEND components MoltenVK)
+endif()
+find_package(Vulkan REQUIRED
+  COMPONENTS ${components})
 
 add_executable(test_tgt main.c)
 target_link_libraries(test_tgt Vulkan::Vulkan)
+target_compile_features(test_tgt PRIVATE cxx_std_11)
 add_test(NAME test_tgt COMMAND test_tgt)
 
 add_executable(test_var main.c)
 target_include_directories(test_var PRIVATE ${Vulkan_INCLUDE_DIRS})
 target_link_libraries(test_var PRIVATE ${Vulkan_LIBRARIES})
+target_compile_features(test_var PRIVATE cxx_std_11)
 add_test(NAME test_var COMMAND test_var)
 
 add_executable(test_tgt_dl main-dynamicVulkanLoading.cpp)
 target_link_libraries(test_tgt_dl Vulkan::Headers ${CMAKE_DL_LIBS})
+target_compile_features(test_tgt_dl PRIVATE cxx_std_11)
 add_test(NAME test_tgt_dl COMMAND test_tgt_dl)
 
 add_executable(test_var_dl main-dynamicVulkanLoading.cpp)
 target_include_directories(test_var_dl PRIVATE ${Vulkan_INCLUDE_DIRS})
 target_link_libraries(test_var_dl ${CMAKE_DL_LIBS})
+target_compile_features(test_var_dl PRIVATE cxx_std_11)
 add_test(NAME test_var_dl COMMAND test_var_dl)
 
+add_executable(test_tgt_glslang main-glslang.cxx)
+target_link_libraries(test_tgt_glslang Vulkan::glslang)
+add_test(NAME test_tgt_glslang COMMAND test_tgt_glslang)
+
+get_property(glslang_debug_location TARGET Vulkan::glslang PROPERTY IMPORTED_LOCATION_DEBUG)
+if(NOT glslang_debug_location)
+  set_property(TARGET test_tgt_glslang
+    PROPERTY
+      MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
+endif()
+
+add_executable(test_tgt_shaderc_combined main-shaderc_combined.cxx)
+target_link_libraries(test_tgt_shaderc_combined Vulkan::shaderc_combined)
+add_test(NAME test_tgt_shaderc_combined COMMAND test_tgt_shaderc_combined)
+
+get_property(shaderc_combined_debug_location TARGET Vulkan::shaderc_combined PROPERTY IMPORTED_LOCATION_DEBUG)
+if(NOT shaderc_combined_debug_location)
+  set_property(TARGET test_tgt_shaderc_combined
+    PROPERTY
+      MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
+endif()
+
+add_executable(test_tgt_SPIRV-Tools main-SPIRV-Tools.c)
+target_link_libraries(test_tgt_SPIRV-Tools Vulkan::SPIRV-Tools)
+add_test(NAME test_tgt_SPIRV-Tools COMMAND test_tgt_SPIRV-Tools)
+
+get_property(SPIRV-Tools_debug_location TARGET Vulkan::SPIRV-Tools PROPERTY IMPORTED_LOCATION_DEBUG)
+if(NOT SPIRV-Tools_debug_location)
+  set_property(TARGET test_tgt_SPIRV-Tools
+    PROPERTY
+      MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
+endif()
+
+if(APPLE)
+  add_executable(test_tgt_MoltenVK main-MoltenVK.cxx)
+  target_link_libraries(test_tgt_MoltenVK Vulkan::MoltenVK)
+  add_test(NAME test_tgt_MoltenVK COMMAND test_tgt_MoltenVK)
+endif()
+
 if(Vulkan_GLSLC_EXECUTABLE)
   add_test(NAME test_glslc
     COMMAND ${CMAKE_COMMAND}
diff --git a/Tests/FindVulkan/Test/main-MoltenVK.cxx b/Tests/FindVulkan/Test/main-MoltenVK.cxx
new file mode 100644
index 0000000..3156979
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-MoltenVK.cxx
@@ -0,0 +1,16 @@
+#include <iostream>
+
+#include <MoltenVK/vk_mvk_moltenvk.h>
+
+int main()
+{
+  char mvk_version[256];
+  char vk_version[256];
+  vkGetVersionStringsMVK(mvk_version, sizeof(mvk_version), vk_version,
+                         sizeof(vk_version));
+
+  std::cout << "MoltenVK version: " << mvk_version << std::endl;
+  std::cout << "Vulkan version: " << vk_version << std::endl;
+
+  return 0;
+}
diff --git a/Tests/FindVulkan/Test/main-SPIRV-Tools.c b/Tests/FindVulkan/Test/main-SPIRV-Tools.c
new file mode 100644
index 0000000..097198d
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-SPIRV-Tools.c
@@ -0,0 +1,15 @@
+#include <assert.h>
+#include <spirv-tools/libspirv.h>
+#include <stdio.h>
+
+int main()
+{
+  const char* spv_version = spvSoftwareVersionString();
+  const char* spv_details = spvSoftwareVersionDetailsString();
+  assert(spv_version);
+  assert(spv_details);
+
+  printf("SPIRV-Tools version: %s (details: %s)", spv_version, spv_details);
+
+  return 0;
+}
diff --git a/Tests/FindVulkan/Test/main-glslang.cxx b/Tests/FindVulkan/Test/main-glslang.cxx
new file mode 100644
index 0000000..81b18d6
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-glslang.cxx
@@ -0,0 +1,24 @@
+#include <cassert>
+#include <iostream>
+
+#include <glslang/Public/ShaderLang.h>
+
+int main()
+{
+  const glslang::Version glslang_version = glslang::GetVersion();
+  const char* glslang_essl_version = glslang::GetEsslVersionString();
+  const char* glslang_glsl_version = glslang::GetGlslVersionString();
+  const int glslang_khronos_tool_id = glslang::GetKhronosToolId();
+
+  std::cout << "glslang Version: " << glslang_version.major << '.'
+            << glslang_version.minor << '.' << glslang_version.patch
+            << " (glsl version: " << glslang_glsl_version
+            << ", essl version:" << glslang_essl_version
+            << ", khronos tool:" << glslang_khronos_tool_id << ')'
+            << std::endl;
+
+  assert(glslang_essl_version);
+  assert(glslang_glsl_version);
+
+  return 0;
+}
diff --git a/Tests/FindVulkan/Test/main-shaderc_combined.cxx b/Tests/FindVulkan/Test/main-shaderc_combined.cxx
new file mode 100644
index 0000000..30449fb
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-shaderc_combined.cxx
@@ -0,0 +1,14 @@
+#include <assert.h>
+#include <shaderc/shaderc.h>
+#include <stdio.h>
+
+int main()
+{
+  unsigned int shaderc_version, shaderc_revision;
+  shaderc_get_spv_version(&shaderc_version, &shaderc_revision);
+
+  printf("shaderc version: %u (revision: %u)", shaderc_version,
+         shaderc_revision);
+
+  return 0;
+}
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index 788c5be..bb4b92c 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -11,11 +11,11 @@
     OR CMAKE_C_COMPILER_ID STREQUAL AppleClang
     OR CMAKE_C_COMPILER_ID STREQUAL LCC
     OR ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" AND
-       CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3" AND
-       NOT CMAKE_GENERATOR MATCHES "Visual Studio")) # No support for VS generators yet.
+       CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3"))
     AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles"
       OR CMAKE_GENERATOR STREQUAL "Ninja"
-      OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)))
+      OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)
+      OR CMAKE_GENERATOR MATCHES "Visual Studio"))
   if ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC")
     set(run_sys_includes_test 1)
   else ()
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
index a746a68..e4973b0 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -23,7 +23,8 @@
 )
 
 add_library(config_specific INTERFACE)
-if(CMAKE_GENERATOR STREQUAL "Xcode")
+get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(isMultiConfig)
   # CMAKE_BUILD_TYPE does not work here for multi-config generators
   target_include_directories(config_specific SYSTEM INTERFACE
     "${CMAKE_CURRENT_SOURCE_DIR}/config_specific"
diff --git a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
index daf8a2d..5c6c8d8 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
+++ b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
@@ -89,7 +89,8 @@
       return 1;
     }
     int resourceGroupCount = std::atoi(resourceGroupCountEnv);
-    if (resourceGroups.size() != std::size_t(resourceGroupCount)) {
+    if (resourceGroups.size() !=
+        static_cast<std::size_t>(resourceGroupCount)) {
       std::cout
         << "CTEST_RESOURCE_GROUP_COUNT does not match expected resource groups"
         << std::endl
diff --git a/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake b/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake
index 059c80f..a532f72 100644
--- a/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake
@@ -3,10 +3,11 @@
 function(run_compile_warn test)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   set(RunCMake_TEST_OUTPUT_MERGE 1)
-  run_cmake(${test})
+  run_cmake_with_options(${test} ${ARGN})
   set(RunCMake_TEST_NO_CLEAN 1)
   run_cmake_command(${test}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
 endfunction()
 
 run_compile_warn(WerrorOn)
 run_compile_warn(WerrorOff)
+run_compile_warn(WerrorOnIgnore "--compile-no-warning-as-error")
diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake
new file mode 100644
index 0000000..1f7ccdb
--- /dev/null
+++ b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake
@@ -0,0 +1,8 @@
+enable_language(CXX)
+
+include(WarningAsErrorOptions.cmake)
+get_warning_options(warning_options)
+
+add_executable(WerrorOn warn.cxx)
+target_compile_options(WerrorOn PUBLIC "${warning_options}")
+set_target_properties(WerrorOn PROPERTIES COMPILE_WARNING_AS_ERROR ON)
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
index d697fc6..04286cc 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_IMPORTED_TARGET.cmake
@@ -1,40 +1,59 @@
-cmake_minimum_required(VERSION 3.12)
+cmake_minimum_required(VERSION 3.17)
 
 project(FindPkgConfig_IMPORTED_TARGET C)
 
+set(shared_lib_prefix "")
+set(shared_lib_suffix ".lib")
+set(static_lib_prefix "lib")
+set(static_lib_suffix ".a")
+
+set(CMAKE_SHARED_LIBRARY_PREFIX ${shared_lib_prefix})
+set(CMAKE_SHARED_LIBRARY_SUFFIX ${shared_lib_suffix})
+set(CMAKE_STATIC_LIBRARY_PREFIX ${static_lib_prefix})
+set(CMAKE_STATIC_LIBRARY_SUFFIX ${static_lib_suffix})
+
 find_package(PkgConfig REQUIRED)
-pkg_check_modules(NCURSES IMPORTED_TARGET QUIET ncurses)
 
-message(STATUS "source: ${CMAKE_CURRENT_SOURCE_DIR} bin ${CMAKE_CURRENT_BINARY_DIR}")
+# to test multiple variations, we must pick unique prefix names (same-named targets are cached for re-use)
+set(prefix_uniquifiers 0 1)
+# whether to apply STATIC_TARGET argument
+set(static_target_args "" STATIC_TARGET)
+foreach (prefix_uniquifier static_target_arg IN ZIP_LISTS prefix_uniquifiers static_target_args)
+  set(prefix "NCURSES${prefix_uniquifier}")
+  message(STATUS "static_target_arg: ${static_target_arg}")
+  pkg_check_modules(${prefix} IMPORTED_TARGET QUIET ${static_target_arg} ncurses)
 
-if (NCURSES_FOUND)
-  set(tgt PkgConfig::NCURSES)
-  if (NOT TARGET ${tgt})
-    message(FATAL_ERROR "FindPkgConfig found ncurses, but did not create an imported target for it")
-  endif ()
-  set(prop_found FALSE)
-  foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES INTERFACE_COMPILE_OPTIONS)
-    get_target_property(value ${tgt} ${prop})
-    if (value)
-      message(STATUS "Found property ${prop} on target: ${value}")
-      set(prop_found TRUE)
+  message(STATUS "source: ${CMAKE_CURRENT_SOURCE_DIR} bin ${CMAKE_CURRENT_BINARY_DIR}")
+
+  if (${prefix}_FOUND)
+    set(tgt PkgConfig::${prefix})
+    message(STATUS "Verifying target \"${tgt}\"")
+    if (NOT TARGET ${tgt})
+      message(FATAL_ERROR "FindPkgConfig found ncurses, but did not create an imported target for it")
     endif ()
-  endforeach ()
-  if (NOT prop_found)
-    message(FATAL_ERROR "target ${tgt} found, but it has no properties")
+    set(prop_found FALSE)
+    foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES INTERFACE_COMPILE_OPTIONS)
+      get_target_property(value ${tgt} ${prop})
+      if (value)
+        message(STATUS "Found property ${prop} on target: ${value}")
+        set(prop_found TRUE)
+      endif ()
+    endforeach ()
+    if (NOT prop_found)
+      message(FATAL_ERROR "target ${tgt} found, but it has no properties")
+    endif ()
+  else ()
+    message(STATUS "skipping test; ncurses not found")
   endif ()
-else ()
-  message(STATUS "skipping test; ncurses not found")
-endif ()
-
+endforeach ()
 
 # Setup for the remaining package tests below
 set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH)
 set(fakePkgDir ${CMAKE_CURRENT_BINARY_DIR}/pc-fakepackage)
 foreach(i 1 2)
   set(pname cmakeinternalfakepackage${i})
-  file(WRITE ${fakePkgDir}/lib/lib${pname}.a "")
-  file(WRITE ${fakePkgDir}/lib/${pname}.lib  "")
+  file(WRITE ${fakePkgDir}/lib/${static_lib_prefix}${pname}${static_lib_suffix} "")
+  file(WRITE ${fakePkgDir}/lib/${shared_lib_prefix}${pname}${shared_lib_suffix} "")
   file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
 "Name: CMakeInternalFakePackage${i}
 Description: Dummy package (${i}) for FindPkgConfig IMPORTED_TARGET test
@@ -49,12 +68,15 @@
 
 # find targets in subdir and check their visibility
 add_subdirectory(target_subdir)
-if (TARGET PkgConfig::FakePackage1_dir)
-  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_dir is visible outside it's directory")
+
+set(tgt PkgConfig::FakePackage1_dir)
+if (TARGET ${tgt})
+  message(FATAL_ERROR "imported target \"${tgt}\" is visible outside its directory")
 endif()
 
-if (NOT TARGET PkgConfig::FakePackage1_global)
-  message(FATAL_ERROR "imported target PkgConfig::FakePackage1_global is not visible outside it's directory")
+set(tgt PkgConfig::FakePackage1_global)
+if (NOT TARGET ${tgt})
+  message(FATAL_ERROR "imported target \"${tgt}\" is not visible outside its directory")
 endif()
 
 # And now do the same for the NO_CMAKE_ENVIRONMENT_PATH - ENV{CMAKE_PREFIX_PATH}
@@ -63,35 +85,52 @@
 unset(ENV{CMAKE_PREFIX_PATH})
 set(ENV{CMAKE_PREFIX_PATH} ${fakePkgDir})
 
-pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
-if (NOT TARGET PkgConfig::FakePackage2)
-  message(FATAL_ERROR "No import target for fake package 2 with prefix path")
-endif()
 
-# check that 2 library entries exist
-list(LENGTH FakePackage2_LINK_LIBRARIES fp2_nlibs)
-if (NOT fp2_nlibs EQUAL 2)
-  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has ${fp2_nlibs} entries but should have exactly 2")
-endif()
+# to test multiple variations, we must pick unique prefix names (same-named targets are cached for re-use)
+set(prefix_uniquifiers 0 1)
+# whether to apply STATIC_TARGET argument
+set(static_target_args "" STATIC_TARGET)
+# whether target properties are populated from the unqualified (i.e. shared library) series of vars, or the STATIC_ series of vars
+set(target_var_qualifiers "" STATIC_)
+set(lib_types shared static)
+foreach (prefix_uniquifier static_target_arg target_var_qualifier lib_type IN ZIP_LISTS prefix_uniquifiers static_target_args target_var_qualifiers lib_types)
+  set(prefix "FakePackage2${prefix_uniquifier}")
+  set(tgt "PkgConfig::${prefix}")
+  pkg_check_modules(${prefix} REQUIRED QUIET IMPORTED_TARGET ${static_target_arg} cmakeinternalfakepackage2)
 
-# check that the full library path is also returned
-list(GET FakePackage2_LINK_LIBRARIES 0 fp2_lib0)
-if (NOT fp2_lib0 STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a")
-  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
-endif()
+  message(STATUS "Verifying library path resolution for lib type \"${lib_type}\"")
+  if (NOT TARGET ${tgt})
+    message(FATAL_ERROR "No import target for fake package 2 with prefix path")
+  endif()
 
-# check that the library that couldn't be found still shows up
-list(GET FakePackage2_LINK_LIBRARIES 1 fp2_lib1)
-if (NOT fp2_lib1 STREQUAL "cmakeinternalfakepackage2-doesnotexist")
-  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on first run: ${FakePackage2_LINK_LIBRARIES}")
-endif()
+  set(link_libraries_var ${prefix}_${target_var_qualifier}LINK_LIBRARIES)
+  # check that 2 library entries exist
+  list(LENGTH ${link_libraries_var} fp2_nlibs)
+  if (NOT fp2_nlibs EQUAL 2)
+    message(FATAL_ERROR "${link_libraries_var} has ${fp2_nlibs} entries but should have exactly 2")
+  endif()
 
-# the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run
-unset(FakePackage2_LINK_LIBRARIES)
-pkg_check_modules(FakePackage2 REQUIRED QUIET IMPORTED_TARGET cmakeinternalfakepackage2)
-if (NOT FakePackage2_LINK_LIBRARIES STREQUAL "${fakePkgDir}/lib/libcmakeinternalfakepackage2.a;cmakeinternalfakepackage2-doesnotexist")
-  message(FATAL_ERROR "FakePackage2_LINK_LIBRARIES has bad content on second run: ${FakePackage2_LINK_LIBRARIES}")
-endif()
+  set(lib_leafname ${${lib_type}_lib_prefix}cmakeinternalfakepackage2${${lib_type}_lib_suffix})
+  message(STATUS "Expecting library leafname \"${lib_leafname}\"")
+  # check that the full library path is also returned
+  list(GET ${link_libraries_var} 0 fp2_lib0)
+  if (NOT fp2_lib0 STREQUAL "${fakePkgDir}/lib/${lib_leafname}")
+    message(FATAL_ERROR "${link_libraries_var} has bad content on first run: ${${link_libraries_var}}")
+  endif()
+
+  # check that the library that couldn't be found still shows up
+  list(GET ${link_libraries_var} 1 fp2_lib1)
+  if (NOT fp2_lib1 STREQUAL "cmakeinternalfakepackage2-doesnotexist")
+    message(FATAL_ERROR "${link_libraries_var} has bad content on first run: ${${link_libraries_var}}")
+  endif()
+
+  # the information in *_LINK_LIBRARIES is not cached, so ensure is also is present on second run
+  unset(${link_libraries_var})
+  pkg_check_modules(${prefix} REQUIRED QUIET IMPORTED_TARGET ${static_target_arg} cmakeinternalfakepackage2)
+  if (NOT ${link_libraries_var} STREQUAL "${fakePkgDir}/lib/${lib_leafname};cmakeinternalfakepackage2-doesnotexist")
+    message(FATAL_ERROR "${link_libraries_var} has bad content on second run: ${${link_libraries_var}}")
+  endif()
+endforeach()
 
 set(pname fakelinkoptionspackage)
 file(WRITE ${fakePkgDir}/lib/pkgconfig/${pname}.pc
@@ -104,10 +143,13 @@
 
 set(expected_link_options -e dummy_main)
 pkg_check_modules(FakeLinkOptionsPackage REQUIRED QUIET IMPORTED_TARGET fakelinkoptionspackage)
-if (NOT TARGET PkgConfig::FakeLinkOptionsPackage)
+
+set(tgt PkgConfig::FakeLinkOptionsPackage)
+message(STATUS "Verifying target \"${tgt}\"")
+if (NOT TARGET ${tgt})
   message(FATAL_ERROR "No import target for fake link options package")
 endif()
-get_target_property(link_options PkgConfig::FakeLinkOptionsPackage INTERFACE_LINK_OPTIONS)
+get_target_property(link_options ${tgt} INTERFACE_LINK_OPTIONS)
 if (NOT link_options STREQUAL expected_link_options)
   message(FATAL_ERROR
     "Additional link options not present in INTERFACE_LINK_OPTIONS property\n"
@@ -115,7 +157,7 @@
   )
 endif()
 
-get_target_property(inc_dirs PkgConfig::FakeLinkOptionsPackage INTERFACE_INCLUDE_DIRECTORIES)
+get_target_property(inc_dirs ${tgt} INTERFACE_INCLUDE_DIRECTORIES)
 set(expected_inc_dirs "/special" "/other" "/more")
 
 if (NOT inc_dirs STREQUAL expected_inc_dirs)
@@ -125,7 +167,7 @@
   )
 endif ()
 
-get_target_property(c_opts PkgConfig::FakeLinkOptionsPackage INTERFACE_COMPILE_OPTIONS)
+get_target_property(c_opts ${tgt} INTERFACE_COMPILE_OPTIONS)
 set(expected_c_opts "-DA-isystem/foo") # this is an invalid option, but a good testcase
 if (NOT c_opts STREQUAL expected_c_opts)
     message(FATAL_ERROR
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
index 6615d80..8966ac3 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
@@ -1,3 +1,6 @@
 -- ZOT_LIBRARIES='zot'
--- ZOT_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/zot/lib/prefix-zot-suffix'
--- ZOT_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/zot/lib;-lzot'
+-- ZOT_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib/dyprefix-zot-dysuffix'
+-- ZOT_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib;-lzot'
+-- ZOT_STATIC_LIBRARIES='zot'
+-- ZOT_STATIC_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib/stprefix-zot-stsuffix'
+-- ZOT_STATIC_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/root/lib;-lzot'
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
index 9f654b5..536addc 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
@@ -1,29 +1,47 @@
 find_package(PkgConfig REQUIRED)
 
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/pkgconfig/zot.pc" "
-prefix=${CMAKE_CURRENT_BINARY_DIR}/zot
+set(ROOT "${CMAKE_CURRENT_BINARY_DIR}/root")
+string(REPLACE " " "\\ " ESCAPED_ROOT "${ROOT}")
+set(LIB_DIR "${ROOT}/lib")
+set(PKGCONFIG_DIR "${LIB_DIR}/pkgconfig")
+
+file(WRITE "${PKGCONFIG_DIR}/zot.pc" "
+prefix=${ESCAPED_ROOT}
 libdir=\${prefix}/lib
 
 Name: Zot
-Description: Dummy packaget to test LIBRARY_DIR support
+Description: Dummy package to test LIBRARY_DIR support
 Version: 1.0
 Libs: -L\${libdir} -lzot
 ")
 
+set(shared_lib_prefix "dyprefix-")
+set(shared_lib_suffix "-dysuffix")
+set(static_lib_prefix "stprefix-")
+set(static_lib_suffix "-stsuffix")
+
+set(CMAKE_SHARED_LIBRARY_PREFIX ${shared_lib_prefix})
+set(CMAKE_SHARED_LIBRARY_SUFFIX ${shared_lib_suffix})
+set(CMAKE_STATIC_LIBRARY_PREFIX ${static_lib_prefix})
+set(CMAKE_STATIC_LIBRARY_SUFFIX ${static_lib_suffix})
+
 # Create a "library" file to find in libdir.
-set(CMAKE_FIND_LIBRARY_PREFIXES "prefix-")
-set(CMAKE_FIND_LIBRARY_SUFFIXES "-suffix")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/prefix-zot-suffix")
+foreach(variant shared static)
+  file(WRITE "${LIB_DIR}/${${variant}_lib_prefix}zot${${variant}_lib_suffix}")
+endforeach()
 
 # 'pkg-config --libs' drops -L flags in PKG_CONFIG_SYSTEM_LIBRARY_PATH by default.
-set(ENV{PKG_CONFIG_SYSTEM_LIBRARY_PATH} "${CMAKE_CURRENT_BINARY_DIR}/zot/lib")
+set(ENV{PKG_CONFIG_SYSTEM_LIBRARY_PATH} "${LIB_DIR}")
 
 # 'pkgconf --libs' also drops -L flags in LIBRARY_PATH by default.
-set(ENV{LIBRARY_PATH}                   "${CMAKE_CURRENT_BINARY_DIR}/zot/lib")
+set(ENV{LIBRARY_PATH}                   "${LIB_DIR}")
 
-set(ENV{PKG_CONFIG_PATH}                "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/pkgconfig")
+set(ENV{PKG_CONFIG_PATH}                "${PKGCONFIG_DIR}")
 pkg_check_modules(ZOT REQUIRED zot)
 
 message(STATUS "ZOT_LIBRARIES='${ZOT_LIBRARIES}'")
 message(STATUS "ZOT_LINK_LIBRARIES='${ZOT_LINK_LIBRARIES}'")
 message(STATUS "ZOT_LDFLAGS='${ZOT_LDFLAGS}'")
+message(STATUS "ZOT_STATIC_LIBRARIES='${ZOT_STATIC_LIBRARIES}'")
+message(STATUS "ZOT_STATIC_LINK_LIBRARIES='${ZOT_STATIC_LINK_LIBRARIES}'")
+message(STATUS "ZOT_STATIC_LDFLAGS='${ZOT_STATIC_LDFLAGS}'")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-stdout.txt
new file mode 100644
index 0000000..edf0262
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-stdout.txt
@@ -0,0 +1,6 @@
+-- IMM_LIBRARIES='imm'
+-- IMM_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-build/root/lib/dyprefix-imm-dysuffix'
+-- IMM_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-build/root/lib;-limm'
+-- IMM_STATIC_LIBRARIES='imm;trns'
+-- IMM_STATIC_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-build/root/lib/stprefix-imm-stsuffix;[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-build/root/lib/stprefix-trns-stsuffix'
+-- IMM_STATIC_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES-build/root/lib;-limm;-ltrns'
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES.cmake
new file mode 100644
index 0000000..bf4ee1e
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LINK_LIBRARIES.cmake
@@ -0,0 +1,53 @@
+find_package(PkgConfig REQUIRED)
+
+set(ROOT "${CMAKE_CURRENT_BINARY_DIR}/root")
+string(REPLACE " " "\\ " ESCAPED_ROOT "${ROOT}")
+set(LIB_DIR "${ROOT}/lib")
+set(PKGCONFIG_DIR "${LIB_DIR}/pkgconfig")
+
+file(WRITE "${PKGCONFIG_DIR}/imm.pc" "
+prefix=${ESCAPED_ROOT}
+libdir=\${prefix}/lib
+
+Name: Immediate
+Description: Dummy package to test *LINK_LIBRARIES support
+Version: 1.0
+Libs: -L\${libdir} -limm
+Libs.private: -ltrns
+")
+file(WRITE "${PKGCONFIG_DIR}/trns.pc" "
+prefix=${ESCAPED_ROOT}
+libdir=\${prefix}/lib
+
+Name: Transitive
+Description: Dummy package to test *LINK_LIBRARIES support
+Version: 1.0
+Libs: -L\${libdir} -ltrns
+")
+
+set(shared_lib_prefix "dyprefix-")
+set(shared_lib_suffix "-dysuffix")
+set(static_lib_prefix "stprefix-")
+set(static_lib_suffix "-stsuffix")
+
+set(CMAKE_SHARED_LIBRARY_PREFIX ${shared_lib_prefix})
+set(CMAKE_SHARED_LIBRARY_SUFFIX ${shared_lib_suffix})
+set(CMAKE_STATIC_LIBRARY_PREFIX ${static_lib_prefix})
+set(CMAKE_STATIC_LIBRARY_SUFFIX ${static_lib_suffix})
+
+# Create "library" files to find in libdir.
+foreach(lib imm trns)
+  foreach(variant shared static)
+    file(WRITE "${LIB_DIR}/${${variant}_lib_prefix}${lib}${${variant}_lib_suffix}")
+  endforeach()
+endforeach()
+
+set(ENV{PKG_CONFIG_PATH}                "${PKGCONFIG_DIR}")
+pkg_check_modules(IMM REQUIRED imm)
+
+message(STATUS "IMM_LIBRARIES='${IMM_LIBRARIES}'")
+message(STATUS "IMM_LINK_LIBRARIES='${IMM_LINK_LIBRARIES}'")
+message(STATUS "IMM_LDFLAGS='${IMM_LDFLAGS}'")
+message(STATUS "IMM_STATIC_LIBRARIES='${IMM_STATIC_LIBRARIES}'")
+message(STATUS "IMM_STATIC_LINK_LIBRARIES='${IMM_STATIC_LINK_LIBRARIES}'")
+message(STATUS "IMM_STATIC_LDFLAGS='${IMM_STATIC_LDFLAGS}'")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
index 5501d9f..6c838a9 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
@@ -1,3 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+
 # Prepare environment to reuse bletch.pc
 file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-bletch/lib/pkgconfig" PC_PATH)
 if(UNIX)
@@ -6,24 +8,41 @@
 set(ENV{PKG_CONFIG_PATH} "${PC_PATH}")
 
 find_package(PkgConfig REQUIRED)
-pkg_check_modules(Bletch IMPORTED_TARGET REQUIRED bletch-framework)
 
-if (Bletch_LDFLAGS_OTHER)
-  message(SEND_ERROR "Bletch_LDFLAGS_OTHER should be empty, but is '${Bletch_LDFLAGS_OTHER}'")
-endif ()
+# to test multiple variations, we must pick unique prefix names (same-named targets are cached for re-use)
+set(prefix_uniquifiers 0 1)
+# whether to apply STATIC_TARGET argument
+set(static_target_args "" STATIC_TARGET)
+# whether target properties are populated from the unqualified (i.e. shared library) series of vars, or the STATIC_ series of vars
+set(target_var_qualifiers "" STATIC_)
+foreach (prefix_uniquifier static_target_arg target_var_qualifier IN ZIP_LISTS prefix_uniquifiers static_target_args target_var_qualifiers)
+  set(prefix "Bletch${prefix_uniquifier}")
+  set(tgt "PkgConfig::${prefix}")
+  pkg_check_modules(${prefix} IMPORTED_TARGET REQUIRED ${static_target_arg} bletch-framework)
+  foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_OPTIONS INTERFACE_COMPILE_OPTIONS)
+    get_target_property(prop_value ${tgt} ${prop})
+    if (prop_value)
+      message(SEND_ERROR "target property ${prop} should not be set, but is '${prop_value}'")
+    endif ()
+  endforeach ()
 
-if (NOT Bletch_LINK_LIBRARIES STREQUAL "-framework foo;-framework bar;bletch;-framework baz")
-  message(SEND_ERROR "Bletch_LINK_LIBRARIES has wrong value '${Bletch_LINK_LIBRARIES}'")
-endif ()
-
-foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_OPTIONS INTERFACE_COMPILE_OPTIONS)
-  get_target_property(prop_value PkgConfig::Bletch ${prop})
-  if (prop_value)
-    message(SEND_ERROR "target property ${prop} should not be set, but is '${prop_value}'")
+  # there is 1 target yet 2 series of variables.
+  # if STATIC_TARGET is set, then the target will follow the STATIC_ qualified series of variables
+  # (otherwise will follow the unqualified series of variables).
+  get_target_property(prop_value ${tgt} INTERFACE_LINK_LIBRARIES)
+  if (NOT prop_value STREQUAL ${prefix}_${target_var_qualifier}LINK_LIBRARIES)
+    message(SEND_ERROR "target property INTERFACE_LINK_LIBRARIES has wrong value '${prop_value}'")
   endif ()
-endforeach ()
 
-get_target_property(prop_value PkgConfig::Bletch INTERFACE_LINK_LIBRARIES)
-if (NOT prop_value STREQUAL Bletch_LINK_LIBRARIES)
-  message(SEND_ERROR "target property INTERFACE_LINK_LIBRARIES has wrong value '${prop_value}'")
-endif ()
+  foreach (var_qualifier IN ITEMS "" STATIC_)
+    set (ldflags_var ${prefix}_${var_qualifier}LDFLAGS_OTHER)
+    if (${ldflags_var})
+      message(SEND_ERROR "${ldflags_var} should be empty, but is '${${ldflags_var}}'")
+    endif ()
+
+    set (linklibs_var ${prefix}_${var_qualifier}LINK_LIBRARIES)
+    if (NOT ${linklibs_var} STREQUAL "-framework foo;-framework bar;bletch;-framework baz")
+      message(SEND_ERROR "${linklibs_var} has wrong value '${${linklibs_var}}'")
+    endif ()
+  endforeach()
+endforeach()
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index f36d1eb..f89b3b3 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -29,11 +29,9 @@
   run_cmake(FindPkgConfig_GET_VARIABLE_PKGCONFIG_PATH)
   run_cmake(FindPkgConfig_cache_variables)
   run_cmake(FindPkgConfig_IMPORTED_TARGET)
+  run_cmake(FindPkgConfig_LINK_LIBRARIES)
   run_cmake(FindPkgConfig_VERSION_OPERATORS)
   run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME)
   run_cmake(FindPkgConfig_empty_target)
-
-  if(NOT RunCMake_BINARY_DIR MATCHES " ")
-    run_cmake(FindPkgConfig_LIBRARY_PATH)
-  endif()
+  run_cmake(FindPkgConfig_LIBRARY_PATH)
 endif ()
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake
index 5ea02a5..9d5d0b5 100644
--- a/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetHostArchNone.cmake
@@ -6,8 +6,14 @@
   cmake_host_system_information(RESULT is_64_bit QUERY IS_64BIT)
   if(is_64_bit)
     if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
-      if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "")
-        message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not empty as expected.")
+      if(CMAKE_GENERATOR STREQUAL "Visual Studio 17 2022")
+        if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "ARM64")
+          message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not 'ARM64' as expected.")
+        endif()
+      else()
+        if(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "")
+          message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not empty as expected.")
+        endif()
       endif()
     elseif(NOT "${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}" STREQUAL "x64")
       message(FATAL_ERROR "CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE is not 'x64' as expected.")
diff --git a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
index 06d48bf..edc655b 100644
--- a/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VerifyHeaderSets/RunCMakeTest.cmake
@@ -9,34 +9,34 @@
   run_cmake_command(${name}-${target}-${BUILD_CONFIG}-build ${CMAKE_COMMAND} --build . --config ${BUILD_CONFIG} --target ${target})
 endfunction()
 
-set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_HEADER_SETS=ON)
+set(RunCMake_TEST_OPTIONS -DCMAKE_VERIFY_INTERFACE_HEADER_SETS=ON)
 if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
   list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
 endif()
 run_cmake(VerifyHeaderSets)
 unset(RunCMake_TEST_OPTIONS)
 
-run_cmake_build(VerifyHeaderSets static_verify_header_sets)
-run_cmake_build(VerifyHeaderSets shared_verify_header_sets)
-run_cmake_build(VerifyHeaderSets object_verify_header_sets)
-run_cmake_build(VerifyHeaderSets interface_verify_header_sets)
-run_cmake_build(VerifyHeaderSets exe_verify_header_sets)
-run_cmake_build(VerifyHeaderSets export_exe_verify_header_sets)
-run_cmake_build(VerifyHeaderSets none_verify_header_sets)
-run_cmake_build(VerifyHeaderSets property_off_verify_header_sets)
-run_cmake_build(VerifyHeaderSets private_verify_header_sets)
-run_cmake_build(VerifyHeaderSets a_h_verify_header_sets)
-run_cmake_build(VerifyHeaderSets dir_c_h_verify_header_sets)
-run_cmake_build(VerifyHeaderSets dir_cxx_h_verify_header_sets)
+run_cmake_build(VerifyHeaderSets static_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets shared_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets object_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets interface_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets exe_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets export_exe_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets none_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets property_off_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets private_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets a_h_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets dir_c_h_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets dir_cxx_h_verify_interface_header_sets)
 
 if(NOT RunCMake_GENERATOR STREQUAL "Xcode")
-  run_cmake_build(VerifyHeaderSets config_verify_header_sets)
+  run_cmake_build(VerifyHeaderSets config_verify_interface_header_sets)
   if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
     set(BUILD_CONFIG Release)
-    run_cmake_build(VerifyHeaderSets config_verify_header_sets)
+    run_cmake_build(VerifyHeaderSets config_verify_interface_header_sets)
     unset(BUILD_CONFIG)
   endif()
 endif()
 
-run_cmake_build(VerifyHeaderSets lang_test_c_verify_header_sets)
-run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_header_sets)
+run_cmake_build(VerifyHeaderSets lang_test_c_verify_interface_header_sets)
+run_cmake_build(VerifyHeaderSets lang_test_cxx_verify_interface_header_sets)
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-stdout.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_interface_header_sets-Debug-build-stdout.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
index 44e028f..100f482 100644
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
+++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-check.cmake
@@ -1,5 +1,5 @@
 function(check_file target filename)
-  set(full_filename "${RunCMake_TEST_BINARY_DIR}/${target}_verify_header_sets/${filename}")
+  set(full_filename "${RunCMake_TEST_BINARY_DIR}/${target}_verify_interface_header_sets/${filename}")
   if(NOT EXISTS "${full_filename}")
     string(APPEND RunCMake_TEST_FAILED "File ${full_filename} should exist but does not\n")
     set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Debug-build-stdout.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Debug-build-stdout.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-result.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-result.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_header_sets-Release-build-stdout.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-config_verify_interface_header_sets-Release-build-stdout.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_header_sets-Debug-build-stdout.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_c_h_verify_interface_header_sets-Debug-build-stdout.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-stdout.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_header_sets-Debug-build-stdout.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-dir_cxx_h_verify_interface_header_sets-Debug-build-stdout.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
rename from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt
rename to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt
deleted file mode 100644
index 8d98f9d..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_header_sets-Debug-build-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-.*
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-none_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt
deleted file mode 100644
index 8d98f9d..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_header_sets-Debug-build-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-.*
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-private_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt
deleted file mode 100644
index d197c91..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-[^0]
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt
deleted file mode 100644
index 8d98f9d..0000000
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_header_sets-Debug-build-stderr.txt
+++ /dev/null
@@ -1 +0,0 @@
-.*
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_interface_header_sets-Debug-build-result.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-a_h_verify_header_sets-Debug-build-result.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_interface_header_sets-Debug-build-result.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_interface_header_sets-Debug-build-stderr.txt
similarity index 100%
copy from Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-exe_verify_header_sets-Debug-build-stderr.txt
copy to Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets-property_off_verify_interface_header_sets-Debug-build-stderr.txt
diff --git a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
index f515031..24298df 100644
--- a/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
+++ b/Tests/RunCMake/VerifyHeaderSets/VerifyHeaderSets.cmake
@@ -27,7 +27,7 @@
 
 add_library(property_off STATIC lib.c)
 target_sources(property_off INTERFACE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
-set_property(TARGET property_off PROPERTY VERIFY_HEADER_SETS OFF)
+set_property(TARGET property_off PROPERTY VERIFY_INTERFACE_HEADER_SETS OFF)
 
 add_library(private STATIC lib.c)
 target_sources(private PRIVATE FILE_SET HEADERS FILES a.h dir/c.h dir/cxx.h)
diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake
index 48d8e1a..0b5fb8d 100644
--- a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake
+++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-all-check.cmake
@@ -1 +1 @@
-check_installed([[^empty1.txt;empty2.txt$]])
+check_installed([[^empty1.txt;empty3.txt$]])
diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake
index 48d8e1a..88e57e3 100644
--- a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake
+++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-dev-check.cmake
@@ -1 +1 @@
-check_installed([[^empty1.txt;empty2.txt$]])
+check_installed([[^empty1.txt;empty2.txt;empty3.txt$]])
diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake
index 48d8e1a..88e57e3 100644
--- a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake
+++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS-uns-check.cmake
@@ -1 +1 @@
-check_installed([[^empty1.txt;empty2.txt$]])
+check_installed([[^empty1.txt;empty2.txt;empty3.txt$]])
diff --git a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake
index aa3f9d1..73c4e35 100644
--- a/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake
+++ b/Tests/RunCMake/install/SCRIPT-ALL_COMPONENTS.cmake
@@ -1,5 +1,16 @@
+
 install(
   SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake"
+  ALL_COMPONENTS
+)
+
+install(
   CODE "write_empty_file(empty2.txt)"
   ALL_COMPONENTS
-  )
+  EXCLUDE_FROM_ALL
+)
+
+install(
+  CODE "write_empty_file(empty3.txt)"
+  ALL_COMPONENTS
+)
diff --git a/Tests/RunCMake/try_compile/CMP0137-Common.cmake b/Tests/RunCMake/try_compile/CMP0137-Common.cmake
new file mode 100644
index 0000000..2c1bc0d
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137-Common.cmake
@@ -0,0 +1,16 @@
+set(CMAKE_ENABLE_EXPORTS 1)
+set(FOO 2)
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES FOO)
+try_compile(RESULT_VAR
+  ${CMAKE_CURRENT_BINARY_DIR}/CMP0137-build
+  ${CMAKE_CURRENT_SOURCE_DIR}/CMP0137
+  TestCMP0137)
+include(${CMAKE_CURRENT_BINARY_DIR}/CMP0137-build/info.cmake OPTIONAL)
+
+message(STATUS "Enabling CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES")
+set(CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES 1)
+try_compile(RESULT_VAR
+  ${CMAKE_CURRENT_BINARY_DIR}/CMP0137-build2
+  ${CMAKE_CURRENT_SOURCE_DIR}/CMP0137
+  TestCMP0137)
+include(${CMAKE_CURRENT_BINARY_DIR}/CMP0137-build2/info.cmake OPTIONAL)
diff --git a/Tests/RunCMake/try_compile/CMP0137-NEW-stdout.txt b/Tests/RunCMake/try_compile/CMP0137-NEW-stdout.txt
new file mode 100644
index 0000000..abc61dc
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137-NEW-stdout.txt
@@ -0,0 +1,5 @@
+-- CMAKE_ENABLE_EXPORTS='1'
+-- FOO='2'
+-- Enabling CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
+-- CMAKE_ENABLE_EXPORTS=''
+-- FOO=''
diff --git a/Tests/RunCMake/try_compile/CMP0137-NEW.cmake b/Tests/RunCMake/try_compile/CMP0137-NEW.cmake
new file mode 100644
index 0000000..f7caa50
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137-NEW.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0137 NEW)
+include(CMP0137-Common.cmake)
diff --git a/Tests/RunCMake/try_compile/CMP0137-WARN-stdout.txt b/Tests/RunCMake/try_compile/CMP0137-WARN-stdout.txt
new file mode 100644
index 0000000..2e4bebe
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137-WARN-stdout.txt
@@ -0,0 +1,5 @@
+-- CMAKE_ENABLE_EXPORTS=''
+-- FOO=''
+-- Enabling CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
+-- CMAKE_ENABLE_EXPORTS=''
+-- FOO=''
diff --git a/Tests/RunCMake/try_compile/CMP0137-WARN.cmake b/Tests/RunCMake/try_compile/CMP0137-WARN.cmake
new file mode 100644
index 0000000..61b5641
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137-WARN.cmake
@@ -0,0 +1,2 @@
+# policy CMP0137 not set
+include(CMP0137-Common.cmake)
diff --git a/Tests/RunCMake/try_compile/CMP0137/CMakeLists.txt b/Tests/RunCMake/try_compile/CMP0137/CMakeLists.txt
new file mode 100644
index 0000000..a3b9fda
--- /dev/null
+++ b/Tests/RunCMake/try_compile/CMP0137/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.23)
+project(TestCMP0137 NONE)
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "
+message(STATUS \"CMAKE_ENABLE_EXPORTS='${CMAKE_ENABLE_EXPORTS}'\")
+message(STATUS \"FOO='${FOO}'\")
+")
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index dcd3799..eca7bf4 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -72,6 +72,8 @@
 run_cmake(CMP0056)
 run_cmake(CMP0066)
 run_cmake(CMP0067)
+run_cmake(CMP0137-WARN)
+run_cmake(CMP0137-NEW)
 
 if(RunCMake_GENERATOR MATCHES "Make|Ninja")
   # Use a single build tree for a few tests without cleaning.
diff --git a/Utilities/Release/README.rst b/Utilities/Release/README.rst
index dfaf831..770b579 100644
--- a/Utilities/Release/README.rst
+++ b/Utilities/Release/README.rst
@@ -91,3 +91,9 @@
 
 The ``macos/`` directory contains scripts used to produce dependencies
 for building CMake binaries on macOS.
+
+Windows
+-------
+
+The ``win/`` directory contains scripts used to produce dependencies
+for building CMake binaries on Windows.
diff --git a/Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch b/Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch
new file mode 100644
index 0000000..39a649e
--- /dev/null
+++ b/Utilities/Release/win/qt-5.12.1-win-x86-msvc-install.patch
@@ -0,0 +1,26 @@
+diff --git a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+index 04ec302..75d5596 100644
+--- a/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
++++ b/lib/cmake/Qt5Core/Qt5CoreConfig.cmake
+@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Core)
+     list(REMOVE_DUPLICATES Qt5Core_COMPILE_DEFINITIONS)
+     list(REMOVE_DUPLICATES Qt5Core_EXECUTABLE_COMPILE_FLAGS)
+ 
+-    set(_Qt5Core_LIB_DEPENDENCIES "")
++    set(_Qt5Core_LIB_DEPENDENCIES "${_qt5Core_install_prefix}/lib/qtpcre2.lib;netapi32.lib;version.lib")
+ 
+ 
+     add_library(Qt5::Core STATIC IMPORTED)
+diff --git a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
+index a07b953..2e07371 100644
+--- a/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
++++ b/lib/cmake/Qt5Widgets/Qt5WidgetsConfig.cmake
+@@ -118,7 +118,7 @@ if (NOT TARGET Qt5::Widgets)
+     list(REMOVE_DUPLICATES Qt5Widgets_COMPILE_DEFINITIONS)
+     list(REMOVE_DUPLICATES Qt5Widgets_EXECUTABLE_COMPILE_FLAGS)
+ 
+-    set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core")
++    set(_Qt5Widgets_LIB_DEPENDENCIES "Qt5::Gui;Qt5::Core;dwmapi.lib;uxtheme.lib")
+ 
+ 
+     add_library(Qt5::Widgets STATIC IMPORTED)
diff --git a/Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1 b/Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1
new file mode 100755
index 0000000..d9e9617
--- /dev/null
+++ b/Utilities/Release/win/qt-5.12.1-win-x86-msvc.ps1
@@ -0,0 +1,118 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Run this script on a Windows host to generate Qt binaries.
+# Set the PATH environment variable to contain the locations of cmake and git.
+
+param (
+  [string]$cmake = 'cmake',
+  [string]$git = 'git',
+  [switch]$trace
+)
+
+if ($trace -eq $true) {
+  Set-PSDebug -Trace 1
+}
+
+$ErrorActionPreference = 'Stop'
+$ProgressPreference = 'SilentlyContinue'
+
+if ($env:VSCMD_ARG_TGT_ARCH -eq "x64") {
+  $arch = "x86_64";
+} elseif ($env:VSCMD_ARG_TGT_ARCH -eq "x86") {
+  $arch = "i386";
+} else {
+  Write-Host "VSCMD_ARG_TGT_ARCH env var not recognized.  Run this from a Visual Studio Command Prompt."
+  exit 1
+}
+
+if ($env:VCToolsVersion -match '^(?<version>[0-9][0-9]\.[0-9])') {
+  $toolset = "msvc_v" + $Matches.version -replace '\.', ''
+} else {
+  Write-Host "VCToolsVersion env var not set.  Run this from a Visual Studio Command Prompt."
+}
+
+$srcname = "qt-everywhere-src-5.12.1"
+$pkgname = "qt-5.12.1-win-$arch-$toolset-1"
+$topdir = $pwd.Path
+$srcdir = Join-Path $topdir $srcname
+$blddir = Join-Path $topdir "$pkgname-build"
+$prefix = Join-Path $topdir $pkgname
+
+# JOM
+if ( -not (Test-Path -Path "jom")) {
+  Invoke-WebRequest -Uri "http://download.qt-project.org/official_releases/jom/unstable-jom.zip" -OutFile jom.zip
+  if ($(Get-FileHash "jom.zip").Hash -ne '128fdd846fe24f8594eed37d1d8929a0ea78df563537c0c1b1861a635013fff8') {
+      exit 1
+  }
+  Expand-Archive -Path jom.zip -DestinationPath jom
+  Remove-Item jom.zip
+}
+$jom = "$topdir\jom\jom.exe"
+
+# Qt Source
+if ( -not (Test-Path -Path $srcdir)) {
+  Invoke-WebRequest -Uri "https://download.qt.io/official_releases/qt/5.12/5.12.1/single/qt-everywhere-src-5.12.1.tar.xz" -OutFile qt.tar.xz
+  if ($(Get-FileHash "qt.tar.xz").Hash -ne 'caffbd625c7bc10ff8c5c7a27dbc7d84fa4de146975c0e1ffe904b514ccd6da4') {
+      exit 1
+  }
+  & $cmake -E tar xvf qt.tar.xz
+  Remove-Item qt.tar.xz
+}
+
+# Build Qt
+if ( -not (Test-Path -Path $blddir)) {
+  New-Item -ItemType Directory -Path $blddir
+  Set-Location -Path "$blddir"
+  & ..\$srcname\configure.bat `
+    -prefix $prefix `
+    -static `
+    -static-runtime `
+    -release `
+    -opensource -confirm-license `
+    -platform win32-msvc `
+    -mp `
+    -gui `
+    -widgets `
+    -qt-pcre `
+    -qt-zlib `
+    -qt-libpng `
+    -qt-libjpeg `
+    -no-gif `
+    -no-icu `
+    -no-pch `
+    -no-angle `
+    -no-opengl `
+    -no-dbus `
+    -no-harfbuzz `
+    -no-accessibility `
+    -skip declarative `
+    -skip multimedia `
+    -skip qtcanvas3d `
+    -skip qtconnectivity `
+    -skip qtdeclarative `
+    -skip qtlocation `
+    -skip qtmultimedia `
+    -skip qtsensors `
+    -skip qtserialport `
+    -skip qtsvg `
+    -skip qtwayland `
+    -skip qtwebchannel `
+    -skip qtwebengine `
+    -skip qtwebsockets `
+    -skip qtxmlpatterns `
+    -nomake examples -nomake tests
+  & $jom -J $env:NUMBER_OF_PROCESSORS
+}
+
+# Install Qt
+if ( -not (Test-Path -Path $prefix)) {
+  & $jom install
+  # Patch the installation.
+  Set-Location -Path $prefix
+  & $git apply -v (Join-Path $PSScriptRoot qt-5.12.1-win-x86-msvc-install.patch)
+}
+
+# Package Qt
+Set-Location -Path $topdir
+& $cmake -E tar cf "$pkgname.zip" "--format=zip" "$pkgname"
diff --git a/Utilities/Release/win/sign-package.ps1 b/Utilities/Release/win/sign-package.ps1
new file mode 100755
index 0000000..0dbefd2
--- /dev/null
+++ b/Utilities/Release/win/sign-package.ps1
@@ -0,0 +1,29 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Run this script on a Windows host in a CMake single-config build tree.
+
+param (
+  [string]$signtool = 'signtool',
+  [string]$cpack = 'bin\cpack',
+  [switch]$trace
+)
+
+if ($trace -eq $true) {
+  Set-PSDebug -Trace 1
+}
+
+$ErrorActionPreference = 'Stop'
+
+# Sign binaries with SHA-1 for Windows 7 and below.
+& $signtool sign -v -a -t http://timestamp.digicert.com bin\*.exe
+
+# Sign binaries with SHA-256 for Windows 8 and above.
+& $signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -as bin\*.exe
+
+# Create packages.
+& $cpack -G ZIP
+& $cpack -G WIX
+
+# Sign installer with SHA-256.
+& $signtool sign -v -a -tr http://timestamp.digicert.com -fd sha256 -td sha256 -d "CMake Windows Installer" cmake-*-win*.msi
diff --git a/Utilities/Scripts/update-curl.bash b/Utilities/Scripts/update-curl.bash
index 64cb659..9715e07 100755
--- a/Utilities/Scripts/update-curl.bash
+++ b/Utilities/Scripts/update-curl.bash
@@ -8,7 +8,7 @@
 readonly ownership="Curl Upstream <curl-library@lists.haxx.se>"
 readonly subtree="Utilities/cmcurl"
 readonly repo="https://github.com/curl/curl.git"
-readonly tag="curl-7_83_0"
+readonly tag="curl-7_83_1"
 readonly shortlog=false
 readonly paths="
   CMake/*
diff --git a/Utilities/cmcurl/include/curl/curlver.h b/Utilities/cmcurl/include/curl/curlver.h
index 3081115..718d58c 100644
--- a/Utilities/cmcurl/include/curl/curlver.h
+++ b/Utilities/cmcurl/include/curl/curlver.h
@@ -30,13 +30,13 @@
 
 /* This is the version number of the libcurl package from which this header
    file origins: */
-#define LIBCURL_VERSION "7.83.0"
+#define LIBCURL_VERSION "7.83.1"
 
 /* The numeric version number is also available "in parts" by using these
    defines: */
 #define LIBCURL_VERSION_MAJOR 7
 #define LIBCURL_VERSION_MINOR 83
-#define LIBCURL_VERSION_PATCH 0
+#define LIBCURL_VERSION_PATCH 1
 
 /* This is the numeric version of the libcurl version number, meant for easier
    parsing and comparisons by programs. The LIBCURL_VERSION_NUM define will
@@ -57,7 +57,7 @@
    CURL_VERSION_BITS() macro since curl's own configure script greps for it
    and needs it to contain the full number.
 */
-#define LIBCURL_VERSION_NUM 0x075300
+#define LIBCURL_VERSION_NUM 0x075301
 
 /*
  * This is the date and time when the full source package was created. The
diff --git a/Utilities/cmcurl/lib/altsvc.c b/Utilities/cmcurl/lib/altsvc.c
index 45929a5..dd2d0eb 100644
--- a/Utilities/cmcurl/lib/altsvc.c
+++ b/Utilities/cmcurl/lib/altsvc.c
@@ -102,12 +102,17 @@
                                       unsigned int dstport)
 {
   struct altsvc *as = calloc(sizeof(struct altsvc), 1);
+  size_t hlen;
   if(!as)
     return NULL;
-
+  hlen = strlen(srchost);
+  DEBUGASSERT(hlen);
   as->src.host = strdup(srchost);
   if(!as->src.host)
     goto error;
+  if(hlen && (srchost[hlen - 1] == '.'))
+    /* strip off trailing any dot */
+    as->src.host[--hlen] = 0;
   as->dst.host = strdup(dsthost);
   if(!as->dst.host)
     goto error;
@@ -398,6 +403,22 @@
   return CURLE_OK;
 }
 
+/* hostcompare() returns true if 'host' matches 'check'. The first host
+ * argument may have a trailing dot present that will be ignored.
+ */
+static bool hostcompare(const char *host, const char *check)
+{
+  size_t hlen = strlen(host);
+  size_t clen = strlen(check);
+
+  if(hlen && (host[hlen - 1] == '.'))
+    hlen--;
+  if(hlen != clen)
+    /* they can't match if they have different lengths */
+    return FALSE;
+  return strncasecompare(host, check, hlen);
+}
+
 /* altsvc_flush() removes all alternatives for this source origin from the
    list */
 static void altsvc_flush(struct altsvcinfo *asi, enum alpnid srcalpnid,
@@ -410,7 +431,7 @@
     n = e->next;
     if((srcalpnid == as->src.alpnid) &&
        (srcport == as->src.port) &&
-       strcasecompare(srchost, as->src.host)) {
+       hostcompare(srchost, as->src.host)) {
       Curl_llist_remove(&asi->list, e, NULL);
       altsvc_free(as);
     }
@@ -635,7 +656,7 @@
       continue;
     }
     if((as->src.alpnid == srcalpnid) &&
-       strcasecompare(as->src.host, srchost) &&
+       hostcompare(srchost, as->src.host) &&
        (as->src.port == srcport) &&
        (versions & as->dst.alpnid)) {
       /* match */
diff --git a/Utilities/cmcurl/lib/c-hyper.c b/Utilities/cmcurl/lib/c-hyper.c
index de09568..6908298 100644
--- a/Utilities/cmcurl/lib/c-hyper.c
+++ b/Utilities/cmcurl/lib/c-hyper.c
@@ -439,6 +439,13 @@
     reasonp = hyper_response_reason_phrase(resp);
     reason_len = hyper_response_reason_phrase_len(resp);
 
+    if(http_status == 417 && data->state.expect100header) {
+      infof(data, "Got 417 while waiting for a 100");
+      data->state.disableexpect = TRUE;
+      data->req.newurl = strdup(data->state.url);
+      Curl_done_sending(data, k);
+    }
+
     result = status_line(data, conn,
                          http_status, http_version, reasonp, reason_len);
     if(result)
@@ -951,6 +958,11 @@
       goto error;
     }
   }
+  else {
+    if(!h2 && !data->state.disableexpect) {
+      data->state.expect100header = TRUE;
+    }
+  }
 
   if(hyper_request_set_method(req, (uint8_t *)method, strlen(method))) {
     failf(data, "error setting method");
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c
index 451881f..0c2d49b 100644
--- a/Utilities/cmcurl/lib/cookie.c
+++ b/Utilities/cmcurl/lib/cookie.c
@@ -427,7 +427,15 @@
 /* Make sure domain contains a dot or is localhost. */
 static bool bad_domain(const char *domain)
 {
-  return !strchr(domain, '.') && !strcasecompare(domain, "localhost");
+  if(strcasecompare(domain, "localhost"))
+    return FALSE;
+  else {
+    /* there must be a dot present, but that dot must not be a trailing dot */
+    char *dot = strchr(domain, '.');
+    if(dot)
+      return dot[1] ? FALSE : TRUE;
+  }
+  return TRUE;
 }
 
 /*
diff --git a/Utilities/cmcurl/lib/easy.c b/Utilities/cmcurl/lib/easy.c
index 65d7464..bd9d695 100644
--- a/Utilities/cmcurl/lib/easy.c
+++ b/Utilities/cmcurl/lib/easy.c
@@ -1139,7 +1139,7 @@
   if(!data->conn)
     /* on first invoke, the transfer has been detached from the connection and
        needs to be reattached */
-    Curl_attach_connnection(data, c);
+    Curl_attach_connection(data, c);
 
   *n = 0;
   result = Curl_read(data, sfd, buffer, buflen, &n1);
@@ -1175,7 +1175,7 @@
   if(!data->conn)
     /* on first invoke, the transfer has been detached from the connection and
        needs to be reattached */
-    Curl_attach_connnection(data, c);
+    Curl_attach_connection(data, c);
 
   *n = 0;
   sigpipe_ignore(data, &pipe_st);
@@ -1209,12 +1209,12 @@
   if(conn->handler->connection_check) {
     /* briefly attach the connection to this transfer for the purpose of
        checking it */
-    Curl_attach_connnection(data, conn);
+    Curl_attach_connection(data, conn);
 
     /* Do a protocol-specific keepalive check on the connection. */
     conn->handler->connection_check(data, conn, CONNCHECK_KEEPALIVE);
     /* detach the connection again */
-    Curl_detach_connnection(data);
+    Curl_detach_connection(data);
   }
 
   return 0; /* continue iteration */
diff --git a/Utilities/cmcurl/lib/hostip.c b/Utilities/cmcurl/lib/hostip.c
index 7f6bbac..7000b85 100644
--- a/Utilities/cmcurl/lib/hostip.c
+++ b/Utilities/cmcurl/lib/hostip.c
@@ -1268,7 +1268,7 @@
   result = Curl_setup_conn(data, protocol_done);
 
   if(result) {
-    Curl_detach_connnection(data);
+    Curl_detach_connection(data);
     Curl_conncache_remove_conn(data, conn, TRUE);
     Curl_disconnect(data, conn, TRUE);
   }
diff --git a/Utilities/cmcurl/lib/hsts.c b/Utilities/cmcurl/lib/hsts.c
index 03fcc9e..b9fa6f7 100644
--- a/Utilities/cmcurl/lib/hsts.c
+++ b/Utilities/cmcurl/lib/hsts.c
@@ -114,16 +114,25 @@
                             curl_off_t expires)
 {
   struct stsentry *sts = hsts_entry();
+  char *duphost;
+  size_t hlen;
   if(!sts)
     return CURLE_OUT_OF_MEMORY;
 
-  sts->expires = expires;
-  sts->includeSubDomains = subdomains;
-  sts->host = strdup(hostname);
-  if(!sts->host) {
+  duphost = strdup(hostname);
+  if(!duphost) {
     free(sts);
     return CURLE_OUT_OF_MEMORY;
   }
+
+  hlen = strlen(duphost);
+  if(duphost[hlen - 1] == '.')
+    /* strip off trailing any dot */
+    duphost[--hlen] = 0;
+
+  sts->host = duphost;
+  sts->expires = expires;
+  sts->includeSubDomains = subdomains;
   Curl_llist_insert_next(&h->list, h->list.tail, sts, &sts->node);
   return CURLE_OK;
 }
@@ -238,10 +247,21 @@
                            bool subdomain)
 {
   if(h) {
+    char buffer[MAX_HSTS_HOSTLEN + 1];
     time_t now = time(NULL);
     size_t hlen = strlen(hostname);
     struct Curl_llist_element *e;
     struct Curl_llist_element *n;
+
+    if((hlen > MAX_HSTS_HOSTLEN) || !hlen)
+      return NULL;
+    memcpy(buffer, hostname, hlen);
+    if(hostname[hlen-1] == '.')
+      /* remove the trailing dot */
+      --hlen;
+    buffer[hlen] = 0;
+    hostname = buffer;
+
     for(e = h->list.head; e; e = n) {
       struct stsentry *sts = e->ptr;
       n = e->next;
@@ -440,7 +460,7 @@
     CURLSTScode sc;
     DEBUGASSERT(h);
     do {
-      char buffer[257];
+      char buffer[MAX_HSTS_HOSTLEN + 1];
       struct curl_hstsentry e;
       e.name = buffer;
       e.namelen = sizeof(buffer)-1;
diff --git a/Utilities/cmcurl/lib/http.c b/Utilities/cmcurl/lib/http.c
index 0d5c449..b215307 100644
--- a/Utilities/cmcurl/lib/http.c
+++ b/Utilities/cmcurl/lib/http.c
@@ -651,6 +651,21 @@
   return result;
 }
 
+/*
+ * Curl_allow_auth_to_host() tells if authentication, cookies or other
+ * "sensitive data" can (still) be sent to this host.
+ */
+bool Curl_allow_auth_to_host(struct Curl_easy *data)
+{
+  struct connectdata *conn = data->conn;
+  return (!data->state.this_is_a_follow ||
+          data->set.allow_auth_to_other_hosts ||
+          (data->state.first_host &&
+           strcasecompare(data->state.first_host, conn->host.name) &&
+           (data->state.first_remote_port == conn->remote_port) &&
+           (data->state.first_remote_protocol == conn->handler->protocol)));
+}
+
 #ifndef CURL_DISABLE_HTTP_AUTH
 /*
  * Output the correct authentication header depending on the auth type
@@ -775,21 +790,6 @@
   return CURLE_OK;
 }
 
-/*
- * Curl_allow_auth_to_host() tells if authentication, cookies or other
- * "sensitive data" can (still) be sent to this host.
- */
-bool Curl_allow_auth_to_host(struct Curl_easy *data)
-{
-  struct connectdata *conn = data->conn;
-  return (!data->state.this_is_a_follow ||
-          data->set.allow_auth_to_other_hosts ||
-          (data->state.first_host &&
-           strcasecompare(data->state.first_host, conn->host.name) &&
-           (data->state.first_remote_port == conn->remote_port) &&
-           (data->state.first_remote_protocol == conn->handler->protocol)));
-}
-
 /**
  * Curl_http_output_auth() setups the authentication headers for the
  * host/proxy and the correct authentication
diff --git a/Utilities/cmcurl/lib/http_proxy.c b/Utilities/cmcurl/lib/http_proxy.c
index 863cbbb..ed08193 100644
--- a/Utilities/cmcurl/lib/http_proxy.c
+++ b/Utilities/cmcurl/lib/http_proxy.c
@@ -967,6 +967,13 @@
       break;
     }
 
+    if(conn->bits.close && data->req.newurl) {
+      /* Connection closed by server. Don't use it anymore */
+      Curl_closesocket(data, conn, conn->sock[sockindex]);
+      conn->sock[sockindex] = CURL_SOCKET_BAD;
+      break;
+    }
+
     /* If we are supposed to continue and request a new URL, which basically
      * means the HTTP authentication is still going on so if the tunnel
      * is complete we start over in INIT state */
diff --git a/Utilities/cmcurl/lib/multi.c b/Utilities/cmcurl/lib/multi.c
index 466425d..8e58d78 100644
--- a/Utilities/cmcurl/lib/multi.c
+++ b/Utilities/cmcurl/lib/multi.c
@@ -118,7 +118,7 @@
 
   /* Important: reset the conn pointer so that we don't point to memory
      that could be freed anytime */
-  Curl_detach_connnection(data);
+  Curl_detach_connection(data);
   Curl_expire_clear(data); /* stop all timers */
 }
 
@@ -635,7 +635,7 @@
   process_pending_handles(data->multi); /* connection / multiplex */
 
   CONNCACHE_LOCK(data);
-  Curl_detach_connnection(data);
+  Curl_detach_connection(data);
   if(CONN_INUSE(conn)) {
     /* Stop if still used. */
     CONNCACHE_UNLOCK(data);
@@ -824,7 +824,7 @@
                                       that vanish with this handle */
 
   /* Remove the association between the connection and the handle */
-  Curl_detach_connnection(data);
+  Curl_detach_connection(data);
 
   if(data->state.lastconnect_id != -1) {
     /* Mark any connect-only connection for closure */
@@ -899,12 +899,12 @@
 }
 
 /*
- * Curl_detach_connnection() removes the given transfer from the connection.
+ * Curl_detach_connection() removes the given transfer from the connection.
  *
  * This is the only function that should clear data->conn. This will
  * occasionally be called with the data->conn pointer already cleared.
  */
-void Curl_detach_connnection(struct Curl_easy *data)
+void Curl_detach_connection(struct Curl_easy *data)
 {
   struct connectdata *conn = data->conn;
   if(conn) {
@@ -916,11 +916,11 @@
 }
 
 /*
- * Curl_attach_connnection() attaches this transfer to this connection.
+ * Curl_attach_connection() attaches this transfer to this connection.
  *
  * This is the only function that should assign data->conn
  */
-void Curl_attach_connnection(struct Curl_easy *data,
+void Curl_attach_connection(struct Curl_easy *data,
                              struct connectdata *conn)
 {
   DEBUGASSERT(!data->conn);
@@ -1540,7 +1540,7 @@
 
     /* take this handle to the perform state right away */
     multistate(data, MSTATE_PERFORMING);
-    Curl_attach_connnection(data, conn);
+    Curl_attach_connection(data, conn);
     k->keepon |= KEEP_RECV; /* setup to receive! */
   }
   return rc;
@@ -2558,7 +2558,7 @@
             /* This is where we make sure that the conn pointer is reset.
                We don't have to do this in every case block above where a
                failure is detected */
-            Curl_detach_connnection(data);
+            Curl_detach_connection(data);
 
             /* remove connection from cache */
             Curl_conncache_remove_conn(data, conn, TRUE);
diff --git a/Utilities/cmcurl/lib/multiif.h b/Utilities/cmcurl/lib/multiif.h
index f4d0ada..5a8c358 100644
--- a/Utilities/cmcurl/lib/multiif.h
+++ b/Utilities/cmcurl/lib/multiif.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,9 +31,9 @@
 void Curl_expire_clear(struct Curl_easy *data);
 void Curl_expire_done(struct Curl_easy *data, expire_id id);
 CURLMcode Curl_update_timer(struct Curl_multi *multi) WARN_UNUSED_RESULT;
-void Curl_attach_connnection(struct Curl_easy *data,
+void Curl_attach_connection(struct Curl_easy *data,
                              struct connectdata *conn);
-void Curl_detach_connnection(struct Curl_easy *data);
+void Curl_detach_connection(struct Curl_easy *data);
 bool Curl_multiplex_wanted(const struct Curl_multi *multi);
 void Curl_set_in_callback(struct Curl_easy *data, bool value);
 bool Curl_is_in_callback(struct Curl_easy *easy);
diff --git a/Utilities/cmcurl/lib/setopt.c b/Utilities/cmcurl/lib/setopt.c
index 0df1afa..05e1a54 100644
--- a/Utilities/cmcurl/lib/setopt.c
+++ b/Utilities/cmcurl/lib/setopt.c
@@ -2294,6 +2294,7 @@
 
   case CURLOPT_SSL_OPTIONS:
     arg = va_arg(param, long);
+    data->set.ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
     data->set.ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
     data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     data->set.ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
@@ -2307,6 +2308,7 @@
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_SSL_OPTIONS:
     arg = va_arg(param, long);
+    data->set.proxy_ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
     data->set.proxy_ssl.enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST);
     data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
     data->set.proxy_ssl.no_partialchain = !!(arg & CURLSSLOPT_NO_PARTIALCHAIN);
@@ -2745,49 +2747,52 @@
   case CURLOPT_TLSAUTH_USERNAME:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME],
                             va_arg(param, char *));
-    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
-      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    if(data->set.str[STRING_TLSAUTH_USERNAME] &&
+       !data->set.ssl.primary.authtype)
+      data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
     break;
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_TLSAUTH_USERNAME:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
                             va_arg(param, char *));
     if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
-       !data->set.proxy_ssl.authtype)
-      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+       !data->set.proxy_ssl.primary.authtype)
+      data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default to
+                                                                  SRP */
     break;
 #endif
   case CURLOPT_TLSAUTH_PASSWORD:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD],
                             va_arg(param, char *));
-    if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype)
-      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    if(data->set.str[STRING_TLSAUTH_USERNAME] &&
+       !data->set.ssl.primary.authtype)
+      data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */
     break;
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_TLSAUTH_PASSWORD:
     result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
                             va_arg(param, char *));
     if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
-       !data->set.proxy_ssl.authtype)
-      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+       !data->set.proxy_ssl.primary.authtype)
+      data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP; /* default */
     break;
 #endif
   case CURLOPT_TLSAUTH_TYPE:
     argptr = va_arg(param, char *);
     if(!argptr ||
        strncasecompare(argptr, "SRP", strlen("SRP")))
-      data->set.ssl.authtype = CURL_TLSAUTH_SRP;
+      data->set.ssl.primary.authtype = CURL_TLSAUTH_SRP;
     else
-      data->set.ssl.authtype = CURL_TLSAUTH_NONE;
+      data->set.ssl.primary.authtype = CURL_TLSAUTH_NONE;
     break;
 #ifndef CURL_DISABLE_PROXY
   case CURLOPT_PROXY_TLSAUTH_TYPE:
     argptr = va_arg(param, char *);
     if(!argptr ||
        strncasecompare(argptr, "SRP", strlen("SRP")))
-      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
+      data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_SRP;
     else
-      data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
+      data->set.proxy_ssl.primary.authtype = CURL_TLSAUTH_NONE;
     break;
 #endif
 #endif
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c
index ef48ed6..6b31d4b 100644
--- a/Utilities/cmcurl/lib/url.c
+++ b/Utilities/cmcurl/lib/url.c
@@ -372,7 +372,7 @@
 
   /* Detach connection if any is left. This should not be normal, but can be
      the case for example with CONNECT_ONLY + recv/send (test 556) */
-  Curl_detach_connnection(data);
+  Curl_detach_connection(data);
   m = data->multi;
   if(m)
     /* This handle is still part of a multi handle, take care of this first
@@ -542,7 +542,7 @@
   set->ssl.primary.verifypeer = TRUE;
   set->ssl.primary.verifyhost = TRUE;
 #ifdef USE_TLS_SRP
-  set->ssl.authtype = CURL_TLSAUTH_NONE;
+  set->ssl.primary.authtype = CURL_TLSAUTH_NONE;
 #endif
   set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
                                                       type */
@@ -859,7 +859,7 @@
 
   /* temporarily attach the connection to this transfer handle for the
      disconnect and shutdown */
-  Curl_attach_connnection(data, conn);
+  Curl_attach_connection(data, conn);
 
   if(conn->handler->disconnect)
     /* This is set if protocol-specific cleanups should be made */
@@ -868,7 +868,7 @@
   conn_shutdown(data, conn);
 
   /* detach it again */
-  Curl_detach_connnection(data);
+  Curl_detach_connection(data);
 
   conn_free(conn);
 }
@@ -1020,12 +1020,12 @@
 
       /* briefly attach the connection to this transfer for the purpose of
          checking it */
-      Curl_attach_connnection(data, conn);
+      Curl_attach_connection(data, conn);
 
       state = conn->handler->connection_check(data, conn, CONNCHECK_ISDEAD);
       dead = (state & CONNRESULT_DEAD);
       /* detach the connection again */
-      Curl_detach_connnection(data);
+      Curl_detach_connection(data);
 
     }
     else {
@@ -1100,6 +1100,12 @@
   }
 }
 
+static bool ssh_config_matches(struct connectdata *one,
+                               struct connectdata *two)
+{
+  return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
+          Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
+}
 /*
  * Given one filled in connection struct (named needle), this function should
  * detect if there already is one that has all the significant details
@@ -1356,6 +1362,11 @@
          (data->state.httpwant < CURL_HTTP_VERSION_2_0))
         continue;
 
+      if(get_protocol_family(needle->handler) == PROTO_FAMILY_SSH) {
+        if(!ssh_config_matches(needle, check))
+          continue;
+      }
+
       if((needle->handler->flags&PROTOPT_SSL)
 #ifndef CURL_DISABLE_PROXY
          || !needle->bits.httpproxy || needle->bits.tunnel_proxy
@@ -1508,7 +1519,7 @@
 
   if(chosen) {
     /* mark it as used before releasing the lock */
-    Curl_attach_connnection(data, chosen);
+    Curl_attach_connection(data, chosen);
     CONNCACHE_UNLOCK(data);
     *usethis = chosen;
     return TRUE; /* yes, we found one to use! */
@@ -1758,11 +1769,17 @@
   conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
   conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
   conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+  conn->ssl_config.ssl_options = data->set.ssl.primary.ssl_options;
+#ifdef USE_TLS_SRP
+#endif
 #ifndef CURL_DISABLE_PROXY
   conn->proxy_ssl_config.verifystatus =
     data->set.proxy_ssl.primary.verifystatus;
   conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
   conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+  conn->proxy_ssl_config.ssl_options = data->set.proxy_ssl.primary.ssl_options;
+#ifdef USE_TLS_SRP
+#endif
 #endif
   conn->ip_version = data->set.ipver;
   conn->bits.connect_only = data->set.connect_only;
@@ -3779,7 +3796,7 @@
     if(!result) {
       conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
 
-      Curl_attach_connnection(data, conn);
+      Curl_attach_connection(data, conn);
       result = Curl_conncache_add_conn(data);
       if(result)
         goto out;
@@ -3848,7 +3865,8 @@
     data->set.str[STRING_SSL_ISSUERCERT_PROXY];
   data->set.proxy_ssl.primary.issuercert_blob =
     data->set.blobs[BLOB_SSL_ISSUERCERT_PROXY];
-  data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
+  data->set.proxy_ssl.primary.CRLfile =
+    data->set.str[STRING_SSL_CRLFILE_PROXY];
   data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
   data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
   data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
@@ -3856,18 +3874,20 @@
   data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
   data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY];
 #endif
-  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
+  data->set.ssl.primary.CRLfile = data->set.str[STRING_SSL_CRLFILE];
   data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE];
   data->set.ssl.key = data->set.str[STRING_KEY];
   data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE];
   data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD];
   data->set.ssl.primary.clientcert = data->set.str[STRING_CERT];
 #ifdef USE_TLS_SRP
-  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME];
-  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD];
+  data->set.ssl.primary.username = data->set.str[STRING_TLSAUTH_USERNAME];
+  data->set.ssl.primary.password = data->set.str[STRING_TLSAUTH_PASSWORD];
 #ifndef CURL_DISABLE_PROXY
-  data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
-  data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
+  data->set.proxy_ssl.primary.username =
+    data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
+  data->set.proxy_ssl.primary.password =
+    data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
 #endif
 #endif
   data->set.ssl.key_blob = data->set.blobs[BLOB_KEY];
@@ -4006,7 +4026,7 @@
        * This is a brand new connection, so let's store it in the connection
        * cache of ours!
        */
-      Curl_attach_connnection(data, conn);
+      Curl_attach_connection(data, conn);
       result = Curl_conncache_add_conn(data);
       if(result)
         goto out;
@@ -4153,7 +4173,7 @@
   else if(result && conn) {
     /* We're not allowed to return failure with memory left allocated in the
        connectdata struct, free those here */
-    Curl_detach_connnection(data);
+    Curl_detach_connection(data);
     Curl_conncache_remove_conn(data, conn, TRUE);
     Curl_disconnect(data, conn, TRUE);
   }
diff --git a/Utilities/cmcurl/lib/urlapi.c b/Utilities/cmcurl/lib/urlapi.c
index 99a0f69..2a36de6 100644
--- a/Utilities/cmcurl/lib/urlapi.c
+++ b/Utilities/cmcurl/lib/urlapi.c
@@ -228,7 +228,7 @@
  */
 bool Curl_is_absolute_url(const char *url, char *buf, size_t buflen)
 {
-  size_t i;
+  int i;
   DEBUGASSERT(!buf || (buflen > MAX_SCHEME_LEN));
   (void)buflen; /* only used in debug-builds */
   if(buf)
@@ -678,8 +678,8 @@
 #endif
   }
   else {
-    /* letters from the second string is not ok */
-    len = strcspn(hostname, " \r\n");
+    /* letters from the second string are not ok */
+    len = strcspn(hostname, " \r\n\t/:#?!@");
     if(hlen != len)
       /* hostname with bad content */
       return CURLUE_BAD_HOSTNAME;
diff --git a/Utilities/cmcurl/lib/urldata.h b/Utilities/cmcurl/lib/urldata.h
index 9c34ec4..584434d 100644
--- a/Utilities/cmcurl/lib/urldata.h
+++ b/Utilities/cmcurl/lib/urldata.h
@@ -253,10 +253,17 @@
   char *cipher_list;     /* list of ciphers to use */
   char *cipher_list13;   /* list of TLS 1.3 cipher suites to use */
   char *pinned_key;
+  char *CRLfile;         /* CRL to check certificate revocation */
   struct curl_blob *cert_blob;
   struct curl_blob *ca_info_blob;
   struct curl_blob *issuercert_blob;
+#ifdef USE_TLS_SRP
+  char *username; /* TLS username (for, e.g., SRP) */
+  char *password; /* TLS password (for, e.g., SRP) */
+  enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
+#endif
   char *curves;          /* list of curves to use */
+  unsigned char ssl_options;  /* the CURLOPT_SSL_OPTIONS bitmask */
   BIT(verifypeer);       /* set TRUE if this is desired */
   BIT(verifyhost);       /* set TRUE if CN/SAN must match hostname */
   BIT(verifystatus);     /* set TRUE if certificate status must be checked */
@@ -266,7 +273,6 @@
 struct ssl_config_data {
   struct ssl_primary_config primary;
   long certverifyresult; /* result from the certificate verification */
-  char *CRLfile;   /* CRL to check certificate revocation */
   curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
   void *fsslctxp;        /* parameter for call back */
   char *cert_type; /* format for certificate (default: PEM)*/
@@ -274,11 +280,6 @@
   struct curl_blob *key_blob;
   char *key_type; /* format for private key (default: PEM) */
   char *key_passwd; /* plain text private key password */
-#ifdef USE_TLS_SRP
-  char *username; /* TLS username (for, e.g., SRP) */
-  char *password; /* TLS password (for, e.g., SRP) */
-  enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
-#endif
   BIT(certinfo);     /* gather lots of certificate info */
   BIT(falsestart);
   BIT(enable_beast); /* allow this flaw for interoperability's sake*/
diff --git a/Utilities/cmcurl/lib/vquic/msh3.c b/Utilities/cmcurl/lib/vquic/msh3.c
index be18e6e..f7bd315 100644
--- a/Utilities/cmcurl/lib/vquic/msh3.c
+++ b/Utilities/cmcurl/lib/vquic/msh3.c
@@ -95,7 +95,9 @@
 
 void Curl_quic_ver(char *p, size_t len)
 {
-  (void)msnprintf(p, len, "msh3/%s", "0.0.1");
+  uint32_t v[4];
+  MsH3Version(v);
+  (void)msnprintf(p, len, "msh3/%d.%d.%d.%d", v[0], v[1], v[2], v[3]);
 }
 
 CURLcode Curl_quic_connect(struct Curl_easy *data,
@@ -121,7 +123,10 @@
     return CURLE_FAILED_INIT;
   }
 
-  qs->conn = MsH3ConnectionOpen(qs->api, conn->host.name, unsecure);
+  qs->conn = MsH3ConnectionOpen(qs->api,
+                                conn->host.name,
+                                (uint16_t)conn->remote_port,
+                                unsecure);
   if(!qs->conn) {
     failf(data, "can't create msh3 connection");
     if(qs->api) {
@@ -357,7 +362,7 @@
   struct HTTP *stream = IfContext;
   (void)Request;
   (void)AbortError;
-  H3BUGF(printf("* msh3_complete, aborted=%hhu\n", Aborted));
+  H3BUGF(printf("* msh3_complete, aborted=%s\n", Aborted ? "true" : "false"));
   msh3_lock_acquire(&stream->recv_lock);
   if(Aborted) {
     stream->recv_error = CURLE_HTTP3; /* TODO - how do we pass AbortError? */
diff --git a/Utilities/cmcurl/lib/vquic/ngtcp2.c b/Utilities/cmcurl/lib/vquic/ngtcp2.c
index abce631..f1a64ee 100644
--- a/Utilities/cmcurl/lib/vquic/ngtcp2.c
+++ b/Utilities/cmcurl/lib/vquic/ngtcp2.c
@@ -264,6 +264,7 @@
 
 static SSL_CTX *quic_ssl_ctx(struct Curl_easy *data)
 {
+  struct connectdata *conn = data->conn;
   SSL_CTX *ssl_ctx = SSL_CTX_new(TLS_method());
 
   SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION);
@@ -291,12 +292,11 @@
     SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
   }
 
-  {
-    struct connectdata *conn = data->conn;
+  if(conn->ssl_config.verifypeer) {
     const char * const ssl_cafile = conn->ssl_config.CAfile;
     const char * const ssl_capath = conn->ssl_config.CApath;
 
-    if(conn->ssl_config.verifypeer) {
+    if(ssl_cafile || ssl_capath) {
       SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
       /* tell OpenSSL where to find CA certificates that are used to verify
          the server's certificate. */
@@ -311,6 +311,13 @@
       infof(data, " CAfile: %s", ssl_cafile ? ssl_cafile : "none");
       infof(data, " CApath: %s", ssl_capath ? ssl_capath : "none");
     }
+#ifdef CURL_CA_FALLBACK
+    else {
+      /* verifying the peer without any CA certificates won't work so
+         use openssl's built-in default as fallback */
+      SSL_CTX_set_default_verify_paths(ssl_ctx);
+    }
+#endif
   }
   return ssl_ctx;
 }
diff --git a/Utilities/cmcurl/lib/vssh/ssh.h b/Utilities/cmcurl/lib/vssh/ssh.h
index 7972081..30d82e5 100644
--- a/Utilities/cmcurl/lib/vssh/ssh.h
+++ b/Utilities/cmcurl/lib/vssh/ssh.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -131,8 +131,8 @@
 
   /* common */
   const char *passphrase;     /* pass-phrase to use */
-  char *rsa_pub;              /* path name */
-  char *rsa;                  /* path name */
+  char *rsa_pub;              /* strdup'ed public key file */
+  char *rsa;                  /* strdup'ed private key file */
   bool authed;                /* the connection has been authenticated fine */
   bool acceptfail;            /* used by the SFTP_QUOTE (continue if
                                  quote command fails) */
diff --git a/Utilities/cmcurl/lib/vtls/gskit.c b/Utilities/cmcurl/lib/vtls/gskit.c
index 9b5fbe4..7a65f92 100644
--- a/Utilities/cmcurl/lib/vtls/gskit.c
+++ b/Utilities/cmcurl/lib/vtls/gskit.c
@@ -293,27 +293,6 @@
 }
 
 
-static CURLcode set_callback(struct Curl_easy *data,
-                             gsk_handle h, GSK_CALLBACK_ID id, void *info)
-{
-  char buffer[STRERROR_LEN];
-  int rc = gsk_attribute_set_callback(h, id, info);
-
-  switch(rc) {
-  case GSK_OK:
-    return CURLE_OK;
-  case GSK_ERROR_IO:
-    failf(data, "gsk_attribute_set_callback() I/O error: %s",
-          Curl_strerror(errno, buffer, sizeof(buffer)));
-    break;
-  default:
-    failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
-    break;
-  }
-  return CURLE_SSL_CONNECT_ERROR;
-}
-
-
 static CURLcode set_ciphers(struct Curl_easy *data,
                             gsk_handle h, unsigned int *protoflags)
 {
@@ -796,13 +775,13 @@
     BACKEND->localfd = sockpair[0];
     BACKEND->remotefd = sockpair[1];
     setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
-               (void *) sobufsize, sizeof(sobufsize));
+               (void *) &sobufsize, sizeof(sobufsize));
     setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
-               (void *) sobufsize, sizeof(sobufsize));
+               (void *) &sobufsize, sizeof(sobufsize));
     setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
-               (void *) sobufsize, sizeof(sobufsize));
+               (void *) &sobufsize, sizeof(sobufsize));
     setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
-               (void *) sobufsize, sizeof(sobufsize));
+               (void *) &sobufsize, sizeof(sobufsize));
     curlx_nonblock(BACKEND->localfd, TRUE);
     curlx_nonblock(BACKEND->remotefd, TRUE);
   }
diff --git a/Utilities/cmcurl/lib/vtls/gtls.c b/Utilities/cmcurl/lib/vtls/gtls.c
index 0535011..dd82755 100644
--- a/Utilities/cmcurl/lib/vtls/gtls.c
+++ b/Utilities/cmcurl/lib/vtls/gtls.c
@@ -445,9 +445,10 @@
   }
 
 #ifdef USE_GNUTLS_SRP
-  if((SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) &&
+  if((SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) &&
      Curl_allow_auth_to_host(data)) {
-    infof(data, "Using TLS-SRP username: %s", SSL_SET_OPTION(username));
+    infof(data, "Using TLS-SRP username: %s",
+          SSL_SET_OPTION(primary.username));
 
     rc = gnutls_srp_allocate_client_credentials(&backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
@@ -457,8 +458,8 @@
     }
 
     rc = gnutls_srp_set_client_credentials(backend->srp_client_cred,
-                                           SSL_SET_OPTION(username),
-                                           SSL_SET_OPTION(password));
+                                           SSL_SET_OPTION(primary.username),
+                                           SSL_SET_OPTION(primary.password));
     if(rc != GNUTLS_E_SUCCESS) {
       failf(data, "gnutls_srp_set_client_cred() failed: %s",
             gnutls_strerror(rc));
@@ -515,19 +516,19 @@
   }
 #endif
 
-  if(SSL_SET_OPTION(CRLfile)) {
+  if(SSL_SET_OPTION(primary.CRLfile)) {
     /* set the CRL list file */
     rc = gnutls_certificate_set_x509_crl_file(backend->cred,
-                                              SSL_SET_OPTION(CRLfile),
+                                              SSL_SET_OPTION(primary.CRLfile),
                                               GNUTLS_X509_FMT_PEM);
     if(rc < 0) {
       failf(data, "error reading crl file %s (%s)",
-            SSL_SET_OPTION(CRLfile), gnutls_strerror(rc));
+            SSL_SET_OPTION(primary.CRLfile), gnutls_strerror(rc));
       return CURLE_SSL_CRL_BADFILE;
     }
     else
       infof(data, "found %d CRL in %s",
-            rc, SSL_SET_OPTION(CRLfile));
+            rc, SSL_SET_OPTION(primary.CRLfile));
   }
 
   /* Initialize TLS session as a client */
@@ -598,7 +599,7 @@
 #ifdef USE_GNUTLS_SRP
   /* Only add SRP to the cipher list if SRP is requested. Otherwise
    * GnuTLS will disable TLS 1.3 support. */
-  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+  if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
     size_t len = strlen(prioritylist);
 
     char *prioritysrp = malloc(len + sizeof(GNUTLS_SRP) + 1);
@@ -693,7 +694,7 @@
 
 #ifdef USE_GNUTLS_SRP
   /* put the credentials to the current session */
-  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+  if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP) {
     rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
                                 backend->srp_client_cred);
     if(rc != GNUTLS_E_SUCCESS) {
@@ -875,8 +876,8 @@
        SSL_CONN_CONFIG(verifyhost) ||
        SSL_CONN_CONFIG(issuercert)) {
 #ifdef USE_GNUTLS_SRP
-      if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
-         && SSL_SET_OPTION(username) != NULL
+      if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
+         && SSL_SET_OPTION(primary.username)
          && !SSL_CONN_CONFIG(verifypeer)
          && gnutls_cipher_get(session)) {
         /* no peer cert, but auth is ok if we have SRP user and cipher and no
@@ -934,7 +935,8 @@
         failf(data, "server certificate verification failed. CAfile: %s "
               "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
               "none",
-              SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
+              SSL_SET_OPTION(primary.CRLfile) ?
+              SSL_SET_OPTION(primary.CRLfile) : "none");
         return CURLE_PEER_FAILED_VERIFICATION;
       }
       else
@@ -1564,8 +1566,8 @@
   gnutls_certificate_free_credentials(backend->cred);
 
 #ifdef USE_GNUTLS_SRP
-  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
-     && SSL_SET_OPTION(username) != NULL)
+  if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
+     && SSL_SET_OPTION(primary.username) != NULL)
     gnutls_srp_free_client_credentials(backend->srp_client_cred);
 #endif
 
diff --git a/Utilities/cmcurl/lib/vtls/mbedtls.c b/Utilities/cmcurl/lib/vtls/mbedtls.c
index 64f57c5..b60b9ca 100644
--- a/Utilities/cmcurl/lib/vtls/mbedtls.c
+++ b/Utilities/cmcurl/lib/vtls/mbedtls.c
@@ -279,7 +279,7 @@
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
   const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
-  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
   const char * const hostname = SSL_HOST_NAME();
 #ifndef CURL_DISABLE_VERBOSE_STRINGS
   const long int port = SSL_HOST_PORT();
@@ -303,8 +303,9 @@
                               &ts_entropy, NULL, 0);
   if(ret) {
     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s",
+    failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
           -ret, errorbuf);
+    return CURLE_FAILED_INIT;
   }
 #else
   mbedtls_entropy_init(&backend->entropy);
@@ -314,8 +315,9 @@
                               &backend->entropy, NULL, 0);
   if(ret) {
     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s",
+    failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
           -ret, errorbuf);
+    return CURLE_FAILED_INIT;
   }
 #endif /* THREADING_SUPPORT */
 
@@ -815,8 +817,8 @@
     if(next_protocol) {
       infof(data, VTLS_INFOF_ALPN_ACCEPTED_1STR, next_protocol);
 #ifdef USE_HTTP2
-      if(!strncmp(next_protocol, ALPN_H2, ALPN_H2_LEN) &&
-         !next_protocol[ALPN_H2_LEN]) {
+      if(!strncmp(next_protocol, ALPN_H2, ALPN_H2_LENGTH) &&
+         !next_protocol[ALPN_H2_LENGTH]) {
         conn->negnpn = CURL_HTTP_VERSION_2;
       }
       else
@@ -1015,7 +1017,7 @@
 
   if(ret) {
     mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-    failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s",
+    failf(data, "mbedtls_ctr_drbg_seed returned (-0x%04X) %s",
           -ret, errorbuf);
   }
   else {
@@ -1023,7 +1025,7 @@
 
     if(ret) {
       mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-      failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s",
+      failf(data, "mbedtls_ctr_drbg_random returned (-0x%04X) %s",
             -ret, errorbuf);
     }
   }
diff --git a/Utilities/cmcurl/lib/vtls/nss.c b/Utilities/cmcurl/lib/vtls/nss.c
index 5b7de9f..cb0509f 100644
--- a/Utilities/cmcurl/lib/vtls/nss.c
+++ b/Utilities/cmcurl/lib/vtls/nss.c
@@ -983,6 +983,9 @@
   PR_Free(common_name);
 }
 
+/* A number of certs that will never occur in a real server handshake */
+#define TOO_MANY_CERTS 300
+
 static CURLcode display_conn_info(struct Curl_easy *data, PRFileDesc *sock)
 {
   CURLcode result = CURLE_OK;
@@ -1018,6 +1021,11 @@
         cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
         while(cert2) {
           i++;
+          if(i >= TOO_MANY_CERTS) {
+            CERT_DestroyCertificate(cert2);
+            failf(data, "certificate loop");
+            return CURLE_SSL_CERTPROBLEM;
+          }
           if(cert2->isRoot) {
             CERT_DestroyCertificate(cert2);
             break;
@@ -2027,13 +2035,13 @@
     }
   }
 
-  if(SSL_SET_OPTION(CRLfile)) {
-    const CURLcode rv = nss_load_crl(SSL_SET_OPTION(CRLfile));
+  if(SSL_SET_OPTION(primary.CRLfile)) {
+    const CURLcode rv = nss_load_crl(SSL_SET_OPTION(primary.CRLfile));
     if(rv) {
       result = rv;
       goto error;
     }
-    infof(data, "  CRLfile: %s", SSL_SET_OPTION(CRLfile));
+    infof(data, "  CRLfile: %s", SSL_SET_OPTION(primary.CRLfile));
   }
 
   if(SSL_SET_OPTION(primary.clientcert)) {
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 3722005..635e9c1 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -215,11 +215,10 @@
  * OpenSSL: supported since 1.0.2, see
  *   https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
  * BoringSSL: supported since 5fd1807d95f7 (committed 2016-09-30)
- * LibreSSL: not tested.
+ * LibreSSL: since 2.5.3 (April 12, 2017)
  */
-#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) && \
-     !defined(LIBRESSL_VERSION_NUMBER)) || \
-    defined(OPENSSL_IS_BORINGSSL)
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) ||  \
+  defined(OPENSSL_IS_BORINGSSL)
 #define HAVE_SSL_CTX_SET_EC_CURVES
 #endif
 
@@ -2663,7 +2662,7 @@
 #endif
   const long int ssl_version = SSL_CONN_CONFIG(version);
 #ifdef USE_OPENSSL_SRP
-  const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+  const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(primary.authtype);
 #endif
   char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
   const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
@@ -2674,7 +2673,7 @@
     (ca_info_blob ? NULL : SSL_CONN_CONFIG(CAfile));
   const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
   const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
-  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  const char * const ssl_crlfile = SSL_SET_OPTION(primary.CRLfile);
   char error_buffer[256];
   struct ssl_backend_data *backend = connssl->backend;
   bool imported_native_ca = false;
@@ -2926,15 +2925,15 @@
 #ifdef USE_OPENSSL_SRP
   if((ssl_authtype == CURL_TLSAUTH_SRP) &&
      Curl_allow_auth_to_host(data)) {
-    char * const ssl_username = SSL_SET_OPTION(username);
-
+    char * const ssl_username = SSL_SET_OPTION(primary.username);
+    char * const ssl_password = SSL_SET_OPTION(primary.password);
     infof(data, "Using TLS-SRP username: %s", ssl_username);
 
     if(!SSL_CTX_set_srp_username(backend->ctx, ssl_username)) {
       failf(data, "Unable to set SRP user name");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
-    if(!SSL_CTX_set_srp_password(backend->ctx, SSL_SET_OPTION(password))) {
+    if(!SSL_CTX_set_srp_password(backend->ctx, ssl_password)) {
       failf(data, "failed setting SRP password");
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
diff --git a/Utilities/cmcurl/lib/vtls/sectransp.c b/Utilities/cmcurl/lib/vtls/sectransp.c
index 8ee8fe9..2e57d83 100644
--- a/Utilities/cmcurl/lib/vtls/sectransp.c
+++ b/Utilities/cmcurl/lib/vtls/sectransp.c
@@ -2045,8 +2045,9 @@
     err = SSLSetPeerDomainName(backend->ssl_ctx, snihost, snilen);
 
     if(err != noErr) {
-      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
+      failf(data, "SSL: SSLSetPeerDomainName() failed: OSStatus %d",
             err);
+      return CURLE_SSL_CONNECT_ERROR;
     }
 
     if((Curl_inet_pton(AF_INET, hostname, &addr))
diff --git a/Utilities/cmcurl/lib/vtls/vtls.c b/Utilities/cmcurl/lib/vtls/vtls.c
index a40ac06..e2d3438 100644
--- a/Utilities/cmcurl/lib/vtls/vtls.c
+++ b/Utilities/cmcurl/lib/vtls/vtls.c
@@ -132,6 +132,7 @@
 {
   if((data->version == needle->version) &&
      (data->version_max == needle->version_max) &&
+     (data->ssl_options == needle->ssl_options) &&
      (data->verifypeer == needle->verifypeer) &&
      (data->verifyhost == needle->verifyhost) &&
      (data->verifystatus == needle->verifystatus) &&
@@ -144,9 +145,15 @@
      Curl_safecmp(data->clientcert, needle->clientcert) &&
      Curl_safecmp(data->random_file, needle->random_file) &&
      Curl_safecmp(data->egdsocket, needle->egdsocket) &&
+#ifdef USE_TLS_SRP
+     Curl_safecmp(data->username, needle->username) &&
+     Curl_safecmp(data->password, needle->password) &&
+     (data->authtype == needle->authtype) &&
+#endif
      Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
      Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
      Curl_safe_strcasecompare(data->curves, needle->curves) &&
+     Curl_safe_strcasecompare(data->CRLfile, needle->CRLfile) &&
      Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
     return TRUE;
 
@@ -163,6 +170,10 @@
   dest->verifyhost = source->verifyhost;
   dest->verifystatus = source->verifystatus;
   dest->sessionid = source->sessionid;
+  dest->ssl_options = source->ssl_options;
+#ifdef USE_TLS_SRP
+  dest->authtype = source->authtype;
+#endif
 
   CLONE_BLOB(cert_blob);
   CLONE_BLOB(ca_info_blob);
@@ -177,6 +188,11 @@
   CLONE_STRING(cipher_list13);
   CLONE_STRING(pinned_key);
   CLONE_STRING(curves);
+  CLONE_STRING(CRLfile);
+#ifdef USE_TLS_SRP
+  CLONE_STRING(username);
+  CLONE_STRING(password);
+#endif
 
   return TRUE;
 }
@@ -196,6 +212,11 @@
   Curl_safefree(sslc->ca_info_blob);
   Curl_safefree(sslc->issuercert_blob);
   Curl_safefree(sslc->curves);
+  Curl_safefree(sslc->CRLfile);
+#ifdef USE_TLS_SRP
+  Curl_safefree(sslc->username);
+  Curl_safefree(sslc->password);
+#endif
 }
 
 #ifdef USE_SSL
diff --git a/Utilities/cmcurl/lib/vtls/x509asn1.c b/Utilities/cmcurl/lib/vtls/x509asn1.c
index f64acb8..dfb9386 100644
--- a/Utilities/cmcurl/lib/vtls/x509asn1.c
+++ b/Utilities/cmcurl/lib/vtls/x509asn1.c
@@ -945,6 +945,24 @@
 
   /* Generate all information records for the public key. */
 
+  if(strcasecompare(algo, "ecPublicKey")) {
+    /*
+     * ECC public key is all the data, a value of type BIT STRING mapped to
+     * OCTET STRING and should not be parsed as an ASN.1 value.
+     */
+    const unsigned long len =
+      (unsigned long)((pubkey->end - pubkey->beg - 2) * 4);
+    if(!certnum)
+      infof(data, "   ECC Public Key (%lu bits)", len);
+    if(data->set.ssl.certinfo) {
+      char q[sizeof(len) * 8 / 3 + 1];
+      msnprintf(q, sizeof(q), "%lu", len);
+      if(Curl_ssl_push_certinfo(data, certnum, "ECC Public Key", q))
+        return 1;
+    }
+    return do_pubkey_field(data, certnum, "ecPublicKey", pubkey);
+  }
+
   /* Get the public key (single element). */
   if(!getASN1Element(&pk, pubkey->beg + 1, pubkey->end))
     return 1;
@@ -971,14 +989,10 @@
     if(!certnum)
       infof(data, "   RSA Public Key (%lu bits)", len);
     if(data->set.ssl.certinfo) {
-      q = curl_maprintf("%lu", len);
-      if(q) {
-        CURLcode result =
-          Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
-        free((char *) q);
-        if(result)
-          return 1;
-      }
+      char r[sizeof(len) * 8 / 3 + 1];
+      msnprintf(r, sizeof(r), "%lu", len);
+      if(Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", r))
+        return 1;
     }
     /* Generate coefficients. */
     if(do_pubkey_field(data, certnum, "rsa(n)", &elem))