Merge branch 'release-4.1' into release-4.2
diff --git a/.clang-tidy b/.clang-tidy
index 35503d4..f83585a 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -36,6 +36,7 @@
 -modernize-use-emplace,\
 -modernize-use-nodiscard,\
 -modernize-use-noexcept,\
+-modernize-use-scoped-lock,\
 -modernize-use-trailing-return-type,\
 -modernize-use-transparent-functors,\
 performance-*,\
@@ -62,6 +63,7 @@
 -readability-static-accessed-through-instance,\
 -readability-suspicious-call-argument,\
 -readability-uppercase-literal-suffix,\
+-readability-use-concise-preprocessor-directives,\
 -readability-use-std-min-max,\
 cmake-*,\
 -cmake-ostringstream-use-cmstrcat,\
diff --git a/.codespellrc b/.codespellrc
index 383e9ce..1149f41 100644
--- a/.codespellrc
+++ b/.codespellrc
@@ -20,15 +20,15 @@
   Tests/StringFileTest/test.utf8,
   Utilities/cm*,
   *.pfx,
+  *-stdout.txt,
+  *-stderr.txt
 
 # noqa: spellcheck off
 ignore-words-list =
   abd,
-  aci,
   ags,
   ake,
   ans,
-  ba,
   ccompiler,
   cconfiguration,
   certi,
@@ -42,9 +42,6 @@
   filetest,
   fo,
   helpfull,
-  hiden,
-  isnt,
-  keypair,
   nd,
   ned,
   nin,
@@ -55,7 +52,6 @@
   seh,
   ser,
   te,
-  upto,
   varn,
   vas,
   wee,
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cccd68c..fc49cb8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -40,6 +40,7 @@
 ################################################################################
 
 # Job prefixes:
+#   - `a:` analysis
 #   - `b:` build
 #   - `k:` package
 #   - `l:` lint
@@ -61,7 +62,7 @@
 
 p:doc-package:
     extends:
-        - .fedora42_sphinx_package
+        - .fedora43_sphinx_package
         - .cmake_prep_doc_linux
         - .linux_x86_64_tags
         - .cmake_doc_artifacts
@@ -103,26 +104,26 @@
         - .linux_x86_64_tags
         - .run_automatically
 
-l:iwyu-debian12:
+l:iwyu-debian13:
     extends:
-        - .debian12_iwyu
+        - .debian13_iwyu
         - .cmake_build_linux
         - .linux_x86_64_tags
         - .cmake_cdash_artifacts
         - .run_automatically
 
-l:tidy-fedora42:
+l:tidy-fedora43:
     extends:
-        - .fedora42_tidy
+        - .fedora43_tidy
         - .cmake_build_linux
         - .cmake_tidy_artifacts
         - .linux_x86_64_tags
         - .cmake_cdash_artifacts
         - .run_automatically
 
-l:sphinx-fedora42:
+l:sphinx-fedora43:
     extends:
-        - .fedora42_sphinx
+        - .fedora43_sphinx
         - .cmake_build_linux
         - .cmake_sphinx_artifacts
         - .linux_x86_64_tags
@@ -131,15 +132,96 @@
         CMAKE_CI_JOB_CONTINUOUS: "true"
         CMAKE_CI_JOB_HELP: "true"
 
-l:clang-analyzer-fedora42:
+l:clang-analyzer-fedora43:
     extends:
-        - .fedora42_clang_analyzer
+        - .fedora43_clang_analyzer
         - .cmake_build_linux
         - .linux_x86_64_tags
         - .run_automatically
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
+l:clazy-fedora43:
+    extends:
+        - .fedora43_clazy
+        - .cmake_build_linux
+        - .linux_x86_64_tags
+        - .run_automatically
+
+# Coverage builds
+
+b:fedora43-gcc-gcov:
+    extends:
+        - .fedora43_gcc_gcov
+        - .cmake_build_linux
+        - .cmake_build_artifacts
+        - .linux_x86_64_tags
+        - .run_manually
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:fedora43-gcc-gcov:
+    extends:
+        - .fedora43_gcc_gcov
+        - .cmake_test_linux
+        - .cmake_coverage_artifacts
+        - .linux_x86_64_tags_x11
+        - .run_dependent
+    # Run coverage analysis even if the tests fail.
+    allow_failure: true
+    needs:
+        - b:fedora43-gcc-gcov
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+a:fedora43-gcc-gcov:
+    extends:
+        - .fedora43_gcc_gcov
+        - .cmake_coverage_linux
+        - .cmake_cdash_artifacts
+        - .linux_x86_64_tags
+        - .run_dependent
+    needs:
+        - t:fedora43-gcc-gcov
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+b:fedora43-bullseye-coverage:
+    extends:
+        - .fedora43_bullseye_coverage
+        - .cmake_build_linux
+        - .cmake_build_artifacts
+        - .linux_x86_64_tags
+        - .run_manually
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:fedora43-bullseye-coverage:
+    extends:
+        - .fedora43_bullseye_coverage
+        - .cmake_test_linux
+        - .cmake_coverage_artifacts
+        - .linux_x86_64_tags_x11
+        - .run_dependent
+    # Run coverage analysis even if the tests fail.
+    allow_failure: true
+    needs:
+        - b:fedora43-bullseye-coverage
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+a:fedora43-bullseye-coverage:
+    extends:
+        - .fedora43_bullseye_coverage
+        - .cmake_coverage_linux
+        - .cmake_cdash_artifacts
+        - .linux_x86_64_tags
+        - .run_dependent
+    needs:
+        - t:fedora43-bullseye-coverage
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 # Linux builds
 
 b:centos7-x86_64:
@@ -163,9 +245,9 @@
         CMAKE_CI_ARTIFACTS_NAME: "artifacts-centos7-aarch64"
         CMAKE_CI_NO_MR: "true"
 
-t:debian12-ninja:
+t:debian13-ninja:
     extends:
-        - .debian12_ninja
+        - .debian13_ninja
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .cmake_junit_artifacts
@@ -174,9 +256,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
 
-t:debian12-aarch64-ninja:
+t:debian13-aarch64-ninja:
     extends:
-        - .debian12_aarch64_ninja
+        - .debian13_aarch64_ninja
         - .cmake_test_linux_release
         - .linux_aarch64_tags
         - .cmake_junit_artifacts
@@ -185,9 +267,9 @@
     variables:
         CMAKE_CI_NO_MR: "true"
 
-t:debian12-ninja-clang:
+t:debian13-ninja-clang:
     extends:
-        - .debian12_ninja_clang
+        - .debian13_ninja_clang
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -195,9 +277,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:debian12-makefiles-clang:
+t:debian13-makefiles-clang:
     extends:
-        - .debian12_makefiles_clang
+        - .debian13_makefiles_clang
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -205,9 +287,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:debian12-ninja-multi-symlinked:
+t:debian13-ninja-multi-symlinked:
     extends:
-        - .debian12_ninja_multi_symlinked
+        - .debian13_ninja_multi_symlinked
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .cmake_junit_artifacts
@@ -217,19 +299,19 @@
         CMAKE_CI_JOB_NIGHTLY: "true"
         CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
 
-t:debian12-hip-radeon:
+t:debian13-hip-radeon:
     extends:
-        - .debian12_hip_radeon
+        - .debian13_hip_radeon
         - .cmake_test_linux_release
-        - .linux_x86_64_tags_rocm5.2
+        - .linux_x86_64_tags_rocm5.7
         - .run_dependent
         - .needs_centos7_x86_64
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-hip-radeon:
+t:fedora43-hip-radeon:
     extends:
-        - .fedora42_hip_radeon
+        - .fedora43_hip_radeon
         - .cmake_test_linux_release
         - .linux_x86_64_tags_rocm6.2
         - .run_dependent
@@ -237,9 +319,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-makefiles-lfortran:
+t:fedora43-makefiles-lfortran:
     extends:
-        - .fedora42_makefiles_lfortran
+        - .fedora43_makefiles_lfortran
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -247,9 +329,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-ninja-lfortran:
+t:fedora43-ninja-lfortran:
     extends:
-        - .fedora42_ninja_lfortran
+        - .fedora43_ninja_lfortran
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -257,9 +339,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-ninja-clang:
+t:fedora43-ninja-clang:
     extends:
-        - .fedora42_ninja_clang
+        - .fedora43_ninja_clang
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -267,9 +349,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-ninja-multi-clang:
+t:fedora43-ninja-multi-clang:
     extends:
-        - .fedora42_ninja_multi_clang
+        - .fedora43_ninja_multi_clang
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -277,9 +359,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-makefiles-clang:
+t:fedora43-makefiles-clang:
     extends:
-        - .fedora42_makefiles_clang
+        - .fedora43_makefiles_clang
         - .cmake_test_linux_release
         - .linux_x86_64_tags
         - .run_dependent
@@ -287,17 +369,17 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-makefiles:
+t:fedora43-makefiles:
     extends:
-        - .fedora42_makefiles
+        - .fedora43_makefiles
         - .cmake_test_linux_release
         - .linux_x86_64_v3_tags
         - .run_dependent
         - .needs_centos7_x86_64
 
-t:fedora42-makefiles-nospace:
+t:fedora43-makefiles-nospace:
     extends:
-        - .fedora42_makefiles
+        - .fedora43_makefiles
         - .cmake_test_linux_release
         - .linux_x86_64_v3_tags
         - .cmake_junit_artifacts
@@ -305,7 +387,17 @@
         - .needs_centos7_x86_64
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
-        CMAKE_CI_BUILD_NAME: fedora42_makefiles_nospace
+        CMAKE_CI_BUILD_NAME: fedora43_makefiles_nospace
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:fedora43-fastbuild:
+    extends:
+        - .fedora43_fastbuild
+        - .cmake_test_linux_release
+        - .linux_x86_64_v3_tags
+        - .run_dependent
+        - .needs_centos7_x86_64
+    variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
 t:nvhpc24.9-ninja:
@@ -419,6 +511,8 @@
         - .cmake_junit_artifacts
         - .run_dependent
         - .needs_centos7_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
 
 t:cuda12.6-nvidia-clang:
     extends:
@@ -441,6 +535,26 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
+t:cuda13.0-nvidia:
+    extends:
+        - .cuda13.0_nvidia
+        - .cmake_test_linux_release
+        - .linux_x86_64_tags_cuda_arch_75
+        - .cmake_junit_artifacts
+        - .run_dependent
+        - .needs_centos7_x86_64
+
+t:cuda13.0-nvidia-fastbuild:
+    extends:
+        - .cuda13.0_nvidia_fastbuild
+        - .cmake_test_linux_release
+        - .linux_x86_64_tags_cuda_arch_75
+        - .cmake_junit_artifacts
+        - .run_dependent
+        - .needs_centos7_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 t:hip6.3-nvidia:
     extends:
         - .hip6.3_nvidia
@@ -461,6 +575,16 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
+t:linux-gcc-cxx-modules-reloc-ninja:
+    extends:
+        - .gcc_cxx_modules_reloc_ninja
+        - .cmake_test_linux_release
+        - .linux_x86_64_tags
+        - .run_dependent
+        - .needs_centos7_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 t:linux-gcc-cxx-modules-ninja:
     extends:
         - .gcc_cxx_modules_ninja
@@ -492,9 +616,9 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:fedora42-ninja:
+b:fedora43-ninja:
     extends:
-        - .fedora42_ninja
+        - .fedora43_ninja
         - .cmake_build_linux
         - .cmake_build_artifacts
         - .linux_x86_64_tags
@@ -502,9 +626,9 @@
     variables:
         CMAKE_CI_JOB_CONTINUOUS: "true"
 
-b:fedora42-makefiles-symlinked:
+b:fedora43-makefiles-symlinked:
     extends:
-        - .fedora42_makefiles_symlinked
+        - .fedora43_makefiles_symlinked
         - .cmake_build_linux
         - .cmake_build_artifacts
         - .linux_x86_64_tags
@@ -512,75 +636,75 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:debian12-makefiles-inplace:
+b:debian13-makefiles-inplace:
     extends:
-        - .debian12_makefiles_inplace
+        - .debian13_makefiles_inplace
         - .cmake_build_linux_standalone
         - .linux_x86_64_tags
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:debian12-extdeps:
+b:debian13-extdeps:
     extends:
-        - .debian12_extdeps
+        - .debian13_extdeps
         - .cmake_build_linux_standalone
         - .linux_x86_64_tags
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:debian12-aarch64-extdeps:
+b:debian13-aarch64-extdeps:
     extends:
-        - .debian12_aarch64_extdeps
+        - .debian13_aarch64_extdeps
         - .cmake_build_linux_standalone
         - .linux_aarch64_tags
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:fedora42-extdeps:
+b:fedora43-extdeps:
     extends:
-        - .fedora42_extdeps
+        - .fedora43_extdeps
         - .cmake_build_linux_standalone
         - .linux_x86_64_tags
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-ninja:
+t:fedora43-ninja:
     extends:
-        - .fedora42_ninja
+        - .fedora43_ninja
         - .cmake_test_linux
         - .linux_x86_64_tags_x11
         - .cmake_test_artifacts
         - .run_dependent
     needs:
-        - b:fedora42-ninja
+        - b:fedora43-ninja
     variables:
         CMAKE_CI_JOB_CONTINUOUS: "true"
 
-t:fedora42-makefiles-symlinked:
+t:fedora43-makefiles-symlinked:
     extends:
-        - .fedora42_makefiles_symlinked
+        - .fedora43_makefiles_symlinked
         - .cmake_test_linux
         - .linux_x86_64_tags_x11
         - .cmake_test_artifacts
         - .run_dependent
     needs:
-        - b:fedora42-makefiles-symlinked
+        - b:fedora43-makefiles-symlinked
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-ninja-multi:
+t:fedora43-ninja-multi:
     extends:
-        - .fedora42_ninja_multi
+        - .fedora43_ninja_multi
         - .cmake_test_linux_external
         - .linux_x86_64_tags
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:fedora42-ninja
+        - t:fedora43-ninja
 
 t:intel2016u2-makefiles:
     extends:
@@ -806,6 +930,13 @@
         CMAKE_CI_BUILD_NAME: oneapi2025.1.0_makefiles
         CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2025.1.0-rocky9
 
+t:oneapi2025.2.0-makefiles:
+    extends:
+        - .cmake_test_linux_inteloneapi_makefiles
+    variables:
+        CMAKE_CI_BUILD_NAME: oneapi2025.2.0_makefiles
+        CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2025.2.0-rocky9
+
 b:linux-x86_64-package:
     extends:
         - .linux_package
@@ -888,9 +1019,9 @@
 
 ## Sanitizer builds
 
-b:fedora42-asan:
+b:fedora43-asan:
     extends:
-        - .fedora42_asan
+        - .fedora43_asan
         - .cmake_build_linux
         - .cmake_build_artifacts
         - .linux_x86_64_tags
@@ -898,17 +1029,31 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:fedora42-asan:
+t:fedora43-asan:
     extends:
-        - .fedora42_asan
+        - .fedora43_asan
         - .cmake_memcheck_linux
         - .linux_x86_64_tags
+        - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - b:fedora42-asan
+        - b:fedora43-asan
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
+t:fedora43-ninja-valgrind:
+    extends:
+        - .fedora43_ninja_valgrind
+        - .cmake_test_linux_release
+        # Use a fast CPU so that timeouts are less of a concern.
+        - .linux_x86_64_tags_fast_x11
+        - .cmake_valgrind_artifacts
+        - .run_dependent
+        - .needs_centos7_x86_64
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+    timeout: 2 hours
+
 # macOS builds
 
 b:macos-x86_64-ninja:
@@ -941,16 +1086,6 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-b:macos-arm64-curl:
-    extends:
-        - .macos_arm64_curl
-        - .cmake_build_macos
-        - .cmake_build_artifacts
-        - .macos_arm64_tags
-        - .run_manually
-    variables:
-        CMAKE_CI_JOB_NIGHTLY: "true"
-
 b:macos-arm64-pch:
     extends:
         - .macos_arm64_pch
@@ -998,17 +1133,6 @@
         CMAKE_CI_JOB_NIGHTLY: "true"
         CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
 
-t:macos-arm64-curl:
-    extends:
-        - .macos_arm64_curl
-        - .cmake_test_macos
-        - .macos_arm64_tags
-        - .run_dependent
-    needs:
-        - b:macos-arm64-curl
-    variables:
-        CMAKE_CI_JOB_NIGHTLY: "true"
-
 b:macos-x86_64-makefiles:
     extends:
         - .macos_x86_64_makefiles
@@ -1060,6 +1184,18 @@
     needs:
         - t:macos-arm64-ninja
 
+t:macos-arm64-fastbuild:
+    extends:
+        - .macos_arm64_fastbuild
+        - .cmake_test_macos_external
+        - .macos_arm64_tags_ext
+        - .cmake_junit_artifacts
+        - .run_dependent
+    needs:
+        - t:macos-arm64-ninja
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
 t:macos-arm64-xcode-symlinked:
     extends:
         - .macos_arm64_xcode_symlinked
@@ -1082,7 +1218,7 @@
     needs:
         - t:macos-x86_64-ninja
     variables:
-        CMAKE_CI_JOB_NIGHTLY: "true"
+        CMAKE_CI_NO_MR: "true"
 
 t:macos-arm64-xcode-ub:
     extends:
@@ -1136,80 +1272,92 @@
 
 # Windows x86_64 jobs
 
-b:windows-vs2022-x64-ninja:
+b:windows-vs2026-x64-ninja:
     extends:
-        - .windows_vs2022_x64_ninja
+        - .windows_vs2026_x64_ninja
         - .cmake_build_windows
         - .cmake_build_artifacts
-        - .windows_x86_64_tags_nonconcurrent_vs2022
+        - .windows_x86_64_tags_nonconcurrent_vs2026
         - .run_manually
     variables:
         CMAKE_CI_JOB_CONTINUOUS: "true"
 
-b:windows-vs2022-x64-pch:
+b:windows-vs2026-x64-pch:
     extends:
-        - .windows_vs2022_x64_pch
+        - .windows_vs2026_x64_pch
         - .cmake_build_windows
-        - .windows_x86_64_tags_nonconcurrent_vs2022
+        - .windows_x86_64_tags_nonconcurrent_vs2026
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-vs2022-x64-ninja:
+t:windows-vs2026-x64-ninja:
     extends:
-        - .windows_vs2022_x64_ninja
+        - .windows_vs2026_x64_ninja
         - .cmake_test_windows
-        - .windows_x86_64_tags_nonconcurrent_vs2022
+        - .windows_x86_64_tags_nonconcurrent_vs2026
         - .cmake_test_artifacts
         - .run_dependent
     needs:
-        - b:windows-vs2022-x64-ninja
+        - b:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_CONTINUOUS: "true"
         CMAKE_CI_JOB_NIGHTLY_NINJA: "true"
 
-t:windows-vs2022-x64-ninja-multi:
+t:windows-vs2026-x64-ninja-multi:
     extends:
-        - .windows_vs2022_x64_ninja_multi
+        - .windows_vs2026_x64_ninja_multi
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent_vs2022
+        - .windows_x86_64_tags_concurrent_vs2026
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-.t:windows-vs2022-x64:
+.t:windows-vs2026-x64:
     extends:
-        - .windows_vs2022_x64
+        - .windows_vs2026_x64
         - .cmake_test_windows_external
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
 
-t:windows-vs2022-x64:
+t:windows-vs2026-x64:
     extends:
-        - .t:windows-vs2022-x64
-        - .windows_x86_64_tags_concurrent_vs2022
+        - .t:windows-vs2026-x64
+        - .windows_x86_64_tags_concurrent_vs2026
     variables:
         CMAKE_CI_JOB_NIGHTLY: "false"
 
-t:windows-vs2022-x64-nightly:
+t:windows-vs2026-x64-nightly:
     extends:
-        - .t:windows-vs2022-x64
-        - .windows_x86_64_tags_concurrent_vs2022_android
+        - .t:windows-vs2026-x64
+        - .windows_x86_64_tags_concurrent_vs2026_android
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-vs2022-x64-i18n:
+t:windows-vs2026-x64-i18n:
     extends:
-        - .t:windows-vs2022-x64
-        - .windows_x86_64_tags_concurrent_vs2022_android
+        - .t:windows-vs2026-x64
+        - .windows_x86_64_tags_concurrent_vs2026_android
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR\\cmake i18n cï\\$CI_CONCURRENT_ID"
-        CMAKE_CONFIGURATION: windows_vs2022_x64_i18n
+        CMAKE_CONFIGURATION: windows_vs2026_x64_i18n
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-vs2022-x64:
+    extends:
+        - .windows_vs2022_x64
+        - .cmake_test_windows_external
+        - .windows_x86_64_tags_concurrent_vs2022_android
+        - .cmake_junit_artifacts
+        - .run_dependent
+    needs:
+        - t:windows-vs2026-x64-ninja
+    variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
 t:windows-vs2019-x64:
@@ -1220,31 +1368,43 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-vs2022-x64-nmake:
+t:windows-vs2026-x64-nmake:
     extends:
-        - .windows_vs2022_x64_nmake
+        - .windows_vs2026_x64_nmake
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent_vs2022
+        - .windows_x86_64_tags_concurrent_vs2026
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-vs2022-x64-jom:
+t:windows-vs2026-x64-jom:
     extends:
-        - .windows_vs2022_x64_jom
+        - .windows_vs2026_x64_jom
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent_vs2022
+        - .windows_x86_64_tags_concurrent_vs2026
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-vs2026-x64-fastbuild:
+    extends:
+        - .windows_vs2026_x64_fastbuild
+        - .cmake_test_windows_external
+        - .windows_x86_64_tags_concurrent_vs2026
+        - .cmake_junit_artifacts
+        - .run_dependent
+    needs:
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1256,7 +1416,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1268,7 +1428,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1276,11 +1436,11 @@
     extends:
         - .windows_clang_ninja
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent
+        - .windows_x86_64_tags_concurrent_vs2022_msvc14.44
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1289,11 +1449,11 @@
     extends:
         - .windows_clang_nmake
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent
+        - .windows_x86_64_tags_concurrent_vs2022_msvc14.44
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_nmake
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1302,11 +1462,11 @@
     extends:
         - .windows_clang_ninja
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent
+        - .windows_x86_64_tags_concurrent_vs2022_msvc14.44
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1315,11 +1475,11 @@
     extends:
         - .windows_clang_nmake
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent
+        - .windows_x86_64_tags_concurrent_vs2022_msvc14.44
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_nmake
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1332,7 +1492,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_intel2021.9_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1341,11 +1501,11 @@
     extends:
         - .windows_inteloneapi_ninja
         - .cmake_test_windows_external
-        - .windows_x86_64_tags_concurrent_vs2022
+        - .windows_x86_64_tags_concurrent_vs2022_msvc14.44
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_BUILD_NAME: windows_oneapi2025.1_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
@@ -1358,7 +1518,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1370,7 +1530,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1382,7 +1542,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1394,7 +1554,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1406,31 +1566,43 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-vs2022-x64-ninja
+        - t:windows-vs2026-x64-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
 # Windows arm64 jobs
 
-b:windows-arm64-vs2022-ninja:
+b:windows-arm64-vs2026-ninja:
     extends:
-        - .windows_arm64_vs2022_ninja
+        - .windows_arm64_vs2026_ninja
         - .cmake_build_windows
         - .cmake_build_artifacts
-        - .windows_arm64_tags_nonconcurrent_vs2022
+        - .windows_arm64_tags_nonconcurrent_vs2026
         - .run_manually
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-arm64-vs2022-ninja:
+t:windows-arm64-vs2026-ninja:
     extends:
-        - .windows_arm64_vs2022_ninja
+        - .windows_arm64_vs2026_ninja
         - .cmake_test_windows
-        - .windows_arm64_tags_nonconcurrent_vs2022
+        - .windows_arm64_tags_nonconcurrent_vs2026
         - .cmake_test_artifacts
         - .run_dependent
     needs:
-        - b:windows-arm64-vs2022-ninja
+        - b:windows-arm64-vs2026-ninja
+    variables:
+        CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-arm64-vs2026:
+    extends:
+        - .windows_arm64_vs2026
+        - .cmake_test_windows_external
+        - .windows_arm64_tags_concurrent_vs2026
+        - .cmake_junit_artifacts
+        - .run_dependent
+    needs:
+        - t:windows-arm64-vs2026-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1442,7 +1614,7 @@
         - .cmake_junit_artifacts
         - .run_dependent
     needs:
-        - t:windows-arm64-vs2022-ninja
+        - t:windows-arm64-vs2026-ninja
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
@@ -1453,7 +1625,7 @@
         - .windows_x86_64_package
         - .cmake_build_windows
         - .cmake_build_package_artifacts
-        - .windows_x86_64_tags_nonconcurrent_vs2022
+        - .windows_x86_64_tags_nonconcurrent_vs2022_msvc14.44
         - .run_only_for_package
     needs:
         - p:doc-package
@@ -1484,7 +1656,7 @@
         - .windows_i386_package
         - .cmake_build_windows
         - .cmake_build_package_artifacts
-        - .windows_x86_64_tags_nonconcurrent_vs2022
+        - .windows_x86_64_tags_nonconcurrent_vs2022_msvc14.44
         - .run_only_for_package
     needs:
         - p:doc-package
@@ -1515,7 +1687,7 @@
         - .windows_arm64_package
         - .cmake_build_windows
         - .cmake_build_package_artifacts
-        - .windows_x86_64_tags_nonconcurrent_vs2022_arm64
+        - .windows_x86_64_tags_nonconcurrent_vs2026_arm64
         - .run_only_for_package
     needs:
         - p:doc-package
diff --git a/.gitlab/.gitignore b/.gitlab/.gitignore
index f66ad97..e8f9c98 100644
--- a/.gitlab/.gitignore
+++ b/.gitlab/.gitignore
@@ -1,7 +1,10 @@
 # Ignore files known to be downloaded by CI jobs.
 /5.15.1-0-202009071110*
+/appimagetool
 /bcc*
 /cmake*
+/emsdk
+/fastbuild
 /iar
 /intel
 /ispc*
diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml
index f11706c..e33cdc8 100644
--- a/.gitlab/artifacts.yml
+++ b/.gitlab/artifacts.yml
@@ -62,6 +62,13 @@
             - ${CMAKE_CI_BUILD_DIR}/DartConfiguration.tcl
             - ${CMAKE_CI_BUILD_DIR}/CTestCustom.cmake
             - ${CMAKE_CI_BUILD_DIR}/cdash-build-id
+
+            # CTest coverage files.
+            - ${CMAKE_CI_BUILD_DIR}/CMakeFiles/TargetDirectories.txt
+            - ${CMAKE_CI_BUILD_DIR}/Bullseye/
+            - ${CMAKE_CI_BUILD_DIR}/**/*.gcno
+            - ${CMAKE_CI_BUILD_DIR}/Source/QtDialog/moc_*.cpp
+            - ${CMAKE_CI_BUILD_DIR}/Source/QtDialog/ui_*.h
         reports:
             annotations:
                 - ${CMAKE_CI_BUILD_DIR}/annotations.json
@@ -139,6 +146,19 @@
             junit:
                 - ${CMAKE_CI_BUILD_DIR}/junit.xml
 
+.cmake_valgrind_artifacts:
+    artifacts:
+        expire_in: 1d
+        when: always
+        reports:
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
+            junit:
+                - ${CMAKE_CI_BUILD_DIR}/junit.xml
+        paths:
+            # Valgrind logs.
+            - ${CMAKE_CI_BUILD_DIR}/Testing/Temporary/MemoryChecker.*.log
+
 .cmake_sphinx_artifacts:
     artifacts:
         expire_in: 1d
@@ -167,6 +187,33 @@
             # Take the install tree.
             - ${CMAKE_CI_BUILD_DIR}/install/
 
+.cmake_coverage_artifacts:
+    artifacts:
+        expire_in: 1d
+        # External testing can be useful even if test jobs fail.
+        when: always
+        reports:
+            junit:
+                - ${CMAKE_CI_BUILD_DIR}/junit.xml
+            annotations:
+                - ${CMAKE_CI_BUILD_DIR}/annotations.json
+        paths:
+            # Generated sources.
+            - ${CMAKE_CI_BUILD_DIR}/Source/QtDialog/moc_*.cpp
+            - ${CMAKE_CI_BUILD_DIR}/Source/QtDialog/ui_*.h
+
+            # CTest coverage files.
+            - ${CMAKE_CI_BUILD_DIR}/CMakeFiles/TargetDirectories.txt
+            - ${CMAKE_CI_BUILD_DIR}/Bullseye/
+            - ${CMAKE_CI_BUILD_DIR}/**/*.gcno
+            - ${CMAKE_CI_BUILD_DIR}/**/*.gcda
+
+            # CTest/CDash information.
+            - ${CMAKE_CI_BUILD_DIR}/Testing/
+            - ${CMAKE_CI_BUILD_DIR}/DartConfiguration.tcl
+            - ${CMAKE_CI_BUILD_DIR}/CTestCustom.cmake
+            - ${CMAKE_CI_BUILD_DIR}/cdash-build-id
+
 .cmake_doc_artifacts:
     artifacts:
         expire_in: 1d
diff --git a/.gitlab/ci/.gitattributes b/.gitlab/ci/.gitattributes
new file mode 100644
index 0000000..b4f5f9d
--- /dev/null
+++ b/.gitlab/ci/.gitattributes
@@ -0,0 +1,2 @@
+# Do not apply a size limit to suppression files.
+*.valgrind.supp  -hooks-max-size
diff --git a/.gitlab/ci/appimagetool-env.sh b/.gitlab/ci/appimagetool-env.sh
new file mode 100644
index 0000000..1dd4674
--- /dev/null
+++ b/.gitlab/ci/appimagetool-env.sh
@@ -0,0 +1,3 @@
+.gitlab/ci/appimagetool.sh
+export PATH=$PWD/.gitlab/appimagetool/bin:$PATH
+appimagetool --version
diff --git a/.gitlab/ci/appimagetool.sh b/.gitlab/ci/appimagetool.sh
new file mode 100755
index 0000000..6ab430f
--- /dev/null
+++ b/.gitlab/ci/appimagetool.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+readonly version="1.9.0.20250814"
+
+case "$(uname -s)-$(uname -m)" in
+    Linux-x86_64)
+        shatool="sha256sum"
+        sha256sum="6414d395eafee09453d2e203d9cc65f867e6ff7e1a8a6c08e444d86cb1d106ad"
+        filename="appimagetool-$version-x86_64"
+        ;;
+    *)
+        echo "Unrecognized platform $(uname -s)-$(uname -m)"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+
+cd .gitlab
+
+# This URL is only visible inside of Kitware's network.  See above filename table.
+baseurl="https://cmake.org/files/dependencies/internal"
+
+tarball="$filename.tar.gz"
+echo "$sha256sum  $tarball" > appimagetool.sha256sum
+curl -OL "$baseurl/$tarball"
+$shatool --check appimagetool.sha256sum
+tar xzf "$tarball"
+rm "$tarball" appimagetool.sha256sum
+mv "$filename" "appimagetool"
diff --git a/.gitlab/ci/bullseye-env.sh b/.gitlab/ci/bullseye-env.sh
new file mode 100644
index 0000000..d3aa9d7
--- /dev/null
+++ b/.gitlab/ci/bullseye-env.sh
@@ -0,0 +1,14 @@
+# Install Bullseye
+.gitlab/ci/bullseye.sh
+unset CMAKE_CI_BULLSEYE_LICENSE
+
+# Make Bullseye tools available but do not override compilers.
+export PATH="$PATH:/opt/bullseye/bin"
+
+# Print the Bullseye startup banner once.
+covc --help 2>&1 | head -1
+
+# Suppress the Bullseye startup banner.
+for tool in cov01 covc; do
+  echo "--no-banner" > "/opt/bullseye/bin/$tool.cfg"
+done
diff --git a/.gitlab/ci/bullseye.sh b/.gitlab/ci/bullseye.sh
new file mode 100755
index 0000000..8c4cd2b
--- /dev/null
+++ b/.gitlab/ci/bullseye.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+set -e
+
+if ! test -f "$CMAKE_CI_BULLSEYE_LICENSE"; then
+    echo "No CMAKE_CI_BULLSEYE_LICENSE file provided!"
+    exit 1
+fi
+
+readonly version="9.22.3"
+
+case "$(uname -s)-$(uname -m)" in
+    Linux-x86_64)
+        tarball="BullseyeCoverage-$version-Linux-x64.tar.xz"
+        sha256sum="d5be7e65d9363161b67fa77a30407c7c200d995af79a422c4e2e278802ba0776"
+        shatool="sha256sum"
+        ;;
+    *)
+        echo "Unrecognized platform $(uname -s)-$(uname -m)"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+
+# See https://www.bullseye.com/download-archive for original archives.
+# This URL is only visible inside of Kitware's network.
+baseurl="https://cmake.org/files/dependencies/internal/bullseye"
+
+dirname="BullseyeCoverage-$version"
+echo "$sha256sum  $tarball" > bullseye.sha256sum
+curl -OL "$baseurl/$tarball"
+$shatool --check bullseye.sha256sum
+tar xJf "$tarball"
+"$dirname/install" --key "$(<"$CMAKE_CI_BULLSEYE_LICENSE")" --prefix=/opt/bullseye
+rm -r "$dirname" "$tarball" bullseye.sha256sum "$CMAKE_CI_BULLSEYE_LICENSE"
diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1
index 1353150..94f6694 100644
--- a/.gitlab/ci/cmake.ps1
+++ b/.gitlab/ci/cmake.ps1
@@ -1,12 +1,12 @@
 $erroractionpreference = "stop"
 
-$version = "3.31.5"
+$version = "4.2.0"
 
 if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
-    $sha256sum = "D4D2D4B9CCD68DAE975A066FCD42EA9807EF40F79EE6971923FD3788E7917585"
+    $sha256sum = "CF35A516C4F5F4646B301E51C8E24B168CC012C3B1453B8F675303B54EB0EF45"
     $platform = "windows-x86_64"
 } elseif ("$env:PROCESSOR_ARCHITECTURE" -eq "ARM64") {
-    $sha256sum = "A734E4E970FDAA4B5957157C059556F56CA5D655014CD4B5FD9194AABA316F31"
+    $sha256sum = "9EB3E88083DDA569A4086C48517F5D49BD7B505DADA79075EA7CB6E2AC6E0A1E"
     $platform = "windows-arm64"
 } else {
     throw ('unknown PROCESSOR_ARCHITECTURE: ' + "$env:PROCESSOR_ARCHITECTURE")
diff --git a/.gitlab/ci/cmake.sh b/.gitlab/ci/cmake.sh
index 10aba43..a0e2a5a 100755
--- a/.gitlab/ci/cmake.sh
+++ b/.gitlab/ci/cmake.sh
@@ -2,22 +2,22 @@
 
 set -e
 
-readonly version="3.31.5"
+readonly version="4.2.0"
 
 case "$(uname -s)-$(uname -m)" in
     Linux-x86_64)
         shatool="sha256sum"
-        sha256sum="2984e70515ff60c5e4a41922b5d715a8168a696a89721e3b114e36f453244f72"
+        sha256sum="bbcebd4c433eab3af03a8c80bb5d84e8dfc3ff8a4ab9d01547b21240c23f7c2c"
         platform="linux-x86_64"
         ;;
     Linux-aarch64)
         shatool="sha256sum"
-        sha256sum="eb92af175ea91e3706ff62484088c3a3774ef3e1a8c399111785dd5f47010164"
+        sha256sum="86f52e9769cd7745e5227931e689e122dc1afc5648cc9b04db601b165f3ac993"
         platform="linux-aarch64"
         ;;
     Darwin-*)
         shatool="shasum -a 256"
-        sha256sum="cc8e3d9bef7eee70db52601a5ed60d221436a8def18388effdab0e7d0866f50d"
+        sha256sum="b8b040a06343b2b6bc090b03a9c2bb4e98037518846989fb7c40ebbf30655c5d"
         platform="macos-universal"
         ;;
     *)
diff --git a/.gitlab/ci/configure_cuda13.0_nvidia.cmake b/.gitlab/ci/configure_cuda13.0_nvidia.cmake
new file mode 100644
index 0000000..71aafcf
--- /dev/null
+++ b/.gitlab/ci/configure_cuda13.0_nvidia.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_cuda13.0_nvidia_common.cmake")
diff --git a/.gitlab/ci/configure_cuda13.0_nvidia_common.cmake b/.gitlab/ci/configure_cuda13.0_nvidia_common.cmake
new file mode 100644
index 0000000..6a66194
--- /dev/null
+++ b/.gitlab/ci/configure_cuda13.0_nvidia_common.cmake
@@ -0,0 +1,8 @@
+set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
+set(CMake_TEST_CUDA_ARCH "75" CACHE STRING "")
+set(CMake_TEST_CUDA_CUPTI "ON" CACHE STRING "")
+set(CMake_TEST_CUDA_STANDARDS "03;11;14;17;20" CACHE STRING "")
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CUDA "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_cuda13.0_nvidia_fastbuild.cmake b/.gitlab/ci/configure_cuda13.0_nvidia_fastbuild.cmake
new file mode 100644
index 0000000..71aafcf
--- /dev/null
+++ b/.gitlab/ci/configure_cuda13.0_nvidia_fastbuild.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_cuda13.0_nvidia_common.cmake")
diff --git a/.gitlab/ci/configure_debian12_iwyu.cmake b/.gitlab/ci/configure_debian12_iwyu.cmake
deleted file mode 100644
index 37ccbf4..0000000
--- a/.gitlab/ci/configure_debian12_iwyu.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMake_RUN_IWYU ON CACHE BOOL "")
-set(CMake_IWYU_OPTIONS "-DCMAKE_IWYU_FORWARD_STD_HASH" CACHE STRING "")
-# Uncomment to diagnose IWYU problems as needed.
-#set(CMake_IWYU_VERBOSE ON CACHE BOOL "")
-set(IWYU_COMMAND "/usr/bin/include-what-you-use-15" CACHE FILEPATH "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_debian12_makefiles_clang.cmake b/.gitlab/ci/configure_debian12_makefiles_clang.cmake
deleted file mode 100644
index 9bd6275..0000000
--- a/.gitlab/ci/configure_debian12_makefiles_clang.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
-set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
-
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
-  set(CMake_TEST_TICLANG_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/ticlang" CACHE PATH "")
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian12_ninja.cmake b/.gitlab/ci/configure_debian12_ninja.cmake
deleted file mode 100644
index efca7a1..0000000
--- a/.gitlab/ci/configure_debian12_ninja.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-set(CMake_TEST_ASM_NASM "ON" CACHE BOOL "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_debian12_ninja_common.cmake")
-set(CMake_TEST_UseSWIG "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian12_ninja_clang.cmake b/.gitlab/ci/configure_debian12_ninja_clang.cmake
deleted file mode 100644
index 1a8e192..0000000
--- a/.gitlab/ci/configure_debian12_ninja_clang.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
-  set(CMake_TEST_TICLANG_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/ticlang" CACHE PATH "")
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian12_ninja_common.cmake b/.gitlab/ci/configure_debian12_ninja_common.cmake
deleted file mode 100644
index 3022725..0000000
--- a/.gitlab/ci/configure_debian12_ninja_common.cmake
+++ /dev/null
@@ -1,123 +0,0 @@
-set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
-set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
-
-set(CMake_TEST_CTestUpdate_BZR "ON" CACHE BOOL "")
-set(CMake_TEST_CTestUpdate_CVS "ON" CACHE BOOL "")
-set(CMake_TEST_CTestUpdate_GIT "ON" CACHE BOOL "")
-set(CMake_TEST_CTestUpdate_HG "ON" CACHE BOOL "")
-set(CMake_TEST_CTestUpdate_SVN "ON" CACHE BOOL "")
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_CTestUpdate_P4 "ON" CACHE BOOL "")
-endif()
-
-set(CMake_TEST_FindALSA "ON" CACHE BOOL "")
-set(CMake_TEST_FindASPELL "ON" CACHE BOOL "")
-set(CMake_TEST_FindBacktrace "ON" CACHE BOOL "")
-set(CMake_TEST_FindBLAS "All;static=1;Generic" CACHE STRING "")
-set(CMake_TEST_FindBoost "ON" CACHE BOOL "")
-set(CMake_TEST_FindBoost_Python "ON" CACHE BOOL "")
-set(CMake_TEST_FindBZip2 "ON" CACHE BOOL "")
-set(CMake_TEST_FindCups "ON" CACHE BOOL "")
-set(CMake_TEST_FindCURL "ON" CACHE BOOL "")
-set(CMake_TEST_FindDevIL "ON" CACHE BOOL "")
-set(CMake_TEST_FindDoxygen_Dot "ON" CACHE BOOL "")
-set(CMake_TEST_FindDoxygen "ON" CACHE BOOL "")
-set(CMake_TEST_FindEXPAT "ON" CACHE BOOL "")
-set(CMake_TEST_FindFontconfig "ON" CACHE BOOL "")
-set(CMake_TEST_FindFreetype "ON" CACHE BOOL "")
-set(CMake_TEST_FindGDAL "ON" CACHE BOOL "")
-set(CMake_TEST_FindGIF "ON" CACHE BOOL "")
-set(CMake_TEST_FindGit "ON" CACHE BOOL "")
-set(CMake_TEST_FindGLEW "ON" CACHE BOOL "")
-set(CMake_TEST_FindGLUT "ON" CACHE BOOL "")
-set(CMake_TEST_FindGnuTLS "ON" CACHE BOOL "")
-set(CMake_TEST_FindGSL "ON" CACHE BOOL "")
-set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
-set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5 "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_MPICH_C_COMPILER "/usr/bin/h5pcc.mpich" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_MPICH_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER "/usr/bin/h5pfc.mpich" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER "/usr/bin/h5pcc.openmpi" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER "/usr/bin/h5pfc.openmpi" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
-set(CMake_TEST_FindHDF5_Serial_C_COMPILER "/usr/bin/h5cc" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_Serial_CXX_COMPILER "/usr/bin/h5c++" CACHE FILEPATH "")
-set(CMake_TEST_FindHDF5_Serial_Fortran_COMPILER "/usr/bin/h5fc" CACHE FILEPATH "")
-set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
-set(CMake_TEST_FindICU "ON" CACHE BOOL "")
-set(CMake_TEST_FindImageMagick "ON" CACHE BOOL "")
-set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
-set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
-set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
-set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
-set(CMake_TEST_FindLAPACK "All;static=1;Generic" CACHE STRING "")
-set(CMake_TEST_FindLibArchive "ON" CACHE BOOL "")
-set(CMake_TEST_FindLibinput "ON" CACHE BOOL "")
-set(CMake_TEST_FindLibLZMA "ON" CACHE BOOL "")
-set(CMake_TEST_FindLibUV "ON" CACHE BOOL "")
-set(CMake_TEST_FindLibXml2 "ON" CACHE BOOL "")
-set(CMake_TEST_FindLibXslt "ON" CACHE BOOL "")
-set(CMake_TEST_FindMPI_C "ON" CACHE BOOL "")
-set(CMake_TEST_FindMPI_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_FindMPI_Fortran "ON" CACHE BOOL "")
-set(CMake_TEST_FindMPI "ON" CACHE BOOL "")
-set(CMake_TEST_FindODBC "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_C "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_Fortran "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenAL "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenSP "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenSSL "ON" CACHE BOOL "")
-set(CMake_TEST_FindPatch "ON" CACHE BOOL "")
-set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
-set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "")
-set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "")
-set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython3 "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython3_IronPython "ON" CACHE BOOL "")
-set(CMake_TEST_FindPython3_PyPy "ON" CACHE BOOL "")
-set(CMake_TEST_FindRuby "ON" CACHE BOOL "")
-#set(CMake_TEST_FindRuby_RBENV "ON" CACHE BOOL "") # fails because system and rbenv versions are same
-set(CMake_TEST_FindRuby_RVM "ON" CACHE BOOL "")
-set(CMake_TEST_FindSDL "ON" CACHE BOOL "")
-set(CMake_TEST_FindSQLite3 "ON" CACHE BOOL "")
-set(CMake_TEST_FindTIFF "ON" CACHE BOOL "")
-set(CMake_TEST_FindwxWidgets "ON" CACHE BOOL "")
-set(CMake_TEST_FindX11 "ON" CACHE BOOL "")
-set(CMake_TEST_FindXalanC "ON" CACHE BOOL "")
-set(CMake_TEST_FindXercesC "ON" CACHE BOOL "")
-
-set(CMake_TEST_ELF_LARGE "ON" CACHE BOOL "")
-set(CMake_TEST_Fortran_SUBMODULES "ON" CACHE BOOL "")
-set(CMake_TEST_IPO_WORKS_C "ON" CACHE BOOL "")
-set(CMake_TEST_IPO_WORKS_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_IPO_WORKS_Fortran "ON" CACHE BOOL "")
-set(CMake_TEST_JQ "/usr/bin/jq" CACHE PATH "")
-set(CMake_TEST_Qt5 "ON" CACHE BOOL "")
-set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
-
-if (NOT "$ENV{SWIFTC}" STREQUAL "")
-  set(CMAKE_Swift_COMPILER "$ENV{SWIFTC}" CACHE FILEPATH "")
-endif()
-
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian12_ninja_multi_symlinked.cmake b/.gitlab/ci/configure_debian12_ninja_multi_symlinked.cmake
deleted file mode 100644
index 646dac8..0000000
--- a/.gitlab/ci/configure_debian12_ninja_multi_symlinked.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_symlinked_common.cmake")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_debian12_ninja_common.cmake")
-set(CMake_TEST_UseSWIG "OFF" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian12_aarch64_extdeps.cmake b/.gitlab/ci/configure_debian13_aarch64_extdeps.cmake
similarity index 100%
rename from .gitlab/ci/configure_debian12_aarch64_extdeps.cmake
rename to .gitlab/ci/configure_debian13_aarch64_extdeps.cmake
diff --git a/.gitlab/ci/configure_debian12_aarch64_ninja.cmake b/.gitlab/ci/configure_debian13_aarch64_ninja.cmake
similarity index 100%
rename from .gitlab/ci/configure_debian12_aarch64_ninja.cmake
rename to .gitlab/ci/configure_debian13_aarch64_ninja.cmake
diff --git a/.gitlab/ci/configure_debian12_extdeps.cmake b/.gitlab/ci/configure_debian13_extdeps.cmake
similarity index 100%
rename from .gitlab/ci/configure_debian12_extdeps.cmake
rename to .gitlab/ci/configure_debian13_extdeps.cmake
diff --git a/.gitlab/ci/configure_debian12_hip_radeon.cmake b/.gitlab/ci/configure_debian13_hip_radeon.cmake
similarity index 100%
rename from .gitlab/ci/configure_debian12_hip_radeon.cmake
rename to .gitlab/ci/configure_debian13_hip_radeon.cmake
diff --git a/.gitlab/ci/configure_debian13_iwyu.cmake b/.gitlab/ci/configure_debian13_iwyu.cmake
new file mode 100644
index 0000000..150eb9c
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_iwyu.cmake
@@ -0,0 +1,7 @@
+set(CMake_RUN_IWYU ON CACHE BOOL "")
+set(CMake_IWYU_OPTIONS "-DCMAKE_IWYU_FORWARD_STD_HASH" CACHE STRING "")
+# Uncomment to diagnose IWYU problems as needed.
+#set(CMake_IWYU_VERBOSE ON CACHE BOOL "")
+set(IWYU_COMMAND "/usr/bin/include-what-you-use-19" CACHE FILEPATH "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_debian13_makefiles_clang.cmake b/.gitlab/ci/configure_debian13_makefiles_clang.cmake
new file mode 100644
index 0000000..c0cf7b5
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_makefiles_clang.cmake
@@ -0,0 +1,11 @@
+set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
+set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
+
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
+  set(CMake_TEST_TICLANG_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/ticlang" CACHE PATH "")
+  set(CMake_TEST_Emscripten_TOOLCHAINS "$ENV{EMSDK}/upstream/emscripten" CACHE PATH "")
+  set(CMake_TEST_Emscripten_NODE "$ENV{EMSDK_NODE}" CACHE PATH "")
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian12_makefiles_inplace.cmake b/.gitlab/ci/configure_debian13_makefiles_inplace.cmake
similarity index 100%
rename from .gitlab/ci/configure_debian12_makefiles_inplace.cmake
rename to .gitlab/ci/configure_debian13_makefiles_inplace.cmake
diff --git a/.gitlab/ci/configure_debian13_ninja.cmake b/.gitlab/ci/configure_debian13_ninja.cmake
new file mode 100644
index 0000000..89d9818
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_ninja.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_ASM_NASM "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_debian13_ninja_common.cmake")
+set(CMake_TEST_UseSWIG "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian13_ninja_clang.cmake b/.gitlab/ci/configure_debian13_ninja_clang.cmake
new file mode 100644
index 0000000..8280304
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_ninja_clang.cmake
@@ -0,0 +1,8 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
+  set(CMake_TEST_TICLANG_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/ticlang" CACHE PATH "")
+  set(CMake_TEST_Emscripten_TOOLCHAINS "$ENV{EMSDK}/upstream/emscripten" CACHE PATH "")
+  set(CMake_TEST_Emscripten_NODE "$ENV{EMSDK_NODE}" CACHE PATH "")
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian13_ninja_common.cmake b/.gitlab/ci/configure_debian13_ninja_common.cmake
new file mode 100644
index 0000000..b638f75
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_ninja_common.cmake
@@ -0,0 +1,123 @@
+set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
+set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
+
+set(CMake_TEST_CTestUpdate_BZR "ON" CACHE BOOL "")
+set(CMake_TEST_CTestUpdate_CVS "ON" CACHE BOOL "")
+set(CMake_TEST_CTestUpdate_GIT "ON" CACHE BOOL "")
+set(CMake_TEST_CTestUpdate_HG "ON" CACHE BOOL "")
+set(CMake_TEST_CTestUpdate_SVN "ON" CACHE BOOL "")
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_CTestUpdate_P4 "ON" CACHE BOOL "")
+endif()
+
+set(CMake_TEST_FindALSA "ON" CACHE BOOL "")
+set(CMake_TEST_FindASPELL "ON" CACHE BOOL "")
+set(CMake_TEST_FindBacktrace "ON" CACHE BOOL "")
+set(CMake_TEST_FindBLAS "All;static=1;Generic" CACHE STRING "")
+set(CMake_TEST_FindBoost "ON" CACHE BOOL "")
+set(CMake_TEST_FindBoost_Python "ON" CACHE BOOL "")
+set(CMake_TEST_FindBZip2 "ON" CACHE BOOL "")
+set(CMake_TEST_FindCups "ON" CACHE BOOL "")
+set(CMake_TEST_FindCURL "ON" CACHE BOOL "")
+set(CMake_TEST_FindDevIL "ON" CACHE BOOL "")
+set(CMake_TEST_FindDoxygen_Dot "ON" CACHE BOOL "")
+set(CMake_TEST_FindDoxygen "ON" CACHE BOOL "")
+set(CMake_TEST_FindEXPAT "ON" CACHE BOOL "")
+set(CMake_TEST_FindFontconfig "ON" CACHE BOOL "")
+set(CMake_TEST_FindFreetype "ON" CACHE BOOL "")
+set(CMake_TEST_FindGDAL "ON" CACHE BOOL "")
+set(CMake_TEST_FindGIF "ON" CACHE BOOL "")
+set(CMake_TEST_FindGit "ON" CACHE BOOL "")
+set(CMake_TEST_FindGLEW "ON" CACHE BOOL "")
+set(CMake_TEST_FindGLUT "ON" CACHE BOOL "")
+set(CMake_TEST_FindGnuTLS "ON" CACHE BOOL "")
+set(CMake_TEST_FindGSL "ON" CACHE BOOL "")
+set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
+set(CMake_TEST_FindGTK2 "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5 "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_MPICH_C_COMPILER "/usr/bin/h5pcc.mpich" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_MPICH_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER "/usr/bin/h5c++.mpich" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_MPICH_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER "/usr/bin/h5pfc.mpich" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_MPICH_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER "/usr/bin/h5pcc.openmpi" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_OpenMPI_C_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER "/usr/bin/h5c++.openmpi" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_OpenMPI_CXX_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER "/usr/bin/h5pfc.openmpi" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_OpenMPI_Fortran_COMPILER_EXPLICIT "ON" CACHE BOOL "")
+set(CMake_TEST_FindHDF5_Serial_C_COMPILER "/usr/bin/h5cc" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_Serial_CXX_COMPILER "/usr/bin/h5c++" CACHE FILEPATH "")
+set(CMake_TEST_FindHDF5_Serial_Fortran_COMPILER "/usr/bin/h5fc" CACHE FILEPATH "")
+set(CMake_TEST_FindIconv "ON" CACHE BOOL "")
+set(CMake_TEST_FindICU "ON" CACHE BOOL "")
+set(CMake_TEST_FindImageMagick "ON" CACHE BOOL "")
+set(CMake_TEST_FindIntl "ON" CACHE BOOL "")
+set(CMake_TEST_FindJNI "ON" CACHE BOOL "")
+set(CMake_TEST_FindJPEG "ON" CACHE BOOL "")
+set(CMake_TEST_FindJsonCpp "ON" CACHE BOOL "")
+set(CMake_TEST_FindLAPACK "All;static=1;Generic" CACHE STRING "")
+set(CMake_TEST_FindLibArchive "ON" CACHE BOOL "")
+set(CMake_TEST_FindLibinput "ON" CACHE BOOL "")
+set(CMake_TEST_FindLibLZMA "ON" CACHE BOOL "")
+set(CMake_TEST_FindLibUV "ON" CACHE BOOL "")
+set(CMake_TEST_FindLibXml2 "ON" CACHE BOOL "")
+set(CMake_TEST_FindLibXslt "ON" CACHE BOOL "")
+set(CMake_TEST_FindMPI_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindMPI_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_FindMPI_Fortran "ON" CACHE BOOL "")
+set(CMake_TEST_FindMPI "ON" CACHE BOOL "")
+set(CMake_TEST_FindODBC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_Fortran "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenAL "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenSP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenSSL "ON" CACHE BOOL "")
+set(CMake_TEST_FindPatch "ON" CACHE BOOL "")
+set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
+set(CMake_TEST_FindPostgreSQL "ON" CACHE BOOL "")
+set(CMake_TEST_FindProtobuf "ON" CACHE BOOL "")
+set(CMake_TEST_FindProtobuf_gRPC "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3 "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_IronPython "ON" CACHE BOOL "")
+set(CMake_TEST_FindPython3_PyPy "ON" CACHE BOOL "")
+set(CMake_TEST_FindRuby "ON" CACHE BOOL "")
+set(CMake_TEST_FindRuby_RBENV "ON" CACHE BOOL "")
+set(CMake_TEST_FindRuby_RVM "ON" CACHE BOOL "")
+set(CMake_TEST_FindSDL "ON" CACHE BOOL "")
+set(CMake_TEST_FindSQLite3 "ON" CACHE BOOL "")
+set(CMake_TEST_FindTIFF "ON" CACHE BOOL "")
+set(CMake_TEST_FindwxWidgets "ON" CACHE BOOL "")
+set(CMake_TEST_FindX11 "ON" CACHE BOOL "")
+set(CMake_TEST_FindXalanC "ON" CACHE BOOL "")
+set(CMake_TEST_FindXercesC "ON" CACHE BOOL "")
+
+set(CMake_TEST_ELF_LARGE "ON" CACHE BOOL "")
+set(CMake_TEST_Fortran_SUBMODULES "ON" CACHE BOOL "")
+set(CMake_TEST_IPO_WORKS_C "ON" CACHE BOOL "")
+set(CMake_TEST_IPO_WORKS_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_IPO_WORKS_Fortran "ON" CACHE BOOL "")
+set(CMake_TEST_JQ "/usr/bin/jq" CACHE PATH "")
+set(CMake_TEST_Qt5 "ON" CACHE BOOL "")
+set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
+
+if (NOT "$ENV{SWIFTC}" STREQUAL "")
+  set(CMAKE_Swift_COMPILER "$ENV{SWIFTC}" CACHE FILEPATH "")
+endif()
+
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian13_ninja_multi_symlinked.cmake b/.gitlab/ci/configure_debian13_ninja_multi_symlinked.cmake
new file mode 100644
index 0000000..7455791
--- /dev/null
+++ b/.gitlab/ci/configure_debian13_ninja_multi_symlinked.cmake
@@ -0,0 +1,7 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_IAR_TOOLCHAINS "/opt/iarsystems" CACHE PATH "")
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_symlinked_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_debian13_ninja_common.cmake")
+set(CMake_TEST_UseSWIG "OFF" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_fedora42_asan.cmake b/.gitlab/ci/configure_fedora42_asan.cmake
deleted file mode 100644
index 60a3cb1..0000000
--- a/.gitlab/ci/configure_fedora42_asan.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "")
-set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "")
-set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_clang_analyzer.cmake b/.gitlab/ci/configure_fedora42_clang_analyzer.cmake
deleted file mode 100644
index c484570..0000000
--- a/.gitlab/ci/configure_fedora42_clang_analyzer.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-set(configure_no_sccache 1)
-set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_common_clang.cmake b/.gitlab/ci/configure_fedora42_common_clang.cmake
deleted file mode 100644
index a4ae3f3..0000000
--- a/.gitlab/ci/configure_fedora42_common_clang.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-set(CMAKE_Fortran_COMPILER "/usr/bin/flang-new" CACHE FILEPATH "")
-set(CMAKE_Fortran_COMPILER_ID "LLVMFlang" CACHE STRING "")
-set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "1" CACHE BOOL "")
-
-set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
-set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23;26" CACHE STRING "")
-
-set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_C "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenACC_Fortran "OFF" CACHE BOOL "") # flang-new fails producing LLVM IR
-set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
-set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora42_extdeps.cmake b/.gitlab/ci/configure_fedora42_extdeps.cmake
deleted file mode 100644
index 8e545f5..0000000
--- a/.gitlab/ci/configure_fedora42_extdeps.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_extdeps_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_makefiles_clang.cmake b/.gitlab/ci/configure_fedora42_makefiles_clang.cmake
deleted file mode 100644
index 36588a5..0000000
--- a/.gitlab/ci/configure_fedora42_makefiles_clang.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora42_makefiles_lfortran.cmake b/.gitlab/ci/configure_fedora42_makefiles_lfortran.cmake
deleted file mode 100644
index ae32c04..0000000
--- a/.gitlab/ci/configure_fedora42_makefiles_lfortran.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_lfortran.cmake")
diff --git a/.gitlab/ci/configure_fedora42_makefiles_symlinked.cmake b/.gitlab/ci/configure_fedora42_makefiles_symlinked.cmake
deleted file mode 100644
index e498a48..0000000
--- a/.gitlab/ci/configure_fedora42_makefiles_symlinked.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-set(CMake_QT_MAJOR_VERSION "6" CACHE STRING "")
-set(CMake_TEST_GUI "ON" CACHE BOOL "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_symlinked_common.cmake")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_ninja.cmake b/.gitlab/ci/configure_fedora42_ninja.cmake
deleted file mode 100644
index 07ce93b..0000000
--- a/.gitlab/ci/configure_fedora42_ninja.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-set(CMake_TEST_GUI "ON" CACHE BOOL "")
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_ISPC "ON" CACHE STRING "")
-endif()
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
-set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
-
-# "Release" flags without "-DNDEBUG" so we get assertions.
-set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "")
-set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "")
-
-# Cover compilation with C++11 only and not higher standards.
-set(CMAKE_CXX_STANDARD "11" CACHE STRING "")
-# Qt 6 requires C++17, so use Qt 5.
-set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_ninja_clang.cmake b/.gitlab/ci/configure_fedora42_ninja_clang.cmake
deleted file mode 100644
index c95388f..0000000
--- a/.gitlab/ci/configure_fedora42_ninja_clang.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database,import_std23" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora42_ninja_lfortran.cmake b/.gitlab/ci/configure_fedora42_ninja_lfortran.cmake
deleted file mode 100644
index ae32c04..0000000
--- a/.gitlab/ci/configure_fedora42_ninja_lfortran.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_lfortran.cmake")
diff --git a/.gitlab/ci/configure_fedora42_ninja_multi_clang.cmake b/.gitlab/ci/configure_fedora42_ninja_multi_clang.cmake
deleted file mode 100644
index a1c7fc0..0000000
--- a/.gitlab/ci/configure_fedora42_ninja_multi_clang.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora42_tidy.cmake b/.gitlab/ci/configure_fedora42_tidy.cmake
deleted file mode 100644
index f5dbe06..0000000
--- a/.gitlab/ci/configure_fedora42_tidy.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
-set(CMake_USE_CLANG_TIDY_MODULE ON CACHE BOOL "")
-set(CMake_CLANG_TIDY_MODULE "$ENV{CI_PROJECT_DIR}/Utilities/ClangTidyModule/build/libcmake-clang-tidy-module.so" CACHE FILEPATH "")
-set(CMake_CLANG_TIDY_EXPORT_FIXES_DIR "$ENV{CI_PROJECT_DIR}/.gitlab/clang-tidy-fixes" CACHE PATH "")
-set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora42_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_asan.cmake b/.gitlab/ci/configure_fedora43_asan.cmake
new file mode 100644
index 0000000..9913430
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_asan.cmake
@@ -0,0 +1,5 @@
+set(CMAKE_C_FLAGS "-fsanitize=address" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "-fsanitize=address" CACHE STRING "")
+set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_bullseye_coverage.cmake b/.gitlab/ci/configure_fedora43_bullseye_coverage.cmake
new file mode 100644
index 0000000..f9dabd8
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_bullseye_coverage.cmake
@@ -0,0 +1,21 @@
+# Compile with Bullseye compiler wrappers, but do not test with them.
+set(CMAKE_C_COMPILER "/opt/bullseye/bin/cc" CACHE PATH "")
+set(CMAKE_CXX_COMPILER "/opt/bullseye/bin/c++" CACHE PATH "")
+
+# Bullseye records a COVFILE id in object files, so they cannot be cached.
+set(configure_no_sccache 1)
+
+# Do not bootstrap for the coverage test suite.
+set(CMAKE_SKIP_BOOTSTRAP_TEST TRUE CACHE BOOL "")
+
+# Shrink stress tests when running with Bullseye.
+set(ENV{KWSYS_TEST_PROCESS_1_COUNT} 11)
+
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_clang_analyzer.cmake b/.gitlab/ci/configure_fedora43_clang_analyzer.cmake
new file mode 100644
index 0000000..c18dfe6
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_clang_analyzer.cmake
@@ -0,0 +1,4 @@
+set(configure_no_sccache 1)
+set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_clazy.cmake b/.gitlab/ci/configure_fedora43_clazy.cmake
new file mode 100644
index 0000000..1943447
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_clazy.cmake
@@ -0,0 +1,5 @@
+set(configure_no_sccache 1)
+set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
+set(CMAKE_USE_SYSTEM_JSONCPP ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_common.cmake b/.gitlab/ci/configure_fedora43_common.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_common.cmake
rename to .gitlab/ci/configure_fedora43_common.cmake
diff --git a/.gitlab/ci/configure_fedora43_common_clang.cmake b/.gitlab/ci/configure_fedora43_common_clang.cmake
new file mode 100644
index 0000000..941a040
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_common_clang.cmake
@@ -0,0 +1,17 @@
+set(CMAKE_Fortran_COMPILER "/usr/bin/flang-21" CACHE FILEPATH "")
+set(CMAKE_Fortran_COMPILER_ID "LLVMFlang" CACHE STRING "")
+set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "1" CACHE BOOL "")
+
+set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
+set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23;26" CACHE STRING "")
+
+set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenACC_Fortran "OFF" CACHE BOOL "") # flang-new fails producing LLVM IR
+set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora42_common_lfortran.cmake b/.gitlab/ci/configure_fedora43_common_lfortran.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_common_lfortran.cmake
rename to .gitlab/ci/configure_fedora43_common_lfortran.cmake
diff --git a/.gitlab/ci/configure_debian12_extdeps.cmake b/.gitlab/ci/configure_fedora43_extdeps.cmake
similarity index 100%
copy from .gitlab/ci/configure_debian12_extdeps.cmake
copy to .gitlab/ci/configure_fedora43_extdeps.cmake
diff --git a/.gitlab/ci/configure_fedora43_fastbuild.cmake b/.gitlab/ci/configure_fedora43_fastbuild.cmake
new file mode 100644
index 0000000..20863a2
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_fastbuild.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora43_gcc_gcov.cmake b/.gitlab/ci/configure_fedora43_gcc_gcov.cmake
new file mode 100644
index 0000000..0b0f46d
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_gcc_gcov.cmake
@@ -0,0 +1,41 @@
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
+
+string(CONCAT coverage_flags
+  "--coverage "
+  "-fprofile-abs-path "
+  # These files are committed generated sources and contain relative path
+  # `#line` directives. CI coverage then cannot find the source files reliably.
+  # See related issue #20001.
+  "-fprofile-exclude-files=cmExprParser[.].*\\;cmFortranParser[.].* "
+  "-fdiagnostics-show-option "
+  "-Wall "
+  "-Wextra "
+  "-Wshadow "
+  "-Wpointer-arith "
+  "-Winvalid-pch "
+  "-Wcast-align "
+  "-Wdisabled-optimization "
+  "-Wwrite-strings "
+  "-fstack-protector-all "
+  "-Wconversion "
+  "-Wno-error=sign-conversion "
+  "-Wno-error=conversion ")
+string(CONCAT link_flags
+  "--coverage ")
+
+set(CMAKE_C_FLAGS "${coverage_flags}" CACHE STRING "")
+set(CMAKE_CXX_FLAGS "${coverage_flags} -Woverloaded-virtual -Wstrict-null-sentinel" CACHE STRING "")
+# Apply `LDFLAGS`.
+set(CMAKE_EXE_LINKER_FLAGS_INIT "${link_flags}" CACHE STRING "")
+set(CMAKE_SHARED_LINKER_FLAGS_INIT "${link_flags}" CACHE STRING "")
+set(CMAKE_MODULE_LINKER_FLAGS_INIT "${link_flags}" CACHE STRING "")
+
+# Do not bootstrap for the coverage test suite.
+set(CMAKE_SKIP_BOOTSTRAP_TEST TRUE CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora42_hip_radeon.cmake b/.gitlab/ci/configure_fedora43_hip_radeon.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_hip_radeon.cmake
rename to .gitlab/ci/configure_fedora43_hip_radeon.cmake
diff --git a/.gitlab/ci/configure_fedora42_makefiles.cmake b/.gitlab/ci/configure_fedora43_makefiles.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_makefiles.cmake
rename to .gitlab/ci/configure_fedora43_makefiles.cmake
diff --git a/.gitlab/ci/configure_fedora43_makefiles_clang.cmake b/.gitlab/ci/configure_fedora43_makefiles_clang.cmake
new file mode 100644
index 0000000..e3f1ef9
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_makefiles_clang.cmake
@@ -0,0 +1,5 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMAKE_TESTS_CDASH_SERVER "https://open.cdash.org" CACHE STRING "")
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora43_makefiles_lfortran.cmake b/.gitlab/ci/configure_fedora43_makefiles_lfortran.cmake
new file mode 100644
index 0000000..918c2c3
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_makefiles_lfortran.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common_lfortran.cmake")
diff --git a/.gitlab/ci/configure_fedora43_makefiles_symlinked.cmake b/.gitlab/ci/configure_fedora43_makefiles_symlinked.cmake
new file mode 100644
index 0000000..c5ef84c
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_makefiles_symlinked.cmake
@@ -0,0 +1,5 @@
+set(CMake_QT_MAJOR_VERSION "6" CACHE STRING "")
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_symlinked_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_ninja.cmake b/.gitlab/ci/configure_fedora43_ninja.cmake
new file mode 100644
index 0000000..43cfbba
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_ninja.cmake
@@ -0,0 +1,22 @@
+set(CMake_TEST_GUI "ON" CACHE BOOL "")
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_CPACK_APPIMAGE "ON" CACHE STRING "")
+  set(CMake_TEST_CPACK_APPIMAGE_RUNTIME_FILE "$ENV{CI_PROJECT_DIR}/.gitlab/appimagetool/lib/appimagetool/runtime" CACHE FILEPATH "")
+  set(CMake_TEST_ISPC "ON" CACHE STRING "")
+endif()
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION "1.3" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
+
+# "Release" flags without "-DNDEBUG" so we get assertions.
+set(CMAKE_C_FLAGS_RELEASE "-O3" CACHE STRING "")
+set(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE STRING "")
+
+# Cover compilation with C++11 only and not higher standards.
+set(CMAKE_CXX_STANDARD "11" CACHE STRING "")
+# Qt 6 requires C++17, so use Qt 5.
+set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_ninja_clang.cmake b/.gitlab/ci/configure_fedora43_ninja_clang.cmake
new file mode 100644
index 0000000..6cf0f85
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_ninja_clang.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database,import_std23" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora43_ninja_lfortran.cmake b/.gitlab/ci/configure_fedora43_ninja_lfortran.cmake
new file mode 100644
index 0000000..918c2c3
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_ninja_lfortran.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common_lfortran.cmake")
diff --git a/.gitlab/ci/configure_fedora42_ninja_multi.cmake b/.gitlab/ci/configure_fedora43_ninja_multi.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_ninja_multi.cmake
rename to .gitlab/ci/configure_fedora43_ninja_multi.cmake
diff --git a/.gitlab/ci/configure_fedora43_ninja_multi_clang.cmake b/.gitlab/ci/configure_fedora43_ninja_multi_clang.cmake
new file mode 100644
index 0000000..522d012
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_ninja_multi_clang.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common_clang.cmake")
diff --git a/.gitlab/ci/configure_fedora43_ninja_valgrind.cmake b/.gitlab/ci/configure_fedora43_ninja_valgrind.cmake
new file mode 100644
index 0000000..d156e20
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_ninja_valgrind.cmake
@@ -0,0 +1,6 @@
+set(CMake_TEST_Qt5 ON CACHE BOOL "")
+set(CMake_TEST_Qt6 ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_valgrind.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_ninja.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_fedora42_sphinx.cmake b/.gitlab/ci/configure_fedora43_sphinx.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_sphinx.cmake
rename to .gitlab/ci/configure_fedora43_sphinx.cmake
diff --git a/.gitlab/ci/configure_fedora42_sphinx_package.cmake b/.gitlab/ci/configure_fedora43_sphinx_package.cmake
similarity index 100%
rename from .gitlab/ci/configure_fedora42_sphinx_package.cmake
rename to .gitlab/ci/configure_fedora43_sphinx_package.cmake
diff --git a/.gitlab/ci/configure_fedora43_tidy.cmake b/.gitlab/ci/configure_fedora43_tidy.cmake
new file mode 100644
index 0000000..5b0bd62
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_tidy.cmake
@@ -0,0 +1,7 @@
+set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
+set(CMake_USE_CLANG_TIDY_MODULE ON CACHE BOOL "")
+set(CMake_CLANG_TIDY_MODULE "$ENV{CI_PROJECT_DIR}/Utilities/ClangTidyModule/build/libcmake-clang-tidy-module.so" CACHE FILEPATH "")
+set(CMake_CLANG_TIDY_EXPORT_FIXES_DIR "$ENV{CI_PROJECT_DIR}/.gitlab/clang-tidy-fixes" CACHE PATH "")
+set(CMake_QT_MAJOR_VERSION "5" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_fedora43_common.cmake")
diff --git a/.gitlab/ci/configure_fedora43_valgrind.cmake b/.gitlab/ci/configure_fedora43_valgrind.cmake
new file mode 100644
index 0000000..0175395
--- /dev/null
+++ b/.gitlab/ci/configure_fedora43_valgrind.cmake
@@ -0,0 +1,2 @@
+# Disable bootstrap testing for Valgrind testing.
+set(CMAKE_SKIP_BOOTSTRAP_TEST OFF CACHE BOOL "")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
new file mode 100644
index 0000000..75e94df
--- /dev/null
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
@@ -0,0 +1,13 @@
+# "Misplace" the `libstdc++.modules.json` file so that
+# `CMAKE_CXX_STDLIB_MODULES_JSON` is needed to use `import std`.
+set(gcc_prefix "/opt/gcc-importstd")
+set(CMake_TEST_CXX_STDLIB_MODULES_JSON
+  "${gcc_prefix}/lib64/libstdc++.modules.json"
+  CACHE FILEPATH "")
+file(MAKE_DIRECTORY
+  "${gcc_prefix}/lib64.reloc")
+file(RENAME
+  "${gcc_prefix}/lib64/libstdc++.modules.json"
+  "${CMake_TEST_CXX_STDLIB_MODULES_JSON}")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_macos_arm64_curl.cmake b/.gitlab/ci/configure_macos_arm64_curl.cmake
deleted file mode 100644
index 73263cb..0000000
--- a/.gitlab/ci/configure_macos_arm64_curl.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# Build with our vendored curl instead of the default system version.
-set(CMAKE_USE_SYSTEM_CURL "OFF" CACHE BOOL "")
-
-set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_macos_arm64_fastbuild.cmake b/.gitlab/ci/configure_macos_arm64_fastbuild.cmake
new file mode 100644
index 0000000..1b976d2
--- /dev/null
+++ b/.gitlab/ci/configure_macos_arm64_fastbuild.cmake
@@ -0,0 +1,2 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_windows_arm64_vs2022.cmake b/.gitlab/ci/configure_windows_arm64_vs2022.cmake
index 290d380..51ee514 100644
--- a/.gitlab/ci/configure_windows_arm64_vs2022.cmake
+++ b/.gitlab/ci/configure_windows_arm64_vs2022.cmake
@@ -1,4 +1,4 @@
-set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,shared" CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
 include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common.cmake")
diff --git a/.gitlab/ci/configure_windows_arm64_vs2026.cmake b/.gitlab/ci/configure_windows_arm64_vs2026.cmake
new file mode 100644
index 0000000..51ee514
--- /dev/null
+++ b/.gitlab/ci/configure_windows_arm64_vs2026.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,shared" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common.cmake")
diff --git a/.gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake b/.gitlab/ci/configure_windows_arm64_vs2026_ninja.cmake
similarity index 100%
rename from .gitlab/ci/configure_windows_arm64_vs2022_ninja.cmake
rename to .gitlab/ci/configure_windows_arm64_vs2026_ninja.cmake
diff --git a/.gitlab/ci/configure_windows_msvc_v71_nmake.cmake b/.gitlab/ci/configure_windows_msvc_v71_nmake.cmake
index 166690a..78587a9 100644
--- a/.gitlab/ci/configure_windows_msvc_v71_nmake.cmake
+++ b/.gitlab/ci/configure_windows_msvc_v71_nmake.cmake
@@ -1 +1,3 @@
+set(CMake_TEST_PrecompileHeaders_TIMEOUT 1000 CACHE STRING "")
+
 include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_i18n.cmake b/.gitlab/ci/configure_windows_vs2022_x64_i18n.cmake
deleted file mode 100644
index 3932f8a..0000000
--- a/.gitlab/ci/configure_windows_vs2022_x64_i18n.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs2022_x64.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
deleted file mode 100644
index 3fb894c..0000000
--- a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-set(CMake_TEST_C_STANDARDS "90;99;11;17" CACHE STRING "")
-set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
-
-if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
-  set(CMake_TEST_CPACK_INNOSETUP "ON" CACHE STRING "")
-  set(CMake_TEST_CPACK_NUGET "ON" CACHE STRING "")
-  set(CMake_TEST_IAR_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/iar" CACHE PATH "")
-  set(CMake_TEST_ISPC "ON" CACHE STRING "")
-  set(CMake_TEST_Swift "ON" CACHE STRING "")
-endif()
-
-set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
-set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
-
-# Release flags without -DNDEBUG so we get assertions.
-set(CMAKE_C_FLAGS_RELEASE "-O2 -Ob2" CACHE STRING "")
-set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Ob2" CACHE STRING "")
-
-include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_wix_common.cmake")
-include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common_ninja.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2026_x64.cmake b/.gitlab/ci/configure_windows_vs2026_x64.cmake
new file mode 100644
index 0000000..89cfdda
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2026_x64.cmake
@@ -0,0 +1,8 @@
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_ANDROID_VS18 ON CACHE BOOL "")
+endif()
+
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,shared" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_jom.cmake b/.gitlab/ci/configure_windows_vs2026_x64_fastbuild.cmake
similarity index 100%
copy from .gitlab/ci/configure_windows_vs2022_x64_jom.cmake
copy to .gitlab/ci/configure_windows_vs2026_x64_fastbuild.cmake
diff --git a/.gitlab/ci/configure_windows_vs2026_x64_i18n.cmake b/.gitlab/ci/configure_windows_vs2026_x64_i18n.cmake
new file mode 100644
index 0000000..958351d
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2026_x64_i18n.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs2026_x64.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_jom.cmake b/.gitlab/ci/configure_windows_vs2026_x64_jom.cmake
similarity index 100%
rename from .gitlab/ci/configure_windows_vs2022_x64_jom.cmake
rename to .gitlab/ci/configure_windows_vs2026_x64_jom.cmake
diff --git a/.gitlab/ci/configure_windows_vs2026_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2026_x64_ninja.cmake
new file mode 100644
index 0000000..2771e3f
--- /dev/null
+++ b/.gitlab/ci/configure_windows_vs2026_x64_ninja.cmake
@@ -0,0 +1,23 @@
+set(CMake_TEST_C_STANDARDS "90;99;11;17;23" CACHE STRING "")
+set(CMake_TEST_CXX_STANDARDS "98;11;14;17;20;23" CACHE STRING "")
+
+if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+  set(CMake_TEST_CPACK_INNOSETUP "ON" CACHE STRING "")
+  set(CMake_TEST_CPACK_NUGET "ON" CACHE STRING "")
+  set(CMake_TEST_IAR_TOOLCHAINS "$ENV{CI_PROJECT_DIR}/.gitlab/iar" CACHE PATH "")
+  set(CMake_TEST_ISPC "ON" CACHE STRING "")
+  set(CMake_TEST_Swift "ON" CACHE STRING "")
+endif()
+
+set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
+set(CMake_TEST_TLS_VERSION_URL_BAD "https://badtls-v1-1.kitware.com:8011" CACHE STRING "")
+
+# Release flags without -DNDEBUG so we get assertions.
+set(CMAKE_C_FLAGS_RELEASE "-O2 -Ob2" CACHE STRING "")
+set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Ob2" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_wix_common.cmake")
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common_ninja.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake b/.gitlab/ci/configure_windows_vs2026_x64_ninja_multi.cmake
similarity index 100%
rename from .gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake
rename to .gitlab/ci/configure_windows_vs2026_x64_ninja_multi.cmake
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_nmake.cmake b/.gitlab/ci/configure_windows_vs2026_x64_nmake.cmake
similarity index 100%
rename from .gitlab/ci/configure_windows_vs2022_x64_nmake.cmake
rename to .gitlab/ci/configure_windows_vs2026_x64_nmake.cmake
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_pch.cmake b/.gitlab/ci/configure_windows_vs2026_x64_pch.cmake
similarity index 100%
rename from .gitlab/ci/configure_windows_vs2022_x64_pch.cmake
rename to .gitlab/ci/configure_windows_vs2026_x64_pch.cmake
diff --git a/.gitlab/ci/ctest_coverage.cmake b/.gitlab/ci/ctest_coverage.cmake
new file mode 100644
index 0000000..c8bcd0a
--- /dev/null
+++ b/.gitlab/ci/ctest_coverage.cmake
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.29)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+find_program(GCOV NAMES gcov)
+set(CTEST_COVERAGE_COMMAND "${GCOV}")
+set(CTEST_COVERAGE_EXTRA_FLAGS
+  --hash-filenames
+  --long-file-names)
+string(REPLACE ";" " " CTEST_COVERAGE_EXTRA_FLAGS "${CTEST_COVERAGE_EXTRA_FLAGS}")
+ctest_coverage(
+  RETURN_VALUE coverage_result)
+ctest_submit(PARTS Coverage)
+
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_annotation.cmake")
+ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
+  "Coverage Report" "https://open.cdash.org/viewCoverage.php?buildid=${build_id}"
+)
+
+if (coverage_result)
+  message(FATAL_ERROR
+    "Failed to gather coverage")
+endif ()
diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake
index 89a5ace..30f796b 100644
--- a/.gitlab/ci/ctest_exclusions.cmake
+++ b/.gitlab/ci/ctest_exclusions.cmake
@@ -27,6 +27,20 @@
     )
 endif()
 
+if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "_valgrind")
+  list(APPEND test_exclusions
+    # Tests that timeout under valgrind.
+    "^RunCMake.NinjaMultiConfig$"
+    "^RunCMake.Autogen_Qt6_1$"
+    "^RunCMake.GoogleTest$"
+    "^RunCMake.CXXModules$"
+    "^RunCMake.CommandLine$"
+
+    # Too spurious under Valgrind.
+    "^RunCMake.testUVProcessChain$"
+    )
+endif()
+
 string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
 if (test_exclusions)
   set(test_exclusions "(${test_exclusions})")
diff --git a/.gitlab/ci/ctest_memcheck.cmake b/.gitlab/ci/ctest_memcheck.cmake
index 36c7777..7121015 100644
--- a/.gitlab/ci/ctest_memcheck.cmake
+++ b/.gitlab/ci/ctest_memcheck.cmake
@@ -16,18 +16,17 @@
   endif ()
 endif ()
 
-set(CTEST_MEMORYCHECK_TYPE "$ENV{CTEST_MEMORYCHECK_TYPE}")
-set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "$ENV{CTEST_MEMORYCHECK_SANITIZER_OPTIONS}")
-
-set(lsan_suppressions "${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_$ENV{CMAKE_CONFIGURATION}.lsan.supp")
-if (EXISTS "${lsan_suppressions}")
-  set(ENV{LSAN_OPTIONS} "suppressions='${lsan_suppressions}'")
+if (NOT "$ENV{CMAKE_CI_TEST_TIMEOUT}" STREQUAL "")
+  set(CTEST_TEST_TIMEOUT "$ENV{CMAKE_CI_TEST_TIMEOUT}")
 endif ()
 
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_prep.cmake")
+
 include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
 ctest_memcheck(
   PARALLEL_LEVEL "${nproc}"
   TEST_LOAD "${nproc}"
+  OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml"
   RETURN_VALUE test_result
   EXCLUDE "${test_exclusions}"
   DEFECT_COUNT defects)
diff --git a/.gitlab/ci/ctest_memcheck_fedora43.valgrind.supp b/.gitlab/ci/ctest_memcheck_fedora43.valgrind.supp
new file mode 100644
index 0000000..acc1d2c
--- /dev/null
+++ b/.gitlab/ci/ctest_memcheck_fedora43.valgrind.supp
@@ -0,0 +1,91 @@
+# Add Valgrind suppressions here.
+{
+   libc_start_main-malloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   ...
+   fun:__libc_start_main@@GLIBC_2.34
+   ...
+}
+{
+   dl_init-malloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   ...
+   fun:_dl_init
+   ...
+}
+{
+   dl_init-calloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:calloc
+   ...
+   fun:_dl_init
+   ...
+}
+{
+   dl_init-realloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:realloc
+   ...
+   fun:_dl_init
+   ...
+}
+{
+   dl_open-malloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   ...
+   fun:_dl_open
+   ...
+}
+{
+   dl_open-calloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:calloc
+   ...
+   fun:_dl_open
+   ...
+}
+{
+   qt5-object-new
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:_Znwm
+   ...
+   fun:_ZN7QObjectC1ER14QObjectPrivatePS_
+   ...
+}
+{
+   qt5-logger-malloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   ...
+   fun:_ZNK14QMessageLogger5debugEv
+   ...
+}
+{
+   strerror_l-malloc
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   fun:malloc
+   fun:__vasprintf_internal
+   fun:__asprintf_chk
+   fun:strerror_l
+   ...
+}
+{
+   bash
+   Memcheck:Leak
+   match-leak-kinds: reachable
+   ...
+   obj:/usr/bin/bash
+   ...
+}
diff --git a/.gitlab/ci/ctest_memcheck_fedora42_asan.lsan.supp b/.gitlab/ci/ctest_memcheck_fedora43_asan.lsan.supp
similarity index 100%
rename from .gitlab/ci/ctest_memcheck_fedora42_asan.lsan.supp
rename to .gitlab/ci/ctest_memcheck_fedora43_asan.lsan.supp
diff --git a/.gitlab/ci/ctest_memcheck_prep.cmake b/.gitlab/ci/ctest_memcheck_prep.cmake
new file mode 100644
index 0000000..1d9d12c
--- /dev/null
+++ b/.gitlab/ci/ctest_memcheck_prep.cmake
@@ -0,0 +1,50 @@
+set(CTEST_MEMORYCHECK_TYPE "$ENV{CTEST_MEMORYCHECK_TYPE}")
+set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "$ENV{CTEST_MEMORYCHECK_SANITIZER_OPTIONS}")
+
+set(lsan_suppressions "${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_$ENV{CMAKE_CONFIGURATION}.lsan.supp")
+if (EXISTS "${lsan_suppressions}")
+  set(ENV{LSAN_OPTIONS} "suppressions='${lsan_suppressions}'")
+endif ()
+
+if (CTEST_MEMORYCHECK_TYPE STREQUAL "Valgrind")
+  find_program(valgrind_exe NAMES valgrind)
+  set(CTEST_MEMORYCHECK_COMMAND "${valgrind_exe}")
+
+  set(valgrind_suppressions "${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_$ENV{CMAKE_CONFIGURATION}.valgrind.supp")
+  set(common_valgrind_suppressions "${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_$ENV{CMAKE_VALGRIND_CONFIGURATION}.valgrind.supp")
+  if (EXISTS "${valgrind_suppressions}")
+    set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${valgrind_suppressions}")
+  elseif (EXISTS "${common_valgrind_suppressions}")
+    set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${common_valgrind_suppressions}")
+  endif ()
+
+  set(valgrind_skip
+    /bin/*
+    /sbin/*
+    /usr/bin/*
+    /usr/lib64/qt5/bin/*
+    /usr/lib64/qt6/bin/*
+    /usr/lib64/qt6/libexec/*
+    bootstrap
+    sample_script
+    */Tests/CTestTest2/kwsysBin/*
+    */Tests/CTestTestCrash/Crash
+    *QtAutogen
+    # Ignore ISPC files which may contain unimplemented instructions.
+    */build/Tests/ISPC/TryCompile/ISPCTryCompile
+    # Ignore anything CI downloads.
+    */.gitlab/*)
+  list(JOIN valgrind_skip "," valgrind_skip)
+  string(CONCAT valgrind_options
+    "--gen-suppressions=all "
+    "--child-silent-after-fork=yes "
+    "--trace-children=yes "
+    "--trace-children-skip=${valgrind_skip} "
+    "--track-origins=yes "
+    "-q "
+    "--leak-check=yes "
+    "--show-reachable=yes "
+    "--num-callers=50 "
+    "-v ")
+  set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "${valgrind_options}")
+endif ()
diff --git a/.gitlab/ci/ctest_standalone.cmake b/.gitlab/ci/ctest_standalone.cmake
index a55ab6c..2981264 100644
--- a/.gitlab/ci/ctest_standalone.cmake
+++ b/.gitlab/ci/ctest_standalone.cmake
@@ -14,6 +14,10 @@
   endif ()
 endif ()
 
+if (NOT "$ENV{CMAKE_CI_TEST_TIMEOUT}" STREQUAL "")
+  set(CTEST_TEST_TIMEOUT "$ENV{CMAKE_CI_TEST_TIMEOUT}")
+endif ()
+
 # Create an entry in CDash.
 ctest_start("${ctest_model}" GROUP "${ctest_group}")
 
@@ -29,6 +33,10 @@
   set(CTEST_CONFIGURE_COMMAND "/opt/extdeps/bin/cmake -C \"${initial_cache}\" -G \"${CTEST_CMAKE_GENERATOR}\" \"${CTEST_SOURCE_DIRECTORY}\"")
 endif()
 
+if ("$ENV{CMAKE_CI_RUN_MEMCHECK}" STREQUAL "true")
+  include("${CMAKE_CURRENT_LIST_DIR}/ctest_memcheck_prep.cmake")
+endif ()
+
 # Configure the project.
 ctest_configure(
   OPTIONS "${cmake_args}"
@@ -89,20 +97,37 @@
 endif ()
 
 include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
-ctest_test(
-  PARALLEL_LEVEL "${nproc}"
-  TEST_LOAD "${nproc}"
-  OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml"
-  RETURN_VALUE test_result
-  ${ctest_label_args}
-  EXCLUDE "${test_exclusions}")
-ctest_submit(PARTS Test)
+set(extra_annotations)
+if ("$ENV{CMAKE_CI_RUN_MEMCHECK}" STREQUAL "true")
+  ctest_memcheck(
+    PARALLEL_LEVEL "${nproc}"
+    TEST_LOAD "${nproc}"
+    OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml"
+    RETURN_VALUE test_result
+    ${ctest_label_args}
+    EXCLUDE "${test_exclusions}")
+  ctest_submit(PARTS Test)
+  ctest_submit(PARTS Memcheck)
+  list(APPEND extra_annotations
+    "Dynamic Analysis"  "https://open.cdash.org/viewDynamicAnalysis.php?buildid=${build_id}"
+  )
+else ()
+  ctest_test(
+    PARALLEL_LEVEL "${nproc}"
+    TEST_LOAD "${nproc}"
+    OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml"
+    RETURN_VALUE test_result
+    ${ctest_label_args}
+    EXCLUDE "${test_exclusions}")
+  ctest_submit(PARTS Test)
+endif ()
 
 ctest_annotation_report("${CTEST_BINARY_DIRECTORY}/annotations.json"
   "All Tests"     "https://open.cdash.org/viewTest.php?buildid=${build_id}"
   "Test Failures" "https://open.cdash.org/viewTest.php?onlyfailed&buildid=${build_id}"
   "Tests Not Run" "https://open.cdash.org/viewTest.php?onlynotrun&buildid=${build_id}"
-  "Test Passes"   "https://open.cdash.org/viewTest.php?onlypassed&buildid=${build_id}")
+  "Test Passes"   "https://open.cdash.org/viewTest.php?onlypassed&buildid=${build_id}"
+  ${extra_annotations})
 
 if (test_result)
   ctest_submit(PARTS Done)
diff --git a/.gitlab/ci/ctest_test.cmake b/.gitlab/ci/ctest_test.cmake
index fa60dd0..f6165b1 100644
--- a/.gitlab/ci/ctest_test.cmake
+++ b/.gitlab/ci/ctest_test.cmake
@@ -16,6 +16,10 @@
   endif ()
 endif ()
 
+if (NOT "$ENV{CMAKE_CI_TEST_TIMEOUT}" STREQUAL "")
+  set(CTEST_TEST_TIMEOUT "$ENV{CMAKE_CI_TEST_TIMEOUT}")
+endif ()
+
 include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
 ctest_test(
   PARALLEL_LEVEL "${nproc}"
diff --git a/.gitlab/ci/docker/cuda13.0/Dockerfile b/.gitlab/ci/docker/cuda13.0/Dockerfile
new file mode 100644
index 0000000..9433296
--- /dev/null
+++ b/.gitlab/ci/docker/cuda13.0/Dockerfile
@@ -0,0 +1,32 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=kitware/nvidia-cuda:13.0.1-devel-ubuntu24.04
+
+FROM ${BASE_IMAGE} AS apt-config
+ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/cross-linux-sbsa/cuda-keyring_1.1-1_all.deb /root/
+RUN --mount=type=tmpfs,target=/var/log \
+    dpkg -i /root/cuda-keyring_1.1-1_all.deb \
+ && rm /root/cuda-keyring_1.1-1_all.deb
+
+FROM apt-config AS apt-cache
+# Populate APT cache w/ the fresh metadata and prefetch packages.
+# Use an empty `docker-clean` file to "hide" the image-provided
+# file to disallow removing packages after `apt-get` operations.
+RUN --mount=type=tmpfs,target=/var/log \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    apt-get update \
+ && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
+FROM apt-config
+MAINTAINER Brad King <brad.king@kitware.com>
+
+RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/cuda13.0/deps_packages.lst b/.gitlab/ci/docker/cuda13.0/deps_packages.lst
new file mode 100644
index 0000000..9863134
--- /dev/null
+++ b/.gitlab/ci/docker/cuda13.0/deps_packages.lst
@@ -0,0 +1,12 @@
+# Host tools
+curl
+git
+unzip
+
+# Compilers
+g++
+g++-aarch64-linux-gnu
+
+# CUDA Extras
+cuda-cross-sbsa-13-0
+cuda-opencl-dev-13-0
diff --git a/.gitlab/ci/docker/debian12-aarch64/docker-clean b/.gitlab/ci/docker/cuda13.0/docker-clean
similarity index 100%
copy from .gitlab/ci/docker/debian12-aarch64/docker-clean
copy to .gitlab/ci/docker/cuda13.0/docker-clean
diff --git a/.gitlab/ci/docker/debian12-aarch64/dpkg-exclude b/.gitlab/ci/docker/cuda13.0/dpkg-exclude
similarity index 100%
copy from .gitlab/ci/docker/debian12-aarch64/dpkg-exclude
copy to .gitlab/ci/docker/cuda13.0/dpkg-exclude
diff --git a/.gitlab/ci/docker/debian12-aarch64/install_deps.sh b/.gitlab/ci/docker/cuda13.0/install_deps.sh
similarity index 100%
copy from .gitlab/ci/docker/debian12-aarch64/install_deps.sh
copy to .gitlab/ci/docker/cuda13.0/install_deps.sh
diff --git a/.gitlab/ci/docker/debian12-aarch64/Dockerfile b/.gitlab/ci/docker/debian12-aarch64/Dockerfile
deleted file mode 100644
index 2344ce5..0000000
--- a/.gitlab/ci/docker/debian12-aarch64/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# syntax=docker/dockerfile:1
-
-ARG BASE_IMAGE=arm64v8/debian:12
-
-FROM ${BASE_IMAGE} AS cuda-keyring
-ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/sbsa/cuda-keyring_1.1-1_all.deb /root/
-RUN --mount=type=tmpfs,target=/var/log \
-    apt-get update \
- && apt-get -y install ca-certificates \
- && dpkg -i /root/cuda-keyring_1.1-1_all.deb \
- && rm /root/cuda-keyring_1.1-1_all.deb
-
-FROM cuda-keyring AS apt-cache
-# Populate APT cache w/ the fresh metadata and prefetch packages.
-# Use an empty `docker-clean` file to "hide" the image-provided
-# file to disallow removing packages after `apt-get` operations.
-RUN --mount=type=tmpfs,target=/var/log \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    apt-get update \
- && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
-
-FROM cuda-keyring
-LABEL maintainer="Brad King <brad.king@kitware.com>"
-
-RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
-    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/debian12-aarch64/deps_packages.lst b/.gitlab/ci/docker/debian12-aarch64/deps_packages.lst
deleted file mode 100644
index 2328194..0000000
--- a/.gitlab/ci/docker/debian12-aarch64/deps_packages.lst
+++ /dev/null
@@ -1,99 +0,0 @@
-# Install build requirements.
-libssl-dev
-
-# Install development tools.
-g++
-curl
-git
-
-# Install optional external build dependencies.
-libarchive-dev
-libbz2-dev
-libcurl4-gnutls-dev
-libexpat1-dev
-libjsoncpp-dev
-liblzma-dev
-libncurses-dev
-librhash-dev
-libuv1-dev
-libzstd-dev
-zlib1g-dev
-
-# Install iwyu runtime deps.
-clang-15
-libncurses6
-
-# Tools needed for the test suite.
-jq
-
-# Packages needed to test CTest.
-bzr
-cvs
-subversion
-mercurial
-
-# Packages needed to test find modules.
-alsa-utils
-aspell
-aspell-en
-doxygen graphviz
-freeglut3-dev
-gnutls-dev
-libarchive-dev
-libaspell-dev
-libblas-dev
-libboost-dev
-libboost-filesystem-dev
-libboost-program-options-dev
-libboost-python-dev
-libboost-thread-dev
-libbz2-dev
-libcups2-dev
-libcurl4-gnutls-dev
-libdevil-dev
-libfontconfig1-dev
-libfreetype6-dev
-libgdal-dev
-libgif-dev
-libgl1-mesa-dev
-libglew-dev
-libgmock-dev
-libgrpc++-dev libgrpc-dev
-libgsl-dev
-libgtest-dev
-libgtk2.0-dev
-libhdf5-dev
-libhdf5-mpich-dev
-libhdf5-openmpi-dev
-libicu-dev
-libinput-dev
-libjpeg-dev
-libjsoncpp-dev
-liblapack-dev
-liblzma-dev
-libmagick++-dev
-libnvpl-blas-dev
-libnvpl-common-dev
-libnvpl-lapack-dev
-libopenal-dev
-libopenmpi-dev openmpi-bin
-libosp-dev
-libpng-dev
-libpq-dev postgresql-server-dev-15
-libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
-libsdl1.2-dev
-libsqlite3-dev
-libtiff-dev
-libuv1-dev
-libwxgtk3.2-dev
-libx11-dev
-libxalan-c-dev
-libxerces-c-dev
-libxml2-dev libxml2-utils
-libxslt-dev xsltproc
-openjdk-17-jdk
-python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
-qtbase5-dev qtbase5-dev-tools
-ruby ruby-dev
-swig
-unixodbc-dev
diff --git a/.gitlab/ci/docker/debian12-x86_64/Dockerfile b/.gitlab/ci/docker/debian12-x86_64/Dockerfile
deleted file mode 100644
index 3a9a6a1..0000000
--- a/.gitlab/ci/docker/debian12-x86_64/Dockerfile
+++ /dev/null
@@ -1,64 +0,0 @@
-# syntax=docker/dockerfile:1
-
-ARG BASE_IMAGE=debian:12
-
-FROM ${BASE_IMAGE} AS apt-cache
-# Populate APT cache w/ the fresh metadata and prefetch packages.
-# Use an empty `docker-clean` file to "hide" the image-provided
-# file to disallow removing packages after `apt-get` operations.
-RUN --mount=type=tmpfs,target=/var/log \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
-    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
-    apt-get update \
- && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
-
-
-FROM ${BASE_IMAGE} AS iwyu-build
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-
-RUN --mount=type=bind,source=install_iwyu.sh,target=/root/install_iwyu.sh \
-    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
-    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/install_iwyu.sh
-
-
-FROM ${BASE_IMAGE} AS rvm-build
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-
-RUN --mount=type=bind,source=install_rvm.sh,target=/root/install_rvm.sh \
-    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
-    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/install_rvm.sh
-
-
-FROM ${BASE_IMAGE}
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-
-ENV RBENV_ROOT=/opt/rbenv
-
-RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
-    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
-    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
-    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/install_deps.sh
-
-RUN --mount=type=bind,from=iwyu-build,source=/root,target=/root \
-    tar -C / -xf /root/iwyu.tar \
- && ln -s /usr/lib/llvm-15/bin/include-what-you-use /usr/bin/include-what-you-use-15
-
-RUN --mount=type=bind,from=rvm-build,source=/root,target=/root \
-    tar -C /usr/local -xf /root/rvm.tar
diff --git a/.gitlab/ci/docker/debian12-x86_64/deps_packages.lst b/.gitlab/ci/docker/debian12-x86_64/deps_packages.lst
deleted file mode 100644
index e6f1188..0000000
--- a/.gitlab/ci/docker/debian12-x86_64/deps_packages.lst
+++ /dev/null
@@ -1,114 +0,0 @@
-# Install build requirements.
-libssl-dev
-
-# Install development tools.
-g++
-curl
-git
-
-# Install optional external build dependencies.
-libarchive-dev
-libbz2-dev
-libcurl4-gnutls-dev
-libexpat1-dev
-libjsoncpp-dev
-liblzma-dev
-libncurses-dev
-librhash-dev
-libuv1-dev
-libzstd-dev
-zlib1g-dev
-
-# Install iwyu runtime deps.
-clang-15
-libncurses6
-
-# Tools needed for the test suite.
-jq
-
-# Packages needed to test CTest.
-bzr
-cvs
-subversion
-mercurial
-
-# Install ASM_NASM language toolchain.
-nasm
-
-# Install HIP language toolchain.
-hipcc
-
-# Install swift runtime deps.
-libncurses5
-
-# Install IAR compiler package dependencies.
-libusb-1.0-0
-udev
-sudo
-
-# Packages needed to test find modules.
-alsa-utils
-aspell
-aspell-en
-doxygen graphviz
-freeglut3-dev
-gnutls-dev
-libarchive-dev
-libaspell-dev
-libblas-dev
-libboost-dev
-libboost-filesystem-dev
-libboost-program-options-dev
-libboost-python-dev
-libboost-thread-dev
-libbz2-dev
-libcups2-dev
-libcurl4-gnutls-dev
-libdevil-dev
-libfontconfig1-dev
-libfreetype6-dev
-libgdal-dev
-libgif-dev
-libgl1-mesa-dev
-libglew-dev
-libgmock-dev
-libgrpc++-dev libgrpc-dev
-libgsl-dev
-libgtest-dev
-libgtk2.0-dev
-libhdf5-dev
-libhdf5-mpich-dev
-libhdf5-openmpi-dev
-libicu-dev
-libinput-dev
-libjpeg-dev
-libjsoncpp-dev
-liblapack-dev
-liblzma-dev
-libmagick++-dev
-libopenal-dev
-libopenmpi-dev openmpi-bin
-libosp-dev
-libpng-dev
-libpq-dev postgresql-server-dev-15
-libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
-libsdl1.2-dev
-libsqlite3-dev
-libtiff-dev
-libuv1-dev
-libwxgtk3.2-dev
-libx11-dev
-libxalan-c-dev
-libxerces-c-dev
-libxml2-dev libxml2-utils
-libxslt-dev xsltproc
-openjdk-17-jdk
-python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
-qtbase5-dev qtbase5-dev-tools
-rbenv ruby-build
-ruby ruby-dev
-swig
-unixodbc-dev
-
-# Packages needed to test ironpython.
-libmono-system-windows-forms4.0-cil
diff --git a/.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh b/.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh
deleted file mode 100755
index bbeceb8..0000000
--- a/.gitlab/ci/docker/debian12-x86_64/install_iwyu.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-
-set -e
-
-# Install development tools.
-apt-get install -y $(grep '^[^#]\+$' /root/iwyu_packages.lst)
-
-cd /root
-git clone "https://github.com/include-what-you-use/include-what-you-use.git"
-cd include-what-you-use
-readonly llvm_version="$( clang-15 --version | head -n1 | cut -d' ' -f4 | cut -d. -f-1 )"
-git checkout "clang_$llvm_version"
-mkdir build
-cd build
-
-cmake -GNinja \
-    -DCMAKE_BUILD_TYPE=Release \
-    "-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$llvm_version" \
-    ..
-ninja
-DESTDIR=/root/iwyu-destdir ninja install
-tar -C /root/iwyu-destdir -cf /root/iwyu.tar .
diff --git a/.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst b/.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst
deleted file mode 100644
index 2dbddba..0000000
--- a/.gitlab/ci/docker/debian12-x86_64/iwyu_packages.lst
+++ /dev/null
@@ -1,9 +0,0 @@
-# Install development tools.
-clang-15
-libclang-15-dev
-llvm-15-dev
-libz-dev
-g++
-cmake
-ninja-build
-git
diff --git a/.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst b/.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst
deleted file mode 100644
index 80f079c..0000000
--- a/.gitlab/ci/docker/debian12-x86_64/rvm_packages.lst
+++ /dev/null
@@ -1,25 +0,0 @@
-autoconf
-automake
-bison
-bzip2
-curl
-g++
-gawk
-gcc
-gnupg2
-libc6-dev
-libffi-dev
-libgdbm-dev
-libgmp-dev
-libncurses5-dev
-libreadline-dev
-libsqlite3-dev
-libssl-dev
-libtool
-libyaml-dev
-make
-patch
-pkg-config
-procps
-sqlite3
-zlib1g-dev
diff --git a/.gitlab/ci/docker/debian13-aarch64/Dockerfile b/.gitlab/ci/docker/debian13-aarch64/Dockerfile
new file mode 100644
index 0000000..4793a96
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-aarch64/Dockerfile
@@ -0,0 +1,34 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=arm64v8/debian:13
+
+FROM ${BASE_IMAGE} AS cuda-keyring
+ADD https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/sbsa/cuda-keyring_1.1-1_all.deb /root/
+RUN --mount=type=tmpfs,target=/var/log \
+    apt-get update \
+ && apt-get -y install ca-certificates \
+ && dpkg -i /root/cuda-keyring_1.1-1_all.deb \
+ && rm /root/cuda-keyring_1.1-1_all.deb
+
+FROM cuda-keyring AS apt-cache
+# Populate APT cache w/ the fresh metadata and prefetch packages.
+# Use an empty `docker-clean` file to "hide" the image-provided
+# file to disallow removing packages after `apt-get` operations.
+RUN --mount=type=tmpfs,target=/var/log \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    apt-get update \
+ && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
+FROM cuda-keyring
+LABEL maintainer="Brad King <brad.king@kitware.com>"
+
+RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/debian13-aarch64/deps_packages.lst b/.gitlab/ci/docker/debian13-aarch64/deps_packages.lst
new file mode 100644
index 0000000..0b76622
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-aarch64/deps_packages.lst
@@ -0,0 +1,99 @@
+# Install build requirements.
+libssl-dev
+
+# Install development tools.
+g++
+curl
+git
+
+# Install optional external build dependencies.
+libarchive-dev
+libbz2-dev
+libcurl4-gnutls-dev
+libexpat1-dev
+libjsoncpp-dev
+liblzma-dev
+libncurses-dev
+librhash-dev
+libuv1-dev
+libzstd-dev
+zlib1g-dev
+
+# Install iwyu runtime deps.
+clang-19
+libncurses6
+
+# Tools needed for the test suite.
+jq
+
+# Packages needed to test CTest.
+bzr
+cvs
+subversion
+mercurial
+
+# Packages needed to test find modules.
+alsa-utils
+aspell
+aspell-en
+doxygen graphviz
+freeglut3-dev
+gnutls-dev
+libarchive-dev
+libaspell-dev
+libblas-dev
+libboost-dev
+libboost-filesystem-dev
+libboost-program-options-dev
+libboost-python-dev
+libboost-thread-dev
+libbz2-dev
+libcups2-dev
+libcurl4-gnutls-dev
+libdevil-dev
+libfontconfig1-dev
+libfreetype6-dev
+libgdal-dev
+libgif-dev
+libgl1-mesa-dev
+libglew-dev
+libgmock-dev
+libgrpc++-dev libgrpc-dev
+libgsl-dev
+libgtest-dev
+libgtk2.0-dev
+libhdf5-dev
+libhdf5-mpich-dev
+libhdf5-openmpi-dev
+libicu-dev
+libinput-dev
+libjpeg-dev
+libjsoncpp-dev
+liblapack-dev
+liblzma-dev
+libmagick++-dev
+libnvpl-blas-dev
+libnvpl-common-dev
+libnvpl-lapack-dev
+libopenal-dev
+libopenmpi-dev openmpi-bin
+libosp-dev
+libpng-dev
+libpq-dev postgresql-server-dev-17
+libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
+libsdl1.2-dev
+libsqlite3-dev
+libtiff-dev
+libuv1-dev
+libwxgtk3.2-dev
+libx11-dev
+libxalan-c-dev
+libxerces-c-dev
+libxml2-dev libxml2-utils
+libxslt-dev xsltproc
+openjdk-25-jdk
+python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
+qtbase5-dev qtbase5-dev-tools
+ruby ruby-dev
+swig
+unixodbc-dev
diff --git a/.gitlab/ci/docker/debian12-aarch64/docker-clean b/.gitlab/ci/docker/debian13-aarch64/docker-clean
similarity index 100%
rename from .gitlab/ci/docker/debian12-aarch64/docker-clean
rename to .gitlab/ci/docker/debian13-aarch64/docker-clean
diff --git a/.gitlab/ci/docker/debian12-aarch64/dpkg-exclude b/.gitlab/ci/docker/debian13-aarch64/dpkg-exclude
similarity index 100%
rename from .gitlab/ci/docker/debian12-aarch64/dpkg-exclude
rename to .gitlab/ci/docker/debian13-aarch64/dpkg-exclude
diff --git a/.gitlab/ci/docker/debian12-aarch64/install_deps.sh b/.gitlab/ci/docker/debian13-aarch64/install_deps.sh
similarity index 100%
rename from .gitlab/ci/docker/debian12-aarch64/install_deps.sh
rename to .gitlab/ci/docker/debian13-aarch64/install_deps.sh
diff --git a/.gitlab/ci/docker/debian13-x86_64/Dockerfile b/.gitlab/ci/docker/debian13-x86_64/Dockerfile
new file mode 100644
index 0000000..3c40e52
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-x86_64/Dockerfile
@@ -0,0 +1,64 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=debian:13
+
+FROM ${BASE_IMAGE} AS apt-cache
+# Populate APT cache w/ the fresh metadata and prefetch packages.
+# Use an empty `docker-clean` file to "hide" the image-provided
+# file to disallow removing packages after `apt-get` operations.
+RUN --mount=type=tmpfs,target=/var/log \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
+    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
+    apt-get update \
+ && apt-get --download-only -y install $(grep -h '^[^#]\+$' /root/*.lst)
+
+
+FROM ${BASE_IMAGE} AS iwyu-build
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+
+RUN --mount=type=bind,source=install_iwyu.sh,target=/root/install_iwyu.sh \
+    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_iwyu.sh
+
+
+FROM ${BASE_IMAGE} AS rvm-build
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+
+RUN --mount=type=bind,source=install_rvm.sh,target=/root/install_rvm.sh \
+    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_rvm.sh
+
+
+FROM ${BASE_IMAGE}
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+
+ENV RBENV_ROOT=/opt/rbenv
+
+RUN --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=dpkg-exclude,target=/etc/dpkg/dpkg.cfg.d/exclude \
+    --mount=type=bind,source=docker-clean,target=/etc/apt/apt.conf.d/docker-clean \
+    --mount=type=cache,from=apt-cache,source=/var/lib/apt/lists,target=/var/lib/apt/lists \
+    --mount=type=cache,from=apt-cache,source=/var/cache/apt,target=/var/cache/apt,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_deps.sh
+
+RUN --mount=type=bind,from=iwyu-build,source=/root,target=/root \
+    tar -C / -xf /root/iwyu.tar \
+ && ln -s /usr/lib/llvm-19/bin/include-what-you-use /usr/bin/include-what-you-use-19
+
+RUN --mount=type=bind,from=rvm-build,source=/root,target=/root \
+    tar -C /usr/local -xf /root/rvm.tar
diff --git a/.gitlab/ci/docker/debian13-x86_64/deps_packages.lst b/.gitlab/ci/docker/debian13-x86_64/deps_packages.lst
new file mode 100644
index 0000000..b1b792c
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-x86_64/deps_packages.lst
@@ -0,0 +1,111 @@
+# Install build requirements.
+libssl-dev
+
+# Install development tools.
+g++
+curl
+git
+
+# Install optional external build dependencies.
+libarchive-dev
+libbz2-dev
+libcurl4-gnutls-dev
+libexpat1-dev
+libjsoncpp-dev
+liblzma-dev
+libncurses-dev
+librhash-dev
+libuv1-dev
+libzstd-dev
+zlib1g-dev
+
+# Install iwyu runtime deps.
+clang-19
+libncurses6
+
+# Tools needed for the test suite.
+jq
+
+# Packages needed to test CTest.
+bzr
+cvs
+subversion
+mercurial
+
+# Install ASM_NASM language toolchain.
+nasm
+
+# Install HIP language toolchain.
+hipcc
+
+# Install IAR compiler package dependencies.
+libusb-1.0-0
+udev
+sudo
+
+# Packages needed to test find modules.
+alsa-utils
+aspell
+aspell-en
+doxygen graphviz
+freeglut3-dev
+gnutls-dev
+libarchive-dev
+libaspell-dev
+libblas-dev
+libboost-dev
+libboost-filesystem-dev
+libboost-program-options-dev
+libboost-python-dev
+libboost-thread-dev
+libbz2-dev
+libcups2-dev
+libcurl4-gnutls-dev
+libdevil-dev
+libfontconfig1-dev
+libfreetype6-dev
+libgdal-dev
+libgif-dev
+libgl1-mesa-dev
+libglew-dev
+libgmock-dev
+libgrpc++-dev libgrpc-dev
+libgsl-dev
+libgtest-dev
+libgtk2.0-dev
+libhdf5-dev
+libhdf5-mpich-dev
+libhdf5-openmpi-dev
+libicu-dev
+libinput-dev
+libjpeg-dev
+libjsoncpp-dev
+liblapack-dev
+liblzma-dev
+libmagick++-dev
+libopenal-dev
+libopenmpi-dev openmpi-bin
+libosp-dev
+libpng-dev
+libpq-dev postgresql-server-dev-17
+libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc
+libsdl1.2-dev
+libsqlite3-dev
+libtiff-dev
+libuv1-dev
+libwxgtk3.2-dev
+libx11-dev
+libxalan-c-dev
+libxerces-c-dev
+libxml2-dev libxml2-utils
+libxslt-dev xsltproc
+openjdk-25-jdk
+python3 python3-dev python3-numpy pypy3 pypy3-dev python3-venv
+qtbase5-dev qtbase5-dev-tools
+rbenv ruby-build
+ruby ruby-dev
+swig
+unixodbc-dev
+
+# Packages needed to test ironpython.
+libmono-system-windows-forms4.0-cil
diff --git a/.gitlab/ci/docker/debian12-x86_64/docker-clean b/.gitlab/ci/docker/debian13-x86_64/docker-clean
similarity index 100%
rename from .gitlab/ci/docker/debian12-x86_64/docker-clean
rename to .gitlab/ci/docker/debian13-x86_64/docker-clean
diff --git a/.gitlab/ci/docker/debian12-x86_64/dpkg-exclude b/.gitlab/ci/docker/debian13-x86_64/dpkg-exclude
similarity index 100%
rename from .gitlab/ci/docker/debian12-x86_64/dpkg-exclude
rename to .gitlab/ci/docker/debian13-x86_64/dpkg-exclude
diff --git a/.gitlab/ci/docker/debian12-x86_64/install_deps.sh b/.gitlab/ci/docker/debian13-x86_64/install_deps.sh
similarity index 100%
rename from .gitlab/ci/docker/debian12-x86_64/install_deps.sh
rename to .gitlab/ci/docker/debian13-x86_64/install_deps.sh
diff --git a/.gitlab/ci/docker/debian13-x86_64/install_iwyu.sh b/.gitlab/ci/docker/debian13-x86_64/install_iwyu.sh
new file mode 100755
index 0000000..6247d8a
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-x86_64/install_iwyu.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -e
+
+# Install development tools.
+apt-get install -y $(grep '^[^#]\+$' /root/iwyu_packages.lst)
+
+cd /root
+git clone "https://github.com/include-what-you-use/include-what-you-use.git"
+cd include-what-you-use
+readonly llvm_version="$( clang-19 --version | head -n1 | cut -d' ' -f4 | cut -d. -f-1 )"
+git checkout "clang_$llvm_version"
+mkdir build
+cd build
+
+cmake -GNinja \
+    -DCMAKE_BUILD_TYPE=Release \
+    "-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$llvm_version" \
+    ..
+ninja
+DESTDIR=/root/iwyu-destdir ninja install
+tar -C /root/iwyu-destdir -cf /root/iwyu.tar .
diff --git a/.gitlab/ci/docker/debian12-x86_64/install_rvm.sh b/.gitlab/ci/docker/debian13-x86_64/install_rvm.sh
similarity index 100%
rename from .gitlab/ci/docker/debian12-x86_64/install_rvm.sh
rename to .gitlab/ci/docker/debian13-x86_64/install_rvm.sh
diff --git a/.gitlab/ci/docker/debian13-x86_64/iwyu_packages.lst b/.gitlab/ci/docker/debian13-x86_64/iwyu_packages.lst
new file mode 100644
index 0000000..7301924
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-x86_64/iwyu_packages.lst
@@ -0,0 +1,9 @@
+# Install development tools.
+clang-19
+libclang-19-dev
+llvm-19-dev
+libz-dev
+g++
+cmake
+ninja-build
+git
diff --git a/.gitlab/ci/docker/debian13-x86_64/rvm_packages.lst b/.gitlab/ci/docker/debian13-x86_64/rvm_packages.lst
new file mode 100644
index 0000000..6ea8a8f
--- /dev/null
+++ b/.gitlab/ci/docker/debian13-x86_64/rvm_packages.lst
@@ -0,0 +1,25 @@
+autoconf
+automake
+bison
+bzip2
+curl
+g++
+gawk
+gcc
+gnupg2
+libc6-dev
+libffi-dev
+libgdbm-dev
+libgmp-dev
+libncurses-dev
+libreadline-dev
+libsqlite3-dev
+libssl-dev
+libtool
+libyaml-dev
+make
+patch
+pkg-config
+procps
+sqlite3
+zlib1g-dev
diff --git a/.gitlab/ci/docker/fedora42-hip/Dockerfile b/.gitlab/ci/docker/fedora42-hip/Dockerfile
deleted file mode 100644
index 22e5e2f..0000000
--- a/.gitlab/ci/docker/fedora42-hip/Dockerfile
+++ /dev/null
@@ -1,12 +0,0 @@
-# syntax=docker/dockerfile:1
-
-ARG BASE_IMAGE=fedora:42
-
-FROM ${BASE_IMAGE} AS dnf-cache
-LABEL maintainer="Brad King <brad.king@kitware.com>"
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=cache,target=/var/lib/dnf \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install -y $(grep -h '^[^#]\+$' /root/*.lst)
diff --git a/.gitlab/ci/docker/fedora42/Dockerfile b/.gitlab/ci/docker/fedora42/Dockerfile
deleted file mode 100644
index e78b76b..0000000
--- a/.gitlab/ci/docker/fedora42/Dockerfile
+++ /dev/null
@@ -1,135 +0,0 @@
-# syntax=docker/dockerfile:1
-
-ARG BASE_IMAGE=fedora:42
-
-FROM ${BASE_IMAGE} AS dnf-cache
-# Populate DNF cache w/ the fresh metadata and prefetch packages.
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
-    --mount=type=bind,source=rbenv_packages.lst,target=/root/rbenv_packages.lst \
-    --mount=type=bind,source=rust_packages.lst,target=/root/rust_packages.lst \
-    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install --downloadonly -y $(grep -h '^[^#]\+$' /root/*.lst)
-
-
-FROM ${BASE_IMAGE} AS rust-build-env
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-# Pre-install prerequisites to build Rust projects.
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=rust_packages.lst,target=/root/rust_packages.lst \
-    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install -y $(grep '^[^#]\+$' /root/rust_packages.lst)
-
-
-FROM rust-build-env AS rust-build
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-# Build the needed Rust packages.
-# https://doc.rust-lang.org/cargo/guide/cargo-home.html?highlight=.cargo#caching-the-cargo-home-in-ci
-RUN --mount=type=bind,source=build_rust.sh,target=/root/build_rust.sh \
-    --mount=type=cache,target=/root/.cargo/registry/index \
-    --mount=type=cache,target=/root/.cargo/registry/cache \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/build_rust.sh
-
-
-FROM ${BASE_IMAGE} AS rvm-build-env
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-# Pre-install prerequisites for RVM.
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
-    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install -y $(grep '^[^#]\+$' /root/rvm_packages.lst)
-
-
-FROM rvm-build-env AS rvm-build
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-# Build Ruby with RVM.
-RUN --mount=type=bind,source=build_rvm.sh,target=/root/build_rvm.sh \
-    --mount=type=cache,target=/usr/local/rvm/archives \
-    --mount=type=cache,target=/usr/local/rvm/gem-cache   \
-    --mount=type=cache,target=/usr/local/rvm/src \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/build_rvm.sh
-
-
-FROM ${BASE_IMAGE} AS rbenv
-# Pre-install prerequisites for `rbenv`.
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=rbenv_packages.lst,target=/root/rbenv_packages.lst \
-    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install -y $(grep '^[^#]\+$' /root/rbenv_packages.lst)
-
-
-FROM rbenv AS rbenv-build
-ENV RBENV_ROOT=/opt/rbenv
-ENV RBENV_BUILD_ROOT=/root/.cache/rbenv-build
-ENV RUBY_BUILD_CACHE_PATH=/root/.cache/rbenv
-# Build Ruby with `rbenv`.
-RUN --mount=type=cache,target=/root/.cache \
-    --mount=type=bind,source=build_rbenv.sh,target=/root/build_rbenv.sh \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/build_rbenv.sh
-
-
-FROM ${BASE_IMAGE} AS iwyu-build-env
-LABEL maintainer="Kyle Edwards <kyle.edwards@kitware.com>"
-# Pre-install prerequisites to build IWYU.
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
-    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    dnf install -y $(grep '^[^#]\+$' /root/iwyu_packages.lst)
-
-
-FROM iwyu-build-env AS iwyu-build
-LABEL maintainer="Kyle Edwards <kyle.edwards@kitware.com>"
-# Build IWYU.
-RUN --mount=type=bind,source=build_iwyu.sh,target=/root/build_iwyu.sh \
-    --mount=type=cache,target=/root/include-what-you-use \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/build_iwyu.sh
-
-
-FROM ${BASE_IMAGE} AS p4-dl
-# Download Perforce.
-# NOTE `curl` is pre-installed in the base image.
-RUN curl -C- -L https://www.perforce.com/downloads/perforce/r21.2/bin.linux26x86_64/helix-core-server.tgz \
-  | tar -C /usr/local/bin -xvzf - -- p4 p4d
-
-
-FROM ${BASE_IMAGE}
-LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
-
-ENV RBENV_ROOT=/opt/rbenv
-
-COPY --from=p4-dl --chown=root:root /usr/local/bin/p4 /usr/local/bin/p4d /usr/local/bin
-
-RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
-    --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
-    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
-    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
-    --mount=type=tmpfs,target=/var/log \
-    --mount=type=tmpfs,target=/tmp \
-    sh /root/install_deps.sh
-
-RUN --mount=type=bind,from=iwyu-build,source=/root,target=/root \
-    tar -C / -xf /root/iwyu.tar
-
-RUN --mount=type=bind,from=rust-build,source=/root,target=/root \
-    tar -C /usr/local -xf /root/rust.tar
-
-RUN --mount=type=bind,from=rvm-build,source=/root,target=/root \
-    tar -C /usr/local -xf /root/rvm.tar
-
-RUN --mount=type=bind,from=rbenv-build,source=/root,target=/root \
-    tar -C / -xf /root/rbenv.tar && rbenv global 3.4.3
diff --git a/.gitlab/ci/docker/fedora42/build_rust.sh b/.gitlab/ci/docker/fedora42/build_rust.sh
deleted file mode 100755
index f20949b..0000000
--- a/.gitlab/ci/docker/fedora42/build_rust.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -e
-
-typos_version=1.29.4
-cargo install --root /usr/local --version "$typos_version" typos-cli
-
-strip /usr/local/bin/typos
-
-tar -C /usr/local -cf /root/rust.tar bin/typos
diff --git a/.gitlab/ci/docker/fedora42/deps_packages.lst b/.gitlab/ci/docker/fedora42/deps_packages.lst
deleted file mode 100644
index 5682514..0000000
--- a/.gitlab/ci/docker/fedora42/deps_packages.lst
+++ /dev/null
@@ -1,141 +0,0 @@
-# Install build requirements.
-ncurses-devel
-openssl-devel
-qt5-qtbase-devel
-qt6-qtbase-devel
-
-# Install development tools.
-clang
-clang-devel
-clang-tools-extra
-clang-tools-extra-devel
-compiler-rt
-flang
-gcc-c++
-git-core
-lfortran
-llvm-devel
-make
-
-# Install optional external build dependencies.
-bzip2-devel
-expat-devel
-jsoncpp-devel
-libarchive-devel
-libcurl-devel
-libuv-devel
-libzstd-devel
-rhash-devel
-xz-devel
-zlib-devel
-
-# Install documentation tools.
-python3-sphinx
-python3-sphinxcontrib-qthelp
-qt5-qttools-devel
-qt6-qttools-devel
-texinfo
-
-# Install lint tools.
-clang-analyzer
-codespell
-
-# Tools needed for the test suite.
-file
-findutils
-jq
-which
-
-# Install ASM_NASM language toolchain.
-nasm
-
-# Packages needed to test CTest.
-breezy
-mercurial
-subversion
-
-# Packages needed to test CPack.
-rpm-build
-
-# Packages needed to test find modules.
-alsa-lib-devel
-aspell
-aspell-devel
-aspell-en
-blas-devel
-boost-devel
-boost-python3-devel
-bzip2-devel
-cups-devel
-DevIL-devel
-doxygen
-expat-devel
-fontconfig-devel
-freeglut-devel
-freetype-devel
-gdal-devel
-gettext
-giflib-devel
-glew-devel
-gmock
-gnutls-devel
-grpc-devel
-grpc-plugins
-gsl-devel
-gtest-devel
-gtk2-devel
-hdf5-devel
-hdf5-mpich-devel
-hdf5-openmpi-devel
-ImageMagick-c++-devel
-jasper-devel
-java-21-openjdk-devel
-jsoncpp-devel
-lapack-devel
-libarchive-devel
-libcurl-devel
-libicu-devel
-libinput-devel
-libjpeg-turbo-devel
-libomp-devel
-libpng-devel
-libtiff-devel
-libuv-devel
-libxml2-devel
-libxslt-devel
-mpich-devel
-openal-soft-devel
-openmpi-devel
-opensp-devel
-patch
-perl
-postgresql-server-devel
-protobuf-c-devel
-protobuf-devel
-protobuf-lite-devel
-pypy2
-pypy2-devel
-pypy3
-pypy3-devel
-python3
-python3-devel
-python3-jsmin
-python3-jsonschema
-python3-numpy
-rbenv
-ruby
-ruby-build-rbenv
-ruby-devel
-rubygems
-SDL-devel
-sqlite-devel
-swig
-systemd-devel
-unixODBC-devel
-wxGTK-devel
-xalan-c-devel
-xerces-c-devel
-xz-devel
-
-# Packages needed to test third-party binaries.
-ncurses-compat-libs
diff --git a/.gitlab/ci/docker/fedora42/install_deps.sh b/.gitlab/ci/docker/fedora42/install_deps.sh
deleted file mode 100755
index d9c9b5c..0000000
--- a/.gitlab/ci/docker/fedora42/install_deps.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-set -e
-
-dnf install -y $(grep '^[^#]\+$' /root/deps_packages.lst)
-
-# Remove tests for Python packages
-for v in 3.13; do
-    find /usr/lib64/python${v}/site-packages -type d -a -name tests -exec rm -rf {} +
-done
diff --git a/.gitlab/ci/docker/fedora43-hip/Dockerfile b/.gitlab/ci/docker/fedora43-hip/Dockerfile
new file mode 100644
index 0000000..0f0cbed
--- /dev/null
+++ b/.gitlab/ci/docker/fedora43-hip/Dockerfile
@@ -0,0 +1,12 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=fedora:43
+
+FROM ${BASE_IMAGE} AS dnf-cache
+LABEL maintainer="Brad King <brad.king@kitware.com>"
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=cache,target=/var/lib/dnf \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install -y $(grep -h '^[^#]\+$' /root/*.lst)
diff --git a/.gitlab/ci/docker/fedora42-hip/deps_packages.lst b/.gitlab/ci/docker/fedora43-hip/deps_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/fedora42-hip/deps_packages.lst
rename to .gitlab/ci/docker/fedora43-hip/deps_packages.lst
diff --git a/.gitlab/ci/docker/fedora42-hip/dnf.conf b/.gitlab/ci/docker/fedora43-hip/dnf.conf
similarity index 100%
rename from .gitlab/ci/docker/fedora42-hip/dnf.conf
rename to .gitlab/ci/docker/fedora43-hip/dnf.conf
diff --git a/.gitlab/ci/docker/fedora43/Dockerfile b/.gitlab/ci/docker/fedora43/Dockerfile
new file mode 100644
index 0000000..57c70b5
--- /dev/null
+++ b/.gitlab/ci/docker/fedora43/Dockerfile
@@ -0,0 +1,135 @@
+# syntax=docker/dockerfile:1
+
+ARG BASE_IMAGE=fedora:43
+
+FROM ${BASE_IMAGE} AS dnf-cache
+# Populate DNF cache w/ the fresh metadata and prefetch packages.
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
+    --mount=type=bind,source=rbenv_packages.lst,target=/root/rbenv_packages.lst \
+    --mount=type=bind,source=rust_packages.lst,target=/root/rust_packages.lst \
+    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install --downloadonly -y $(grep -h '^[^#]\+$' /root/*.lst)
+
+
+FROM ${BASE_IMAGE} AS rust-build-env
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+# Pre-install prerequisites to build Rust projects.
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=rust_packages.lst,target=/root/rust_packages.lst \
+    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install -y $(grep '^[^#]\+$' /root/rust_packages.lst)
+
+
+FROM rust-build-env AS rust-build
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+# Build the needed Rust packages.
+# https://doc.rust-lang.org/cargo/guide/cargo-home.html?highlight=.cargo#caching-the-cargo-home-in-ci
+RUN --mount=type=bind,source=build_rust.sh,target=/root/build_rust.sh \
+    --mount=type=cache,target=/root/.cargo/registry/index \
+    --mount=type=cache,target=/root/.cargo/registry/cache \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/build_rust.sh
+
+
+FROM ${BASE_IMAGE} AS rvm-build-env
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+# Pre-install prerequisites for RVM.
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=rvm_packages.lst,target=/root/rvm_packages.lst \
+    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install -y $(grep '^[^#]\+$' /root/rvm_packages.lst)
+
+
+FROM rvm-build-env AS rvm-build
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+# Build Ruby with RVM.
+RUN --mount=type=bind,source=build_rvm.sh,target=/root/build_rvm.sh \
+    --mount=type=cache,target=/usr/local/rvm/archives \
+    --mount=type=cache,target=/usr/local/rvm/gem-cache   \
+    --mount=type=cache,target=/usr/local/rvm/src \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/build_rvm.sh
+
+
+FROM ${BASE_IMAGE} AS rbenv
+# Pre-install prerequisites for `rbenv`.
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=rbenv_packages.lst,target=/root/rbenv_packages.lst \
+    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install -y $(grep '^[^#]\+$' /root/rbenv_packages.lst)
+
+
+FROM rbenv AS rbenv-build
+ENV RBENV_ROOT=/opt/rbenv
+ENV RBENV_BUILD_ROOT=/root/.cache/rbenv-build
+ENV RUBY_BUILD_CACHE_PATH=/root/.cache/rbenv
+# Build Ruby with `rbenv`.
+RUN --mount=type=cache,target=/root/.cache \
+    --mount=type=bind,source=build_rbenv.sh,target=/root/build_rbenv.sh \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/build_rbenv.sh
+
+
+FROM ${BASE_IMAGE} AS iwyu-build-env
+LABEL maintainer="Kyle Edwards <kyle.edwards@kitware.com>"
+# Pre-install prerequisites to build IWYU.
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=iwyu_packages.lst,target=/root/iwyu_packages.lst \
+    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    dnf install -y $(grep '^[^#]\+$' /root/iwyu_packages.lst)
+
+
+FROM iwyu-build-env AS iwyu-build
+LABEL maintainer="Kyle Edwards <kyle.edwards@kitware.com>"
+# Build IWYU.
+RUN --mount=type=bind,source=build_iwyu.sh,target=/root/build_iwyu.sh \
+    --mount=type=cache,target=/root/include-what-you-use \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/build_iwyu.sh
+
+
+FROM ${BASE_IMAGE} AS p4-dl
+# Download Perforce.
+# NOTE `curl` is pre-installed in the base image.
+RUN curl -C- -L https://www.perforce.com/downloads/perforce/r21.2/bin.linux26x86_64/helix-core-server.tgz \
+  | tar -C /usr/local/bin -xvzf - -- p4 p4d
+
+
+FROM ${BASE_IMAGE}
+LABEL maintainer="Ben Boeckel <ben.boeckel@kitware.com>"
+
+ENV RBENV_ROOT=/opt/rbenv
+
+COPY --from=p4-dl --chown=root:root /usr/local/bin/p4 /usr/local/bin/p4d /usr/local/bin
+
+RUN --mount=type=bind,source=dnf.conf,target=/etc/dnf/dnf.conf \
+    --mount=type=bind,source=install_deps.sh,target=/root/install_deps.sh \
+    --mount=type=bind,source=deps_packages.lst,target=/root/deps_packages.lst \
+    --mount=type=cache,from=dnf-cache,source=/var/cache/libdnf5,target=/var/cache/libdnf5,sharing=private \
+    --mount=type=tmpfs,target=/var/log \
+    --mount=type=tmpfs,target=/tmp \
+    sh /root/install_deps.sh
+
+RUN --mount=type=bind,from=iwyu-build,source=/root,target=/root \
+    tar -C / -xf /root/iwyu.tar
+
+RUN --mount=type=bind,from=rust-build,source=/root,target=/root \
+    tar -C /usr/local -xf /root/rust.tar
+
+RUN --mount=type=bind,from=rvm-build,source=/root,target=/root \
+    tar -C /usr/local -xf /root/rvm.tar
+
+RUN --mount=type=bind,from=rbenv-build,source=/root,target=/root \
+    tar -C / -xf /root/rbenv.tar && rbenv global 3.4.3
diff --git a/.gitlab/ci/docker/fedora42/build_iwyu.sh b/.gitlab/ci/docker/fedora43/build_iwyu.sh
similarity index 100%
rename from .gitlab/ci/docker/fedora42/build_iwyu.sh
rename to .gitlab/ci/docker/fedora43/build_iwyu.sh
diff --git a/.gitlab/ci/docker/fedora42/build_rbenv.sh b/.gitlab/ci/docker/fedora43/build_rbenv.sh
similarity index 100%
rename from .gitlab/ci/docker/fedora42/build_rbenv.sh
rename to .gitlab/ci/docker/fedora43/build_rbenv.sh
diff --git a/.gitlab/ci/docker/fedora43/build_rust.sh b/.gitlab/ci/docker/fedora43/build_rust.sh
new file mode 100755
index 0000000..5dcea8f
--- /dev/null
+++ b/.gitlab/ci/docker/fedora43/build_rust.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+typos_version=1.38.1
+cargo install --root /usr/local --version "$typos_version" typos-cli
+
+strip /usr/local/bin/typos
+
+tar -C /usr/local -cf /root/rust.tar bin/typos
diff --git a/.gitlab/ci/docker/fedora42/build_rvm.sh b/.gitlab/ci/docker/fedora43/build_rvm.sh
similarity index 100%
rename from .gitlab/ci/docker/fedora42/build_rvm.sh
rename to .gitlab/ci/docker/fedora43/build_rvm.sh
diff --git a/.gitlab/ci/docker/fedora43/deps_packages.lst b/.gitlab/ci/docker/fedora43/deps_packages.lst
new file mode 100644
index 0000000..7873533
--- /dev/null
+++ b/.gitlab/ci/docker/fedora43/deps_packages.lst
@@ -0,0 +1,145 @@
+# Install build requirements.
+ncurses-devel
+openssl-devel
+qt5-qtbase-devel
+qt6-qtbase-devel
+
+# Install development tools.
+clang
+clang-devel
+clang-tools-extra
+clang-tools-extra-devel
+compiler-rt
+flang
+gcc-c++
+git-core
+lfortran
+llvm-devel
+make
+
+# Install optional external build dependencies.
+bzip2-devel
+expat-devel
+jsoncpp-devel
+libarchive-devel
+libcurl-devel
+libuv-devel
+libzstd-devel
+rhash-devel
+xz-devel
+zlib-devel
+
+# Install documentation tools.
+python3-sphinx
+python3-sphinxcontrib-qthelp
+qt5-qttools-devel
+qt6-qttools-devel
+texinfo
+
+# Install lint tools.
+clang-analyzer
+clazy
+codespell
+valgrind
+
+# Tools needed for the test suite.
+file
+findutils
+jq
+which
+
+# Install ASM_NASM language toolchain.
+nasm
+
+# Packages needed to test CTest.
+breezy
+mercurial
+subversion
+
+# Packages needed to test CPack.
+appstream
+patchelf
+rpm-build
+
+# Packages needed to test find modules.
+alsa-lib-devel
+aspell
+aspell-devel
+aspell-en
+blas-devel
+boost-devel
+boost-python3-devel
+bzip2-devel
+cups-devel
+DevIL-devel
+doxygen
+expat-devel
+fontconfig-devel
+freeglut-devel
+freetype-devel
+gdal-devel
+gettext
+giflib-devel
+glew-devel
+gmock
+gnutls-devel
+grpc-devel
+grpc-plugins
+gsl-devel
+gtest-devel
+gtk2-devel
+hdf5-devel
+hdf5-mpich-devel
+hdf5-openmpi-devel
+ImageMagick-c++-devel
+jasper-devel
+java-21-openjdk-devel
+jsoncpp-devel
+lapack-devel
+libarchive-devel
+libcurl-devel
+libicu-devel
+libinput-devel
+libjpeg-turbo-devel
+libomp-devel
+libpng-devel
+libtiff-devel
+libuv-devel
+libxml2-devel
+libxslt-devel
+mpich-devel
+openal-soft-devel
+openmpi-devel
+opensp-devel
+patch
+perl
+postgresql-server-devel
+protobuf-c-devel
+protobuf-devel
+protobuf-lite-devel
+pypy2
+pypy2-devel
+pypy3
+pypy3-devel
+python3
+python3-devel
+python3-jsmin
+python3-jsonschema
+python3-numpy
+rbenv
+ruby
+ruby-build-rbenv
+ruby-devel
+rubygems
+SDL-devel
+sqlite-devel
+swig
+systemd-devel
+unixODBC-devel
+wxGTK-devel
+xalan-c-devel
+xerces-c-devel
+xz-devel
+
+# Packages needed to test third-party binaries.
+ncurses-compat-libs
diff --git a/.gitlab/ci/docker/fedora42/dnf.conf b/.gitlab/ci/docker/fedora43/dnf.conf
similarity index 100%
rename from .gitlab/ci/docker/fedora42/dnf.conf
rename to .gitlab/ci/docker/fedora43/dnf.conf
diff --git a/.gitlab/ci/docker/fedora43/install_deps.sh b/.gitlab/ci/docker/fedora43/install_deps.sh
new file mode 100755
index 0000000..6ee3a3d
--- /dev/null
+++ b/.gitlab/ci/docker/fedora43/install_deps.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+dnf install -y $(grep '^[^#]\+$' /root/deps_packages.lst)
+
+# Remove tests for Python packages
+for v in 3.14; do
+    find /usr/lib64/python${v}/site-packages -type d -a -name tests -exec rm -rf {} +
+done
diff --git a/.gitlab/ci/docker/fedora42/iwyu_packages.lst b/.gitlab/ci/docker/fedora43/iwyu_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/fedora42/iwyu_packages.lst
rename to .gitlab/ci/docker/fedora43/iwyu_packages.lst
diff --git a/.gitlab/ci/docker/fedora42/rbenv_packages.lst b/.gitlab/ci/docker/fedora43/rbenv_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/fedora42/rbenv_packages.lst
rename to .gitlab/ci/docker/fedora43/rbenv_packages.lst
diff --git a/.gitlab/ci/docker/fedora42/rust_packages.lst b/.gitlab/ci/docker/fedora43/rust_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/fedora42/rust_packages.lst
rename to .gitlab/ci/docker/fedora43/rust_packages.lst
diff --git a/.gitlab/ci/docker/fedora42/rvm_packages.lst b/.gitlab/ci/docker/fedora43/rvm_packages.lst
similarity index 100%
rename from .gitlab/ci/docker/fedora42/rvm_packages.lst
rename to .gitlab/ci/docker/fedora43/rvm_packages.lst
diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake
index d2560dd..0c0d3d1 100644
--- a/.gitlab/ci/download_qt.cmake
+++ b/.gitlab/ci/download_qt.cmake
@@ -36,7 +36,8 @@
     set(qt_abi "win64_msvc${msvc_year}_64")
   elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2017" OR
           "$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2019" OR
-          "$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2022")
+          "$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2022" OR
+          "$ENV{CMAKE_CONFIGURATION}" MATCHES "vs2026")
     set(qt_platform "windows_x86")
     set(msvc_year "2019")
     set(qt_abi "win64_msvc${msvc_year}_64")
diff --git a/.gitlab/ci/emsdk-env.sh b/.gitlab/ci/emsdk-env.sh
new file mode 100644
index 0000000..c62e0e7
--- /dev/null
+++ b/.gitlab/ci/emsdk-env.sh
@@ -0,0 +1,3 @@
+.gitlab/ci/emsdk.sh
+. .gitlab/emsdk/emsdk_env.sh
+em++ --version
diff --git a/.gitlab/ci/emsdk.sh b/.gitlab/ci/emsdk.sh
new file mode 100755
index 0000000..0a798a2
--- /dev/null
+++ b/.gitlab/ci/emsdk.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+set -e
+
+case "$(uname -s)-$(uname -m)" in
+    Linux-x86_64)
+        ;;
+    *)
+        echo "Unrecognized platform $(uname -s)-$(uname -m)"
+        exit 1
+        ;;
+esac
+
+cd .gitlab
+
+version=4.0.9
+dirname="emsdk-$version"
+filename="$dirname.tar.gz"
+curl -OJL "https://github.com/emscripten-core/emsdk/archive/refs/tags/$version.tar.gz"
+tar xzf "$filename"
+mv "$dirname" emsdk
+emsdk/emsdk install "$version"
+emsdk/emsdk activate "$version"
+
+rm -f "$filename"
diff --git a/.gitlab/ci/env_cuda13.0_nvidia_fastbuild.sh b/.gitlab/ci/env_cuda13.0_nvidia_fastbuild.sh
new file mode 100644
index 0000000..5e8b2df
--- /dev/null
+++ b/.gitlab/ci/env_cuda13.0_nvidia_fastbuild.sh
@@ -0,0 +1 @@
+source .gitlab/ci/fastbuild-env.sh
diff --git a/.gitlab/ci/env_debian12_hip_radeon.sh b/.gitlab/ci/env_debian12_hip_radeon.sh
deleted file mode 100644
index 793c985..0000000
--- a/.gitlab/ci/env_debian12_hip_radeon.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-export HIPCXX=/usr/bin/clang++-15
-export HIPFLAGS='--rocm-path=/usr --rocm-device-lib-path=/usr/lib/x86_64-linux-gnu/amdgcn/bitcode'
-
-# FIXME(debian): Clang is supposed to automatically parse a HIP version file.
-# The ROCm installer places it at '$prefix/bin/.hipVersion', but the package
-# on Debian moves it to '$prefix/share/hip/version'.  llvm-toolchain package
-# version 15.0.7-4 has 'debian/patches/amdgpu/usr-search-paths.patch' for this,
-# but Debian 12 currently provides version 15.0.6-4 without the patch.
-export HIPFLAGS="$HIPFLAGS --hip-version=5.2"
diff --git a/.gitlab/ci/env_debian12_makefiles_clang.sh b/.gitlab/ci/env_debian12_makefiles_clang.sh
deleted file mode 100644
index e4ee249..0000000
--- a/.gitlab/ci/env_debian12_makefiles_clang.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if test "$CMAKE_CI_NIGHTLY" = "true"; then
-  source .gitlab/ci/iar-env.sh
-  source .gitlab/ci/ticlang-env.sh
-fi
-
-export CC=/usr/bin/clang-15
-export CXX=/usr/bin/clang++-15
diff --git a/.gitlab/ci/env_debian12_ninja_clang.sh b/.gitlab/ci/env_debian12_ninja_clang.sh
deleted file mode 100644
index e4ee249..0000000
--- a/.gitlab/ci/env_debian12_ninja_clang.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-if test "$CMAKE_CI_NIGHTLY" = "true"; then
-  source .gitlab/ci/iar-env.sh
-  source .gitlab/ci/ticlang-env.sh
-fi
-
-export CC=/usr/bin/clang-15
-export CXX=/usr/bin/clang++-15
diff --git a/.gitlab/ci/env_debian12_aarch64_extdeps.sh b/.gitlab/ci/env_debian13_aarch64_extdeps.sh
similarity index 100%
rename from .gitlab/ci/env_debian12_aarch64_extdeps.sh
rename to .gitlab/ci/env_debian13_aarch64_extdeps.sh
diff --git a/.gitlab/ci/env_debian12_extdeps.sh b/.gitlab/ci/env_debian13_extdeps.sh
similarity index 100%
rename from .gitlab/ci/env_debian12_extdeps.sh
rename to .gitlab/ci/env_debian13_extdeps.sh
diff --git a/.gitlab/ci/env_debian13_hip_radeon.sh b/.gitlab/ci/env_debian13_hip_radeon.sh
new file mode 100644
index 0000000..0f7df8d
--- /dev/null
+++ b/.gitlab/ci/env_debian13_hip_radeon.sh
@@ -0,0 +1 @@
+export HIPCXX=/usr/bin/clang++-17
diff --git a/.gitlab/ci/env_debian13_makefiles_clang.sh b/.gitlab/ci/env_debian13_makefiles_clang.sh
new file mode 100644
index 0000000..8878718
--- /dev/null
+++ b/.gitlab/ci/env_debian13_makefiles_clang.sh
@@ -0,0 +1,8 @@
+if test "$CMAKE_CI_NIGHTLY" = "true"; then
+  source .gitlab/ci/iar-env.sh
+  source .gitlab/ci/ticlang-env.sh
+  source .gitlab/ci/emsdk-env.sh
+fi
+
+export CC=/usr/bin/clang-19
+export CXX=/usr/bin/clang++-19
diff --git a/.gitlab/ci/env_debian12_ninja.sh b/.gitlab/ci/env_debian13_ninja.sh
similarity index 100%
rename from .gitlab/ci/env_debian12_ninja.sh
rename to .gitlab/ci/env_debian13_ninja.sh
diff --git a/.gitlab/ci/env_debian13_ninja_clang.sh b/.gitlab/ci/env_debian13_ninja_clang.sh
new file mode 100644
index 0000000..8878718
--- /dev/null
+++ b/.gitlab/ci/env_debian13_ninja_clang.sh
@@ -0,0 +1,8 @@
+if test "$CMAKE_CI_NIGHTLY" = "true"; then
+  source .gitlab/ci/iar-env.sh
+  source .gitlab/ci/ticlang-env.sh
+  source .gitlab/ci/emsdk-env.sh
+fi
+
+export CC=/usr/bin/clang-19
+export CXX=/usr/bin/clang++-19
diff --git a/.gitlab/ci/env_debian12_ninja_multi_symlinked.sh b/.gitlab/ci/env_debian13_ninja_multi_symlinked.sh
similarity index 100%
rename from .gitlab/ci/env_debian12_ninja_multi_symlinked.sh
rename to .gitlab/ci/env_debian13_ninja_multi_symlinked.sh
diff --git a/.gitlab/ci/env_fedora42_common_clang.sh b/.gitlab/ci/env_fedora42_common_clang.sh
deleted file mode 100644
index 43775d2..0000000
--- a/.gitlab/ci/env_fedora42_common_clang.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-export CC=/usr/bin/clang-20
-export CXX=/usr/bin/clang++-20
-export FC=/usr/bin/flang-20
diff --git a/.gitlab/ci/env_fedora42_extdeps.sh b/.gitlab/ci/env_fedora42_extdeps.sh
deleted file mode 100644
index 7076e18..0000000
--- a/.gitlab/ci/env_fedora42_extdeps.sh
+++ /dev/null
@@ -1 +0,0 @@
-source .gitlab/ci/env_extdeps_common.sh
diff --git a/.gitlab/ci/env_fedora42_hip_radeon.sh b/.gitlab/ci/env_fedora42_hip_radeon.sh
deleted file mode 100644
index cc57cc7..0000000
--- a/.gitlab/ci/env_fedora42_hip_radeon.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-export HIPCXX=/usr/bin/clang++-20
-export HIPFLAGS='--rocm-path=/usr --rocm-device-lib-path=/usr/lib64/rocm/llvm/lib/clang/18/amdgcn/bitcode'
diff --git a/.gitlab/ci/env_fedora42_makefiles_clang.sh b/.gitlab/ci/env_fedora42_makefiles_clang.sh
deleted file mode 100644
index 8067256..0000000
--- a/.gitlab/ci/env_fedora42_makefiles_clang.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_common_clang.sh
diff --git a/.gitlab/ci/env_fedora42_makefiles_lfortran.sh b/.gitlab/ci/env_fedora42_makefiles_lfortran.sh
deleted file mode 100644
index 9d559f9..0000000
--- a/.gitlab/ci/env_fedora42_makefiles_lfortran.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_common_lfortran.sh
diff --git a/.gitlab/ci/env_fedora42_makefiles_symlinked.cmake b/.gitlab/ci/env_fedora42_makefiles_symlinked.cmake
deleted file mode 100644
index fcf100a..0000000
--- a/.gitlab/ci/env_fedora42_makefiles_symlinked.cmake
+++ /dev/null
@@ -1 +0,0 @@
-include("${CMAKE_CURRENT_LIST_DIR}/env_fedora42_makefiles.cmake")
diff --git a/.gitlab/ci/env_fedora42_makefiles_symlinked.sh b/.gitlab/ci/env_fedora42_makefiles_symlinked.sh
deleted file mode 100644
index c18e125..0000000
--- a/.gitlab/ci/env_fedora42_makefiles_symlinked.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_makefiles.sh
diff --git a/.gitlab/ci/env_fedora42_ninja.sh b/.gitlab/ci/env_fedora42_ninja.sh
deleted file mode 100644
index 217ff30..0000000
--- a/.gitlab/ci/env_fedora42_ninja.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-if test "$CMAKE_CI_NIGHTLY" = "true"; then
-  source .gitlab/ci/ispc-env.sh
-fi
diff --git a/.gitlab/ci/env_fedora42_ninja_clang.sh b/.gitlab/ci/env_fedora42_ninja_clang.sh
deleted file mode 100644
index 8067256..0000000
--- a/.gitlab/ci/env_fedora42_ninja_clang.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_common_clang.sh
diff --git a/.gitlab/ci/env_fedora42_ninja_lfortran.sh b/.gitlab/ci/env_fedora42_ninja_lfortran.sh
deleted file mode 100644
index 9d559f9..0000000
--- a/.gitlab/ci/env_fedora42_ninja_lfortran.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_common_lfortran.sh
diff --git a/.gitlab/ci/env_fedora42_ninja_multi_clang.sh b/.gitlab/ci/env_fedora42_ninja_multi_clang.sh
deleted file mode 100644
index 8067256..0000000
--- a/.gitlab/ci/env_fedora42_ninja_multi_clang.sh
+++ /dev/null
@@ -1 +0,0 @@
-. .gitlab/ci/env_fedora42_common_clang.sh
diff --git a/.gitlab/ci/env_fedora42_asan.sh b/.gitlab/ci/env_fedora43_asan.sh
similarity index 100%
rename from .gitlab/ci/env_fedora42_asan.sh
rename to .gitlab/ci/env_fedora43_asan.sh
diff --git a/.gitlab/ci/env_fedora43_bullseye_coverage.sh b/.gitlab/ci/env_fedora43_bullseye_coverage.sh
new file mode 100644
index 0000000..57f92ab
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_bullseye_coverage.sh
@@ -0,0 +1,10 @@
+source .gitlab/ci/bullseye-env.sh
+
+# Store Bullseye activation state in the work directory.
+export COVAPPDATADIR="$CI_PROJECT_DIR/build/Bullseye"
+
+# Collect all coverage in a single location.
+export COVFILE="$COVAPPDATADIR/CMake.cov"
+
+# Suppress the Bullseye startup banner on compilation.
+export COVCOPT="--no-banner"
diff --git a/.gitlab/ci/env_fedora42_clang_analyzer.sh b/.gitlab/ci/env_fedora43_clang_analyzer.sh
similarity index 100%
rename from .gitlab/ci/env_fedora42_clang_analyzer.sh
rename to .gitlab/ci/env_fedora43_clang_analyzer.sh
diff --git a/.gitlab/ci/env_fedora43_clazy.sh b/.gitlab/ci/env_fedora43_clazy.sh
new file mode 100644
index 0000000..007c52d
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_clazy.sh
@@ -0,0 +1,25 @@
+export CC=/usr/bin/clang
+export CXX=/usr/bin/clazy
+export CLANGXX=/usr/bin/clang++
+
+export CLAZY_CHECKS="level2\
+,no-base-class-event\
+,no-connect-3arg-lambda\
+,no-connect-by-name\
+,no-container-inside-loop\
+,no-copyable-polymorphic\
+,no-ctor-missing-parent-argument\
+,no-function-args-by-ref\
+,no-missing-qobject-macro\
+,no-non-pod-global-static\
+,no-old-style-connect\
+,no-qproperty-without-notify\
+,no-qstring-allocations\
+,no-range-loop-detach\
+,no-range-loop-reference\
+,no-reserve-candidates\
+,no-rule-of-three\
+,no-rule-of-two-soft\
+,no-static-pmf\
+,no-strict-iterators\
+"
diff --git a/.gitlab/ci/env_fedora43_common_clang.sh b/.gitlab/ci/env_fedora43_common_clang.sh
new file mode 100644
index 0000000..55533e7
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_common_clang.sh
@@ -0,0 +1,3 @@
+export CC=/usr/bin/clang-21
+export CXX=/usr/bin/clang++-21
+export FC=/usr/bin/flang-21
diff --git a/.gitlab/ci/env_fedora42_common_lfortran.sh b/.gitlab/ci/env_fedora43_common_lfortran.sh
similarity index 100%
rename from .gitlab/ci/env_fedora42_common_lfortran.sh
rename to .gitlab/ci/env_fedora43_common_lfortran.sh
diff --git a/.gitlab/ci/env_debian12_extdeps.sh b/.gitlab/ci/env_fedora43_extdeps.sh
similarity index 100%
copy from .gitlab/ci/env_debian12_extdeps.sh
copy to .gitlab/ci/env_fedora43_extdeps.sh
diff --git a/.gitlab/ci/env_fedora43_fastbuild.sh b/.gitlab/ci/env_fedora43_fastbuild.sh
new file mode 100644
index 0000000..5e8b2df
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_fastbuild.sh
@@ -0,0 +1 @@
+source .gitlab/ci/fastbuild-env.sh
diff --git a/.gitlab/ci/env_fedora43_hip_radeon.sh b/.gitlab/ci/env_fedora43_hip_radeon.sh
new file mode 100644
index 0000000..2c942a8
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_hip_radeon.sh
@@ -0,0 +1,2 @@
+export HIPCXX=/usr/bin/clang++-21
+export HIPFLAGS='--rocm-path=/usr --rocm-device-lib-path=/usr/lib64/rocm/llvm/lib/clang/19/amdgcn/bitcode'
diff --git a/.gitlab/ci/env_fedora42_makefiles.cmake b/.gitlab/ci/env_fedora43_makefiles.cmake
similarity index 100%
rename from .gitlab/ci/env_fedora42_makefiles.cmake
rename to .gitlab/ci/env_fedora43_makefiles.cmake
diff --git a/.gitlab/ci/env_fedora42_makefiles.sh b/.gitlab/ci/env_fedora43_makefiles.sh
similarity index 100%
rename from .gitlab/ci/env_fedora42_makefiles.sh
rename to .gitlab/ci/env_fedora43_makefiles.sh
diff --git a/.gitlab/ci/env_fedora43_makefiles_clang.sh b/.gitlab/ci/env_fedora43_makefiles_clang.sh
new file mode 100644
index 0000000..3953f88
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_makefiles_clang.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_common_clang.sh
diff --git a/.gitlab/ci/env_fedora43_makefiles_lfortran.sh b/.gitlab/ci/env_fedora43_makefiles_lfortran.sh
new file mode 100644
index 0000000..6b02339
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_makefiles_lfortran.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_common_lfortran.sh
diff --git a/.gitlab/ci/env_fedora43_makefiles_symlinked.cmake b/.gitlab/ci/env_fedora43_makefiles_symlinked.cmake
new file mode 100644
index 0000000..fb004e8
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_makefiles_symlinked.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/env_fedora43_makefiles.cmake")
diff --git a/.gitlab/ci/env_fedora43_makefiles_symlinked.sh b/.gitlab/ci/env_fedora43_makefiles_symlinked.sh
new file mode 100644
index 0000000..448b592
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_makefiles_symlinked.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_makefiles.sh
diff --git a/.gitlab/ci/env_fedora43_ninja.sh b/.gitlab/ci/env_fedora43_ninja.sh
new file mode 100644
index 0000000..a2b941b
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_ninja.sh
@@ -0,0 +1,4 @@
+if test "$CMAKE_CI_NIGHTLY" = "true"; then
+  source .gitlab/ci/appimagetool-env.sh
+  source .gitlab/ci/ispc-env.sh
+fi
diff --git a/.gitlab/ci/env_fedora43_ninja_clang.sh b/.gitlab/ci/env_fedora43_ninja_clang.sh
new file mode 100644
index 0000000..3953f88
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_ninja_clang.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_common_clang.sh
diff --git a/.gitlab/ci/env_fedora43_ninja_lfortran.sh b/.gitlab/ci/env_fedora43_ninja_lfortran.sh
new file mode 100644
index 0000000..6b02339
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_ninja_lfortran.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_common_lfortran.sh
diff --git a/.gitlab/ci/env_fedora42_ninja_multi.sh b/.gitlab/ci/env_fedora43_ninja_multi.sh
similarity index 100%
rename from .gitlab/ci/env_fedora42_ninja_multi.sh
rename to .gitlab/ci/env_fedora43_ninja_multi.sh
diff --git a/.gitlab/ci/env_fedora43_ninja_multi_clang.sh b/.gitlab/ci/env_fedora43_ninja_multi_clang.sh
new file mode 100644
index 0000000..3953f88
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_ninja_multi_clang.sh
@@ -0,0 +1 @@
+. .gitlab/ci/env_fedora43_common_clang.sh
diff --git a/.gitlab/ci/env_fedora43_ninja_valgrind.sh b/.gitlab/ci/env_fedora43_ninja_valgrind.sh
new file mode 100644
index 0000000..cc89d0b
--- /dev/null
+++ b/.gitlab/ci/env_fedora43_ninja_valgrind.sh
@@ -0,0 +1 @@
+source .gitlab/ci/env_fedora43_ninja.sh
diff --git a/.gitlab/ci/env_macos_arm64_fastbuild.sh b/.gitlab/ci/env_macos_arm64_fastbuild.sh
new file mode 100644
index 0000000..6b25127
--- /dev/null
+++ b/.gitlab/ci/env_macos_arm64_fastbuild.sh
@@ -0,0 +1 @@
+. .gitlab/ci/fastbuild-env.sh
diff --git a/.gitlab/ci/env_macos_x86_64_makefiles.sh b/.gitlab/ci/env_macos_x86_64_makefiles.sh
index 7496372..dca8dd7 100644
--- a/.gitlab/ci/env_macos_x86_64_makefiles.sh
+++ b/.gitlab/ci/env_macos_x86_64_makefiles.sh
@@ -2,3 +2,4 @@
 if test "$CMAKE_CI_NIGHTLY" = "true"; then
   source .gitlab/ci/ispc-env.sh
 fi
+export CFLAGS=-Wstrict-prototypes
diff --git a/.gitlab/ci/env_windows_arm64_vs2022_ninja.ps1 b/.gitlab/ci/env_windows_arm64_vs2026_ninja.ps1
similarity index 100%
rename from .gitlab/ci/env_windows_arm64_vs2022_ninja.ps1
rename to .gitlab/ci/env_windows_arm64_vs2026_ninja.ps1
diff --git a/.gitlab/ci/env_windows_vs2026_x64.ps1 b/.gitlab/ci/env_windows_vs2026_x64.ps1
new file mode 100644
index 0000000..42aec11
--- /dev/null
+++ b/.gitlab/ci/env_windows_vs2026_x64.ps1
@@ -0,0 +1,4 @@
+if ("$env:CMAKE_CI_NIGHTLY" -eq "true") {
+  $cmake = "build\install\bin\cmake"
+  . ".gitlab/ci/qt-env.ps1"
+}
diff --git a/.gitlab/ci/env_windows_vs2026_x64_fastbuild.ps1 b/.gitlab/ci/env_windows_vs2026_x64_fastbuild.ps1
new file mode 100644
index 0000000..803fefc
--- /dev/null
+++ b/.gitlab/ci/env_windows_vs2026_x64_fastbuild.ps1
@@ -0,0 +1,2 @@
+. .gitlab/ci/fastbuild-env.ps1
+Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_jom.ps1 b/.gitlab/ci/env_windows_vs2026_x64_jom.ps1
similarity index 100%
rename from .gitlab/ci/env_windows_vs2022_x64_jom.ps1
rename to .gitlab/ci/env_windows_vs2026_x64_jom.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1 b/.gitlab/ci/env_windows_vs2026_x64_ninja.ps1
similarity index 100%
rename from .gitlab/ci/env_windows_vs2022_x64_ninja.ps1
rename to .gitlab/ci/env_windows_vs2026_x64_ninja.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_ninja_multi.ps1 b/.gitlab/ci/env_windows_vs2026_x64_ninja_multi.ps1
similarity index 100%
rename from .gitlab/ci/env_windows_vs2022_x64_ninja_multi.ps1
rename to .gitlab/ci/env_windows_vs2026_x64_ninja_multi.ps1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_nmake.ps1 b/.gitlab/ci/env_windows_vs2026_x64_nmake.ps1
similarity index 100%
rename from .gitlab/ci/env_windows_vs2022_x64_nmake.ps1
rename to .gitlab/ci/env_windows_vs2026_x64_nmake.ps1
diff --git a/.gitlab/ci/fastbuild-env.ps1 b/.gitlab/ci/fastbuild-env.ps1
new file mode 100644
index 0000000..9b7cc8f
--- /dev/null
+++ b/.gitlab/ci/fastbuild-env.ps1
@@ -0,0 +1,4 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/fastbuild.ps1"
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\fastbuild;$env:PATH"
+Write-Host "fbuild version: $(fbuild -version)"
diff --git a/.gitlab/ci/fastbuild-env.sh b/.gitlab/ci/fastbuild-env.sh
new file mode 100644
index 0000000..2bdf524
--- /dev/null
+++ b/.gitlab/ci/fastbuild-env.sh
@@ -0,0 +1,3 @@
+.gitlab/ci/fastbuild.sh
+export PATH=$PWD/.gitlab/fastbuild:$PATH
+fbuild -version
diff --git a/.gitlab/ci/fastbuild.ps1 b/.gitlab/ci/fastbuild.ps1
new file mode 100644
index 0000000..ac74fcb
--- /dev/null
+++ b/.gitlab/ci/fastbuild.ps1
@@ -0,0 +1,24 @@
+$erroractionpreference = "stop"
+
+if ("$env:PROCESSOR_ARCHITECTURE" -eq "AMD64") {
+    $sha256sum = "65EA2572275CD326116F39047F60008D8F90373AF1EB419C1CF1DE65379321AC"
+    $filename = "FASTBuild-Windows-x64-v1.15"
+} else {
+    throw ('unknown PROCESSOR_ARCHITECTURE: ' + "$env:PROCESSOR_ARCHITECTURE")
+}
+
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+$ProgressPreference = 'SilentlyContinue'
+# This URL is only visible inside of Kitware's network.  See above filename table.
+Invoke-WebRequest -Uri "https://cmake.org/files/dependencies/internal/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+    exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir\fastbuild")
+Remove-Item "$outdir\$tarball"
diff --git a/.gitlab/ci/fastbuild.sh b/.gitlab/ci/fastbuild.sh
new file mode 100755
index 0000000..3a6625d
--- /dev/null
+++ b/.gitlab/ci/fastbuild.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+set -e
+
+case "$(uname -s)-$(uname -m)" in
+    Linux-x86_64)
+        shatool="sha256sum"
+        sha256sum="2c7b4c833c7f2846119aaa72bfa92df5b7da1aa17a0e62187ac0bbcbbf5cce8e"
+        filename="FASTBuild-Linux-x64-v1.15"
+        exenames="fastbuild/fbuild fastbuild/fbuildworker"
+        ;;
+    Darwin-*)
+        shatool="shasum -a 256"
+        sha256sum="875fedc71a2b479b22e90fcc77db75513b1d88794fd71cfe3889f41b225efbaa"
+        filename="FASTBuild-OSX-x64+ARM-v1.15"
+        exenames="fastbuild/FBuild fastbuild/FBuildWorker"
+        ;;
+    *)
+        echo "Unrecognized platform $(uname -s)-$(uname -m)"
+        exit 1
+        ;;
+esac
+readonly shatool
+readonly sha256sum
+
+readonly tarball="$filename.zip"
+
+cd .gitlab
+
+echo "$sha256sum  $tarball" > fastbuild.sha256sum
+# This URL is only visible inside of Kitware's network.  See above filename table.
+curl -OL "https://cmake.org/files/dependencies/internal/$tarball"
+$shatool --check fastbuild.sha256sum
+mkdir -p fastbuild
+unzip -d fastbuild -q "$tarball"
+chmod +x $exenames
+rm "$tarball" fastbuild.sha256sum
diff --git a/.gitlab/ci/iar-env.sh b/.gitlab/ci/iar-env.sh
index 9ec7494..39a5580 100644
--- a/.gitlab/ci/iar-env.sh
+++ b/.gitlab/ci/iar-env.sh
@@ -1,10 +1,10 @@
 files='
-bxarm-9.60.4.deb
+bxarm-9.70.1.deb
 bxavr-8.10.2.deb
 bxrh850-3.10.2.deb
-bxriscv-3.30.1.deb
-bxrl78-5.10.3.deb
-bxrx-5.10.1.deb
+bxriscv-3.40.1.deb
+bxrl78-5.20.1.deb
+bxrx-5.20.1.deb
 '
 for f in $files; do
   # This URL is only visible inside of Kitware's network.
@@ -12,12 +12,12 @@
 done
 
 echo '
-cd92a136bc9bbb1e713121cb407131b54250d2ae30809df3cd752c6383e1878f  bxarm-9.60.4.deb
+3b16748e560ab8fa3ffe6d6807186ac706134c78bc9db911112ab3ee67c7b997  bxarm-9.70.1.deb
 4a1065291952a23a8bfbbaa4eb36ca49b0af8653b8faab34ce955d9d48d64506  bxavr-8.10.2.deb
 b14085a0f21750c58168125d3cece2e3fcbd4c6495c652b5e65b6637bac0ac31  bxrh850-3.10.2.deb
-517e18dffdd4345f97c480b5128c7feea25ec1c3f06e62d8e2e6808c401d514a  bxriscv-3.30.1.deb
-3deca7f6afd5f47684464ad748334ab0690097a109d9c680603450074fc32ccf  bxrl78-5.10.3.deb
-260e592c48cbaf902b13bdb2feeeba83068978131fcb5c027dab17e715dec7e7  bxrx-5.10.1.deb
+2e7de58a3aad43ef4199b811edd4dae9c4bff633376393f12fcb77ca27aba831  bxriscv-3.40.1.deb
+6a2b6163dd971635715f49cb072c853e5de55d2b0089f319a6a9f6db540af4bd  bxrl78-5.20.1.deb
+059667a53b6683b1b09b7842d71e784c04bc2376734421c3a628acdbc6bef9e3  bxrx-5.20.1.deb
 ' > bxdebs.sha256sum
 sha256sum --check bxdebs.sha256sum
 
diff --git a/.gitlab/ci/iar.ps1 b/.gitlab/ci/iar.ps1
index 2034fa2..4c1093d 100644
--- a/.gitlab/ci/iar.ps1
+++ b/.gitlab/ci/iar.ps1
@@ -7,12 +7,12 @@
 $iar_dir = New-Item -Force -ItemType Directory -Path "$outdir\iar"
 
 $files = @{
-    "bxarm-9.60.4.11196-1.zip" = "0DE5F610D0FA3A6513C856BC2403A84D5277F1F6D0D65A6022D1FD745BC4AF6A"
+    "bxarm-9.70.1.13552-1.zip" = "866792FA6881C28610558E87EE02A45752CC06E7550FB57682720CDC300DA0B7"
     "BXAVR-8102-1.zip"         = "862EFD23531854506070D5647F9B32197B80E5A727304BFBD8E386A3DAADF093"
     "BXRH850-3102-1.zip"       = "8D1D009A0D138C7CA8431316123CB85CE1B41319A68B997F90D2E338CD469C7F"
-    "BXRISCV-3301-1.zip"       = "59FF23F7B98EE72567A23942DE799AF137791A19BFEC102B2A59821FABBCA55A"
-    "BXRL78-5103-1.zip"        = "00398E7197735A7B0A4310BF906808E883548814475C12D6EF2C03388F77E6A7"
-    "BXRX-5101-1.zip"          = "D63E95ECD454B4998946C2D9DC1CB6CEF69CE15524C11A123263E6A8E88D9899"
+    "BXRISCV-3401-1.zip"       = "633F9BF64429923B0C478FB8ED0C47B3A67BC9B23DD9A2851DE66AC70DA64E06"
+    "bxrl78-5.20.1.2826-1.zip" = "71E981EC18C5BC031A356D89C4D6579DF0B0EF9EB34AB3B46A48DA3F3737C2D4"
+    "bxrx-5.20.1.6541-1.zip"   = "C000B333618A253482DCCB8F06CB902F6D9D0B7D554B863175D316004FBFFC82"
 }
 
 foreach ($f in $files.GetEnumerator()) {
diff --git a/.gitlab/ci/post_build_fedora42_tidy.sh b/.gitlab/ci/post_build_fedora43_tidy.sh
similarity index 100%
rename from .gitlab/ci/post_build_fedora42_tidy.sh
rename to .gitlab/ci/post_build_fedora43_tidy.sh
diff --git a/.gitlab/ci/pre_build_fedora43_bullseye_coverage.sh b/.gitlab/ci/pre_build_fedora43_bullseye_coverage.sh
new file mode 100644
index 0000000..ab78d8f
--- /dev/null
+++ b/.gitlab/ci/pre_build_fedora43_bullseye_coverage.sh
@@ -0,0 +1,2 @@
+# Turn on Bullseye coverage for build step.
+cov01 --on
diff --git a/.gitlab/ci/pre_configure.ps1 b/.gitlab/ci/pre_configure.ps1
new file mode 100644
index 0000000..8c4a4a6
--- /dev/null
+++ b/.gitlab/ci/pre_configure.ps1
@@ -0,0 +1,4 @@
+$pwsh = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
+if (Test-Path -Path ".gitlab/ci/pre_configure_$env:CMAKE_CONFIGURATION.ps1" -PathType Leaf) {
+  . ".gitlab/ci/pre_configure_$env:CMAKE_CONFIGURATION.ps1"
+}
diff --git a/.gitlab/ci/pre_configure.sh b/.gitlab/ci/pre_configure.sh
new file mode 100755
index 0000000..29ce813
--- /dev/null
+++ b/.gitlab/ci/pre_configure.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+quietly() {
+  readonly log="/tmp/quietly-$RANDOM.log"
+  if ! "$@" >"$log" 2>&1; then
+    ret=$?
+    cat "$log"
+    rm -f "$log"
+    exit $ret
+  fi
+  rm -f "$log"
+}
+
+if test -r ".gitlab/ci/pre_configure_${CMAKE_CONFIGURATION}.sh"; then
+  source ".gitlab/ci/pre_configure_${CMAKE_CONFIGURATION}.sh"
+fi
diff --git a/.gitlab/ci/pre_configure_fedora43_bullseye_coverage.sh b/.gitlab/ci/pre_configure_fedora43_bullseye_coverage.sh
new file mode 100644
index 0000000..ec54ff2
--- /dev/null
+++ b/.gitlab/ci/pre_configure_fedora43_bullseye_coverage.sh
@@ -0,0 +1,2 @@
+# Turn off Bullseye coverage for configure step.
+cov01 --off
diff --git a/.gitlab/ci/pre_build_fedora42_tidy.sh b/.gitlab/ci/pre_configure_fedora43_tidy.sh
similarity index 100%
rename from .gitlab/ci/pre_build_fedora42_tidy.sh
rename to .gitlab/ci/pre_configure_fedora43_tidy.sh
diff --git a/.gitlab/ci/pre_test.ps1 b/.gitlab/ci/pre_test.ps1
new file mode 100644
index 0000000..4936d98
--- /dev/null
+++ b/.gitlab/ci/pre_test.ps1
@@ -0,0 +1,4 @@
+$pwsh = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
+if (Test-Path -Path ".gitlab/ci/pre_test_$env:CMAKE_CONFIGURATION.ps1" -PathType Leaf) {
+  . ".gitlab/ci/pre_test_$env:CMAKE_CONFIGURATION.ps1"
+}
diff --git a/.gitlab/ci/pre_test.sh b/.gitlab/ci/pre_test.sh
new file mode 100755
index 0000000..f529861
--- /dev/null
+++ b/.gitlab/ci/pre_test.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+set -e
+
+quietly() {
+  readonly log="/tmp/quietly-$RANDOM.log"
+  if ! "$@" >"$log" 2>&1; then
+    ret=$?
+    cat "$log"
+    rm -f "$log"
+    exit $ret
+  fi
+  rm -f "$log"
+}
+
+if test -r ".gitlab/ci/pre_test_${CMAKE_CONFIGURATION}.sh"; then
+  source ".gitlab/ci/pre_test_${CMAKE_CONFIGURATION}.sh"
+fi
diff --git a/.gitlab/ci/pre_test_fedora43_bullseye_coverage.sh b/.gitlab/ci/pre_test_fedora43_bullseye_coverage.sh
new file mode 100644
index 0000000..4e892d2
--- /dev/null
+++ b/.gitlab/ci/pre_test_fedora43_bullseye_coverage.sh
@@ -0,0 +1,2 @@
+# Turn on Bullseye coverage for test step.
+cov01 --on
diff --git a/.gitlab/ci/repackage/appimagetool.sh b/.gitlab/ci/repackage/appimagetool.sh
new file mode 100755
index 0000000..03ce12d
--- /dev/null
+++ b/.gitlab/ci/repackage/appimagetool.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+set -e
+
+arch="$1"
+version="${2-1.9.0.20250814}"
+
+dir="appimagetool-$version-$arch"
+mkdir "$dir"
+mkdir -p "$dir/lib/appimagetool"
+
+filename="appimagetool-$arch.AppImage"
+curl -OL "https://github.com/AppImage/appimagetool/releases/download/continuous/$filename"
+chmod +x "$filename"
+"./$filename" --appimage-extract
+mv "squashfs-root/usr/bin" "$dir/bin"
+rm -rf "$filename" "squashfs-root"
+
+filename="runtime-$arch"
+curl -OL "https://github.com/AppImage/type2-runtime/releases/download/continuous/$filename"
+mv "$filename" "$dir/lib/appimagetool/runtime"
+
+cat >"$dir/README.txt" <<EOF
+This was packaged using CMake's ".gitlab/ci/repackage/appimagetool.sh" script.
+EOF
+
+tar czf "$dir.tar.gz" "$dir"
+rm -rf "$dir"
diff --git a/.gitlab/ci/repackage/iar.ps1 b/.gitlab/ci/repackage/iar.ps1
index 5a8c1e5..eb140cd 100644
--- a/.gitlab/ci/repackage/iar.ps1
+++ b/.gitlab/ci/repackage/iar.ps1
@@ -23,12 +23,26 @@
   "arm/config/flashloader"
   "arm/drivers"
   "arm/src"
+  "riscv/config/debugger"
+  "riscv/config/flashloader"
+  "riscv/drivers"
+  "riscv/src"
+  "rl78/config/debugger"
+  "rl78/config/flashloader"
+  "rl78/drivers"
+  "rl78/src"
+  "rx/config/debugger"
+  "rx/config/flashloader"
+  "rx/drivers"
+  "rx/src"
   )
 
 Write-Host "Installing to: $package_dir"
 Start-Process -Wait -FilePath "$installer_file" -ArgumentList "/hide_usd /autoinstall/$package_dir"
 foreach ($p in $exclude) {
-    Remove-Item "$package_dir/$p" -Recurse -Force
+    if (Test-Path "$package_dir/$p") {
+        Remove-Item "$package_dir/$p" -Recurse -Force
+    }
 }
 
 @"
diff --git a/.gitlab/ci/swift-env.sh b/.gitlab/ci/swift-env.sh
index fa0c81e..5225cdf 100644
--- a/.gitlab/ci/swift-env.sh
+++ b/.gitlab/ci/swift-env.sh
@@ -1,7 +1,7 @@
-curl -L -O "https://download.swift.org/swift-5.7.1-release/ubuntu1804/swift-5.7.1-RELEASE/swift-5.7.1-RELEASE-ubuntu18.04.tar.gz"
-echo '2b30f9efc969d9e96f0836d0871130dffb369822a3823ee6f3db44c29c1698e3  swift-5.7.1-RELEASE-ubuntu18.04.tar.gz' > swift.sha256sum
+curl -L -O "https://download.swift.org/swift-6.2.1-release/debian12/swift-6.2.1-RELEASE/swift-6.2.1-RELEASE-debian12.tar.gz"
+echo 'd6405e4fb7f092cbb9973a892ce8410837b4335f67d95bf8607baef1f69939e4  swift-6.2.1-RELEASE-debian12.tar.gz' > swift.sha256sum
 sha256sum --check swift.sha256sum
 mkdir /opt/swift
-tar xzf swift-5.7.1-RELEASE-ubuntu18.04.tar.gz -C /opt/swift --strip-components=2
-rm swift-5.7.1-RELEASE-ubuntu18.04.tar.gz swift.sha256sum
+tar xzf swift-6.2.1-RELEASE-debian12.tar.gz -C /opt/swift --strip-components=2
+rm swift-6.2.1-RELEASE-debian12.tar.gz swift.sha256sum
 export SWIFTC="/opt/swift/bin/swiftc"
diff --git a/.gitlab/ci/ticlang.sh b/.gitlab/ci/ticlang.sh
index 66fa863..a0e4b19 100755
--- a/.gitlab/ci/ticlang.sh
+++ b/.gitlab/ci/ticlang.sh
@@ -5,9 +5,9 @@
 case "$(uname -s)-$(uname -m)" in
     Linux-x86_64)
         shatool="sha256sum"
-        sha256sum="c69ac58e403b82eac1c407cc67b35fab5d95c5d8db75b019095f9412aacff27d"
-        filename="ti_cgt_armllvm_3.2.1.LTS_linux-x64_installer.bin"
-        dirname="ti-cgt-armllvm_3.2.1.LTS"
+        sha256sum="98c60ecc259a07a54be6fcc0f55990332f493bfe5dad460c0ba83963f5dcb06f"
+        filename="ti_cgt_armllvm_4.0.4.LTS_linux-x64_installer.bin"
+        dirname="ti-cgt-armllvm_4.0.4.LTS"
         ;;
     *)
         echo "Unrecognized platform $(uname -s)-$(uname -m)"
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 47f0d5f..2317e5f 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -5,7 +5,7 @@
 ### Release
 
 .linux_prep_source:
-    image: "fedora:42"
+    image: "fedora:43"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -58,23 +58,23 @@
 
 ### Debian
 
-.debian12:
-    image: "kitware/cmake:ci-debian12-x86_64-2025-03-31"
+.debian13:
+    image: "kitware/cmake:ci-debian13-x86_64-2025-11-11"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
         CMAKE_ARCH: x86_64
 
-.debian12_iwyu:
-    extends: .debian12
+.debian13_iwyu:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_iwyu
+        CMAKE_CONFIGURATION: debian13_iwyu
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_CI_NO_INSTALL: 1
 
-.debian12_aarch64:
-    image: "kitware/cmake:ci-debian12-aarch64-2025-03-31"
+.debian13_aarch64:
+    image: "kitware/cmake:ci-debian13-aarch64-2025-11-11"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -82,202 +82,246 @@
 
 ### Fedora
 
-.fedora42:
-    image: "kitware/cmake:ci-fedora42-x86_64-2025-04-22"
+.fedora43:
+    image: "kitware/cmake:ci-fedora43-x86_64-2025-11-06"
 
     variables:
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
         CMAKE_ARCH: x86_64
 
-.fedora42_hip:
-    image: "kitware/cmake:ci-fedora42-hip-x86_64-2025-04-22"
+.fedora43_hip:
+    image: "kitware/cmake:ci-fedora43-hip-x86_64-2025-10-29"
 
     variables:
         # FIXME(rocclr): device modules fail loading from binaries in paths with spaces
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
         CMAKE_ARCH: x86_64
 
-#### Lint builds
+#### Coverage builds
 
-.fedora42_tidy:
-    extends: .fedora42
+.fedora43_gcc_gcov:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_tidy
+        # See issue #20001
+        CMAKE_GENERATOR: "Unix Makefiles"
+        CMAKE_CONFIGURATION: fedora43_gcc_gcov
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_CI_BUILD_TYPE: Debug
+        CMAKE_CI_TEST_TIMEOUT: "1500"
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora42_clang_analyzer:
-    extends: .fedora42
+.fedora43_bullseye_coverage:
+    extends: .fedora43
+    environment:
+        name: bullseye-coverage
+    variables:
+        # See issue #20001
+        CMAKE_GENERATOR: "Unix Makefiles"
+        CMAKE_CONFIGURATION: fedora43_bullseye_coverage
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_CI_BUILD_TYPE: Debug
+        CMAKE_CI_TEST_TIMEOUT: "1500"
+        CMAKE_CI_NO_INSTALL: 1
+
+#### Lint builds
+
+.fedora43_tidy:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_clang_analyzer
+        CMAKE_CONFIGURATION: fedora43_tidy
+        CMAKE_CI_NO_INSTALL: 1
+
+.fedora43_clang_analyzer:
+    extends: .fedora43
+
+    variables:
+        CMAKE_CONFIGURATION: fedora43_clang_analyzer
         CMAKE_CI_BUILD_TYPE: Debug
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora42_sphinx:
-    extends: .fedora42
+.fedora43_clazy:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_sphinx
+        CMAKE_CONFIGURATION: fedora43_clazy
+        CMAKE_CI_BUILD_TYPE: Debug
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_CI_NO_INSTALL: 1
+
+.fedora43_sphinx:
+    extends: .fedora43
+
+    variables:
+        CMAKE_CONFIGURATION: fedora43_sphinx
         CTEST_NO_WARNINGS_ALLOWED: 1
         CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
         CMAKE_CI_NO_INSTALL: 1
 
-.fedora42_sphinx_package:
-    extends: .fedora42
+.fedora43_sphinx_package:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_sphinx_package
+        CMAKE_CONFIGURATION: fedora43_sphinx_package
         CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
 
 #### Build and test
 
-.debian12_ninja:
-    extends: .debian12
+.debian13_ninja:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_ninja
+        CMAKE_CONFIGURATION: debian13_ninja
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.debian12_aarch64_ninja:
-    extends: .debian12_aarch64
+.debian13_aarch64_ninja:
+    extends: .debian13_aarch64
 
     variables:
-        CMAKE_CONFIGURATION: debian12_aarch64_ninja
+        CMAKE_CONFIGURATION: debian13_aarch64_ninja
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.debian12_makefiles_inplace:
-    extends: .debian12
+.debian13_makefiles_inplace:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_makefiles_inplace
+        CMAKE_CONFIGURATION: debian13_makefiles_inplace
         CMAKE_GENERATOR: "Unix Makefiles"
         CMAKE_CI_BOOTSTRAP: 1
         CMAKE_CI_INPLACE: 1
         CMAKE_CI_NO_INSTALL: 1
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.debian12_ninja_multi_symlinked:
-    extends: .debian12
+.debian13_ninja_multi_symlinked:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_ninja_multi_symlinked
+        CMAKE_CONFIGURATION: debian13_ninja_multi_symlinked
         CMAKE_GENERATOR: "Ninja Multi-Config"
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_CI_IN_SYMLINK_TREE: 1
         CMAKE_CI_BUILD_DIR: "real_work/work/build"
 
-.debian12_extdeps:
-    extends: .debian12
+.debian13_extdeps:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_extdeps
+        CMAKE_CONFIGURATION: debian13_extdeps
         CMAKE_CI_BUILD_TYPE: Release
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.debian12_aarch64_extdeps:
-    extends: .debian12_aarch64
+.debian13_aarch64_extdeps:
+    extends: .debian13_aarch64
 
     variables:
-        CMAKE_CONFIGURATION: debian12_aarch64_extdeps
+        CMAKE_CONFIGURATION: debian13_aarch64_extdeps
         CMAKE_CI_BUILD_TYPE: Release
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.fedora42_extdeps:
-    extends: .fedora42
+.fedora43_extdeps:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_extdeps
+        CMAKE_CONFIGURATION: fedora43_extdeps
         CMAKE_CI_BUILD_TYPE: Release
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.fedora42_ninja:
-    extends: .fedora42
+.fedora43_ninja:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_ninja
+        CMAKE_CONFIGURATION: fedora43_ninja
         CMAKE_CI_BUILD_TYPE: Release
         CTEST_NO_WARNINGS_ALLOWED: 1
 
-.fedora42_ninja_multi:
-    extends: .fedora42
+.fedora43_ninja_multi:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_ninja_multi
+        CMAKE_CONFIGURATION: fedora43_ninja_multi
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "Ninja Multi-Config"
 
-.fedora42_makefiles:
-    extends: .fedora42
+.fedora43_makefiles:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_makefiles
+        CMAKE_CONFIGURATION: fedora43_makefiles
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "Unix Makefiles"
 
-.fedora42_makefiles_symlinked:
-    extends: .fedora42
+.fedora43_makefiles_symlinked:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_makefiles_symlinked
+        CMAKE_CONFIGURATION: fedora43_makefiles_symlinked
         CTEST_NO_WARNINGS_ALLOWED: 1
         CMAKE_GENERATOR: "Unix Makefiles"
         CMAKE_CI_IN_SYMLINK_TREE: 1
         CMAKE_CI_BUILD_DIR: "real_work/work/build"
 
+.fedora43_fastbuild:
+    extends: .fedora43
+
+    variables:
+        CMAKE_CONFIGURATION: fedora43_fastbuild
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_GENERATOR: "FASTBuild"
+
 ### Clang Compiler
 
-.debian12_makefiles_clang:
-    extends: .debian12
+.debian13_makefiles_clang:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_makefiles_clang
+        CMAKE_CONFIGURATION: debian13_makefiles_clang
         CMAKE_GENERATOR: "Unix Makefiles"
 
-.debian12_ninja_clang:
-    extends: .debian12
+.debian13_ninja_clang:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_ninja_clang
+        CMAKE_CONFIGURATION: debian13_ninja_clang
 
-.fedora42_makefiles_clang:
-    extends: .fedora42
+.fedora43_makefiles_clang:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_makefiles_clang
+        CMAKE_CONFIGURATION: fedora43_makefiles_clang
         CMAKE_GENERATOR: "Unix Makefiles"
 
-.fedora42_makefiles_lfortran:
-    extends: .fedora42
+.fedora43_makefiles_lfortran:
+    extends: .fedora43
 
     variables:
         # FIXME(lfortran): -rpath flags with spaces not forwarded
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
-        CMAKE_CONFIGURATION: fedora42_makefiles_lfortran
+        CMAKE_CONFIGURATION: fedora43_makefiles_lfortran
         CMAKE_GENERATOR: "Unix Makefiles"
         CTEST_LABELS: "Fortran"
 
-.fedora42_ninja_lfortran:
-    extends: .fedora42
+.fedora43_ninja_lfortran:
+    extends: .fedora43
 
     variables:
         # FIXME(lfortran): -rpath flags with spaces not forwarded
         GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake-ci"
-        CMAKE_CONFIGURATION: fedora42_ninja_lfortran
+        CMAKE_CONFIGURATION: fedora43_ninja_lfortran
         CTEST_LABELS: "Fortran"
 
-.fedora42_ninja_clang:
-    extends: .fedora42
+.fedora43_ninja_clang:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_ninja_clang
+        CMAKE_CONFIGURATION: fedora43_ninja_clang
 
-.fedora42_ninja_multi_clang:
-    extends: .fedora42
+.fedora43_ninja_multi_clang:
+    extends: .fedora43
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_ninja_multi_clang
+        CMAKE_CONFIGURATION: fedora43_ninja_multi_clang
         CMAKE_GENERATOR: "Ninja Multi-Config"
 
 ### Sanitizers
@@ -293,13 +337,31 @@
         CTEST_MEMORYCHECK_TYPE: AddressSanitizer
         CTEST_MEMORYCHECK_SANITIZER_OPTIONS: ""
 
-.fedora42_asan:
+.fedora_valgrind_addon:
+    extends: .fedora_memcheck
+
+    variables:
+        CTEST_MEMORYCHECK_TYPE: Valgrind
+        CMAKE_CI_RUN_MEMCHECK: "true"
+        CMAKE_CI_TEST_TIMEOUT: "1500"
+        CMAKE_VALGRIND_CONFIGURATION: fedora43
+
+.fedora43_asan:
     extends:
-        - .fedora42
+        - .fedora43
         - .fedora_asan_addon
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_asan
+        CMAKE_CONFIGURATION: fedora43_asan
+
+
+.fedora43_ninja_valgrind:
+    extends:
+        - .fedora43
+        - .fedora_valgrind_addon
+
+    variables:
+        CMAKE_CONFIGURATION: fedora43_ninja_valgrind
 
 ### Intel Compiler
 
@@ -451,6 +513,26 @@
         CMAKE_CONFIGURATION: cuda12.6_clang
         CTEST_NO_WARNINGS_ALLOWED: 1
 
+.cuda13.0:
+    extends: .cuda
+    image: "kitware/cmake:ci-cuda13.0-x86_64-2025-10-20"
+    variables:
+        CMAKE_ARCH: x86_64
+
+.cuda13.0_nvidia:
+    extends: .cuda13.0
+    variables:
+        CMAKE_CONFIGURATION: cuda13.0_nvidia
+        CTEST_NO_WARNINGS_ALLOWED: 1
+
+.cuda13.0_nvidia_fastbuild:
+    extends: .cuda13.0
+
+    variables:
+        CMAKE_CONFIGURATION: cuda13.0_nvidia_fastbuild
+        CTEST_NO_WARNINGS_ALLOWED: 1
+        CMAKE_GENERATOR: "FASTBuild"
+
 ### HIP builds
 
 .hip6.3:
@@ -470,18 +552,18 @@
         CMAKE_CONFIGURATION: hip6.3_radeon
         CMAKE_GENERATOR: "Ninja Multi-Config"
 
-.debian12_hip_radeon:
-    extends: .debian12
+.debian13_hip_radeon:
+    extends: .debian13
 
     variables:
-        CMAKE_CONFIGURATION: debian12_hip_radeon
+        CMAKE_CONFIGURATION: debian13_hip_radeon
         CTEST_LABELS: "HIP"
 
-.fedora42_hip_radeon:
-    extends: .fedora42_hip
+.fedora43_hip_radeon:
+    extends: .fedora43_hip
 
     variables:
-        CMAKE_CONFIGURATION: fedora42_hip_radeon
+        CMAKE_CONFIGURATION: fedora43_hip_radeon
         CTEST_LABELS: "HIP"
 
 .hip6.3_nvidia:
@@ -508,6 +590,13 @@
     variables:
         CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja
 
+.gcc_cxx_modules_reloc_ninja:
+    extends: .gcc_cxx_modules_x86_64
+
+    variables:
+        CMAKE_CONFIGURATION: linux_gcc_cxx_modules_reloc_ninja
+        CTEST_LABELS: "CXXModules"
+
 .gcc_cxx_modules_ninja_multi:
     extends: .gcc_cxx_modules_x86_64
 
@@ -554,6 +643,13 @@
         - linux-x86_64
         - x11
 
+.linux_x86_64_tags_fast_x11:
+    tags:
+        - cmake
+        - docker
+        - linux-x86_64-v4
+        - x11
+
 .linux_x86_64_tags_cuda_arch_30:
     tags:
         - cmake
@@ -575,11 +671,18 @@
         - docker
         - linux-x86_64-v3
 
-.linux_x86_64_tags_rocm5.2:
+.linux_x86_64_tags_cuda_arch_75:
+    tags:
+        - cmake
+        - cuda-arch-75
+        - docker
+        - linux-x86_64
+
+.linux_x86_64_tags_rocm5.7:
     tags:
         - cmake
         - radeon
-        - rocm-5.2
+        - rocm-5.7
         - docker
         - linux-x86_64
 
@@ -638,14 +741,14 @@
 
 .cmake_version_update_linux:
     stage: build
-    extends: .fedora42
+    extends: .fedora43
     script:
         - .gitlab/ci/cmake_version_update.sh
     interruptible: false # The job internally fetches and retries.
 
 .cmake_spellcheck_linux:
     stage: build
-    extends: .fedora42
+    extends: .fedora43
     script:
         - .gitlab/ci/codespell.bash
         - .gitlab/ci/typos.bash
@@ -659,8 +762,9 @@
         - .gitlab/ci/sccache.sh
         - sccache --start-server
         - sccache --show-stats
-        - .gitlab/ci/pre_build.sh
+        - .gitlab/ci/pre_configure.sh
         - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+        - .gitlab/ci/pre_build.sh
         - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
         - .gitlab/ci/post_build.sh
         - sccache --show-stats
@@ -672,6 +776,7 @@
 
     script:
         - *before_script_linux
+        - .gitlab/ci/pre_test.sh
         - "$LAUNCHER ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake"
 
     interruptible: true
@@ -685,6 +790,16 @@
 
     interruptible: true
 
+.cmake_coverage_linux:
+    stage: test
+
+    script:
+        - *before_script_linux
+        - "$LAUNCHER ctest --output-on-failure -V -S .gitlab/ci/ctest_coverage.cmake"
+    coverage: '/Percentage Coverage: \d+.\d+%/'
+
+    interruptible: true
+
 .cmake_build_linux_release:
     stage: build
 
@@ -773,6 +888,7 @@
         - .needs_centos7_x86_64
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
+        CMAKE_CI_NO_MR: "true"
 
 .cmake_test_linux_inteloneapi_makefiles:
     extends:
@@ -816,7 +932,7 @@
 .cmake_org_help:
     stage: build
     extends:
-        - .fedora42
+        - .fedora43
         - .linux_x86_64_tags
         - .cmake_org_help_artifacts
     script:
diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml
index cf93e06..c8aaec6 100644
--- a/.gitlab/os-macos.yml
+++ b/.gitlab/os-macos.yml
@@ -47,13 +47,6 @@
         CMAKE_CI_IN_SYMLINK_TREE: 1
         CMAKE_CI_BUILD_DIR: "real_work/work/build"
 
-.macos_arm64_curl:
-    extends: .macos_build
-
-    variables:
-        CMAKE_CONFIGURATION: macos_arm64_curl
-        CTEST_NO_WARNINGS_ALLOWED: 1
-
 .macos_arm64_pch:
     extends: .macos_arm64_ninja
 
@@ -135,6 +128,14 @@
         CMAKE_CONFIGURATION: macos_x86_64_ninja_ub
         CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
 
+.macos_arm64_fastbuild:
+    extends: .macos
+
+    variables:
+        CMAKE_CONFIGURATION: macos_arm64_fastbuild
+        CMAKE_GENERATOR: FASTBuild
+        CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
 ## Tags
 
 .macos_x86_64_tags:
@@ -197,8 +198,9 @@
         # Allow the server to already be running.
         - "sccache --start-server || :"
         - sccache --show-stats
-        - .gitlab/ci/pre_build.sh
+        - .gitlab/ci/pre_configure.sh
         - ctest -VV -S .gitlab/ci/ctest_configure.cmake
+        - .gitlab/ci/pre_build.sh
         - ctest -VV -S .gitlab/ci/ctest_build.cmake
         - .gitlab/ci/post_build.sh
         - sccache --show-stats
@@ -210,6 +212,7 @@
 
     script:
         - *before_script_macos
+        - .gitlab/ci/pre_test.sh
         - ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake
 
     interruptible: true
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index 34a4433..1fed177 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -35,52 +35,64 @@
         VCVARSPLATFORM: "x64"
         VCVARSVERSION: "14.43.34808"
 
-.windows_vcvarsall_vs2022_x64:
+.windows_vcvarsall_vs2022_x64_msvc14.44:
     variables:
         VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
         VCVARSPLATFORM: "x64"
         VCVARSVERSION: "14.44.35207"
 
-.windows_vcvarsall_vs2022_x86:
+.windows_vcvarsall_vs2022_x86_msvc14.44:
     variables:
         VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
         VCVARSPLATFORM: "x86"
         VCVARSVERSION: "14.44.35207"
 
-.windows_vcvarsall_vs2022_x64_arm64:
+.windows_vcvarsall_vs2026_x64:
     variables:
-        VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSALL: "${VS180COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSPLATFORM: "x64"
+        VCVARSVERSION: "14.50.35717"
+
+.windows_vcvarsall_vs2026_x86:
+    variables:
+        VCVARSALL: "${VS180COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSPLATFORM: "x86"
+        VCVARSVERSION: "14.50.35717"
+
+.windows_vcvarsall_vs2026_x64_arm64:
+    variables:
+        VCVARSALL: "${VS180COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
         VCVARSPLATFORM: "x64_arm64"
-        VCVARSVERSION: "14.44.35207"
+        VCVARSVERSION: "14.50.35717"
 
-.windows_arm64_vcvarsall_vs2022:
+.windows_arm64_vcvarsall_vs2026:
     variables:
-        VCVARSALL: "${VS170COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
+        VCVARSALL: "${VS180COMNTOOLS}\\..\\..\\VC\\Auxiliary\\Build\\vcvarsall.bat"
         VCVARSPLATFORM: "arm64"
-        VCVARSVERSION: "14.44.35207"
+        VCVARSVERSION: "14.50.35717"
 
-.windows_vs2022_x64_pch:
+.windows_vs2026_x64_pch:
     extends:
-        - .windows_vs2022_x64_ninja
+        - .windows_vs2026_x64_ninja
 
     variables:
-        CMAKE_CONFIGURATION: windows_vs2022_x64_pch
+        CMAKE_CONFIGURATION: windows_vs2026_x64_pch
 
-.windows_vs2022_x64_ninja:
+.windows_vs2026_x64_ninja:
     extends:
         - .windows_build_ninja
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2026_x64
 
     variables:
-        CMAKE_CONFIGURATION: windows_vs2022_x64_ninja
+        CMAKE_CONFIGURATION: windows_vs2026_x64_ninja
 
-.windows_arm64_vs2022_ninja:
+.windows_arm64_vs2026_ninja:
     extends:
         - .windows_build_ninja
-        - .windows_arm64_vcvarsall_vs2022
+        - .windows_arm64_vcvarsall_vs2026
 
     variables:
-        CMAKE_CONFIGURATION: windows_arm64_vs2022_ninja
+        CMAKE_CONFIGURATION: windows_arm64_vs2026_ninja
 
 .windows_package:
     extends:
@@ -93,7 +105,7 @@
 .windows_x86_64_package:
     extends:
         - .windows_package
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2022_x64_msvc14.44
 
     variables:
         CMAKE_CONFIGURATION: windows_x86_64_package
@@ -101,7 +113,7 @@
 .windows_i386_package:
     extends:
         - .windows_package
-        - .windows_vcvarsall_vs2022_x86
+        - .windows_vcvarsall_vs2022_x86_msvc14.44
 
     variables:
         CMAKE_CONFIGURATION: windows_i386_package
@@ -109,13 +121,23 @@
 .windows_arm64_package:
     extends:
         - .windows_package
-        - .windows_vcvarsall_vs2022_x64_arm64
+        - .windows_vcvarsall_vs2026_x64_arm64
 
     variables:
         CMAKE_CONFIGURATION: windows_arm64_package
 
 ### External testing
 
+.windows_vs2026_x64:
+    extends: .windows
+
+    variables:
+        CMAKE_CONFIGURATION: windows_vs2026_x64
+        CMAKE_GENERATOR: "Visual Studio 18 2026"
+        CMAKE_GENERATOR_PLATFORM: "x64"
+        CMAKE_GENERATOR_TOOLSET: "v145,version=14.50.35717"
+        CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
 .windows_vs2022_x64:
     extends: .windows
 
@@ -187,34 +209,50 @@
         CMAKE_CI_BUILD_TYPE: Release
         CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
 
-.windows_vs2022_x64_nmake:
+.windows_fastbuild:
+    extends: .windows
+
+    variables:
+        CMAKE_GENERATOR: "FASTBuild"
+        CMAKE_CI_BUILD_TYPE: Release
+        CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
+.windows_vs2026_x64_nmake:
     extends:
         - .windows_nmake
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2026_x64
 
     variables:
-        CMAKE_CONFIGURATION: windows_vs2022_x64_nmake
+        CMAKE_CONFIGURATION: windows_vs2026_x64_nmake
 
-.windows_vs2022_x64_jom:
+.windows_vs2026_x64_jom:
     extends:
         - .windows_jom
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2026_x64
 
     variables:
-        CMAKE_CONFIGURATION: windows_vs2022_x64_jom
+        CMAKE_CONFIGURATION: windows_vs2026_x64_jom
 
-.windows_vs2022_x64_ninja_multi:
+.windows_vs2026_x64_ninja_multi:
     extends:
         - .windows_ninja_multi
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2026_x64
 
     variables:
-        CMAKE_CONFIGURATION: windows_vs2022_x64_ninja_multi
+        CMAKE_CONFIGURATION: windows_vs2026_x64_ninja_multi
+
+.windows_vs2026_x64_fastbuild:
+    extends:
+        - .windows_fastbuild
+        - .windows_vcvarsall_vs2026_x64
+
+    variables:
+        CMAKE_CONFIGURATION: windows_vs2026_x64_fastbuild
 
 .windows_clang_ninja:
     extends:
         - .windows_ninja
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2022_x64_msvc14.44
 
     variables:
         CMAKE_CONFIGURATION: windows_clang_ninja
@@ -222,7 +260,7 @@
 .windows_clang_nmake:
     extends:
         - .windows_nmake
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2022_x64_msvc14.44
 
     variables:
         CMAKE_CONFIGURATION: windows_clang_nmake
@@ -244,7 +282,7 @@
 .windows_inteloneapi_ninja:
     extends:
         - .windows_ninja
-        - .windows_vcvarsall_vs2022_x64
+        - .windows_vcvarsall_vs2022_x64_msvc14.44
 
     variables:
         CMAKE_CONFIGURATION: windows_inteloneapi_ninja
@@ -279,6 +317,16 @@
     variables:
         CMAKE_CONFIGURATION: windows_orangec6.73.1
 
+.windows_arm64_vs2026:
+    extends: .windows
+
+    variables:
+        CMAKE_CONFIGURATION: windows_arm64_vs2026
+        CMAKE_GENERATOR: "Visual Studio 18 2026"
+        CMAKE_GENERATOR_PLATFORM: "ARM64"
+        CMAKE_GENERATOR_TOOLSET: "v145,version=14.50.35717"
+        CMAKE_CI_NIGHTLY_IGNORE_DEPS: "true"
+
 .windows_arm64_vs2022:
     extends: .windows
 
@@ -322,7 +370,44 @@
         - sign-windows-v1
         - nonconcurrent
 
-.windows_x86_64_tags_nonconcurrent_vs2022:
+.windows_x86_64_tags_nonconcurrent_vs2026:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows-x86_64
+        - shell
+        - vs2026
+        - msvc-14.50
+        - nonconcurrent
+
+.windows_x86_64_tags_nonconcurrent_vs2026_arm64:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows-x86_64
+        - shell
+        - vs2026
+        - msvc-14.50-arm64
+        - nonconcurrent
+
+.windows_x86_64_tags_concurrent_vs2026:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows-x86_64
+        - shell
+        - vs2026
+        - msvc-14.50
+        - concurrent
+
+.windows_x86_64_tags_concurrent_vs2026_android:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows-x86_64
+        - shell
+        - vs2026
+        - vs18-android
+        - msvc-14.50
+        - concurrent
+
+.windows_x86_64_tags_nonconcurrent_vs2022_msvc14.44:
     tags:
         - cmake # Since this is a bare runner, pin to a project.
         - windows-x86_64
@@ -331,16 +416,7 @@
         - msvc-14.44
         - nonconcurrent
 
-.windows_x86_64_tags_nonconcurrent_vs2022_arm64:
-    tags:
-        - cmake # Since this is a bare runner, pin to a project.
-        - windows-x86_64
-        - shell
-        - vs2022
-        - msvc-14.44-arm64
-        - nonconcurrent
-
-.windows_x86_64_tags_concurrent_vs2022:
+.windows_x86_64_tags_concurrent_vs2022_msvc14.44:
     tags:
         - cmake # Since this is a bare runner, pin to a project.
         - windows-x86_64
@@ -385,15 +461,24 @@
         - shell
         - concurrent
 
-.windows_arm64_tags_nonconcurrent_vs2022:
+.windows_arm64_tags_nonconcurrent_vs2026:
     tags:
         - cmake # Since this is a bare runner, pin to a project.
         - windows-arm64
         - shell
-        - vs2022
-        - msvc-14.44
+        - vs2026
+        - msvc-14.50
         - nonconcurrent
 
+.windows_arm64_tags_concurrent_vs2026:
+    tags:
+        - cmake # Since this is a bare runner, pin to a project.
+        - windows-arm64
+        - shell
+        - vs2026
+        - msvc-14.50
+        - concurrent
+
 .windows_arm64_tags_concurrent_vs2022:
     tags:
         - cmake # Since this is a bare runner, pin to a project.
@@ -425,12 +510,14 @@
         - Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
         - sccache --start-server
         - sccache --show-stats
-        - (& "$pwsh" -File ".gitlab/ci/pre_build.ps1")
+        - (& "$pwsh" -File ".gitlab/ci/pre_configure.ps1")
         - ctest -VV -S .gitlab/ci/ctest_configure.cmake
+        - (& "$pwsh" -File ".gitlab/ci/pre_build.ps1")
         - ctest -VV -S .gitlab/ci/ctest_build.cmake
         - (& "$pwsh" -File ".gitlab/ci/post_build.ps1")
         - sccache --show-stats
-        - sccache --stop-server
+        # Tolerate already-stopped server.
+        - (sccache --stop-server)
 
     interruptible: true
 
@@ -452,6 +539,7 @@
     script:
         - *before_script_windows
         - Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
+        - (& "$pwsh" -File ".gitlab/ci/pre_test.ps1")
         - ctest --output-on-failure -V -S .gitlab/ci/ctest_test.cmake
 
     interruptible: true
diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml
index c489c54..47316d1 100644
--- a/.gitlab/upload.yml
+++ b/.gitlab/upload.yml
@@ -1,7 +1,7 @@
 # Steps for uploading artifacts
 
 .rsync_upload_package:
-    image: "fedora:42"
+    image: "fedora:43"
     stage: upload
     tags:
         - cmake
@@ -21,7 +21,7 @@
 
 .rsync_upload_help:
     stage: upload
-    image: "fedora:42"
+    image: "fedora:43"
     tags:
         - cmake
         - docker
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 8b6d940..1f9477c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -29,7 +29,7 @@
       - id: check-useless-excludes
 
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v5.0.0
+    rev: v6.0.0
     hooks:
       - id: check-case-conflict
       - id: check-json
@@ -39,6 +39,7 @@
                 CMakeLib/testCTestResourceSpec_data/spec13
               | RunCMake/CTestResourceAllocation/invalid
               )\.json
+      - id: check-toml
       - id: check-yaml
       - id: end-of-file-fixer
         # NOTE Exclude tests directory: some test files have no
@@ -80,7 +81,7 @@
         pass_filenames: false
 
   - repo: https://github.com/sphinx-contrib/sphinx-lint
-    rev: v1.0.0
+    rev: v1.0.1
     hooks:
       - id: sphinx-lint
         # NOTE Looks like `bad-dedent` gives too many false-positives.
@@ -102,13 +103,14 @@
       - id: rst-inline-touching-normal
 
   - repo: https://github.com/codespell-project/codespell
-    rev: v2.4.0
+    rev: v2.4.1
     hooks:
       - id: codespell
         stages: [commit-msg, pre-commit]
 
-  - repo: https://github.com/crate-ci/typos
-    rev: v1.30.0
+    # NOTE See BUG https://github.com/crate-ci/typos/issues/390
+  - repo: https://github.com/adhtruong/mirrors-typos
+    rev: v1.39.0
     hooks:
       - id: typos
         # NOTE Override hook's default args to prevent automatic
diff --git a/.typos.toml b/.typos.toml
index 5ad2245..db890af 100644
--- a/.typos.toml
+++ b/.typos.toml
@@ -5,10 +5,10 @@
 check-file = true
 check-filename = true
 extend-ignore-re = [
-    # NOTE Allow to mark a block of text to exclude from spellchecking
-    "(?s)(#|/(/|\\*)|\\.\\.)\\s*(NOQA|noqa):? spellcheck(: *|=| +)off.*?\\n\\s*(#|/(/|\\*)|\\.\\.)\\s*(NOQA|noqa):? spellcheck(: *|=| +)on"
+    # NOTE Allow to mark block of text to exclude from spellchecking inside C++ or hash-style comments (CMake,Python,&etc.)
+    "(?s)(#|//)\\s*(NOQA|noqa):? spellcheck(: *|=| +)off.*?\\n\\s*(#|//)\\s*(NOQA|noqa):? spellcheck(: *|=| +)on"
     # NOTE Allow to mark a line to exclude from spellchecking
-  , "(?Rm)^.*(#|/(/|\\*)|\\.\\.)\\s*(NOQA|noqa):? spellcheck(: *|=| +)disable-line$"
+  , "(?Rm)^.*(#|//)\\s*(NOQA|noqa):? spellcheck(: *|=| +)disable-line$"
     # NOTE Stop checking from this line to the end of file
     # This line is a marker added by Git to the `COMMIT_EDITMSG`.
   , "(?sm)^# ------------------------ >8 ------------------------$.*"
@@ -18,7 +18,13 @@
 # `extend-ignore-identifiers-re` to this section,
 # please also modify the `.gitlab/ci/typos.bash`
 # script accordingly.
-#extend-ignore-identifiers-re=["\\b[0-9a-f]{10}\\b"]
+#extend-ignore-identifiers-re=["\\b[0-9a-f]{8,12}\\b"]
+
+[default.extend-identifiers]
+_tru64 = "_tru64"
+__tru64 = "__tru64"
+__TRU64__ = "__TRU64__"
+Tru64 = "Tru64"
 
 # Add repo-wide false positives here in the form of `word = "word"`.
 # Check the manual for details.
@@ -34,31 +40,8 @@
 restat = "restat"
 # SpectreMitigation
 Spectre = "Spectre"
-
-[type.cmake.extend-identifiers]
-COMMANDs = "COMMANDs"
-xCOMMANDx = "xCOMMANDx"
-TYPEs = "TYPEs"
-
-[type.cmake.extend-words]
-# Some compiler's options trigger false-positives
-Fo = "Fo"
-ot = "ot"
-# Part of compiler executable name, e.g., `arm-unknown-nto-qnx6`, but also could be in a literal string.
-nto = "nto"
-
-[type.cpp.extend-identifiers]
-APPENDed = "APPENDed"
-
-[type.json.extend-identifiers]
-# Some compiler options from `Templates/MSBuild/FlagTables/*.json` trigger too many false-positives.
-Fo = "Fo"
-fo = "fo"
-Ot = "Ot"
-SEH = "SEH"
-
-[type.py.extend-identifiers]
-typ = "typ"
+# Identifier used in source code (`GlobalTargetInfo`)
+gti = "gti"
 
 [files]
 ignore-hidden = false
@@ -77,3 +60,41 @@
     # FIXME: Fix spelling typos in tests.  Exclude for now.
   , "Tests"
   ]
+
+# BEGIN Type-specific settings
+[type.cmake.extend-identifiers]
+COMMANDs = "COMMANDs"
+xCOMMANDx = "xCOMMANDx"
+TYPEs = "TYPEs"
+
+[type.cmake.extend-words]
+# Some compiler's options trigger false-positives
+Fo = "Fo"
+ot = "ot"
+# Part of compiler executable name, e.g., `arm-unknown-nto-qnx6`, but also could be in a literal string.
+nto = "nto"
+
+[type.cpp.extend-identifiers]
+APPENDed = "APPENDed"
+setp = "setp"
+setp_ = "setp_"
+
+[type.json.extend-identifiers]
+# Some compiler options from `Templates/MSBuild/FlagTables/*.json` trigger too many false-positives.
+Fo = "Fo"
+fo = "fo"
+Ot = "Ot"
+SEH = "SEH"
+
+[type.py.extend-identifiers]
+typ = "typ"
+
+[type.sh.extend-identifiers]
+xTRUEx = "xTRUEx"
+
+[type.rst]
+extend-ignore-re = [
+    # NOTE Allow to mark block of text to exclude from spellchecking as RST comments
+    "(?s)\\.\\.\\s+(NOQA|noqa):? spellcheck(: *|=| +)off.*?\\n\\.\\.\\s+(NOQA|noqa):? spellcheck(: *|=| +)on"
+  ]
+# END Type-specific settings
diff --git a/Auxiliary/vim/cmake.vim.in b/Auxiliary/vim/cmake.vim.in
index 39d7193..a7c857e 100644
--- a/Auxiliary/vim/cmake.vim.in
+++ b/Auxiliary/vim/cmake.vim.in
@@ -13,16 +13,25 @@
 "               https://cmake.org/licensing
 "               This implies that distribution with Vim is allowed
 
-if exists("b:current_syntax")
+if exists('b:current_syntax')
   finish
 endif
-let s:keepcpo= &cpo
-set cpo&vim
+let s:keepcpo= &cpoptions
+set cpoptions&vim
 
-syn region cmakeBracketArgument start="\[\z(=\?\|=[0-9]*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn cluster cmakeControl contains=
+      \ cmakeIf,
+      \ cmakeElse,
+      \ cmakeForeach,
+      \ cmakeWhile,
+      \ cmakeBlock,
+      \ cmakeFunction,
+      \ cmakeMacro
 
-syn region cmakeComment start="#" end="$" contains=cmakeTodo,@Spell
-syn region cmakeBracketComment start="\[\z(=*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn region cmakeBracketArgument start="\[\z(=*\)\[" end="\]\z1\]" fold contains=cmakeTodo,@Spell
+
+syn region cmakeComment start="#\(\[=*\[\)\@!" end="$" contains=cmakeTodo,@Spell
+syn region cmakeBracketComment start="#\[\z(=*\)\[" end="\]\z1\]" fold contains=cmakeTodo,@Spell
 
 syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
 syn region cmakeRegistry start="\[" end="]" contained oneline contains=cmakeTodo,cmakeEscaped
@@ -35,7 +44,15 @@
 
 syn region cmakeEnvironment start="$ENV{" end="}" contained oneline contains=cmakeTodo
 
-syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell
+syn region cmakeArguments start="(" end=")" contains=ALLBUT,@cmakeControl,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell fold
+syn region cmakeIf matchgroup=cmakeKeyword start=/^\s*\<if\>/ end=/^\s*\<endif\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn match cmakeElse /^\s*\<else\(if\)\?\>/ contained contains=NONE
+
+syn region cmakeForeach matchgroup=cmakeKeyword start=/^\s*\<foreach\>/ end=/^\s*\<endforeach\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeWhile matchgroup=cmakeKeyword start=/^\s*\<while\>/ end=/^\s*\<endwhile\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeFunction matchgroup=cmakeKeyword start=/^\s*\<function\>/ end=/^\s*\<endfunction\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeBlock matchgroup=cmakeKeyword start=/^\s*\<block\>/ end=/^\s*\<endblock\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeMacro matchgroup=cmakeKeyword start=/^\s*\<macro\>/ end=/^\s*\<endmacro\>/ transparent fold contains=@cmakeControl,cmakeArguments
 
 syn case match
 
@@ -59,14 +76,6 @@
 @COMMAND_LIST@
             \ nextgroup=cmakeArguments
 
-syn keyword cmakeCommandConditional
-@CONDITIONALS@
-            \ nextgroup=cmakeArguments
-
-syn keyword cmakeCommandRepeat
-@LOOPS@
-            \ nextgroup=cmakeArguments
-
 syn keyword cmakeCommandDeprecated
 @DEPRECATED@
             \ nextgroup=cmakeArguments
@@ -80,14 +89,14 @@
 hi def link cmakeBracketArgument String
 hi def link cmakeBracketComment Comment
 hi def link cmakeCommand Function
-hi def link cmakeCommandConditional Conditional
 hi def link cmakeCommandDeprecated WarningMsg
-hi def link cmakeCommandRepeat Repeat
 hi def link cmakeComment Comment
+hi def link cmakeElse Conditional
 hi def link cmakeEnvironment Special
 hi def link cmakeEscaped Special
 hi def link cmakeGeneratorExpression WarningMsg
 hi def link cmakeGeneratorExpressions Constant
+hi def link cmakeKeyword Conditional
 hi def link cmakeModule Include
 hi def link cmakeProperty Constant
 hi def link cmakeRegistry Underlined
@@ -122,9 +131,9 @@
 hi def link cmakeKWwrite_basic_package_version_file ModeMsg
 hi def link cmakeKWconfigure_package_config_file_constants Constant
 
-let b:current_syntax = "cmake"
+let b:current_syntax = 'cmake'
 
-let &cpo = s:keepcpo
+let &cpoptions = s:keepcpo
 unlet s:keepcpo
 
 " vim: set nowrap:
diff --git a/Auxiliary/vim/extract-upper-case.pl b/Auxiliary/vim/extract-upper-case.pl
index 7f40b74..ed821b5 100755
--- a/Auxiliary/vim/extract-upper-case.pl
+++ b/Auxiliary/vim/extract-upper-case.pl
@@ -24,7 +24,7 @@
 
 # control-statements
 my %conditional = map { $_ => 1 } qw(if else elseif endif);
-my %loop = map { $_ => 1 } qw(foreach while endforeach endwhile);
+my %loopetc = map { $_ => 1 } qw(block foreach function macro while endblock endfunction endforeach endmacro endwhile);
 
 # decrecated
 my %deprecated = map { $_ => 1 } qw(build_name exec_program export_library_dependencies install_files install_programs install_targets link_libraries make_directory output_required_files remove subdir_depends subdirs use_mangled_mesa utility_source variable_requires write_file);
@@ -141,7 +141,7 @@
 		if ($1 eq "COMMAND_LIST") {
 			# do not include "special" commands in this list
 			my @tmp = grep { ! exists $conditional{$_} and
-			                 ! exists $loop{$_} and
+			                 ! exists $loopetc{$_} and
 			                 ! exists $deprecated{$_} } @commands;
 			print_list(\*OUT, @tmp);
 		} elsif ($1 eq "VARIABLE_LIST") {
@@ -150,10 +150,6 @@
 			print_list(\*OUT, @modules);
 		} elsif ($1 eq "GENERATOR_EXPRESSIONS") {
 			print_list(\*OUT, @generator_expr);
-		} elsif ($1 eq "CONDITIONALS") {
-			print_list(\*OUT, keys %conditional);
-		} elsif ($1 eq "LOOPS") {
-			print_list(\*OUT, keys %loop);
 		} elsif ($1 eq "DEPRECATED") {
 			print_list(\*OUT, keys %deprecated);
 		} elsif ($1 eq "PROPERTIES") {
diff --git a/Auxiliary/vim/indent/cmake.vim b/Auxiliary/vim/indent/cmake.vim
index 28ecf84..fe30643 100644
--- a/Auxiliary/vim/indent/cmake.vim
+++ b/Auxiliary/vim/indent/cmake.vim
@@ -9,7 +9,7 @@
 "               https://cmake.org/licensing
 "               This implies that distribution with Vim is allowed
 
-if exists("b:did_indent")
+if exists('b:did_indent')
   finish
 endif
 let b:did_indent = 1
@@ -20,11 +20,11 @@
 let b:undo_indent = "setl inde< indk<"
 
 " Only define the function once.
-if exists("*CMakeGetIndent")
+if exists('*CMakeGetIndent')
   finish
 endif
-let s:keepcpo= &cpo
-set cpo&vim
+let s:keepcpo= &cpoptions
+set cpoptions&vim
 
 fun! CMakeGetIndent(lnum)
   let this_line = getline(a:lnum)
@@ -95,5 +95,5 @@
   return ind
 endfun
 
-let &cpo = s:keepcpo
+let &cpoptions = s:keepcpo
 unlet s:keepcpo
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 64e18e8..adcfed4 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -1,13 +1,13 @@
 " Vim syntax file
 " Program:      CMake - Cross-Platform Makefile Generator
-" Version:      cmake version 3.27.20230713-gdc88dd5
+" Version:      cmake version 4.1.20250715-g2c3f83a
 " Language:     CMake
 " Author:       Andy Cedilnik <andy.cedilnik@kitware.com>,
 "               Nicholas Hutchinson <nshutchinson@gmail.com>,
 "               Patrick Boettcher <patrick.boettcher@posteo.de>
 " Maintainer:   Dimitri Merejkowsky <d.merej@gmail.com>
 " Former Maintainer: Karthik Krishnan <karthik.krishnan@kitware.com>
-" Last Change:  2023 Jul 13
+" Last Change:  2025 Jul 15
 "
 " License:      The CMake license applies to this file. See
 "               https://cmake.org/licensing
@@ -19,10 +19,19 @@
 let s:keepcpo= &cpo
 set cpo&vim
 
-syn region cmakeBracketArgument start="\[\z(=*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn cluster cmakeControl contains=
+      \ cmakeIf,
+      \ cmakeElse,
+      \ cmakeForeach,
+      \ cmakeWhile,
+      \ cmakeBlock,
+      \ cmakeFunction,
+      \ cmakeMacro
+
+syn region cmakeBracketArgument start="\[\z(=*\)\[" end="\]\z1\]" fold contains=cmakeTodo,@Spell
 
 syn region cmakeComment start="#\(\[=*\[\)\@!" end="$" contains=cmakeTodo,@Spell
-syn region cmakeBracketComment start="#\[\z(=*\)\[" end="\]\z1\]" contains=cmakeTodo,@Spell
+syn region cmakeBracketComment start="#\[\z(=*\)\[" end="\]\z1\]" fold contains=cmakeTodo,@Spell
 
 syn match cmakeEscaped /\(\\\\\|\\"\|\\n\|\\t\)/ contained
 syn region cmakeRegistry start="\[" end="]" contained oneline contains=cmakeTodo,cmakeEscaped
@@ -35,7 +44,15 @@
 
 syn region cmakeEnvironment start="$ENV{" end="}" contained oneline contains=cmakeTodo
 
-syn region cmakeArguments start="(" end=")" contains=ALLBUT,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandConditional,cmakeCommandRepeat,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell
+syn region cmakeArguments start="(" end=")" contains=ALLBUT,@cmakeControl,cmakeGeneratorExpressions,cmakeCommand,cmakeCommandDeprecated,cmakeCommandManuallyAdded,cmakeArguments,cmakeTodo,@Spell fold
+syn region cmakeIf matchgroup=cmakeKeyword start=/^\s*\<if\>/ end=/^\s*\<endif\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn match cmakeElse /^\s*\<else\(if\)\?\>/ contained contains=NONE
+
+syn region cmakeForeach matchgroup=cmakeKeyword start=/^\s*\<foreach\>/ end=/^\s*\<endforeach\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeWhile matchgroup=cmakeKeyword start=/^\s*\<while\>/ end=/^\s*\<endwhile\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeFunction matchgroup=cmakeKeyword start=/^\s*\<function\>/ end=/^\s*\<endfunction\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeBlock matchgroup=cmakeKeyword start=/^\s*\<block\>/ end=/^\s*\<endblock\>/ transparent fold contains=@cmakeControl,cmakeArguments
+syn region cmakeMacro matchgroup=cmakeKeyword start=/^\s*\<macro\>/ end=/^\s*\<endmacro\>/ transparent fold contains=@cmakeControl,cmakeArguments
 
 syn case match
 
@@ -45,6 +62,7 @@
             \ ADDITIONAL_MAKE_CLEAN_FILES
             \ ADVANCED
             \ AIX_EXPORT_ALL_SYMBOLS
+            \ AIX_SHARED_LIBRARY_ARCHIVE
             \ ALIASED_TARGET
             \ ALIAS_GLOBAL
             \ ALLOW_DUPLICATE_CUSTOM_TARGETS
@@ -69,20 +87,20 @@
             \ ARCHIVE_OUTPUT_NAME
             \ ATTACHED_FILES
             \ ATTACHED_FILES_ON_FAIL
+            \ AUTOGEN_BETTER_GRAPH_MULTI_CONFIG
             \ AUTOGEN_BUILD_DIR
             \ AUTOGEN_COMMAND_LINE_LENGTH_MAX
             \ AUTOGEN_ORIGIN_DEPENDS
             \ AUTOGEN_PARALLEL
             \ AUTOGEN_SOURCE_GROUP
-            \ AUTOGEN_USE_SYSTEM_INCLUDE
             \ AUTOGEN_TARGETS_FOLDER
             \ AUTOGEN_TARGET_DEPENDS
             \ AUTOGEN_USE_SYSTEM_INCLUDE
-            \ AUTOGEN_BETTER_GRAPH_MULTI_CONFIG
             \ AUTOMOC
             \ AUTOMOC_COMPILER_PREDEFINES
             \ AUTOMOC_DEPEND_FILTERS
             \ AUTOMOC_EXECUTABLE
+            \ AUTOMOC_INCLUDE_DIRECTORIES
             \ AUTOMOC_MACRO_NAMES
             \ AUTOMOC_MOC_OPTIONS
             \ AUTOMOC_PATH_PREFIX
@@ -111,6 +129,7 @@
             \ CMAKE_CUDA_KNOWN_FEATURES
             \ CMAKE_CXX_KNOWN_FEATURES
             \ CMAKE_C_KNOWN_FEATURES
+            \ CMAKE_HIP_KNOWN_FEATURES
             \ CMAKE_ROLE
             \ COMMON_LANGUAGE_RUNTIME
             \ COMPATIBLE_INTERFACE_BOOL
@@ -147,15 +166,16 @@
             \ CXX_MODULE_DIRS
             \ CXX_MODULE_SET
             \ CXX_MODULE_SETS
+            \ CXX_MODULE_STD
             \ CXX_SCAN_FOR_MODULES
             \ CXX_STANDARD
             \ CXX_STANDARD_REQUIRED
             \ C_EXTENSIONS
             \ C_STANDARD
             \ C_STANDARD_REQUIRED
+            \ DEBUGGER_WORKING_DIRECTORY
             \ DEBUG_CONFIGURATIONS
             \ DEBUG_POSTFIX
-            \ DEBUGGER_WORKING_DIRECTORY
             \ DEFINE_SYMBOL
             \ DEFINITIONS
             \ DEPENDS
@@ -178,12 +198,16 @@
             \ ENVIRONMENT_MODIFICATION
             \ EXCLUDE_FROM_ALL
             \ EXCLUDE_FROM_DEFAULT_BUILD
+            \ EXPORT_BUILD_DATABASE
             \ EXPORT_COMPILE_COMMANDS
+            \ EXPORT_FIND_PACKAGE_NAME
             \ EXPORT_NAME
             \ EXPORT_NO_SYSTEM
             \ EXPORT_PROPERTIES
             \ EXTERNAL_OBJECT
             \ EchoString
+            \ FASTBUILD_CACHING
+            \ FASTBUILD_DISTRIBUTION
             \ FAIL_REGULAR_EXPRESSION
             \ FIND_LIBRARY_USE_LIB32_PATHS
             \ FIND_LIBRARY_USE_LIB64_PATHS
@@ -195,11 +219,13 @@
             \ FOLDER
             \ FRAMEWORK
             \ FRAMEWORK_VERSION
+            \ Fortran_BUILDING_INSTRINSIC_MODULES
             \ Fortran_BUILDING_INTRINSIC_MODULES
             \ Fortran_FORMAT
             \ Fortran_MODULE_DIRECTORY
             \ Fortran_PREPROCESS
             \ GENERATED
+            \ GENERATED_RESOURCE_SPEC_FILE
             \ GENERATOR_FILE_NAME
             \ GENERATOR_IS_MULTI_CONFIG
             \ GHS_INTEGRITY_APP
@@ -221,6 +247,11 @@
             \ IMPORTED
             \ IMPORTED_COMMON_LANGUAGE_RUNTIME
             \ IMPORTED_CONFIGURATIONS
+            \ IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS
+            \ IMPORTED_CXX_MODULES_COMPILE_FEATURES
+            \ IMPORTED_CXX_MODULES_COMPILE_OPTIONS
+            \ IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES
+            \ IMPORTED_CXX_MODULES_LINK_LIBRARIES
             \ IMPORTED_GLOBAL
             \ IMPORTED_IMPLIB
             \ IMPORTED_LIBNAME
@@ -239,12 +270,12 @@
             \ INCLUDE_DIRECTORIES
             \ INCLUDE_REGULAR_EXPRESSION
             \ INSTALL_NAME_DIR
+            \ INSTALL_PARALLEL
             \ INSTALL_REMOVE_ENVIRONMENT_RPATH
             \ INSTALL_RPATH
             \ INSTALL_RPATH_USE_LINK_PATH
             \ INTERFACE_AUTOMOC_MACRO_NAMES
             \ INTERFACE_AUTOUIC_OPTIONS
-            \ INTERFACE_AUTOMOC_MACRO_NAMES
             \ INTERFACE_COMPILE_DEFINITIONS
             \ INTERFACE_COMPILE_FEATURES
             \ INTERFACE_COMPILE_OPTIONS
@@ -278,6 +309,7 @@
             \ LIBRARY_OUTPUT_DIRECTORY
             \ LIBRARY_OUTPUT_NAME
             \ LINKER_LANGUAGE
+            \ LINKER_TYPE
             \ LINK_DEPENDS
             \ LINK_DEPENDS_NO_SHARED
             \ LINK_DIRECTORIES
@@ -286,10 +318,12 @@
             \ LINK_INTERFACE_MULTIPLICITY
             \ LINK_LIBRARIES
             \ LINK_LIBRARIES_ONLY_TARGETS
+            \ LINK_LIBRARIES_STRATEGY
             \ LINK_LIBRARY_OVERRIDE
             \ LINK_OPTIONS
             \ LINK_SEARCH_END_STATIC
             \ LINK_SEARCH_START_STATIC
+            \ LINK_WARNING_AS_ERROR
             \ LINK_WHAT_YOU_USE
             \ LISTFILE_STACK
             \ LOCATION
@@ -340,6 +374,7 @@
             \ PROCESSORS
             \ PROCESSOR_AFFINITY
             \ PROJECT_LABEL
+            \ PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
             \ PUBLIC_HEADER
             \ REPORT_UNDEFINED_PROPERTIES
             \ REQUIRED_FILES
@@ -366,6 +401,7 @@
             \ SOURCES
             \ SOURCE_DIR
             \ SOVERSION
+            \ SPDX_LICENSE
             \ STATIC_LIBRARY_FLAGS
             \ STATIC_LIBRARY_OPTIONS
             \ STRINGS
@@ -373,28 +409,33 @@
             \ SUFFIX
             \ SYMBOLIC
             \ SYSTEM
+            \ Swift_COMPILATION_MODE
             \ Swift_DEPENDENCIES_FILE
             \ Swift_DIAGNOSTICS_FILE
             \ Swift_LANGUAGE_VERSION
             \ Swift_MODULE_DIRECTORY
             \ Swift_MODULE_NAME
-            \ Swift_COMPILATION_MODE
             \ TARGET_ARCHIVES_MAY_BE_SHARED_LIBS
             \ TARGET_MESSAGES
             \ TARGET_SUPPORTS_SHARED_LIBS
             \ TESTS
             \ TEST_INCLUDE_FILE
             \ TEST_INCLUDE_FILES
+            \ TEST_LAUNCHER
             \ TIMEOUT
             \ TIMEOUT_AFTER_MATCH
             \ TIMEOUT_SIGNAL_GRACE_PERIOD
             \ TIMEOUT_SIGNAL_NAME
+            \ TRANSITIVE_COMPILE_PROPERTIES
+            \ TRANSITIVE_LINK_PROPERTIES
             \ TYPE
             \ UNITY_BUILD
             \ UNITY_BUILD_BATCH_SIZE
             \ UNITY_BUILD_CODE_AFTER_INCLUDE
             \ UNITY_BUILD_CODE_BEFORE_INCLUDE
+            \ UNITY_BUILD_FILENAME_PREFIX
             \ UNITY_BUILD_MODE
+            \ UNITY_BUILD_RELOCATABLE
             \ UNITY_BUILD_UNIQUE_ID
             \ UNITY_GROUP
             \ USE_FOLDERS
@@ -405,6 +446,7 @@
             \ VISIBILITY_INLINES_HIDDEN
             \ VS_CONFIGURATION_TYPE
             \ VS_COPY_TO_OUT_DIR
+            \ VS_CUSTOM_COMMAND_DISABLE_PARALLEL_BUILD
             \ VS_DEBUGGER_COMMAND
             \ VS_DEBUGGER_COMMAND_ARGUMENTS
             \ VS_DEBUGGER_ENVIRONMENT
@@ -418,6 +460,7 @@
             \ VS_DOTNET_STARTUP_OBJECT
             \ VS_DOTNET_TARGET_FRAMEWORK_VERSION
             \ VS_DPI_AWARE
+            \ VS_FILTER_PROPS
             \ VS_FRAMEWORK_REFERENCES
             \ VS_GLOBAL_KEYWORD
             \ VS_GLOBAL_PROJECT_TYPES
@@ -450,10 +493,11 @@
             \ VS_SHADER_TYPE
             \ VS_SHADER_VARIABLE_NAME
             \ VS_SOLUTION_DEPLOY
+            \ VS_SOLUTION_ITEMS
             \ VS_STARTUP_PROJECT
             \ VS_TOOL_OVERRIDE
             \ VS_USER_PROPS
-            \ VS_FILTER_PROPS
+            \ VS_USE_DEBUG_LIBRARIES
             \ VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
             \ VS_WINRT_COMPONENT
             \ VS_WINRT_EXTENSIONS
@@ -479,45 +523,46 @@
             \ XCODE_SCHEME_ARGUMENTS
             \ XCODE_SCHEME_DEBUG_AS_ROOT
             \ XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
-            \ XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
             \ XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
             \ XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
             \ XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
             \ XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+            \ XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
             \ XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
             \ XCODE_SCHEME_ENVIRONMENT
             \ XCODE_SCHEME_EXECUTABLE
             \ XCODE_SCHEME_GUARD_MALLOC
+            \ XCODE_SCHEME_LAUNCH_CONFIGURATION
             \ XCODE_SCHEME_LAUNCH_MODE
             \ XCODE_SCHEME_LLDB_INIT_FILE
             \ XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
             \ XCODE_SCHEME_MALLOC_GUARD_EDGES
             \ XCODE_SCHEME_MALLOC_SCRIBBLE
             \ XCODE_SCHEME_MALLOC_STACK
+            \ XCODE_SCHEME_TEST_CONFIGURATION
             \ XCODE_SCHEME_THREAD_SANITIZER
             \ XCODE_SCHEME_THREAD_SANITIZER_STOP
             \ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
             \ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
-            \ XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
-            \ XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
-            \ XCODE_SCHEME_LAUNCH_CONFIGURATION
-            \ XCODE_SCHEME_TEST_CONFIGURATION
             \ XCODE_SCHEME_WORKING_DIRECTORY
             \ XCODE_SCHEME_ZOMBIE_OBJECTS
             \ XCODE_XCCONFIG
             \ XCTEST
 
 syn keyword cmakeVariable contained
+            \ AIX
             \ ANDROID
             \ APPLE
             \ BORLAND
             \ BSD
             \ BUILD_SHARED_LIBS
+            \ BUILD_TESTING
             \ CACHE
             \ CMAKE_ABSOLUTE_DESTINATION_FILES
             \ CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
             \ CMAKE_ADSP_ROOT
             \ CMAKE_AIX_EXPORT_ALL_SYMBOLS
+            \ CMAKE_AIX_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
             \ CMAKE_ANDROID_API
             \ CMAKE_ANDROID_API_MIN
@@ -556,9 +601,12 @@
             \ CMAKE_ASM_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_ASM_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_ASM_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_ASM_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_ASM_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_ASM_ARCHIVE_APPEND
             \ CMAKE_ASM_ARCHIVE_CREATE
             \ CMAKE_ASM_ARCHIVE_FINISH
+            \ CMAKE_ASM_ATTRIBUTES
             \ CMAKE_ASM_BYTE_ORDER
             \ CMAKE_ASM_CLANG_TIDY
             \ CMAKE_ASM_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -570,6 +618,10 @@
             \ CMAKE_ASM_COMPILER_FRONTEND_VARIANT
             \ CMAKE_ASM_COMPILER_ID
             \ CMAKE_ASM_COMPILER_LAUNCHER
+            \ CMAKE_ASM_COMPILER_LINKER
+            \ CMAKE_ASM_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_ASM_COMPILER_LINKER_ID
+            \ CMAKE_ASM_COMPILER_LINKER_VERSION
             \ CMAKE_ASM_COMPILER_LOADED
             \ CMAKE_ASM_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_ASM_COMPILER_RANLIB
@@ -580,8 +632,10 @@
             \ CMAKE_ASM_CPPCHECK
             \ CMAKE_ASM_CPPLINT
             \ CMAKE_ASM_CREATE_SHARED_LIBRARY
+            \ CMAKE_ASM_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_ASM_CREATE_SHARED_MODULE
             \ CMAKE_ASM_CREATE_STATIC_LIBRARY
+            \ CMAKE_ASM_DEVICE_LINK_MODE
             \ CMAKE_ASM_EXTENSIONS
             \ CMAKE_ASM_EXTENSIONS_DEFAULT
             \ CMAKE_ASM_FLAGS
@@ -594,6 +648,10 @@
             \ CMAKE_ASM_FLAGS_RELEASE_INIT
             \ CMAKE_ASM_FLAGS_RELWITHDEBINFO
             \ CMAKE_ASM_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_ASM_HOST_COMPILER
+            \ CMAKE_ASM_HOST_COMPILER_ID
+            \ CMAKE_ASM_HOST_COMPILER_VERSION
+            \ CMAKE_ASM_ICSTAT
             \ CMAKE_ASM_IGNORE_EXTENSIONS
             \ CMAKE_ASM_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_ASM_IMPLICIT_LINK_DIRECTORIES
@@ -607,18 +665,23 @@
             \ CMAKE_ASM_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_ASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_ASM_LINK_DEF_FILE_FLAG
             \ CMAKE_ASM_LINK_EXECUTABLE
             \ CMAKE_ASM_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_ASM_LINK_LIBRARY_FLAG
             \ CMAKE_ASM_LINK_LIBRARY_SUFFIX
+            \ CMAKE_ASM_LINK_MODE
             \ CMAKE_ASM_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_ASM_MASM
             \ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_ASM_MASM_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_ASM_MASM_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_ASM_MASM_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_ASM_MASM_ARCHIVE_APPEND
             \ CMAKE_ASM_MASM_ARCHIVE_CREATE
             \ CMAKE_ASM_MASM_ARCHIVE_FINISH
+            \ CMAKE_ASM_MASM_ATTRIBUTES
             \ CMAKE_ASM_MASM_BYTE_ORDER
             \ CMAKE_ASM_MASM_CLANG_TIDY
             \ CMAKE_ASM_MASM_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -630,6 +693,10 @@
             \ CMAKE_ASM_MASM_COMPILER_FRONTEND_VARIANT
             \ CMAKE_ASM_MASM_COMPILER_ID
             \ CMAKE_ASM_MASM_COMPILER_LAUNCHER
+            \ CMAKE_ASM_MASM_COMPILER_LINKER
+            \ CMAKE_ASM_MASM_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_ASM_MASM_COMPILER_LINKER_ID
+            \ CMAKE_ASM_MASM_COMPILER_LINKER_VERSION
             \ CMAKE_ASM_MASM_COMPILER_LOADED
             \ CMAKE_ASM_MASM_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_ASM_MASM_COMPILER_RANLIB
@@ -640,8 +707,10 @@
             \ CMAKE_ASM_MASM_CPPCHECK
             \ CMAKE_ASM_MASM_CPPLINT
             \ CMAKE_ASM_MASM_CREATE_SHARED_LIBRARY
+            \ CMAKE_ASM_MASM_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_ASM_MASM_CREATE_SHARED_MODULE
             \ CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY
+            \ CMAKE_ASM_MASM_DEVICE_LINK_MODE
             \ CMAKE_ASM_MASM_EXTENSIONS
             \ CMAKE_ASM_MASM_EXTENSIONS_DEFAULT
             \ CMAKE_ASM_MASM_FLAGS
@@ -654,6 +723,10 @@
             \ CMAKE_ASM_MASM_FLAGS_RELEASE_INIT
             \ CMAKE_ASM_MASM_FLAGS_RELWITHDEBINFO
             \ CMAKE_ASM_MASM_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_ASM_MASM_HOST_COMPILER
+            \ CMAKE_ASM_MASM_HOST_COMPILER_ID
+            \ CMAKE_ASM_MASM_HOST_COMPILER_VERSION
+            \ CMAKE_ASM_MASM_ICSTAT
             \ CMAKE_ASM_MASM_IGNORE_EXTENSIONS
             \ CMAKE_ASM_MASM_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_ASM_MASM_IMPLICIT_LINK_DIRECTORIES
@@ -667,10 +740,12 @@
             \ CMAKE_ASM_MASM_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_ASM_MASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_MASM_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_ASM_MASM_LINK_DEF_FILE_FLAG
             \ CMAKE_ASM_MASM_LINK_EXECUTABLE
             \ CMAKE_ASM_MASM_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_ASM_MASM_LINK_LIBRARY_FLAG
             \ CMAKE_ASM_MASM_LINK_LIBRARY_SUFFIX
+            \ CMAKE_ASM_MASM_LINK_MODE
             \ CMAKE_ASM_MASM_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_ASM_MASM_OUTPUT_EXTENSION
             \ CMAKE_ASM_MASM_PLATFORM_ID
@@ -681,17 +756,23 @@
             \ CMAKE_ASM_MASM_STANDARD
             \ CMAKE_ASM_MASM_STANDARD_DEFAULT
             \ CMAKE_ASM_MASM_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_ASM_MASM_STANDARD_LATEST
             \ CMAKE_ASM_MASM_STANDARD_LIBRARIES
+            \ CMAKE_ASM_MASM_STANDARD_LINK_DIRECTORIES
             \ CMAKE_ASM_MASM_STANDARD_REQUIRED
             \ CMAKE_ASM_MASM_SUPPORTED
+            \ CMAKE_ASM_MASM_USING_LINKER_MODE
             \ CMAKE_ASM_MASM_VISIBILITY_PRESET
             \ CMAKE_ASM_NASM
             \ CMAKE_ASM_NASM_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_ASM_NASM_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_ASM_NASM_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_ASM_NASM_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_ASM_NASM_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_ASM_NASM_ARCHIVE_APPEND
             \ CMAKE_ASM_NASM_ARCHIVE_CREATE
             \ CMAKE_ASM_NASM_ARCHIVE_FINISH
+            \ CMAKE_ASM_NASM_ATTRIBUTES
             \ CMAKE_ASM_NASM_BYTE_ORDER
             \ CMAKE_ASM_NASM_CLANG_TIDY
             \ CMAKE_ASM_NASM_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -703,6 +784,10 @@
             \ CMAKE_ASM_NASM_COMPILER_FRONTEND_VARIANT
             \ CMAKE_ASM_NASM_COMPILER_ID
             \ CMAKE_ASM_NASM_COMPILER_LAUNCHER
+            \ CMAKE_ASM_NASM_COMPILER_LINKER
+            \ CMAKE_ASM_NASM_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_ASM_NASM_COMPILER_LINKER_ID
+            \ CMAKE_ASM_NASM_COMPILER_LINKER_VERSION
             \ CMAKE_ASM_NASM_COMPILER_LOADED
             \ CMAKE_ASM_NASM_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_ASM_NASM_COMPILER_RANLIB
@@ -713,8 +798,10 @@
             \ CMAKE_ASM_NASM_CPPCHECK
             \ CMAKE_ASM_NASM_CPPLINT
             \ CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY
+            \ CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_ASM_NASM_CREATE_SHARED_MODULE
             \ CMAKE_ASM_NASM_CREATE_STATIC_LIBRARY
+            \ CMAKE_ASM_NASM_DEVICE_LINK_MODE
             \ CMAKE_ASM_NASM_EXTENSIONS
             \ CMAKE_ASM_NASM_EXTENSIONS_DEFAULT
             \ CMAKE_ASM_NASM_FLAGS
@@ -727,6 +814,10 @@
             \ CMAKE_ASM_NASM_FLAGS_RELEASE_INIT
             \ CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO
             \ CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_ASM_NASM_HOST_COMPILER
+            \ CMAKE_ASM_NASM_HOST_COMPILER_ID
+            \ CMAKE_ASM_NASM_HOST_COMPILER_VERSION
+            \ CMAKE_ASM_NASM_ICSTAT
             \ CMAKE_ASM_NASM_IGNORE_EXTENSIONS
             \ CMAKE_ASM_NASM_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_ASM_NASM_IMPLICIT_LINK_DIRECTORIES
@@ -740,10 +831,12 @@
             \ CMAKE_ASM_NASM_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_ASM_NASM_LINKER_WRAPPER_FLAG
             \ CMAKE_ASM_NASM_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_ASM_NASM_LINK_DEF_FILE_FLAG
             \ CMAKE_ASM_NASM_LINK_EXECUTABLE
             \ CMAKE_ASM_NASM_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_ASM_NASM_LINK_LIBRARY_FLAG
             \ CMAKE_ASM_NASM_LINK_LIBRARY_SUFFIX
+            \ CMAKE_ASM_NASM_LINK_MODE
             \ CMAKE_ASM_NASM_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_ASM_NASM_OUTPUT_EXTENSION
             \ CMAKE_ASM_NASM_PLATFORM_ID
@@ -754,9 +847,12 @@
             \ CMAKE_ASM_NASM_STANDARD
             \ CMAKE_ASM_NASM_STANDARD_DEFAULT
             \ CMAKE_ASM_NASM_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_ASM_NASM_STANDARD_LATEST
             \ CMAKE_ASM_NASM_STANDARD_LIBRARIES
+            \ CMAKE_ASM_NASM_STANDARD_LINK_DIRECTORIES
             \ CMAKE_ASM_NASM_STANDARD_REQUIRED
             \ CMAKE_ASM_NASM_SUPPORTED
+            \ CMAKE_ASM_NASM_USING_LINKER_MODE
             \ CMAKE_ASM_NASM_VISIBILITY_PRESET
             \ CMAKE_ASM_OUTPUT_EXTENSION
             \ CMAKE_ASM_PLATFORM_ID
@@ -767,9 +863,12 @@
             \ CMAKE_ASM_STANDARD
             \ CMAKE_ASM_STANDARD_DEFAULT
             \ CMAKE_ASM_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_ASM_STANDARD_LATEST
             \ CMAKE_ASM_STANDARD_LIBRARIES
+            \ CMAKE_ASM_STANDARD_LINK_DIRECTORIES
             \ CMAKE_ASM_STANDARD_REQUIRED
             \ CMAKE_ASM_SUPPORTED
+            \ CMAKE_ASM_USING_LINKER_MODE
             \ CMAKE_ASM_VISIBILITY_PRESET
             \ CMAKE_AUTOGEN_BETTER_GRAPH_MULTI_CONFIG
             \ CMAKE_AUTOGEN_COMMAND_LINE_LENGTH_MAX
@@ -781,20 +880,18 @@
             \ CMAKE_AUTOMOC_COMPILER_PREDEFINES
             \ CMAKE_AUTOMOC_DEPEND_FILTERS
             \ CMAKE_AUTOMOC_EXECUTABLE
+            \ CMAKE_AUTOMOC_INCLUDE_DIRECTORIES
             \ CMAKE_AUTOMOC_MACRO_NAMES
             \ CMAKE_AUTOMOC_MOC_OPTIONS
             \ CMAKE_AUTOMOC_PATH_PREFIX
             \ CMAKE_AUTOMOC_RELAXED_MODE
-            \ CMAKE_AUTOMOC_EXECUTABLE
             \ CMAKE_AUTORCC
             \ CMAKE_AUTORCC_EXECUTABLE
             \ CMAKE_AUTORCC_OPTIONS
-            \ CMAKE_AUTORCC_EXECUTABLE
             \ CMAKE_AUTOUIC
             \ CMAKE_AUTOUIC_EXECUTABLE
             \ CMAKE_AUTOUIC_OPTIONS
             \ CMAKE_AUTOUIC_SEARCH_PATHS
-            \ CMAKE_AUTOUIC_EXECUTABLE
             \ CMAKE_BACKWARDS_COMPATIBILITY
             \ CMAKE_BINARY_DIR
             \ CMAKE_BUILD_RPATH
@@ -832,9 +929,12 @@
             \ CMAKE_CSharp_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_CSharp_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_CSharp_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_CSharp_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_CSharp_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_CSharp_ARCHIVE_APPEND
             \ CMAKE_CSharp_ARCHIVE_CREATE
             \ CMAKE_CSharp_ARCHIVE_FINISH
+            \ CMAKE_CSharp_ATTRIBUTES
             \ CMAKE_CSharp_BYTE_ORDER
             \ CMAKE_CSharp_CLANG_TIDY
             \ CMAKE_CSharp_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -846,6 +946,10 @@
             \ CMAKE_CSharp_COMPILER_FRONTEND_VARIANT
             \ CMAKE_CSharp_COMPILER_ID
             \ CMAKE_CSharp_COMPILER_LAUNCHER
+            \ CMAKE_CSharp_COMPILER_LINKER
+            \ CMAKE_CSharp_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_CSharp_COMPILER_LINKER_ID
+            \ CMAKE_CSharp_COMPILER_LINKER_VERSION
             \ CMAKE_CSharp_COMPILER_LOADED
             \ CMAKE_CSharp_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_CSharp_COMPILER_RANLIB
@@ -856,8 +960,10 @@
             \ CMAKE_CSharp_CPPCHECK
             \ CMAKE_CSharp_CPPLINT
             \ CMAKE_CSharp_CREATE_SHARED_LIBRARY
+            \ CMAKE_CSharp_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_CSharp_CREATE_SHARED_MODULE
             \ CMAKE_CSharp_CREATE_STATIC_LIBRARY
+            \ CMAKE_CSharp_DEVICE_LINK_MODE
             \ CMAKE_CSharp_EXTENSIONS
             \ CMAKE_CSharp_EXTENSIONS_DEFAULT
             \ CMAKE_CSharp_FLAGS
@@ -870,6 +976,10 @@
             \ CMAKE_CSharp_FLAGS_RELEASE_INIT
             \ CMAKE_CSharp_FLAGS_RELWITHDEBINFO
             \ CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_CSharp_HOST_COMPILER
+            \ CMAKE_CSharp_HOST_COMPILER_ID
+            \ CMAKE_CSharp_HOST_COMPILER_VERSION
+            \ CMAKE_CSharp_ICSTAT
             \ CMAKE_CSharp_IGNORE_EXTENSIONS
             \ CMAKE_CSharp_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_CSharp_IMPLICIT_LINK_DIRECTORIES
@@ -883,10 +993,12 @@
             \ CMAKE_CSharp_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_CSharp_LINKER_WRAPPER_FLAG
             \ CMAKE_CSharp_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_CSharp_LINK_DEF_FILE_FLAG
             \ CMAKE_CSharp_LINK_EXECUTABLE
             \ CMAKE_CSharp_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_CSharp_LINK_LIBRARY_FLAG
             \ CMAKE_CSharp_LINK_LIBRARY_SUFFIX
+            \ CMAKE_CSharp_LINK_MODE
             \ CMAKE_CSharp_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_CSharp_OUTPUT_EXTENSION
             \ CMAKE_CSharp_PLATFORM_ID
@@ -897,9 +1009,12 @@
             \ CMAKE_CSharp_STANDARD
             \ CMAKE_CSharp_STANDARD_DEFAULT
             \ CMAKE_CSharp_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_CSharp_STANDARD_LATEST
             \ CMAKE_CSharp_STANDARD_LIBRARIES
+            \ CMAKE_CSharp_STANDARD_LINK_DIRECTORIES
             \ CMAKE_CSharp_STANDARD_REQUIRED
             \ CMAKE_CSharp_SUPPORTED
+            \ CMAKE_CSharp_USING_LINKER_MODE
             \ CMAKE_CSharp_VISIBILITY_PRESET
             \ CMAKE_CTEST_ARGUMENTS
             \ CMAKE_CTEST_COMMAND
@@ -908,9 +1023,12 @@
             \ CMAKE_CUDA_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_CUDA_ANDROID_TOOLCHAIN_SUFFIX
             \ CMAKE_CUDA_ARCHITECTURES
+            \ CMAKE_CUDA_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_CUDA_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_CUDA_ARCHIVE_APPEND
             \ CMAKE_CUDA_ARCHIVE_CREATE
             \ CMAKE_CUDA_ARCHIVE_FINISH
+            \ CMAKE_CUDA_ATTRIBUTES
             \ CMAKE_CUDA_BYTE_ORDER
             \ CMAKE_CUDA_CLANG_TIDY
             \ CMAKE_CUDA_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -922,6 +1040,10 @@
             \ CMAKE_CUDA_COMPILER_FRONTEND_VARIANT
             \ CMAKE_CUDA_COMPILER_ID
             \ CMAKE_CUDA_COMPILER_LAUNCHER
+            \ CMAKE_CUDA_COMPILER_LINKER
+            \ CMAKE_CUDA_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_CUDA_COMPILER_LINKER_ID
+            \ CMAKE_CUDA_COMPILER_LINKER_VERSION
             \ CMAKE_CUDA_COMPILER_LOADED
             \ CMAKE_CUDA_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_CUDA_COMPILER_RANLIB
@@ -933,8 +1055,10 @@
             \ CMAKE_CUDA_CPPCHECK
             \ CMAKE_CUDA_CPPLINT
             \ CMAKE_CUDA_CREATE_SHARED_LIBRARY
+            \ CMAKE_CUDA_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_CUDA_CREATE_SHARED_MODULE
             \ CMAKE_CUDA_CREATE_STATIC_LIBRARY
+            \ CMAKE_CUDA_DEVICE_LINK_MODE
             \ CMAKE_CUDA_EXTENSIONS
             \ CMAKE_CUDA_EXTENSIONS_DEFAULT
             \ CMAKE_CUDA_FLAGS
@@ -948,6 +1072,9 @@
             \ CMAKE_CUDA_FLAGS_RELWITHDEBINFO
             \ CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT
             \ CMAKE_CUDA_HOST_COMPILER
+            \ CMAKE_CUDA_HOST_COMPILER_ID
+            \ CMAKE_CUDA_HOST_COMPILER_VERSION
+            \ CMAKE_CUDA_ICSTAT
             \ CMAKE_CUDA_IGNORE_EXTENSIONS
             \ CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES
@@ -961,10 +1088,12 @@
             \ CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_CUDA_LINKER_WRAPPER_FLAG
             \ CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_CUDA_LINK_DEF_FILE_FLAG
             \ CMAKE_CUDA_LINK_EXECUTABLE
             \ CMAKE_CUDA_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_CUDA_LINK_LIBRARY_FLAG
             \ CMAKE_CUDA_LINK_LIBRARY_SUFFIX
+            \ CMAKE_CUDA_LINK_MODE
             \ CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_CUDA_OUTPUT_EXTENSION
             \ CMAKE_CUDA_PLATFORM_ID
@@ -978,10 +1107,13 @@
             \ CMAKE_CUDA_STANDARD
             \ CMAKE_CUDA_STANDARD_DEFAULT
             \ CMAKE_CUDA_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_CUDA_STANDARD_LATEST
             \ CMAKE_CUDA_STANDARD_LIBRARIES
+            \ CMAKE_CUDA_STANDARD_LINK_DIRECTORIES
             \ CMAKE_CUDA_STANDARD_REQUIRED
             \ CMAKE_CUDA_SUPPORTED
             \ CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
+            \ CMAKE_CUDA_USING_LINKER_MODE
             \ CMAKE_CUDA_VISIBILITY_PRESET
             \ CMAKE_CURRENT_BINARY_DIR
             \ CMAKE_CURRENT_FUNCTION
@@ -996,9 +1128,12 @@
             \ CMAKE_CXX_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_CXX_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_CXX_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_CXX_ARCHIVE_APPEND
             \ CMAKE_CXX_ARCHIVE_CREATE
             \ CMAKE_CXX_ARCHIVE_FINISH
+            \ CMAKE_CXX_ATTRIBUTES
             \ CMAKE_CXX_BYTE_ORDER
             \ CMAKE_CXX_CLANG_TIDY
             \ CMAKE_CXX_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1009,7 +1144,12 @@
             \ CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN
             \ CMAKE_CXX_COMPILER_FRONTEND_VARIANT
             \ CMAKE_CXX_COMPILER_ID
+            \ CMAKE_CXX_COMPILER_IMPORT_STD
             \ CMAKE_CXX_COMPILER_LAUNCHER
+            \ CMAKE_CXX_COMPILER_LINKER
+            \ CMAKE_CXX_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_CXX_COMPILER_LINKER_ID
+            \ CMAKE_CXX_COMPILER_LINKER_VERSION
             \ CMAKE_CXX_COMPILER_LOADED
             \ CMAKE_CXX_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_CXX_COMPILER_RANLIB
@@ -1021,8 +1161,10 @@
             \ CMAKE_CXX_CPPCHECK
             \ CMAKE_CXX_CPPLINT
             \ CMAKE_CXX_CREATE_SHARED_LIBRARY
+            \ CMAKE_CXX_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_CXX_CREATE_SHARED_MODULE
             \ CMAKE_CXX_CREATE_STATIC_LIBRARY
+            \ CMAKE_CXX_DEVICE_LINK_MODE
             \ CMAKE_CXX_EXTENSIONS
             \ CMAKE_CXX_EXTENSIONS_DEFAULT
             \ CMAKE_CXX_FLAGS
@@ -1035,6 +1177,10 @@
             \ CMAKE_CXX_FLAGS_RELEASE_INIT
             \ CMAKE_CXX_FLAGS_RELWITHDEBINFO
             \ CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_CXX_HOST_COMPILER
+            \ CMAKE_CXX_HOST_COMPILER_ID
+            \ CMAKE_CXX_HOST_COMPILER_VERSION
+            \ CMAKE_CXX_ICSTAT
             \ CMAKE_CXX_IGNORE_EXTENSIONS
             \ CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES
@@ -1048,11 +1194,14 @@
             \ CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_CXX_LINKER_WRAPPER_FLAG
             \ CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_CXX_LINK_DEF_FILE_FLAG
             \ CMAKE_CXX_LINK_EXECUTABLE
             \ CMAKE_CXX_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_CXX_LINK_LIBRARY_FLAG
             \ CMAKE_CXX_LINK_LIBRARY_SUFFIX
+            \ CMAKE_CXX_LINK_MODE
             \ CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG
+            \ CMAKE_CXX_MODULE_STD
             \ CMAKE_CXX_OUTPUT_EXTENSION
             \ CMAKE_CXX_PLATFORM_ID
             \ CMAKE_CXX_SCAN_FOR_MODULES
@@ -1063,16 +1212,22 @@
             \ CMAKE_CXX_STANDARD
             \ CMAKE_CXX_STANDARD_DEFAULT
             \ CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_CXX_STANDARD_LATEST
             \ CMAKE_CXX_STANDARD_LIBRARIES
+            \ CMAKE_CXX_STANDARD_LINK_DIRECTORIES
             \ CMAKE_CXX_STANDARD_REQUIRED
             \ CMAKE_CXX_SUPPORTED
+            \ CMAKE_CXX_USING_LINKER_MODE
             \ CMAKE_CXX_VISIBILITY_PRESET
             \ CMAKE_C_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_C_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_C_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_C_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_C_ARCHIVE_APPEND
             \ CMAKE_C_ARCHIVE_CREATE
             \ CMAKE_C_ARCHIVE_FINISH
+            \ CMAKE_C_ATTRIBUTES
             \ CMAKE_C_BYTE_ORDER
             \ CMAKE_C_CLANG_TIDY
             \ CMAKE_C_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1084,6 +1239,10 @@
             \ CMAKE_C_COMPILER_FRONTEND_VARIANT
             \ CMAKE_C_COMPILER_ID
             \ CMAKE_C_COMPILER_LAUNCHER
+            \ CMAKE_C_COMPILER_LINKER
+            \ CMAKE_C_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_C_COMPILER_LINKER_ID
+            \ CMAKE_C_COMPILER_LINKER_VERSION
             \ CMAKE_C_COMPILER_LOADED
             \ CMAKE_C_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_C_COMPILER_RANLIB
@@ -1095,8 +1254,10 @@
             \ CMAKE_C_CPPCHECK
             \ CMAKE_C_CPPLINT
             \ CMAKE_C_CREATE_SHARED_LIBRARY
+            \ CMAKE_C_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_C_CREATE_SHARED_MODULE
             \ CMAKE_C_CREATE_STATIC_LIBRARY
+            \ CMAKE_C_DEVICE_LINK_MODE
             \ CMAKE_C_EXTENSIONS
             \ CMAKE_C_EXTENSIONS_DEFAULT
             \ CMAKE_C_FLAGS
@@ -1109,6 +1270,10 @@
             \ CMAKE_C_FLAGS_RELEASE_INIT
             \ CMAKE_C_FLAGS_RELWITHDEBINFO
             \ CMAKE_C_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_C_HOST_COMPILER
+            \ CMAKE_C_HOST_COMPILER_ID
+            \ CMAKE_C_HOST_COMPILER_VERSION
+            \ CMAKE_C_ICSTAT
             \ CMAKE_C_IGNORE_EXTENSIONS
             \ CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_C_IMPLICIT_LINK_DIRECTORIES
@@ -1122,10 +1287,12 @@
             \ CMAKE_C_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_C_LINKER_WRAPPER_FLAG
             \ CMAKE_C_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_C_LINK_DEF_FILE_FLAG
             \ CMAKE_C_LINK_EXECUTABLE
             \ CMAKE_C_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_C_LINK_LIBRARY_FLAG
             \ CMAKE_C_LINK_LIBRARY_SUFFIX
+            \ CMAKE_C_LINK_MODE
             \ CMAKE_C_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_C_OUTPUT_EXTENSION
             \ CMAKE_C_PLATFORM_ID
@@ -1136,13 +1303,16 @@
             \ CMAKE_C_STANDARD
             \ CMAKE_C_STANDARD_DEFAULT
             \ CMAKE_C_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_C_STANDARD_LATEST
             \ CMAKE_C_STANDARD_LIBRARIES
+            \ CMAKE_C_STANDARD_LINK_DIRECTORIES
             \ CMAKE_C_STANDARD_REQUIRED
             \ CMAKE_C_SUPPORTED
+            \ CMAKE_C_USING_LINKER_MODE
             \ CMAKE_C_VISIBILITY_PRESET
+            \ CMAKE_DEBUGGER_WORKING_DIRECTORY
             \ CMAKE_DEBUG_POSTFIX
             \ CMAKE_DEBUG_TARGET_PROPERTIES
-            \ CMAKE_DEBUGGER_WORKING_DIRECTORY
             \ CMAKE_DEFAULT_BUILD_TYPE
             \ CMAKE_DEFAULT_CONFIGS
             \ CMAKE_DEPENDS_IN_PROJECT_ONLY
@@ -1178,16 +1348,20 @@
             \ CMAKE_EXECUTABLE_SUFFIX_RC
             \ CMAKE_EXECUTABLE_SUFFIX_Swift
             \ CMAKE_EXECUTE_PROCESS_COMMAND_ECHO
+            \ CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL
             \ CMAKE_EXE_LINKER_FLAGS
             \ CMAKE_EXE_LINKER_FLAGS_INIT
+            \ CMAKE_EXPORT_BUILD_DATABASE
             \ CMAKE_EXPORT_COMPILE_COMMANDS
-            \ CMAKE_EXPORT_SARIF
+            \ CMAKE_EXPORT_FIND_PACKAGE_NAME
             \ CMAKE_EXPORT_NO_PACKAGE_REGISTRY
             \ CMAKE_EXPORT_PACKAGE_REGISTRY
+            \ CMAKE_EXPORT_SARIF
             \ CMAKE_EXTRA_GENERATOR
             \ CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
             \ CMAKE_FIND_APPBUNDLE
             \ CMAKE_FIND_DEBUG_MODE
+            \ CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG
             \ CMAKE_FIND_FRAMEWORK
             \ CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
             \ CMAKE_FIND_LIBRARY_PREFIXES
@@ -1203,13 +1377,13 @@
             \ CMAKE_FIND_PACKAGE_SORT_ORDER
             \ CMAKE_FIND_PACKAGE_TARGETS_GLOBAL
             \ CMAKE_FIND_PACKAGE_WARN_NO_MODULE
+            \ CMAKE_FIND_REQUIRED
             \ CMAKE_FIND_ROOT_PATH
             \ CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
             \ CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
             \ CMAKE_FIND_ROOT_PATH_MODE_PACKAGE
             \ CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
             \ CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH
-            \ CMAKE_FIND_USE_INSTALL_PREFIX
             \ CMAKE_FIND_USE_CMAKE_PATH
             \ CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
             \ CMAKE_FIND_USE_INSTALL_PREFIX
@@ -1224,9 +1398,12 @@
             \ CMAKE_Fortran_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_Fortran_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_Fortran_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_Fortran_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_Fortran_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_Fortran_ARCHIVE_APPEND
             \ CMAKE_Fortran_ARCHIVE_CREATE
             \ CMAKE_Fortran_ARCHIVE_FINISH
+            \ CMAKE_Fortran_ATTRIBUTES
             \ CMAKE_Fortran_BYTE_ORDER
             \ CMAKE_Fortran_CLANG_TIDY
             \ CMAKE_Fortran_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1238,6 +1415,10 @@
             \ CMAKE_Fortran_COMPILER_FRONTEND_VARIANT
             \ CMAKE_Fortran_COMPILER_ID
             \ CMAKE_Fortran_COMPILER_LAUNCHER
+            \ CMAKE_Fortran_COMPILER_LINKER
+            \ CMAKE_Fortran_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_Fortran_COMPILER_LINKER_ID
+            \ CMAKE_Fortran_COMPILER_LINKER_VERSION
             \ CMAKE_Fortran_COMPILER_LOADED
             \ CMAKE_Fortran_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_Fortran_COMPILER_RANLIB
@@ -1248,8 +1429,10 @@
             \ CMAKE_Fortran_CPPCHECK
             \ CMAKE_Fortran_CPPLINT
             \ CMAKE_Fortran_CREATE_SHARED_LIBRARY
+            \ CMAKE_Fortran_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_Fortran_CREATE_SHARED_MODULE
             \ CMAKE_Fortran_CREATE_STATIC_LIBRARY
+            \ CMAKE_Fortran_DEVICE_LINK_MODE
             \ CMAKE_Fortran_EXTENSIONS
             \ CMAKE_Fortran_EXTENSIONS_DEFAULT
             \ CMAKE_Fortran_FLAGS
@@ -1263,6 +1446,10 @@
             \ CMAKE_Fortran_FLAGS_RELWITHDEBINFO
             \ CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT
             \ CMAKE_Fortran_FORMAT
+            \ CMAKE_Fortran_HOST_COMPILER
+            \ CMAKE_Fortran_HOST_COMPILER_ID
+            \ CMAKE_Fortran_HOST_COMPILER_VERSION
+            \ CMAKE_Fortran_ICSTAT
             \ CMAKE_Fortran_IGNORE_EXTENSIONS
             \ CMAKE_Fortran_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES
@@ -1276,10 +1463,12 @@
             \ CMAKE_Fortran_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_Fortran_LINKER_WRAPPER_FLAG
             \ CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_Fortran_LINK_DEF_FILE_FLAG
             \ CMAKE_Fortran_LINK_EXECUTABLE
             \ CMAKE_Fortran_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_Fortran_LINK_LIBRARY_FLAG
             \ CMAKE_Fortran_LINK_LIBRARY_SUFFIX
+            \ CMAKE_Fortran_LINK_MODE
             \ CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_Fortran_MODDIR_DEFAULT
             \ CMAKE_Fortran_MODDIR_FLAG
@@ -1295,9 +1484,12 @@
             \ CMAKE_Fortran_STANDARD
             \ CMAKE_Fortran_STANDARD_DEFAULT
             \ CMAKE_Fortran_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_Fortran_STANDARD_LATEST
             \ CMAKE_Fortran_STANDARD_LIBRARIES
+            \ CMAKE_Fortran_STANDARD_LINK_DIRECTORIES
             \ CMAKE_Fortran_STANDARD_REQUIRED
             \ CMAKE_Fortran_SUPPORTED
+            \ CMAKE_Fortran_USING_LINKER_MODE
             \ CMAKE_Fortran_VISIBILITY_PRESET
             \ CMAKE_GENERATOR
             \ CMAKE_GENERATOR_INSTANCE
@@ -1314,9 +1506,12 @@
             \ CMAKE_HIP_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_HIP_ANDROID_TOOLCHAIN_SUFFIX
             \ CMAKE_HIP_ARCHITECTURES
+            \ CMAKE_HIP_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_HIP_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_HIP_ARCHIVE_APPEND
             \ CMAKE_HIP_ARCHIVE_CREATE
             \ CMAKE_HIP_ARCHIVE_FINISH
+            \ CMAKE_HIP_ATTRIBUTES
             \ CMAKE_HIP_BYTE_ORDER
             \ CMAKE_HIP_CLANG_TIDY
             \ CMAKE_HIP_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1328,6 +1523,10 @@
             \ CMAKE_HIP_COMPILER_FRONTEND_VARIANT
             \ CMAKE_HIP_COMPILER_ID
             \ CMAKE_HIP_COMPILER_LAUNCHER
+            \ CMAKE_HIP_COMPILER_LINKER
+            \ CMAKE_HIP_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_HIP_COMPILER_LINKER_ID
+            \ CMAKE_HIP_COMPILER_LINKER_VERSION
             \ CMAKE_HIP_COMPILER_LOADED
             \ CMAKE_HIP_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_HIP_COMPILER_RANLIB
@@ -1339,8 +1538,10 @@
             \ CMAKE_HIP_CPPCHECK
             \ CMAKE_HIP_CPPLINT
             \ CMAKE_HIP_CREATE_SHARED_LIBRARY
+            \ CMAKE_HIP_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_HIP_CREATE_SHARED_MODULE
             \ CMAKE_HIP_CREATE_STATIC_LIBRARY
+            \ CMAKE_HIP_DEVICE_LINK_MODE
             \ CMAKE_HIP_EXTENSIONS
             \ CMAKE_HIP_EXTENSIONS_DEFAULT
             \ CMAKE_HIP_FLAGS
@@ -1353,6 +1554,10 @@
             \ CMAKE_HIP_FLAGS_RELEASE_INIT
             \ CMAKE_HIP_FLAGS_RELWITHDEBINFO
             \ CMAKE_HIP_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_HIP_HOST_COMPILER
+            \ CMAKE_HIP_HOST_COMPILER_ID
+            \ CMAKE_HIP_HOST_COMPILER_VERSION
+            \ CMAKE_HIP_ICSTAT
             \ CMAKE_HIP_IGNORE_EXTENSIONS
             \ CMAKE_HIP_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_HIP_IMPLICIT_LINK_DIRECTORIES
@@ -1366,12 +1571,15 @@
             \ CMAKE_HIP_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_HIP_LINKER_WRAPPER_FLAG
             \ CMAKE_HIP_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_HIP_LINK_DEF_FILE_FLAG
             \ CMAKE_HIP_LINK_EXECUTABLE
             \ CMAKE_HIP_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_HIP_LINK_LIBRARY_FLAG
             \ CMAKE_HIP_LINK_LIBRARY_SUFFIX
+            \ CMAKE_HIP_LINK_MODE
             \ CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_HIP_OUTPUT_EXTENSION
+            \ CMAKE_HIP_PLATFORM
             \ CMAKE_HIP_PLATFORM_ID
             \ CMAKE_HIP_SIMULATE_ID
             \ CMAKE_HIP_SIMULATE_VERSION
@@ -1380,13 +1588,18 @@
             \ CMAKE_HIP_STANDARD
             \ CMAKE_HIP_STANDARD_DEFAULT
             \ CMAKE_HIP_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_HIP_STANDARD_LATEST
             \ CMAKE_HIP_STANDARD_LIBRARIES
+            \ CMAKE_HIP_STANDARD_LINK_DIRECTORIES
             \ CMAKE_HIP_STANDARD_REQUIRED
             \ CMAKE_HIP_SUPPORTED
+            \ CMAKE_HIP_USING_LINKER_MODE
             \ CMAKE_HIP_VISIBILITY_PRESET
             \ CMAKE_HOME_DIRECTORY
+            \ CMAKE_HOST_AIX
             \ CMAKE_HOST_APPLE
             \ CMAKE_HOST_BSD
+            \ CMAKE_HOST_EXECUTABLE_SUFFIX
             \ CMAKE_HOST_LINUX
             \ CMAKE_HOST_SOLARIS
             \ CMAKE_HOST_SYSTEM
@@ -1427,9 +1640,12 @@
             \ CMAKE_Java_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_Java_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_Java_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_Java_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_Java_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_Java_ARCHIVE_APPEND
             \ CMAKE_Java_ARCHIVE_CREATE
             \ CMAKE_Java_ARCHIVE_FINISH
+            \ CMAKE_Java_ATTRIBUTES
             \ CMAKE_Java_BYTE_ORDER
             \ CMAKE_Java_CLANG_TIDY
             \ CMAKE_Java_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1441,6 +1657,10 @@
             \ CMAKE_Java_COMPILER_FRONTEND_VARIANT
             \ CMAKE_Java_COMPILER_ID
             \ CMAKE_Java_COMPILER_LAUNCHER
+            \ CMAKE_Java_COMPILER_LINKER
+            \ CMAKE_Java_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_Java_COMPILER_LINKER_ID
+            \ CMAKE_Java_COMPILER_LINKER_VERSION
             \ CMAKE_Java_COMPILER_LOADED
             \ CMAKE_Java_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_Java_COMPILER_RANLIB
@@ -1451,8 +1671,10 @@
             \ CMAKE_Java_CPPCHECK
             \ CMAKE_Java_CPPLINT
             \ CMAKE_Java_CREATE_SHARED_LIBRARY
+            \ CMAKE_Java_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_Java_CREATE_SHARED_MODULE
             \ CMAKE_Java_CREATE_STATIC_LIBRARY
+            \ CMAKE_Java_DEVICE_LINK_MODE
             \ CMAKE_Java_EXTENSIONS
             \ CMAKE_Java_EXTENSIONS_DEFAULT
             \ CMAKE_Java_FLAGS
@@ -1465,6 +1687,10 @@
             \ CMAKE_Java_FLAGS_RELEASE_INIT
             \ CMAKE_Java_FLAGS_RELWITHDEBINFO
             \ CMAKE_Java_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_Java_HOST_COMPILER
+            \ CMAKE_Java_HOST_COMPILER_ID
+            \ CMAKE_Java_HOST_COMPILER_VERSION
+            \ CMAKE_Java_ICSTAT
             \ CMAKE_Java_IGNORE_EXTENSIONS
             \ CMAKE_Java_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_Java_IMPLICIT_LINK_DIRECTORIES
@@ -1478,10 +1704,12 @@
             \ CMAKE_Java_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_Java_LINKER_WRAPPER_FLAG
             \ CMAKE_Java_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_Java_LINK_DEF_FILE_FLAG
             \ CMAKE_Java_LINK_EXECUTABLE
             \ CMAKE_Java_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_Java_LINK_LIBRARY_FLAG
             \ CMAKE_Java_LINK_LIBRARY_SUFFIX
+            \ CMAKE_Java_LINK_MODE
             \ CMAKE_Java_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_Java_OUTPUT_EXTENSION
             \ CMAKE_Java_PLATFORM_ID
@@ -1492,9 +1720,12 @@
             \ CMAKE_Java_STANDARD
             \ CMAKE_Java_STANDARD_DEFAULT
             \ CMAKE_Java_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_Java_STANDARD_LATEST
             \ CMAKE_Java_STANDARD_LIBRARIES
+            \ CMAKE_Java_STANDARD_LINK_DIRECTORIES
             \ CMAKE_Java_STANDARD_REQUIRED
             \ CMAKE_Java_SUPPORTED
+            \ CMAKE_Java_USING_LINKER_MODE
             \ CMAKE_Java_VISIBILITY_PRESET
             \ CMAKE_KATE_FILES_MODE
             \ CMAKE_KATE_MAKE_ARGUMENTS
@@ -1503,19 +1734,23 @@
             \ CMAKE_LIBRARY_OUTPUT_DIRECTORY
             \ CMAKE_LIBRARY_PATH
             \ CMAKE_LIBRARY_PATH_FLAG
+            \ CMAKE_LINKER_TYPE
             \ CMAKE_LINK_DEF_FILE_FLAG
             \ CMAKE_LINK_DEPENDS_NO_SHARED
             \ CMAKE_LINK_DEPENDS_USE_LINKER
             \ CMAKE_LINK_DIRECTORIES_BEFORE
             \ CMAKE_LINK_INTERFACE_LIBRARIES
             \ CMAKE_LINK_LIBRARIES_ONLY_TARGETS
+            \ CMAKE_LINK_LIBRARIES_STRATEGY
             \ CMAKE_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_LINK_LIBRARY_FLAG
             \ CMAKE_LINK_LIBRARY_SUFFIX
             \ CMAKE_LINK_SEARCH_END_STATIC
             \ CMAKE_LINK_SEARCH_START_STATIC
+            \ CMAKE_LINK_WARNING_AS_ERROR
             \ CMAKE_LINK_WHAT_YOU_USE
             \ CMAKE_LINK_WHAT_YOU_USE_CHECK
+            \ CMAKE_LIST_FILE_NAME
             \ CMAKE_MACOSX_BUNDLE
             \ CMAKE_MACOSX_RPATH
             \ CMAKE_MAJOR_VERSION
@@ -1552,6 +1787,7 @@
             \ CMAKE_OBJC_LINKER_LAUNCHER
             \ CMAKE_OBJC_STANDARD
             \ CMAKE_OBJC_STANDARD_REQUIRED
+            \ CMAKE_OBJDUMP
             \ CMAKE_OBJECT_PATH_MAX
             \ CMAKE_OPTIMIZE_DEPENDENCIES
             \ CMAKE_OSX_ARCHITECTURES
@@ -1562,15 +1798,23 @@
             \ CMAKE_PCH_INSTANTIATE_TEMPLATES
             \ CMAKE_PCH_WARN_INVALID
             \ CMAKE_PDB_OUTPUT_DIRECTORY
+            \ CMAKE_PKG_CONFIG_DISABLE_UNINSTALLED
+            \ CMAKE_PKG_CONFIG_PC_LIB_DIRS
+            \ CMAKE_PKG_CONFIG_PC_PATH
+            \ CMAKE_PKG_CONFIG_SYSROOT_DIR
+            \ CMAKE_PKG_CONFIG_TOP_BUILD_DIR
             \ CMAKE_PLATFORM_NO_VERSIONED_SONAME
+            \ CMAKE_POLICY_VERSION_MINIMUM
             \ CMAKE_POSITION_INDEPENDENT_CODE
             \ CMAKE_PREFIX_PATH
             \ CMAKE_PROGRAM_PATH
+            \ CMAKE_PROJECT_COMPAT_VERSION
             \ CMAKE_PROJECT_DESCRIPTION
             \ CMAKE_PROJECT_HOMEPAGE_URL
             \ CMAKE_PROJECT_INCLUDE
             \ CMAKE_PROJECT_INCLUDE_BEFORE
             \ CMAKE_PROJECT_NAME
+            \ CMAKE_PROJECT_SPDX_LICENSE
             \ CMAKE_PROJECT_TOP_LEVEL_INCLUDES
             \ CMAKE_PROJECT_VERSION
             \ CMAKE_PROJECT_VERSION_MAJOR
@@ -1582,9 +1826,12 @@
             \ CMAKE_RC_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_RC_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_RC_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_RC_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_RC_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_RC_ARCHIVE_APPEND
             \ CMAKE_RC_ARCHIVE_CREATE
             \ CMAKE_RC_ARCHIVE_FINISH
+            \ CMAKE_RC_ATTRIBUTES
             \ CMAKE_RC_BYTE_ORDER
             \ CMAKE_RC_CLANG_TIDY
             \ CMAKE_RC_CLANG_TIDY_EXPORT_FIXES_DIR
@@ -1596,6 +1843,10 @@
             \ CMAKE_RC_COMPILER_FRONTEND_VARIANT
             \ CMAKE_RC_COMPILER_ID
             \ CMAKE_RC_COMPILER_LAUNCHER
+            \ CMAKE_RC_COMPILER_LINKER
+            \ CMAKE_RC_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_RC_COMPILER_LINKER_ID
+            \ CMAKE_RC_COMPILER_LINKER_VERSION
             \ CMAKE_RC_COMPILER_LOADED
             \ CMAKE_RC_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_RC_COMPILER_RANLIB
@@ -1606,8 +1857,10 @@
             \ CMAKE_RC_CPPCHECK
             \ CMAKE_RC_CPPLINT
             \ CMAKE_RC_CREATE_SHARED_LIBRARY
+            \ CMAKE_RC_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_RC_CREATE_SHARED_MODULE
             \ CMAKE_RC_CREATE_STATIC_LIBRARY
+            \ CMAKE_RC_DEVICE_LINK_MODE
             \ CMAKE_RC_EXTENSIONS
             \ CMAKE_RC_EXTENSIONS_DEFAULT
             \ CMAKE_RC_FLAGS
@@ -1620,6 +1873,10 @@
             \ CMAKE_RC_FLAGS_RELEASE_INIT
             \ CMAKE_RC_FLAGS_RELWITHDEBINFO
             \ CMAKE_RC_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_RC_HOST_COMPILER
+            \ CMAKE_RC_HOST_COMPILER_ID
+            \ CMAKE_RC_HOST_COMPILER_VERSION
+            \ CMAKE_RC_ICSTAT
             \ CMAKE_RC_IGNORE_EXTENSIONS
             \ CMAKE_RC_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_RC_IMPLICIT_LINK_DIRECTORIES
@@ -1633,10 +1890,12 @@
             \ CMAKE_RC_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_RC_LINKER_WRAPPER_FLAG
             \ CMAKE_RC_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_RC_LINK_DEF_FILE_FLAG
             \ CMAKE_RC_LINK_EXECUTABLE
             \ CMAKE_RC_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_RC_LINK_LIBRARY_FLAG
             \ CMAKE_RC_LINK_LIBRARY_SUFFIX
+            \ CMAKE_RC_LINK_MODE
             \ CMAKE_RC_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_RC_OUTPUT_EXTENSION
             \ CMAKE_RC_PLATFORM_ID
@@ -1647,14 +1906,18 @@
             \ CMAKE_RC_STANDARD
             \ CMAKE_RC_STANDARD_DEFAULT
             \ CMAKE_RC_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_RC_STANDARD_LATEST
             \ CMAKE_RC_STANDARD_LIBRARIES
+            \ CMAKE_RC_STANDARD_LINK_DIRECTORIES
             \ CMAKE_RC_STANDARD_REQUIRED
             \ CMAKE_RC_SUPPORTED
+            \ CMAKE_RC_USING_LINKER_MODE
             \ CMAKE_RC_VISIBILITY_PRESET
             \ CMAKE_ROOT
             \ CMAKE_RULE_MESSAGES
             \ CMAKE_RUNTIME_OUTPUT_DIRECTORY
             \ CMAKE_SCRIPT_MODE_FILE
+            \ CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX
             \ CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS
             \ CMAKE_SHARED_LIBRARY_PREFIX
             \ CMAKE_SHARED_LIBRARY_SUFFIX
@@ -1697,12 +1960,16 @@
             \ CMAKE_Swift_ANDROID_TOOLCHAIN_MACHINE
             \ CMAKE_Swift_ANDROID_TOOLCHAIN_PREFIX
             \ CMAKE_Swift_ANDROID_TOOLCHAIN_SUFFIX
+            \ CMAKE_Swift_ARCHIVER_WRAPPER_FLAG
+            \ CMAKE_Swift_ARCHIVER_WRAPPER_FLAG_SEP
             \ CMAKE_Swift_ARCHIVE_APPEND
             \ CMAKE_Swift_ARCHIVE_CREATE
             \ CMAKE_Swift_ARCHIVE_FINISH
+            \ CMAKE_Swift_ATTRIBUTES
             \ CMAKE_Swift_BYTE_ORDER
             \ CMAKE_Swift_CLANG_TIDY
             \ CMAKE_Swift_CLANG_TIDY_EXPORT_FIXES_DIR
+            \ CMAKE_Swift_COMPILATION_MODE
             \ CMAKE_Swift_COMPILER
             \ CMAKE_Swift_COMPILER_ABI
             \ CMAKE_Swift_COMPILER_AR
@@ -1711,6 +1978,10 @@
             \ CMAKE_Swift_COMPILER_FRONTEND_VARIANT
             \ CMAKE_Swift_COMPILER_ID
             \ CMAKE_Swift_COMPILER_LAUNCHER
+            \ CMAKE_Swift_COMPILER_LINKER
+            \ CMAKE_Swift_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CMAKE_Swift_COMPILER_LINKER_ID
+            \ CMAKE_Swift_COMPILER_LINKER_VERSION
             \ CMAKE_Swift_COMPILER_LOADED
             \ CMAKE_Swift_COMPILER_PREDEFINES_COMMAND
             \ CMAKE_Swift_COMPILER_RANLIB
@@ -1721,8 +1992,10 @@
             \ CMAKE_Swift_CPPCHECK
             \ CMAKE_Swift_CPPLINT
             \ CMAKE_Swift_CREATE_SHARED_LIBRARY
+            \ CMAKE_Swift_CREATE_SHARED_LIBRARY_ARCHIVE
             \ CMAKE_Swift_CREATE_SHARED_MODULE
             \ CMAKE_Swift_CREATE_STATIC_LIBRARY
+            \ CMAKE_Swift_DEVICE_LINK_MODE
             \ CMAKE_Swift_EXTENSIONS
             \ CMAKE_Swift_EXTENSIONS_DEFAULT
             \ CMAKE_Swift_FLAGS
@@ -1735,6 +2008,10 @@
             \ CMAKE_Swift_FLAGS_RELEASE_INIT
             \ CMAKE_Swift_FLAGS_RELWITHDEBINFO
             \ CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT
+            \ CMAKE_Swift_HOST_COMPILER
+            \ CMAKE_Swift_HOST_COMPILER_ID
+            \ CMAKE_Swift_HOST_COMPILER_VERSION
+            \ CMAKE_Swift_ICSTAT
             \ CMAKE_Swift_IGNORE_EXTENSIONS
             \ CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES
             \ CMAKE_Swift_IMPLICIT_LINK_DIRECTORIES
@@ -1749,10 +2026,12 @@
             \ CMAKE_Swift_LINKER_PREFERENCE_PROPAGATES
             \ CMAKE_Swift_LINKER_WRAPPER_FLAG
             \ CMAKE_Swift_LINKER_WRAPPER_FLAG_SEP
+            \ CMAKE_Swift_LINK_DEF_FILE_FLAG
             \ CMAKE_Swift_LINK_EXECUTABLE
             \ CMAKE_Swift_LINK_LIBRARY_FILE_FLAG
             \ CMAKE_Swift_LINK_LIBRARY_FLAG
             \ CMAKE_Swift_LINK_LIBRARY_SUFFIX
+            \ CMAKE_Swift_LINK_MODE
             \ CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG
             \ CMAKE_Swift_MODULE_DIRECTORY
             \ CMAKE_Swift_NUM_THREADS
@@ -1765,13 +2044,18 @@
             \ CMAKE_Swift_STANDARD
             \ CMAKE_Swift_STANDARD_DEFAULT
             \ CMAKE_Swift_STANDARD_INCLUDE_DIRECTORIES
+            \ CMAKE_Swift_STANDARD_LATEST
             \ CMAKE_Swift_STANDARD_LIBRARIES
+            \ CMAKE_Swift_STANDARD_LINK_DIRECTORIES
             \ CMAKE_Swift_STANDARD_REQUIRED
             \ CMAKE_Swift_SUPPORTED
+            \ CMAKE_Swift_USING_LINKER_MODE
             \ CMAKE_Swift_VISIBILITY_PRESET
             \ CMAKE_TASKING_TOOLSET
+            \ CMAKE_TEST_LAUNCHER
             \ CMAKE_TLS_CAINFO
             \ CMAKE_TLS_VERIFY
+            \ CMAKE_TLS_VERSION
             \ CMAKE_TOOLCHAIN_FILE
             \ CMAKE_TRY_COMPILE_CONFIGURATION
             \ CMAKE_TRY_COMPILE_NO_PLATFORM_VARIABLES
@@ -1780,6 +2064,7 @@
             \ CMAKE_TWEAK_VERSION
             \ CMAKE_UNITY_BUILD
             \ CMAKE_UNITY_BUILD_BATCH_SIZE
+            \ CMAKE_UNITY_BUILD_RELOCATABLE
             \ CMAKE_UNITY_BUILD_UNIQUE_ID
             \ CMAKE_USER_MAKE_RULES_OVERRIDE
             \ CMAKE_USER_MAKE_RULES_OVERRIDE_ASM
@@ -1818,6 +2103,7 @@
             \ CMAKE_VS_PLATFORM_TOOLSET
             \ CMAKE_VS_PLATFORM_TOOLSET_CUDA
             \ CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR
+            \ CMAKE_VS_PLATFORM_TOOLSET_FORTRAN
             \ CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE
             \ CMAKE_VS_PLATFORM_TOOLSET_VERSION
             \ CMAKE_VS_SDK_EXCLUDE_DIRECTORIES
@@ -1830,6 +2116,7 @@
             \ CMAKE_VS_TARGET_FRAMEWORK_IDENTIFIER
             \ CMAKE_VS_TARGET_FRAMEWORK_TARGETS_VERSION
             \ CMAKE_VS_TARGET_FRAMEWORK_VERSION
+            \ CMAKE_VS_USE_DEBUG_LIBRARIES
             \ CMAKE_VS_VERSION_BUILD_NUMBER
             \ CMAKE_VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
             \ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION
@@ -1840,6 +2127,7 @@
             \ CMAKE_WATCOM_RUNTIME_LIBRARY
             \ CMAKE_WIN32_EXECUTABLE
             \ CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
+            \ CMAKE_WINDOWS_KMDF_VERSION
             \ CMAKE_XCODE_BUILD_SYSTEM
             \ CMAKE_XCODE_GENERATE_SCHEME
             \ CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY
@@ -1848,28 +2136,26 @@
             \ CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER
             \ CMAKE_XCODE_SCHEME_ADDRESS_SANITIZER_USE_AFTER_RETURN
             \ CMAKE_XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING
-            \ CMAKE_XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
             \ CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
             \ CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
             \ CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
             \ CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+            \ CMAKE_XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE
             \ CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
             \ CMAKE_XCODE_SCHEME_ENVIRONMENT
             \ CMAKE_XCODE_SCHEME_GUARD_MALLOC
+            \ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
             \ CMAKE_XCODE_SCHEME_LAUNCH_MODE
             \ CMAKE_XCODE_SCHEME_LLDB_INIT_FILE
             \ CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
             \ CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
             \ CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
             \ CMAKE_XCODE_SCHEME_MALLOC_STACK
+            \ CMAKE_XCODE_SCHEME_TEST_CONFIGURATION
             \ CMAKE_XCODE_SCHEME_THREAD_SANITIZER
             \ CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
             \ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
             \ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
-            \ CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
-            \ CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
-            \ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
-            \ CMAKE_XCODE_SCHEME_TEST_CONFIGURATION
             \ CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
             \ CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
             \ CMAKE_XCODE_XCCONFIG
@@ -1903,7 +2189,6 @@
             \ CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
             \ CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
             \ CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
-            \ CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION
             \ CTEST_CUSTOM_MEMCHECK_IGNORE
             \ CTEST_CUSTOM_POST_MEMCHECK
             \ CTEST_CUSTOM_POST_TEST
@@ -1923,6 +2208,7 @@
             \ CTEST_DROP_SITE_PASSWORD
             \ CTEST_DROP_SITE_USER
             \ CTEST_EXTRA_COVERAGE_GLOB
+            \ CTEST_EXTRA_SUBMIT_FILES
             \ CTEST_GIT_COMMAND
             \ CTEST_GIT_INIT_SUBMODULES
             \ CTEST_GIT_UPDATE_CUSTOM
@@ -1936,6 +2222,7 @@
             \ CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
             \ CTEST_MEMORYCHECK_TYPE
             \ CTEST_NIGHTLY_START_TIME
+            \ CTEST_NOTES_FILES
             \ CTEST_P4_CLIENT
             \ CTEST_P4_COMMAND
             \ CTEST_P4_OPTIONS
@@ -1953,6 +2240,8 @@
             \ CTEST_SVN_UPDATE_OPTIONS
             \ CTEST_TEST_LOAD
             \ CTEST_TEST_TIMEOUT
+            \ CTEST_TLS_VERIFY
+            \ CTEST_TLS_VERSION
             \ CTEST_TRIGGER_SITE
             \ CTEST_UPDATE_COMMAND
             \ CTEST_UPDATE_OPTIONS
@@ -2226,6 +2515,7 @@
             \ DOXYGEN_USE_PDFLATEX
             \ DOXYGEN_VERBATIM_HEADERS
             \ DOXYGEN_VERBATIM_VARS
+            \ Doxygen_VERSION
             \ DOXYGEN_VERSION
             \ DOXYGEN_WARNINGS
             \ DOXYGEN_WARN_AS_ERROR
@@ -2259,17 +2549,20 @@
             \ MSVC_VERSION
             \ MSYS
             \ PROJECT_BINARY_DIR
+            \ PROJECT_COMPAT_VERSION
             \ PROJECT_DESCRIPTION
             \ PROJECT_HOMEPAGE_URL
             \ PROJECT_IS_TOP_LEVEL
             \ PROJECT_NAME
             \ PROJECT_SOURCE_DIR
+            \ PROJECT_SPDX_LICENSE
             \ PROJECT_VERSION
             \ PROJECT_VERSION_MAJOR
             \ PROJECT_VERSION_MINOR
             \ PROJECT_VERSION_PATCH
             \ PROJECT_VERSION_TWEAK
             \ UNIX
+            \ WASI
             \ WIN32
             \ WINCE
             \ WINDOWS_PHONE
@@ -2287,7 +2580,9 @@
             \ BUILD_ALWAYS
             \ BUILD_BYPRODUCTS
             \ BUILD_COMMAND
+            \ BUILD_ENVIRONMENT_MODIFICATION
             \ BUILD_IN_SOURCE
+            \ BUILD_JOB_SERVER_AWARE
             \ CHECKOUT
             \ CMAKE_ARGS
             \ CMAKE_CACHE_ARGS
@@ -2296,12 +2591,14 @@
             \ CMAKE_INSTALL_MODE
             \ COMMENT
             \ CONFIGURE_COMMAND
+            \ CONFIGURE_ENVIRONMENT_MODIFICATION
             \ CONFIGURE_HANDLED_BY_BUILD
             \ CVS
             \ CVSROOT
             \ CVS_MODULE
             \ CVS_REPOSITORY
             \ CVS_TAG
+            \ DCMAKE_PREFIX_PATH
             \ DEPENDEES
             \ DEPENDERS
             \ DEPENDS
@@ -2341,7 +2638,8 @@
             \ INSTALL_BYPRODUCTS
             \ INSTALL_COMMAND
             \ INSTALL_DIR
-            \ JOB_POOLS
+            \ INSTALL_ENVIRONMENT_MODIFICATION
+            \ INSTALL_JOB_SERVER_AWARE
             \ LIST_SEPARATOR
             \ LOG_BUILD
             \ LOG_CONFIGURE
@@ -2380,10 +2678,12 @@
             \ TEST_AFTER_INSTALL
             \ TEST_BEFORE_INSTALL
             \ TEST_COMMAND
+            \ TEST_ENVIRONMENT_MODIFICATION
             \ TEST_EXCLUDE_FROM_MAIN
             \ TIMEOUT
             \ TLS_CAINFO
             \ TLS_VERIFY
+            \ TLS_VERSION
             \ TMP_DIR
             \ TRUE
             \ UPDATE_COMMAND
@@ -2407,11 +2707,10 @@
             \ BYPASS_PROVIDER
             \ CMAKE_PROJECT_
             \ CONFIGURE_COMMAND
-            \ COPY
             \ CORRECT
             \ DCMAKE_TOOLCHAIN_FILE
-            \ DESTINATION
             \ DOWNLOAD_NO_EXTRACT
+            \ EXCLUDE_FROM_ALL
             \ EXISTS
             \ FETCHCONTENT_BASE_DIR
             \ FETCHCONTENT_FULLY_DISCONNECTED
@@ -2433,6 +2732,7 @@
             \ NAME
             \ NAMES
             \ NEVER
+            \ NOT
             \ NOTE
             \ OFF
             \ OPTIONAL
@@ -2441,6 +2741,7 @@
             \ PACKAGE_VERSION_COMPATIBLE
             \ PACKAGE_VERSION_EXACT
             \ QUIET
+            \ REQUIRED
             \ SOURCE_SUBDIR
             \ STREQUAL
             \ SUBBUILD_DIR
@@ -2449,10 +2750,10 @@
             \ SYSTEM
             \ TARGET
             \ TEST_COMMAND
-            \ TRUE
             \ URL
             \ URL_HASH
             \ VERIFY_INTERFACE_HEADER_SETS
+            \ WARNING
             \ WRITE
             \ WRONG
             \ _BINARY_DIR
@@ -2475,11 +2776,13 @@
             \ _FLAGS_
 
 syn keyword cmakeKWadd_custom_command contained
+            \ ALIAS
             \ APPEND
             \ ARGS
             \ BNF
             \ BYPRODUCTS
             \ CC
+            \ CODEGEN
             \ COMMAND
             \ COMMAND_EXPAND_LISTS
             \ COMMENT
@@ -2493,11 +2796,14 @@
             \ INCLUDE_DIRECTORIES
             \ JOB_POOL
             \ JOB_POOLS
+            \ JOB_SERVER_AWARE
             \ JOIN
             \ MAIN_DEPENDENCY
             \ MODULE
             \ NOT
+            \ OPTIMIZE_DEPENDENCIES
             \ OUTPUT
+            \ OUTPUTS
             \ PATH
             \ POST_BUILD
             \ PRE_BUILD
@@ -2525,6 +2831,7 @@
             \ INCLUDE_DIRECTORIES
             \ JOB_POOL
             \ JOB_POOLS
+            \ JOB_SERVER_AWARE
             \ JOIN
             \ PATH
             \ SOURCES
@@ -2542,6 +2849,7 @@
 
 syn keyword cmakeKWadd_dependencies contained
             \ DEPENDS
+            \ MANUALLY_ADDED_DEPENDENCIES
             \ OBJECT_DEPENDS
 
 syn keyword cmakeKWadd_executable contained
@@ -2573,7 +2881,6 @@
             \ HEADER_FILE_ONLY
             \ HEADER_SETS
             \ IMPORTED
-            \ IMPORTED_
             \ IMPORTED_IMPLIB
             \ IMPORTED_IMPLIB_
             \ IMPORTED_LOCATION
@@ -2589,7 +2896,6 @@
             \ LIBRARY_OUTPUT_DIRECTORY
             \ MODULE
             \ OBJECT
-            \ ON
             \ OUTPUT_NAME
             \ POSITION_INDEPENDENT_CODE
             \ POST_BUILD
@@ -2631,22 +2937,25 @@
             \ SYSTEM
 
 syn keyword cmakeKWadd_test contained
-            \ BUILD_TESTING
             \ COMMAND
             \ COMMAND_EXPAND_LISTS
             \ CONFIGURATIONS
+            \ CROSSCOMPILING_EMULATOR
             \ FAIL_REGULAR_EXPRESSION
             \ NAME
             \ OFF
             \ PASS_REGULAR_EXPRESSION
             \ SKIP_REGULAR_EXPRESSION
             \ TARGET_FILE
+            \ TEST
+            \ TEST_LAUNCHER
             \ WILL_FAIL
             \ WORKING_DIRECTORY
 
 syn keyword cmakeKWblock contained
             \ PARENT_SCOPE
             \ POLICIES
+            \ POP
             \ PROPAGATE
             \ PUSH
             \ SCOPE_FOR
@@ -2723,6 +3032,7 @@
             \ LISTS
             \ LTS
             \ MATCHES
+            \ MSYSTEM_PREFIX
             \ NNN
             \ NOT
             \ NUMBER_OF_LOGICAL_CORES
@@ -2755,6 +3065,16 @@
             \ VIEW
             \ WINDOWS_REGISTRY
 
+syn keyword cmakeKWcmake_instrumentation contained
+            \ API
+            \ API_VERSION
+            \ CALLBACK
+            \ CMAKE_EXPERIMENTAL_INSTRUMENTATION
+            \ DATA_VERSION
+            \ HOOKS
+            \ JSON
+            \ QUERIES
+
 syn keyword cmakeKWcmake_language contained
             \ AND
             \ ANY
@@ -2771,6 +3091,7 @@
             \ DEFER
             \ DIRECTORY
             \ EVAL
+            \ EXIT
             \ FALSE
             \ FETCHCONTENT_MAKEAVAILABLE_SERIAL
             \ FETCHCONTENT_SOURCE_DIR_
@@ -2790,6 +3111,7 @@
             \ OVERRIDE_FIND_PACKAGE
             \ PATH
             \ POP_BACK
+            \ PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
             \ QUIET
             \ SET_DEPENDENCY_PROVIDER
             \ SOURCE_DIR
@@ -2803,7 +3125,9 @@
             \ _PATH
 
 syn keyword cmakeKWcmake_minimum_required contained
+            \ CMAKE_POLICY_DEFAULT_CMP
             \ FATAL_ERROR
+            \ NNNN
             \ VERSION
 
 syn keyword cmakeKWcmake_parse_arguments contained
@@ -2813,21 +3137,13 @@
             \ FALSE
             \ FAST
             \ FILES
-            \ MY_INSTALL
-            \ MY_INSTALL_CONFIGURATIONS
-            \ MY_INSTALL_DESTINATION
-            \ MY_INSTALL_FAST
-            \ MY_INSTALL_KEYWORDS_MISSING_VALUES
-            \ MY_INSTALL_OPTIONAL
-            \ MY_INSTALL_RENAME
-            \ MY_INSTALL_TARGETS
-            \ MY_INSTALL_UNPARSED_ARGUMENTS
+            \ NOTE
             \ OPTIONAL
             \ PARSE_ARGV
             \ RENAME
             \ TARGETS
             \ TRUE
-            \ UNDEFINED
+            \ UNSET
             \ _KEYWORDS_MISSING_VALUES
             \ _UNPARSED_ARGUMENTS
 
@@ -2893,6 +3209,72 @@
             \ TRUE
             \ XOR
 
+syn keyword cmakeKWcmake_pkg_config contained
+            \ ALLOW_SYSTEM_INCLUDES
+            \ ALLOW_SYSTEM_LIBS
+            \ BEST_EFFORT
+            \ BIND_PC_REQUIRES
+            \ CMAKE_PKG_CONFIG_ALLOW_SYS_INCLUDES
+            \ CMAKE_PKG_CONFIG_ALLOW_SYS_LIBS
+            \ CMAKE_PKG_CONFIG_CFLAGS
+            \ CMAKE_PKG_CONFIG_COMPILE_OPTIONS
+            \ CMAKE_PKG_CONFIG_CONFLICTS
+            \ CMAKE_PKG_CONFIG_DESCRIPTION
+            \ CMAKE_PKG_CONFIG_INCLUDES
+            \ CMAKE_PKG_CONFIG_LIBDIRS
+            \ CMAKE_PKG_CONFIG_LIBNAMES
+            \ CMAKE_PKG_CONFIG_LIBS
+            \ CMAKE_PKG_CONFIG_LINK_OPTIONS
+            \ CMAKE_PKG_CONFIG_NAME
+            \ CMAKE_PKG_CONFIG_PKGCONF_INCLUDES
+            \ CMAKE_PKG_CONFIG_PKGCONF_LIB_DIRS
+            \ CMAKE_PKG_CONFIG_PROVIDES
+            \ CMAKE_PKG_CONFIG_REQUIRES
+            \ CMAKE_PKG_CONFIG_SYS_INCLUDE_DIRS
+            \ CMAKE_PKG_CONFIG_SYS_LIB_DIRS
+            \ CMAKE_PKG_CONFIG_VERSION
+            \ CPATH
+            \ CPLUS_INCLUDE_PATH
+            \ C_INCLUDE_PATH
+            \ DISABLE_UNINSTALLED
+            \ ENV_MODE
+            \ EXACT
+            \ EXTRACT
+            \ FDO
+            \ IGNORE
+            \ IMPORT
+            \ IMPORTED
+            \ INTERFACE_LINK_LIBRARIES
+            \ OBJC_INCLUDE_PATH
+            \ PC_LIBDIR
+            \ PC_PATH
+            \ PC_SYSROOT_DIR
+            \ PERMISSIVE
+            \ PKGCONF
+            \ PKGCONFIG_
+            \ PKG_CONFIG_
+            \ PKG_CONFIG_ALLOW_
+            \ PKG_CONFIG_ALLOW_SYSTEM_CFLAGS
+            \ PKG_CONFIG_ALLOW_SYSTEM_LIBS
+            \ PKG_CONFIG_DISABLE_UNINSTALLED
+            \ PKG_CONFIG_LIBDIR
+            \ PKG_CONFIG_PATH
+            \ PKG_CONFIG_SYSROOT_DIR
+            \ PKG_CONFIG_SYSROOT_PATH
+            \ PKG_CONFIG_SYSTEM_INCLUDE_PATH
+            \ PKG_CONFIG_SYSTEM_LIBRARY_PATH
+            \ PKG_CONFIG_TOP_BUILD_DIR
+            \ POPULATE
+            \ PREFIX
+            \ QUIET
+            \ REQUIRED
+            \ STRICTNESS
+            \ SYSTEM_INCLUDE_DIRS
+            \ SYSTEM_LIBRARY_DIRS
+            \ TOP_BUILD_DIR
+            \ _FOUND
+            \ _PRIVATE
+
 syn keyword cmakeKWcmake_policy contained
             \ CMAKE_POLICY_DEFAULT_CMP
             \ CMP
@@ -3011,8 +3393,6 @@
             \ CAPTURE_CMAKE_ERROR
             \ CDASH_UPLOAD
             \ CDASH_UPLOAD_TYPE
-            \ CTEST_EXTRA_SUBMIT_FILES
-            \ CTEST_NOTES_FILES
             \ FILES
             \ HTTPHEADER
             \ PARTS
@@ -3034,10 +3414,13 @@
             \ EXCLUDE_FIXTURE
             \ EXCLUDE_FIXTURE_CLEANUP
             \ EXCLUDE_FIXTURE_SETUP
+            \ EXCLUDE_FROM_FILE
             \ EXCLUDE_LABEL
             \ INCLUDE
+            \ INCLUDE_FROM_FILE
             \ INCLUDE_LABEL
             \ LABELS
+            \ NOT
             \ OFF
             \ ON
             \ OUTPUT_JUNIT
@@ -3074,11 +3457,14 @@
             \ BRIEF_DOCS
             \ CACHED_VARIABLE
             \ CMAKE_
+            \ DEFINED
             \ DIRECTORY
             \ FULL_DOCS
             \ GLOBAL
             \ INHERITED
             \ INITIALIZE_FROM_VARIABLE
+            \ MY_NEW_PROP
+            \ NONE
             \ PROPERTY
             \ SOURCE
             \ TARGET
@@ -3105,13 +3491,15 @@
             \ OBJCXX
             \ OPTIONAL
 
-syn keyword cmakeKWenable_testing contained
-            \ BUILD_TESTING
-
 syn keyword cmakeKWexec_program contained
             \ ARGS
+            \ COMMAND
+            \ ERROR_VARIABLE
+            \ OUTPUT_STRIP_TRAILING_WHITESPACE
             \ OUTPUT_VARIABLE
+            \ RESULT_VARIABLE
             \ RETURN_VALUE
+            \ WORKING_DIRECTORY
 
 syn keyword cmakeKWexecute_process contained
             \ ANSI
@@ -3148,17 +3536,43 @@
 syn keyword cmakeKWexport contained
             \ ANDROID_MK
             \ APPEND
+            \ APPENDIX
+            \ AUTO
+            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES
+            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
+            \ CMAKE_MAP_IMPORTED_CONFIG_
+            \ COMPAT_VERSION
             \ CONFIG
+            \ CPS
             \ CXX_MODULES_DIRECTORY
+            \ DEFAULT_CONFIGURATIONS
+            \ DEFAULT_LICENSE
+            \ DEFAULT_TARGETS
+            \ DESCRIPTION
+            \ ENABLED
             \ EXPORT
             \ EXPORT_LINK_INTERFACE_LIBRARIES
+            \ EXPORT_PACKAGE_DEPENDENCIES
+            \ EXTRA_ARGS
             \ FILE
+            \ HOMEPAGE_URL
             \ IMPORTED_
+            \ LICENSE
+            \ LOWER_CASE_FILE
             \ NAMESPACE
             \ NDK
+            \ NO_PROJECT_METADATA
             \ OLD
             \ PACKAGE
+            \ PACKAGE_DEPENDENCY
+            \ PACKAGE_INFO
+            \ PROJECT
+            \ REQUIRED
+            \ SETUP
             \ TARGETS
+            \ VERSION
+            \ VERSION_SCHEMA
+            \ XCFRAMEWORK_LOCATION
 
 syn keyword cmakeKWexport_library_dependencies contained
             \ APPEND
@@ -3180,7 +3594,7 @@
             \ CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM
             \ CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL
             \ CMAKE_INSTALL_MODE
-            \ CMAKE_OBJDUMP
+            \ CMAKE_MATCH_
             \ CODE
             \ COMPILE_FEATURES
             \ COMPRESSION
@@ -3197,13 +3611,14 @@
             \ CREATE_LINK
             \ CRLF
             \ DESTINATION
-            \ DIRECTORIES
             \ DIRECTORY_PERMISSIONS
             \ DLL
             \ DOS
             \ DOWNLOAD
+            \ ELF
             \ ENCODING
             \ ESCAPE_QUOTES
+            \ EXCLUDE
             \ EXECUTABLES
             \ EXPAND_TILDE
             \ EXPECTED_HASH
@@ -3244,6 +3659,7 @@
             \ LOCK
             \ LOG
             \ MAKE_DIRECTORY
+            \ MATCHALL
             \ MODULES
             \ MTIME
             \ MYLIBRARY
@@ -3309,6 +3725,7 @@
             \ TIMESTAMP
             \ TLS_CAINFO
             \ TLS_VERIFY
+            \ TLS_VERSION
             \ TOUCH
             \ TOUCH_NOCREATE
             \ TO_CMAKE_PATH
@@ -3323,7 +3740,9 @@
             \ USE_SOURCE_PERMISSIONS
             \ UTC
             \ UTF
+            \ VAR
             \ VERBOSE
+            \ WORKING_DIRECTORY
             \ WORLD_EXECUTE
             \ WORLD_READ
             \ WORLD_WRITE
@@ -3339,7 +3758,9 @@
             \ DOC
             \ DVAR
             \ FALSE
+            \ FIND_XXX_ORDER
             \ FIND_XXX_REGISTRY_VIEW
+            \ FIND_XXX_ROOT
             \ HINTS
             \ HOST
             \ INCLUDE
@@ -3356,6 +3777,7 @@
             \ NO_PACKAGE_ROOT_PATH
             \ NO_SYSTEM_ENVIRONMENT_PATH
             \ ONLY_CMAKE_FIND_ROOT_PATH
+            \ OPTIONAL
             \ PACKAGENAME
             \ PARENT_SCOPE
             \ PATHS
@@ -3374,7 +3796,9 @@
             \ DOC
             \ DVAR
             \ FALSE
+            \ FIND_XXX_ORDER
             \ FIND_XXX_REGISTRY_VIEW
+            \ FIND_XXX_ROOT
             \ HINTS
             \ HOST
             \ LIB
@@ -3392,6 +3816,7 @@
             \ NO_PACKAGE_ROOT_PATH
             \ NO_SYSTEM_ENVIRONMENT_PATH
             \ ONLY_CMAKE_FIND_ROOT_PATH
+            \ OPTIONAL
             \ PACKAGENAME
             \ PARENT_SCOPE
             \ PATHS
@@ -3404,17 +3829,17 @@
 
 syn keyword cmakeKWfind_package contained
             \ ABI
+            \ ASC
             \ BOTH
             \ BUNDLE
             \ BYPASS_PROVIDER
             \ CATEGORY
             \ CMAKE_DISABLE_FIND_PACKAGE_
-            \ CMAKE_REQUIRE_FIND_PACKAGE_
+            \ CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ CMAKE_FIND_USE_
             \ CMAKE_REQUIRE_FIND_PACKAGE_
             \ COMPONENTS
-            \ CONFIG
             \ CONFIGS
             \ DEC
             \ DVAR
@@ -3422,6 +3847,7 @@
             \ EXCLUDE
             \ FALSE
             \ FIND_PACKAGE_VERSION_FORMAT
+            \ FIND_XXX_REGISTRY_VIEW
             \ FRAMEWORK
             \ GLOBAL
             \ HINTS
@@ -3430,6 +3856,7 @@
             \ MODULE
             \ NAMES
             \ NATURAL
+            \ NONE
             \ NO_CMAKE_BUILDS_PATH
             \ NO_CMAKE_ENVIRONMENT_PATH
             \ NO_CMAKE_FIND_ROOT_PATH
@@ -3443,8 +3870,8 @@
             \ NO_PACKAGE_ROOT_PATH
             \ NO_POLICY_SCOPE
             \ NO_SYSTEM_ENVIRONMENT_PATH
-            \ OLD
             \ ONLY_CMAKE_FIND_ROOT_PATH
+            \ OPTIONAL
             \ OPTIONAL_COMPONENTS
             \ PACKAGENAME
             \ PACKAGE_FIND_NAME
@@ -3477,7 +3904,6 @@
             \ QUIET
             \ REGISTRY_VIEW
             \ REQUIRED
-            \ SET
             \ TARGET
             \ TRUE
             \ VALUE
@@ -3501,7 +3927,9 @@
             \ DOC
             \ DVAR
             \ FALSE
+            \ FIND_XXX_ORDER
             \ FIND_XXX_REGISTRY_VIEW
+            \ FIND_XXX_ROOT
             \ HINTS
             \ HOST
             \ INCLUDE
@@ -3518,6 +3946,7 @@
             \ NO_PACKAGE_ROOT_PATH
             \ NO_SYSTEM_ENVIRONMENT_PATH
             \ ONLY_CMAKE_FIND_ROOT_PATH
+            \ OPTIONAL
             \ PACKAGENAME
             \ PARENT_SCOPE
             \ PATHS
@@ -3536,10 +3965,13 @@
             \ DOC
             \ DVAR
             \ FALSE
+            \ FIND_XXX_ORDER
             \ FIND_XXX_REGISTRY_VIEW
+            \ FIND_XXX_ROOT
             \ HINTS
             \ HOST
             \ MATCHES
+            \ MY_SCRIPT
             \ NAMES
             \ NAMES_PER_DIR
             \ NOT
@@ -3553,6 +3985,7 @@
             \ NO_PACKAGE_ROOT_PATH
             \ NO_SYSTEM_ENVIRONMENT_PATH
             \ ONLY_CMAKE_FIND_ROOT_PATH
+            \ OPTIONAL
             \ PACKAGENAME
             \ PARENT_SCOPE
             \ PATHS
@@ -3635,11 +4068,10 @@
 
 syn keyword cmakeKWget_target_property contained
             \ INHERITED
-            \ VAR
 
 syn keyword cmakeKWget_test_property contained
+            \ DIRECTORY
             \ INHERITED
-            \ VAR
 
 syn keyword cmakeKWif contained
             \ CMAKE_MATCH_
@@ -3656,15 +4088,17 @@
             \ IN_LIST
             \ IS_ABSOLUTE
             \ IS_DIRECTORY
+            \ IS_EXECUTABLE
             \ IS_NEWER_THAN
+            \ IS_READABLE
             \ IS_SYMLINK
+            \ IS_WRITABLE
             \ LESS
             \ LESS_EQUAL
             \ MATCHES
             \ NNNN
             \ NOT
             \ OFF
-            \ OR
             \ PATH_EQUAL
             \ POLICY
             \ STREQUAL
@@ -3708,15 +4142,14 @@
             \ __CURRENT_FILE_VAR__
 
 syn keyword cmakeKWinstall contained
-            \ AFTER
-            \ AIX
             \ ALL_COMPONENTS
+            \ APPENDIX
             \ APT
             \ ARCHIVE
-            \ BEFORE
             \ BUILD_TYPE
-            \ BUNDLE
             \ BUNDLE_EXECUTABLE
+            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES
+            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
             \ CMAKE_INSTALL_BINDIR
             \ CMAKE_INSTALL_DATADIR
             \ CMAKE_INSTALL_DATAROOTDIR
@@ -3724,6 +4157,7 @@
             \ CMAKE_INSTALL_INCLUDEDIR
             \ CMAKE_INSTALL_INFODIR
             \ CMAKE_INSTALL_LIBDIR
+            \ CMAKE_INSTALL_LIBEXECDIR
             \ CMAKE_INSTALL_LOCALEDIR
             \ CMAKE_INSTALL_LOCALSTATEDIR
             \ CMAKE_INSTALL_MANDIR
@@ -3732,9 +4166,12 @@
             \ CMAKE_INSTALL_SBINDIR
             \ CMAKE_INSTALL_SHARESTATEDIR
             \ CMAKE_INSTALL_SYSCONFDIR
+            \ CMAKE_MAP_IMPORTED_CONFIG_
             \ CODE
+            \ COMPAT_VERSION
             \ COMPONENT
             \ CONFIGURATIONS
+            \ CPS
             \ CVS
             \ CXX_MODULES_BMI
             \ CXX_MODULES_DIRECTORY
@@ -3742,19 +4179,28 @@
             \ DATAROOT
             \ DBUILD_TYPE
             \ DCOMPONENT
+            \ DEFAULT_CONFIGURATIONS
+            \ DEFAULT_LICENSE
+            \ DEFAULT_TARGETS
+            \ DESCRIPTION
             \ DESTDIR
             \ DESTINATION
             \ DIRECTORY
             \ DIRECTORY_PERMISSIONS
             \ DLL
             \ DOC
+            \ ENABLED
             \ ENABLE_EXPORTS
+            \ EXCLUDE_EMPTY_DIRECTORIES
             \ EXCLUDE_FROM_ALL
             \ EXECUTABLES
             \ EXPORT
             \ EXPORT_ANDROID_MK
+            \ EXPORT_FIND_PACKAGE_NAME
             \ EXPORT_LINK_INTERFACE_LIBRARIES
             \ EXPORT_NAME
+            \ EXPORT_PACKAGE_DEPENDENCIES
+            \ EXTRA_ARGS
             \ FILES
             \ FILES_MATCHING
             \ FILE_PERMISSIONS
@@ -3765,15 +4211,19 @@
             \ GROUP_READ
             \ GROUP_WRITE
             \ HEADERS
+            \ HOMEPAGE_URL
             \ IMPORTED_RUNTIME_ARTIFACTS
             \ INCLUDES
-            \ INFO
+            \ INSTALL_PARALLEL
             \ INSTALL_PREFIX
             \ INTERFACE
             \ INTERFACE_INCLUDE_DIRECTORIES
+            \ LIBEXEC
             \ LIBRARY
+            \ LICENSE
             \ LOCALE
             \ LOCALSTATE
+            \ LOWER_CASE_FILE
             \ MACOSX_BUNDLE
             \ MAN
             \ MESSAGE_NEVER
@@ -3782,11 +4232,14 @@
             \ NAMELINK_SKIP
             \ NAMESPACE
             \ NDK
+            \ NO_PROJECT_METADATA
             \ OBJECTS
+            \ OFF
             \ OPTIONAL
             \ OWNER_EXECUTE
             \ OWNER_READ
             \ OWNER_WRITE
+            \ PACKAGE_INFO
             \ PATTERN
             \ PERMISSIONS
             \ POST_EXCLUDE_FILES
@@ -3799,9 +4252,12 @@
             \ PRE_INSTALL_SCRIPT
             \ PRIVATE_HEADER
             \ PROGRAMS
+            \ PROJECT
             \ PROPERTIES
+            \ PROPERTY
             \ PUBLIC_HEADER
             \ RENAME
+            \ REQUIRED
             \ RESOURCE
             \ RPM
             \ RUNSTATE
@@ -3811,8 +4267,11 @@
             \ SCRIPT
             \ SETGID
             \ SETUID
+            \ SETUP
             \ SHAREDSTATE
             \ SOVERSION
+            \ SPDX
+            \ SPDX_LICENSE
             \ STATIC
             \ SYSCONF
             \ TARGETS
@@ -3820,6 +4279,7 @@
             \ TYPE
             \ USE_SOURCE_PERMISSIONS
             \ VERSION
+            \ VERSION_SCHEMA
             \ WORLD_EXECUTE
             \ WORLD_READ
             \ WORLD_WRITE
@@ -3896,7 +4356,9 @@
 syn keyword cmakeKWload_cache contained
             \ EXCLUDE
             \ INCLUDE_INTERNALS
+            \ OTHER_PROJECT_INTERNAL_CACHE_VAR
             \ READ_WITH_PREFIX
+            \ STATUS
 
 syn keyword cmakeKWload_command contained
             \ CMAKE_LOADED_COMMAND_
@@ -3955,7 +4417,10 @@
             \ ASM_MASM
             \ ASM_NASM
             \ ATT
+            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
             \ CMAKE_PROJECT_
+            \ COMPAT_VERSION
+            \ CPS
             \ CUDA
             \ DESCRIPTION
             \ HIP
@@ -3967,14 +4432,16 @@
             \ OBJC
             \ OBJCXX
             \ PROJECT
+            \ SPDX_LICENSE
             \ VERSION
             \ _BINARY_DIR
+            \ _COMPAT_VERSION
             \ _DESCRIPTION
             \ _HOMEPAGE_URL
             \ _INCLUDE_BEFORE
             \ _IS_TOP_LEVEL
             \ _SOURCE_DIR
-            \ _VERSION
+            \ _SPDX_LICENSE
             \ _VERSION_MAJOR
             \ _VERSION_MINOR
             \ _VERSION_PATCH
@@ -4051,6 +4518,7 @@
             \ PROPERTIES
 
 syn keyword cmakeKWset_tests_properties contained
+            \ DIRECTORY
             \ NAME
             \ PROPERTIES
 
@@ -4195,28 +4663,35 @@
 
 syn keyword cmakeKWtarget_link_libraries contained
             \ ALIAS
+            \ CMAKE_
             \ DA
             \ DAG
             \ DEBUG_CONFIGURATIONS
             \ DOBJ
+            \ GCC
             \ IMPORTED
+            \ IMPORTED_CONFIGURATIONS
             \ IMPORTED_NO_SONAME
             \ INTERFACE
             \ INTERFACE_LINK_LIBRARIES
+            \ LANG
+            \ LINKER
             \ LINK_FLAGS
             \ LINK_INTERFACE_LIBRARIES
-            \ LINK_INTERFACE_LIBRARIES_DEBUG
             \ LINK_INTERFACE_MULTIPLICITY
+            \ LINK_LIBRARIES_STRATEGY
             \ LINK_OPTIONS
             \ LINK_PRIVATE
             \ LINK_PUBLIC
             \ OBJECT
-            \ OLD
             \ PRIVATE
             \ PUBLIC
             \ SHARED
+            \ SHELL
             \ STATIC
             \ TARGET_OBJECTS
+            \ _LINKER_WRAPPER_FLAG
+            \ _LINKER_WRAPPER_FLAG_SEP
 
 syn keyword cmakeKWtarget_link_options contained
             \ ALIAS
@@ -4250,7 +4725,6 @@
             \ BUILD_INTERFACE
             \ COMPILE_LANGUAGE
             \ DISABLE_PRECOMPILE_HEADERS
-            \ EXPORT
             \ FI
             \ GCC
             \ IMPORTED
@@ -4312,27 +4786,29 @@
             \ CUDA_STANDARD
             \ CUDA_STANDARD_REQUIRED
             \ CXX_EXTENSIONS
+            \ CXX_MODULE
+            \ CXX_MODULES
             \ CXX_STANDARD
             \ CXX_STANDARD_REQUIRED
             \ C_EXTENSIONS
             \ C_STANDARD
             \ C_STANDARD_REQUIRED
+            \ DCOMPILE_DEFINITIONS
             \ DEFINED
             \ DLINK_LIBRARIES
             \ DVAR
             \ EXECUTABLE
             \ FALSE
+            \ FILE_SET
             \ GHS
-            \ HIP_EXTENSIONS
-            \ HIP_STANDARD
-            \ HIP_STANDARD_REQUIRED
             \ INCLUDE_DIRECTORIES
-            \ LANG
+            \ LINKER_LANGUAGE
             \ LINK_DIRECTORIES
             \ LINK_LIBRARIES
             \ LINK_OPTIONS
             \ LOG_DESCRIPTION
             \ MULTI
+            \ NORMAL
             \ NOT
             \ NO_CACHE
             \ NO_LOG
@@ -4345,8 +4821,9 @@
             \ OUTPUT_VARIABLE
             \ PRIVATE
             \ PROJECT
+            \ PROPAGATE_TOP_LEVEL_INCLUDES_TO_TRY_COMPILE
             \ RESULTVAR
-            \ SOURCES
+            \ SOURCES_TYPE
             \ SOURCE_DIR
             \ SOURCE_FROM_CONTENT
             \ SOURCE_FROM_FILE
@@ -4355,7 +4832,6 @@
             \ STATIC_LIBRARY_OPTIONS
             \ TARGET
             \ TRUE
-            \ TYPE
             \ VALUE
             \ _EXTENSIONS
             \ _STANDARD
@@ -4369,8 +4845,8 @@
             \ COPY_FILE
             \ COPY_FILE_ERROR
             \ FAILED_TO_RUN
-            \ FALSE
             \ LANG
+            \ LINKER_LANGUAGE
             \ LINK_LIBRARIES
             \ LINK_OPTIONS
             \ LOG_DESCRIPTION
@@ -4379,11 +4855,10 @@
             \ RUN_OUTPUT_STDERR_VARIABLE
             \ RUN_OUTPUT_STDOUT_VARIABLE
             \ RUN_OUTPUT_VARIABLE
-            \ SOURCES
+            \ SOURCES_TYPE
             \ SOURCE_FROM_CONTENT
             \ SOURCE_FROM_FILE
             \ SOURCE_FROM_VAR
-            \ TRUE
             \ WORKING_DIRECTORY
             \ _EXTENSIONS
             \ _STANDARD
@@ -4423,7 +4898,6 @@
 syn keyword cmakeGeneratorExpressions contained
             \ ABSOLUTE_PATH
             \ ACTION
-            \ AIX
             \ ANGLE
             \ APPEND
             \ ARCHIVE_OUTPUT_NAME
@@ -4440,6 +4914,7 @@
             \ COMMAND_CONFIG
             \ COMMAND_EXPAND_LISTS
             \ COMPARE
+            \ COMPATIBLE_INTERFACE_
             \ COMPILE_DEFINITIONS
             \ COMPILE_FEATURES
             \ COMPILE_LANGUAGE
@@ -4453,16 +4928,25 @@
             \ CONFIG
             \ CONFIGURATION
             \ CONTENT
+            \ CUDA_COMPILER_FRONTEND_VARIANT
             \ CUDA_COMPILER_ID
+            \ CUDA_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CUDA_COMPILER_LINKER_ID
             \ CUDA_COMPILER_VERSION
             \ CUDA_RESOLVE_DEVICE_SYMBOLS
             \ CUDA_SEPARABLE_COMPILATION
             \ CUSTOM_KEYS
+            \ CXX_COMPILER_FRONTEND_VARIANT
             \ CXX_COMPILER_ID
+            \ CXX_COMPILER_LINKER_FRONTEND_VARIANT
+            \ CXX_COMPILER_LINKER_ID
             \ CXX_COMPILER_VERSION
             \ CXX_CONFIG
             \ CXX_STANDARD
+            \ C_COMPILER_FRONTEND_VARIANT
             \ C_COMPILER_ID
+            \ C_COMPILER_LINKER_FRONTEND_VARIANT
+            \ C_COMPILER_LINKER_ID
             \ C_COMPILER_VERSION
             \ C_STANDARD
             \ DEBUG_MODE
@@ -4501,9 +4985,11 @@
             \ HAS_ROOT_PATH
             \ HAS_STEM
             \ HAVE_SOME_FEATURE
+            \ HIP_COMPILER_FRONTEND_VARIANT
             \ HIP_COMPILER_ID
+            \ HIP_COMPILER_LINKER_FRONTEND_VARIANT
+            \ HIP_COMPILER_LINKER_ID
             \ HIP_COMPILER_VERSION
-            \ HIP_STANDARD
             \ HOST_LINK
             \ IF
             \ IGNORE
@@ -4519,7 +5005,9 @@
             \ INSTALL_RPATH
             \ INTERFACE_LINK_LIBRARIES
             \ INTERFACE_LINK_LIBRARIES_DIRECT
+            \ INTERFACE_PROP
             \ IN_LIST
+            \ ISPC_COMPILER_FRONTEND_VARIANT
             \ ISPC_COMPILER_ID
             \ ISPC_COMPILER_VERSION
             \ IS_ABSOLUTE
@@ -4546,14 +5034,21 @@
             \ MAKE_C_IDENTIFIER
             \ MAP_IMPORTED_CONFIG_
             \ MODULE
+            \ NATIVE_PATH
             \ NATURAL
             \ NO
             \ NORMALIZE
             \ NORMAL_PATH
             \ NOT
+            \ OBJCXX_COMPILER_FRONTEND_VARIANT
             \ OBJCXX_COMPILER_ID
+            \ OBJCXX_COMPILER_LINKER_FRONTEND_VARIANT
+            \ OBJCXX_COMPILER_LINKER_ID
             \ OBJCXX_COMPILER_VERSION
+            \ OBJC_COMPILER_FRONTEND_VARIANT
             \ OBJC_COMPILER_ID
+            \ OBJC_COMPILER_LINKER_FRONTEND_VARIANT
+            \ OBJC_COMPILER_LINKER_ID
             \ OBJC_COMPILER_VERSION
             \ OBJECT
             \ OFF
@@ -4577,6 +5072,7 @@
             \ PREPEND
             \ PRIVATE
             \ PUBLIC
+            \ QUOTE
             \ REGEX
             \ RELATIVE_PATH
             \ REMOVE_AT
@@ -4665,6 +5161,8 @@
             \ TRANSFORM_REPLACE
             \ TRANSFORM_STRIP
             \ TRANSFORM_TOLOWER
+            \ TRANSITIVE_COMPILE_PROPERTIES
+            \ TRANSITIVE_LINK_PROPERTIES
             \ UNKNOWN
             \ UPPER_CASE
             \ VERBATIM
@@ -4674,6 +5172,9 @@
             \ VERSION_LESS_EQUAL
             \ WHOLE_ARCHIVE
             \ WRONG
+            \ _COMPILER_FRONTEND_VARIANT
+            \ _COMPILER_LINKER_FRONTEND_VARIANT
+            \ _COMPILER_LINKER_ID
             \ _LINK_GROUP_USING_
             \ _LINK_LIBRARY_USING_
             \ _POSTFIX
@@ -4694,15 +5195,16 @@
             \ add_subdirectory
             \ add_test
             \ aux_source_directory
-            \ block
             \ break
             \ build_command
             \ cmake_file_api
             \ cmake_host_system_information
+            \ cmake_instrumentation
             \ cmake_language
             \ cmake_minimum_required
             \ cmake_parse_arguments
             \ cmake_path
+            \ cmake_pkg_config
             \ cmake_policy
             \ configure_file
             \ continue
@@ -4723,9 +5225,6 @@
             \ define_property
             \ enable_language
             \ enable_testing
-            \ endblock
-            \ endfunction
-            \ endmacro
             \ execute_process
             \ export
             \ file
@@ -4735,7 +5234,6 @@
             \ find_path
             \ find_program
             \ fltk_wrap_ui
-            \ function
             \ get_cmake_property
             \ get_directory_property
             \ get_filename_component
@@ -4753,7 +5251,6 @@
             \ list
             \ load_cache
             \ load_command
-            \ macro
             \ mark_as_advanced
             \ math
             \ message
@@ -4788,20 +5285,6 @@
             \ variable_watch
             \ nextgroup=cmakeArguments
 
-syn keyword cmakeCommandConditional
-            \ else
-            \ elseif
-            \ endif
-            \ if
-            \ nextgroup=cmakeArguments
-
-syn keyword cmakeCommandRepeat
-            \ endforeach
-            \ endwhile
-            \ foreach
-            \ while
-            \ nextgroup=cmakeArguments
-
 syn keyword cmakeCommandDeprecated
             \ build_name
             \ exec_program
@@ -4830,14 +5313,14 @@
 hi def link cmakeBracketArgument String
 hi def link cmakeBracketComment Comment
 hi def link cmakeCommand Function
-hi def link cmakeCommandConditional Conditional
 hi def link cmakeCommandDeprecated WarningMsg
-hi def link cmakeCommandRepeat Repeat
 hi def link cmakeComment Comment
+hi def link cmakeElse Conditional
 hi def link cmakeEnvironment Special
 hi def link cmakeEscaped Special
 hi def link cmakeGeneratorExpression WarningMsg
 hi def link cmakeGeneratorExpressions Constant
+hi def link cmakeKeyword Conditional
 hi def link cmakeModule Include
 hi def link cmakeProperty Constant
 hi def link cmakeRegistry Underlined
@@ -4863,10 +5346,12 @@
 hi def link cmakeKWbuild_command ModeMsg
 hi def link cmakeKWcmake_file_api ModeMsg
 hi def link cmakeKWcmake_host_system_information ModeMsg
+hi def link cmakeKWcmake_instrumentation ModeMsg
 hi def link cmakeKWcmake_language ModeMsg
 hi def link cmakeKWcmake_minimum_required ModeMsg
 hi def link cmakeKWcmake_parse_arguments ModeMsg
 hi def link cmakeKWcmake_path ModeMsg
+hi def link cmakeKWcmake_pkg_config ModeMsg
 hi def link cmakeKWcmake_policy ModeMsg
 hi def link cmakeKWconfigure_file ModeMsg
 hi def link cmakeKWcreate_test_sourcelist ModeMsg
@@ -4883,7 +5368,6 @@
 hi def link cmakeKWdefine_property ModeMsg
 hi def link cmakeKWdoxygen_add_docs ModeMsg
 hi def link cmakeKWenable_language ModeMsg
-hi def link cmakeKWenable_testing ModeMsg
 hi def link cmakeKWexec_program ModeMsg
 hi def link cmakeKWexecute_process ModeMsg
 hi def link cmakeKWexport ModeMsg
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake
index 3ac6030..f38fe6d 100644
--- a/CMakeCPack.cmake
+++ b/CMakeCPack.cmake
@@ -11,7 +11,7 @@
 endif()
 
 if(CMake_INSTALL_DEPENDENCIES)
-  include(${CMake_SOURCE_DIR}/Modules/InstallRequiredSystemLibraries.cmake)
+  include(InstallRequiredSystemLibraries)
 endif()
 
 set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/LICENSE.txt")
@@ -52,7 +52,7 @@
 endif()
 
 # Command for configure IFW script templates
-include(${CMake_SOURCE_DIR}/Modules/CPackIFWConfigureFile.cmake)
+include(CPackIFWConfigureFile)
 
 # Advanced IFW configuration
 set(_cpifwrc CPACK_IFW_COMPONENT_GROUP_CMAKE_)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef6e301..f26b228 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file LICENSE.rst or https://cmake.org/licensing for details.
 
-cmake_minimum_required(VERSION 3.13...3.31 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...4.0 FATAL_ERROR)
 set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
 set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
 
@@ -485,13 +485,21 @@
         NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") OR
        CMAKE_C_COMPILER_ID STREQUAL "AppleClang" OR
        CMAKE_C_COMPILER_ID STREQUAL "LCC")
-      set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
+      set(C_FLAGS_LIST -Wcast-align -Wchar-subscripts
                        -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
                        -Wmissing-format-attribute -fno-common -Wundef
+                       -Werror=implicit-function-declaration
+                       -Wstrict-prototypes
       )
       set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W
                          -Wshadow -Wpointer-arith -Wformat-security -Wundef
       )
+      if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND
+          NOT (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11))
+        list(APPEND CXX_FLAGS_LIST
+          -Wundefined-func-template
+        )
+      endif()
 
       foreach(FLAG_LANG IN ITEMS C CXX)
         foreach(FLAG IN LISTS ${FLAG_LANG}_FLAGS_LIST)
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index d924480..6daca61 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -126,6 +126,9 @@
 
   # Exclude Qt source files from coverage results:
   "[A-Za-z]./[Qq]t/qt-.+-opensource-src"
+
+  # Exclude coverage results from coverage test directories.
+  "/Testing/.*Coverage/"
   )
 
 list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index 31565b5..8d66752 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -357,6 +357,7 @@
   Execute the command with the given current working directory.
   If it is a relative path, it will be interpreted relative to the
   build tree directory corresponding to the current source directory.
+  If not specified, set to :variable:`CMAKE_CURRENT_BINARY_DIR`.
 
   This option is currently ignored if ``APPEND`` is given, but a future
   version may use it.
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index b574cba..83fe6b4 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -191,6 +191,7 @@
   Execute the command with the given current working directory.
   If it is a relative path it will be interpreted relative to the
   build tree directory corresponding to the current source directory.
+  If not specified, set to :variable:`CMAKE_CURRENT_BINARY_DIR`.
 
   .. versionadded:: 3.13
     Arguments to ``WORKING_DIRECTORY`` may use
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst
index 50cb0bc..66ce327 100644
--- a/Help/command/add_library.rst
+++ b/Help/command/add_library.rst
@@ -196,6 +196,30 @@
     call are ``PRIVATE`` to the interface library and do not appear in its
     :prop_tgt:`INTERFACE_SOURCES` target property.
 
+.. signature::
+  add_library(<name> INTERFACE SYMBOLIC)
+  :target: INTERFACE-SYMBOLIC
+
+  .. versionadded:: 4.2
+
+  Add a symbolic :ref:`Interface Library <Interface Libraries>` target.
+  Symbolic interface libraries are useful for representing optional components
+  or features in a package.  They have no usage requirements, do not compile
+  sources, and do not produce a library artifact on disk, but they may be
+  exported and installed.  They can also be tested for existence with the
+  regular :command:`if(TARGET)` subcommand.
+
+  A symbolic interface library may be used as a linkable target to enforce the
+  presence of optional components in a dependency.  For example, if a library
+  ``libgui`` may or may not provide a feature ``widget``, a consumer package
+  can link against ``widget`` to express that it requires this component to be
+  available.  This allows :command:`find_package` calls that declare required
+  components to be validated by linking against the corresponding symbolic
+  targets.
+
+  A symbolic interface library has the :prop_tgt:`SYMBOLIC` target property
+  set to true.
+
 .. _`add_library imported libraries`:
 
 Imported Libraries
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index dbaa4fb..bbfcca2 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -114,4 +114,5 @@
 Unlike the above ``NAME`` signature, target names are not supported
 in the command-line.  Furthermore, tests added with this signature do not
 support :manual:`generator expressions <cmake-generator-expressions(7)>`
-in the command-line or test properties.
+in the command-line or test properties, and the :prop_tgt:`TEST_LAUNCHER`
+and :prop_tgt:`CROSSCOMPILING_EMULATOR` target properties are not supported.
diff --git a/Help/command/cmake_instrumentation.rst b/Help/command/cmake_instrumentation.rst
index 22e77ea..0d2cd50 100644
--- a/Help/command/cmake_instrumentation.rst
+++ b/Help/command/cmake_instrumentation.rst
@@ -19,8 +19,9 @@
     API_VERSION <version>
     DATA_VERSION <version>
     [HOOKS <hooks>...]
-    [QUERIES <queries>...]
+    [OPTIONS <options>...]
     [CALLBACK <callback>]
+    [CUSTOM_CONTENT <name> <type> <content>]
   )
 
 The ``API_VERSION`` and ``DATA_VERSION`` must always be given.  Currently, the
@@ -28,7 +29,7 @@
 for details of the ``API_VERSION`` and :ref:`cmake-instrumentation Data v1` for details
 of the ``DATA_VERSION``.
 
-Each of the optional keywords ``HOOKS``, ``QUERIES``, and ``CALLBACK``
+Each of the optional keywords ``HOOKS``, ``OPTIONS``, and ``CALLBACK``
 correspond to one of the parameters to the :ref:`cmake-instrumentation v1 Query Files`.
 The ``CALLBACK`` keyword can be provided multiple times to create multiple callbacks.
 
@@ -36,6 +37,34 @@
 ``<build>/.cmake/instrumentation/v1/query/generated`` to enable instrumentation
 with the provided arguments.
 
+.. _`cmake_instrumentation CUSTOM_CONTENT`:
+
+Custom CMake Content
+^^^^^^^^^^^^^^^^^^^^
+
+The ``CUSTOM_CONTENT`` argument specifies certain data from configure time to
+include in each :ref:`cmake-instrumentation v1 CMake Content File`. This
+may be used to associate instrumentation data with certain information about its
+configuration, such as the optimization level or whether it is part of a
+coverage build.
+
+``CUSTOM_CONTENT`` expects ``name``, ``type`` and ``content`` arguments.
+
+``name`` is a specifier to identify the content being reported.
+
+``type`` specifies how the content should be interpreted. Supported values are:
+  * ``STRING`` the content is a string.
+  * ``BOOL`` the content should be interpreted as a boolean. It will be ``true``
+    under the same conditions that ``if()`` would be true for the given value.
+  * ``LIST`` the content is a CMake ``;`` separated list that should be parsed.
+  * ``JSON`` the content should be parsed as a JSON string. This can be a
+    number such as ``1`` or ``5.0``, a quoted string such as ``\"string\"``,
+    a boolean value ``true``/``false``, or a JSON object such as
+    ``{ \"key\" : \"value\" }`` that may be constructed using
+    ``string(JSON ...)`` commands.
+
+``content`` is the actual content to report.
+
 Example
 ^^^^^^^
 
@@ -48,9 +77,12 @@
     API_VERSION 1
     DATA_VERSION 1
     HOOKS postGenerate preCMakeBuild postCMakeBuild
-    QUERIES staticSystemInformation dynamicSystemInformation
+    OPTIONS staticSystemInformation dynamicSystemInformation trace
     CALLBACK ${CMAKE_COMMAND} -P /path/to/handle_data.cmake
     CALLBACK ${CMAKE_COMMAND} -P /path/to/handle_data_2.cmake
+    CUSTOM_CONTENT myString STRING string
+    CUSTOM_CONTENT myList   LIST   "item1;item2"
+    CUSTOM_CONTENT myObject JSON   "{ \"key\" : \"value\" }"
   )
 
 .. code-block:: json
@@ -60,11 +92,26 @@
     "hooks": [
       "postGenerate", "preCMakeBuild", "postCMakeBuild"
     ],
-    "queries": [
-      "staticSystemInformation", "dynamicSystemInformation"
+    "options": [
+      "staticSystemInformation", "dynamicSystemInformation", "trace"
     ],
     "callbacks": [
       "/path/to/cmake -P /path/to/handle_data.cmake"
       "/path/to/cmake -P /path/to/handle_data_2.cmake"
     ]
   }
+
+This will also result in the following content included in each
+:ref:`cmake-instrumentation v1 CMake Content File`:
+
+.. code-block:: json
+
+  "custom": {
+    "myString": "string",
+    "myList": [
+      "item1", "item2"
+    ],
+    "myObject": {
+      "key": "value"
+    }
+  }
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index a9c7653..e3a30fa 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -16,6 +16,7 @@
   cmake_language(`SET_DEPENDENCY_PROVIDER`_ <command> SUPPORTED_METHODS <methods>...)
   cmake_language(`GET_MESSAGE_LOG_LEVEL`_ <out-var>)
   cmake_language(`EXIT`_ <exit-code>)
+  cmake_language(`TRACE`_ <boolean> ...)
 
 Introduction
 ^^^^^^^^^^^^
@@ -534,3 +535,28 @@
   shell or platform, and some shells may interpret values
   above 125 specially.  Therefore, it is advisable to only
   specify an ``<exit-code>`` in the range 0 to 125.
+
+Trace Control
+^^^^^^^^^^^^^
+
+.. versionadded:: 4.2
+
+.. signature::
+  cmake_language(TRACE ON [EXPAND])
+  cmake_language(TRACE OFF)
+  :target:
+    TRACE
+    TRACE-OFF
+
+  The TRACE subcommand controls runtime tracing of executed CMake commands and
+  macros within the current process. When enabled, trace output is written
+  in the same format as if CMake had been started with the
+  :option:`cmake --trace` or :option:`cmake --trace-expand` command line options.
+
+  Tracing scopes are nestable. Multiple ``TRACE ON`` calls may be active at the
+  same time, and each ``TRACE OFF`` deactivates one nesting level.
+
+  If CMake is run with :option:`cmake --trace` or :option:`cmake --trace-expand`,
+  those options override and force tracing globally, regardless of
+  ``cmake_language(TRACE OFF)`` calls. In such cases, the command may still
+  be invoked but has no effect on the trace state.
diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst
index 3094ad6..3fc3b7c 100644
--- a/Help/command/cmake_path.rst
+++ b/Help/command/cmake_path.rst
@@ -30,14 +30,14 @@
   `Normalization`_
 
   `Decomposition`_
-    cmake_path(`GET`_ <path-var> :ref:`ROOT_NAME <GET_ROOT_NAME>` <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`ROOT_DIRECTORY <GET_ROOT_DIRECTORY>` <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`ROOT_PATH <GET_ROOT_PATH>` <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`FILENAME <GET_FILENAME>` <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`EXTENSION <GET_EXTENSION>` [LAST_ONLY] <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`STEM <GET_STEM>` [LAST_ONLY] <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`RELATIVE_PART <GET_RELATIVE_PART>` <out-var>)
-    cmake_path(`GET`_ <path-var> :ref:`PARENT_PATH <GET_PARENT_PATH>` <out-var>)
+    cmake_path(`GET`_ <path-var> `ROOT_NAME <GET ... ROOT_NAME_>`_ <out-var>)
+    cmake_path(`GET`_ <path-var> `ROOT_DIRECTORY <GET ... ROOT_DIRECTORY_>`_ <out-var>)
+    cmake_path(`GET`_ <path-var> `ROOT_PATH <GET ... ROOT_PATH_>`_ <out-var>)
+    cmake_path(`GET`_ <path-var> `FILENAME <GET ... FILENAME_>`_ <out-var>)
+    cmake_path(`GET`_ <path-var> `EXTENSION <GET ... EXTENSION_>`_ [LAST_ONLY] <out-var>)
+    cmake_path(`GET`_ <path-var> `STEM <GET ... STEM_>`_ [LAST_ONLY] <out-var>)
+    cmake_path(`GET`_ <path-var> `RELATIVE_PART <GET ... RELATIVE_PART_>`_ <out-var>)
+    cmake_path(`GET`_ <path-var> `PARENT_PATH <GET ... PARENT_PATH_>`_ <out-var>)
 
   `Query`_
     cmake_path(`HAS_ROOT_NAME`_ <path-var> <out-var>)
@@ -51,10 +51,12 @@
     cmake_path(`IS_ABSOLUTE`_ <path-var> <out-var>)
     cmake_path(`IS_RELATIVE`_ <path-var> <out-var>)
     cmake_path(`IS_PREFIX`_ <path-var> <input> [NORMALIZE] <out-var>)
-    cmake_path(`COMPARE`_ <input1> <OP> <input2> <out-var>)
+
+  `Comparison`_
+    cmake_path(`COMPARE`_ <input1> <op> <input2> <out-var>)
 
   `Modification`_
-    cmake_path(:ref:`SET <cmake_path-SET>` <path-var> [NORMALIZE] <input>)
+    cmake_path(`SET`_ <path-var> [NORMALIZE] <input>)
     cmake_path(`APPEND`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
     cmake_path(`APPEND_STRING`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
     cmake_path(`REMOVE_FILENAME`_ <path-var> [OUTPUT_VARIABLE <out-var>])
@@ -69,8 +71,8 @@
 
   `Native Conversion`_
     cmake_path(`NATIVE_PATH`_ <path-var> [NORMALIZE] <out-var>)
-    cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST`_ <out-var> [NORMALIZE])
-    cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST`_ <out-var> [NORMALIZE])
+    cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST <CONVERT ... TO_CMAKE_PATH_LIST_>`_ <out-var> [NORMALIZE])
+    cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST <CONVERT ... TO_NATIVE_PATH_LIST_>`_ <out-var> [NORMALIZE])
 
   `Hashing`_
     cmake_path(`HASH`_ <path-var> <out-var>)
@@ -172,12 +174,11 @@
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 While a path can be created with care using an ordinary :command:`set`
-command, it is recommended to use :ref:`cmake_path(SET) <cmake_path-SET>`
-instead, as it automatically converts the path to the required form where
-required.  The :ref:`cmake_path(APPEND) <APPEND>` subcommand may
-be another suitable alternative where a path needs to be constructed by
-joining fragments.  The following example compares the three methods for
-constructing the same path:
+command, it is recommended to use :command:`cmake_path(SET)` instead, as it
+automatically converts the path to the required form where required.  The
+:command:`cmake_path(APPEND)` subcommand may be another suitable alternative
+where a path needs to be constructed by joining fragments. The following
+example compares the three methods for constructing the same path:
 
 .. code-block:: cmake
 
@@ -224,21 +225,12 @@
 ^^^^^^^^^^^^^
 
 .. _GET:
-.. _GET_ROOT_NAME:
-.. _GET_ROOT_DIRECTORY:
-.. _GET_ROOT_PATH:
-.. _GET_FILENAME:
-.. _GET_EXTENSION:
-.. _GET_STEM:
-.. _GET_RELATIVE_PART:
-.. _GET_PARENT_PATH:
 
 The following forms of the ``GET`` subcommand each retrieve a different
 component or group of components from a path.  See
 `Path Structure And Terminology`_ for the meaning of each path component.
 
-.. code-block:: cmake
-
+.. signature::
   cmake_path(GET <path-var> ROOT_NAME <out-var>)
   cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>)
   cmake_path(GET <path-var> ROOT_PATH <out-var>)
@@ -247,17 +239,26 @@
   cmake_path(GET <path-var> STEM [LAST_ONLY] <out-var>)
   cmake_path(GET <path-var> RELATIVE_PART <out-var>)
   cmake_path(GET <path-var> PARENT_PATH <out-var>)
+  :target:
+    GET ... ROOT_NAME
+    GET ... ROOT_DIRECTORY
+    GET ... ROOT_PATH
+    GET ... FILENAME
+    GET ... EXTENSION
+    GET ... STEM
+    GET ... RELATIVE_PART
+    GET ... PARENT_PATH
 
-If a requested component is not present in the path, an empty string will be
-stored in ``<out-var>``.  For example, only Windows systems have the concept
-of a ``root-name``, so when the host machine is non-Windows, the ``ROOT_NAME``
-subcommand will always return an empty string.
+  If a requested component is not present in the path, an empty string will be
+  stored in ``<out-var>``.  For example, only Windows systems have the concept
+  of a ``root-name``, so when the host machine is non-Windows, the ``ROOT_NAME``
+  subcommand will always return an empty string.
 
-For ``PARENT_PATH``, if the `HAS_RELATIVE_PART`_ subcommand returns false,
-the result is a copy of ``<path-var>``.  Note that this implies that a root
-directory is considered to have a parent, with that parent being itself.
-Where `HAS_RELATIVE_PART`_ returns true, the result will essentially be
-``<path-var>`` with one less element.
+  For ``PARENT_PATH``, if the :cref:`HAS_RELATIVE_PART` sub-command returns
+  false, the result is a copy of ``<path-var>``.  Note that this implies that a
+  root directory is considered to have a parent, with that parent being itself.
+  Where :cref:`HAS_RELATIVE_PART` returns true, the result will essentially be
+  ``<path-var>`` with one less element.
 
 Root examples
 """""""""""""
@@ -394,22 +395,12 @@
 Query
 ^^^^^
 
-Each of the ``GET`` subcommands has a corresponding ``HAS_...``
-subcommand which can be used to discover whether a particular path
+Each of the `cmake_path(GET) <GET_>`_ subcommands has a corresponding
+``HAS_...`` subcommand which can be used to discover whether a particular path
 component is present.  See `Path Structure And Terminology`_ for the
 meaning of each path component.
 
-.. _HAS_ROOT_NAME:
-.. _HAS_ROOT_DIRECTORY:
-.. _HAS_ROOT_PATH:
-.. _HAS_FILENAME:
-.. _HAS_EXTENSION:
-.. _HAS_STEM:
-.. _HAS_RELATIVE_PART:
-.. _HAS_PARENT_PATH:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(HAS_ROOT_NAME <path-var> <out-var>)
   cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>)
   cmake_path(HAS_ROOT_PATH <path-var> <out-var>)
@@ -419,88 +410,85 @@
   cmake_path(HAS_RELATIVE_PART <path-var> <out-var>)
   cmake_path(HAS_PARENT_PATH <path-var> <out-var>)
 
-Each of the above follows the predictable pattern of setting ``<out-var>``
-to true if the path has the associated component, or false otherwise.
-Note the following special cases:
+  Each of the above follows the predictable pattern of setting ``<out-var>``
+  to true if the path has the associated component, or false otherwise.
+  Note the following special cases:
 
-* For ``HAS_ROOT_PATH``, a true result will only be returned if at least one
-  of ``root-name`` or ``root-directory`` is non-empty.
+  * For ``HAS_ROOT_PATH``, a true result will only be returned if at least one
+    of ``root-name`` or ``root-directory`` is non-empty.
 
-* For ``HAS_PARENT_PATH``, the root directory is also considered to have a
-  parent, which will be itself.  The result is true except if the path
-  consists of just a :ref:`filename <FILENAME_DEF>`.
+  * For ``HAS_PARENT_PATH``, the root directory is also considered to have a
+    parent, which will be itself.  The result is true except if the path
+    consists of just a :ref:`filename <FILENAME_DEF>`.
 
-.. _IS_ABSOLUTE:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(IS_ABSOLUTE <path-var> <out-var>)
 
-Sets ``<out-var>`` to true if ``<path-var>`` is absolute.  An absolute path
-is a path that unambiguously identifies the location of a file without
-reference to an additional starting location.  On Windows, this means the
-path must have both a ``root-name`` and a ``root-directory-separator`` to be
-considered absolute.  On other platforms, just a ``root-directory-separator``
-is sufficient.  Note that this means on Windows, ``IS_ABSOLUTE`` can be
-false while ``HAS_ROOT_DIRECTORY`` can be true.
+  Sets ``<out-var>`` to true if ``<path-var>`` is absolute.  An absolute path
+  is a path that unambiguously identifies the location of a file without
+  reference to an additional starting location.  On Windows, this means the
+  path must have both a ``root-name`` and a ``root-directory-separator`` to be
+  considered absolute.  On other platforms, just a ``root-directory-separator``
+  is sufficient.  Note that this means on Windows, ``IS_ABSOLUTE`` can be
+  false while :cref:`HAS_ROOT_DIRECTORY` can be true.
 
-.. _IS_RELATIVE:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(IS_RELATIVE <path-var> <out-var>)
 
-This will store the opposite of ``IS_ABSOLUTE`` in ``<out-var>``.
+  This will store the opposite of :cref:`IS_ABSOLUTE` in ``<out-var>``.
 
-.. _IS_PREFIX:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>)
 
-Checks if ``<path-var>`` is the prefix of ``<input>``.
+  Checks if ``<path-var>`` is the prefix of ``<input>``.
 
-When the ``NORMALIZE`` option is specified, ``<path-var>`` and ``<input>``
-are :ref:`normalized <Normalization>` before the check.
+  When the ``NORMALIZE`` option is specified, ``<path-var>`` and ``<input>``
+  are :ref:`normalized <Normalization>` before the check.
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  set(path "/a/b/c")
-  cmake_path(IS_PREFIX path "/a/b/c/d" result) # result = true
-  cmake_path(IS_PREFIX path "/a/b" result)     # result = false
-  cmake_path(IS_PREFIX path "/x/y/z" result)   # result = false
+    set(path "/a/b/c")
+    cmake_path(IS_PREFIX path "/a/b/c/d" result) # result = true
+    cmake_path(IS_PREFIX path "/a/b" result)     # result = false
+    cmake_path(IS_PREFIX path "/x/y/z" result)   # result = false
 
-  set(path "/a/b")
-  cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE result)   # result = true
+    set(path "/a/b")
+    cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE result)   # result = true
 
-.. _Path COMPARE:
+.. _Path Comparison:
+
+Comparison
+^^^^^^^^^^
+
 .. _COMPARE:
 
-.. code-block:: cmake
-
+.. signature::
   cmake_path(COMPARE <input1> EQUAL <input2> <out-var>)
   cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>)
+  :target:
+    COMPARE ... EQUAL
+    COMPARE ... NOT_EQUAL
 
-Compares the lexical representations of two paths provided as string literals.
-No normalization is performed on either path, except multiple consecutive
-directory separators are effectively collapsed into a single separator.
-Equality is determined according to the following pseudo-code logic:
+  Compares the lexical representations of two paths provided as string literals.
+  No normalization is performed on either path, except multiple consecutive
+  directory separators are effectively collapsed into a single separator.
+  Equality is determined according to the following pseudo-code logic:
 
-::
+  ::
 
-  if(NOT <input1>.root_name() STREQUAL <input2>.root_name())
-    return FALSE
+    if(NOT <input1>.root_name() STREQUAL <input2>.root_name())
+      return FALSE
 
-  if(<input1>.has_root_directory() XOR <input2>.has_root_directory())
-    return FALSE
+    if(<input1>.has_root_directory() XOR <input2>.has_root_directory())
+      return FALSE
 
-  Return FALSE if a relative portion of <input1> is not lexicographically
-  equal to the relative portion of <input2>. This comparison is performed path
-  component-wise. If all of the components compare equal, then return TRUE.
+    Return FALSE if a relative portion of <input1> is not lexicographically
+    equal to the relative portion of <input2>. This comparison is performed path
+    component-wise. If all of the components compare equal, then return TRUE.
 
-.. note::
-  Unlike most other ``cmake_path()`` subcommands, the ``COMPARE`` subcommand
-  takes literal strings as input, not the names of variables.
+  .. note::
+    Unlike most other ``cmake_path()`` subcommands, the ``COMPARE`` subcommand
+    takes literal strings as input, not the names of variables.
 
 
 .. _Path Modification:
@@ -508,150 +496,129 @@
 Modification
 ^^^^^^^^^^^^
 
-.. _cmake_path-SET:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(SET <path-var> [NORMALIZE] <input>)
 
-Assign the ``<input>`` path to ``<path-var>``.  If ``<input>`` is a native
-path, it is converted into a cmake-style path with forward-slashes
-(``/``). On Windows, the long filename marker is taken into account.
+  Assigns the ``<input>`` path to ``<path-var>``.  If ``<input>`` is a native
+  path, it is converted into a cmake-style path with forward-slashes
+  (``/``). On Windows, the long filename marker is taken into account.
 
-When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
-<Normalization>` after the conversion.
+  When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
+  <Normalization>` after the conversion.
 
-For example:
+  For example:
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  set(native_path "c:\\a\\b/..\\c")
-  cmake_path(SET path "${native_path}")
-  message("CMake path is \"${path}\"")
+    set(native_path "c:\\a\\b/..\\c")
+    cmake_path(SET path "${native_path}")
+    message("CMake path is \"${path}\"")
 
-  cmake_path(SET path NORMALIZE "${native_path}")
-  message("Normalized CMake path is \"${path}\"")
+    cmake_path(SET path NORMALIZE "${native_path}")
+    message("Normalized CMake path is \"${path}\"")
 
-Output::
+  Output::
 
-  CMake path is "c:/a/b/../c"
-  Normalized CMake path is "c:/a/c"
+    CMake path is "c:/a/b/../c"
+    Normalized CMake path is "c:/a/c"
 
-.. _APPEND:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
 
-Append all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as
-the ``directory-separator``.  Depending on the ``<input>``, the previous
-contents of ``<path-var>`` may be discarded.  For each ``<input>`` argument,
-the following algorithm (pseudo-code) applies:
+  Appends all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as
+  the ``directory-separator``.  Depending on the ``<input>``, the previous
+  contents of ``<path-var>`` may be discarded.  For each ``<input>`` argument,
+  the following algorithm (pseudo-code) applies:
 
-::
+  ::
 
-  # <path> is the contents of <path-var>
+    # <path> is the contents of <path-var>
 
-  if(<input>.is_absolute() OR
-     (<input>.has_root_name() AND
-      NOT <input>.root_name() STREQUAL <path>.root_name()))
-    replace <path> with <input>
-    return()
-  endif()
+    if(<input>.is_absolute() OR
+      (<input>.has_root_name() AND
+        NOT <input>.root_name() STREQUAL <path>.root_name()))
+      replace <path> with <input>
+      return()
+    endif()
 
-  if(<input>.has_root_directory())
-    remove any root-directory and the entire relative path from <path>
-  elseif(<path>.has_filename() OR
-         (NOT <path-var>.has_root_directory() OR <path>.is_absolute()))
-    append directory-separator to <path>
-  endif()
+    if(<input>.has_root_directory())
+      remove any root-directory and the entire relative path from <path>
+    elseif(<path>.has_filename() OR
+          (NOT <path-var>.has_root_directory() OR <path>.is_absolute()))
+      append directory-separator to <path>
+    endif()
 
-  append <input> omitting any root-name to <path>
+    append <input> omitting any root-name to <path>
 
-.. _APPEND_STRING:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
 
-Append all the ``<input>`` arguments to the ``<path-var>`` without adding any
-``directory-separator``.
+  Appends all the ``<input>`` arguments to the ``<path-var>`` without adding any
+  ``directory-separator``.
 
-.. _REMOVE_FILENAME:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>])
 
-Removes the :ref:`filename <FILENAME_DEF>` component (as returned by
-:ref:`GET ... FILENAME <GET_FILENAME>`) from ``<path-var>``.  After removal,
-any trailing ``directory-separator`` is left alone, if present.
+  Removes the :ref:`filename <FILENAME_DEF>` component (as returned by
+  :cref:`GET ... FILENAME`) from ``<path-var>``.  After removal, any trailing
+  ``directory-separator`` is left alone, if present.
 
-If ``OUTPUT_VARIABLE`` is not given, then after this function returns,
-`HAS_FILENAME`_ returns false for ``<path-var>``.
+  If ``OUTPUT_VARIABLE`` is not given, then after this function returns,
+  :cref:`HAS_FILENAME` returns false for ``<path-var>``.
 
-For example:
+  For example:
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  set(path "/a/b")
-  cmake_path(REMOVE_FILENAME path)
-  message("First path is \"${path}\"")
+    set(path "/a/b")
+    cmake_path(REMOVE_FILENAME path)
+    message("First path is \"${path}\"")
 
-  # filename is now already empty, the following removes nothing
-  cmake_path(REMOVE_FILENAME path)
-  message("Second path is \"${path}\"")
+    # filename is now already empty, the following removes nothing
+    cmake_path(REMOVE_FILENAME path)
+    message("Second path is \"${path}\"")
 
-Output::
+  Output::
 
-  First path is "/a/"
-  Second path is "/a/"
+    First path is "/a/"
+    Second path is "/a/"
 
-.. _REPLACE_FILENAME:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>])
 
-Replaces the :ref:`filename <FILENAME_DEF>` component from ``<path-var>``
-with ``<input>``.  If ``<path-var>`` has no filename component (i.e.
-`HAS_FILENAME`_ returns false), the path is unchanged.  The operation is
-equivalent to the following:
+  Replaces the :ref:`filename <FILENAME_DEF>` component from ``<path-var>``
+  with ``<input>``.  If ``<path-var>`` has no filename component (i.e.
+  :cref:`HAS_FILENAME` returns false), the path is unchanged. The operation is
+  equivalent to the following:
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  cmake_path(HAS_FILENAME path has_filename)
-  if(has_filename)
-    cmake_path(REMOVE_FILENAME path)
-    cmake_path(APPEND path "${input}")
-  endif()
+    cmake_path(HAS_FILENAME path has_filename)
+    if(has_filename)
+      cmake_path(REMOVE_FILENAME path)
+      cmake_path(APPEND path "${input}")
+    endif()
 
-.. _REMOVE_EXTENSION:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY]
                                          [OUTPUT_VARIABLE <out-var>])
 
-Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``.
+  Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``.
 
-.. _REPLACE_EXTENSION:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input>
                                [OUTPUT_VARIABLE <out-var>])
 
-Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``.  Its effect
-is equivalent to the following:
+  Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``.  Its effect
+  is equivalent to the following:
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  cmake_path(REMOVE_EXTENSION path)
-  if(NOT input MATCHES "^\\.")
-    cmake_path(APPEND_STRING path ".")
-  endif()
-  cmake_path(APPEND_STRING path "${input}")
+    cmake_path(REMOVE_EXTENSION path)
+    if(NOT input MATCHES "^\\.")
+      cmake_path(APPEND_STRING path ".")
+    endif()
+    cmake_path(APPEND_STRING path "${input}")
 
 
 .. _Path Generation:
@@ -659,50 +626,41 @@
 Generation
 ^^^^^^^^^^
 
-.. _NORMAL_PATH:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>])
 
-Normalize ``<path-var>`` according the steps described in :ref:`Normalization`.
+  Normalizes ``<path-var>`` according the steps described in
+  :ref:`Normalization`.
 
-.. _cmake_path-RELATIVE_PATH:
-.. _RELATIVE_PATH:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>]
                                       [OUTPUT_VARIABLE <out-var>])
 
-Modifies ``<path-var>`` to make it relative to the ``BASE_DIRECTORY`` argument.
-If ``BASE_DIRECTORY`` is not specified, the default base directory will be
-:variable:`CMAKE_CURRENT_SOURCE_DIR`.
+  Modifies ``<path-var>`` to make it relative to the ``BASE_DIRECTORY`` argument.
+  If ``BASE_DIRECTORY`` is not specified, the default base directory will be
+  :variable:`CMAKE_CURRENT_SOURCE_DIR`.
 
-For reference, the algorithm used to compute the relative path is the same
-as that used by C++
-`std::filesystem::path::lexically_relative
-<https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_.
+  For reference, the algorithm used to compute the relative path is the same
+  as that used by C++
+  `std::filesystem::path::lexically_relative
+  <https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_.
 
-.. _ABSOLUTE_PATH:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE]
                                       [OUTPUT_VARIABLE <out-var>])
 
-If ``<path-var>`` is a relative path (`IS_RELATIVE`_ is true), it is evaluated
-relative to the given base directory specified by ``BASE_DIRECTORY`` option.
-If ``BASE_DIRECTORY`` is not specified, the default base directory will be
-:variable:`CMAKE_CURRENT_SOURCE_DIR`.
+  If ``<path-var>`` is a relative path (:cref:`IS_RELATIVE` is true), it is
+  evaluated relative to the given base directory specified by ``BASE_DIRECTORY``
+  option. If ``BASE_DIRECTORY`` is not specified, the default base directory
+  will be :variable:`CMAKE_CURRENT_SOURCE_DIR`.
 
-When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
-<Normalization>` after the path computation.
+  When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
+  <Normalization>` after the path computation.
 
-Because ``cmake_path()`` does not access the filesystem, symbolic links are
-not resolved and any leading tilde is not expanded.  To compute a real path
-with symbolic links resolved and leading tildes expanded, use the
-:command:`file(REAL_PATH)` command instead.
+  Because ``cmake_path()`` does not access the filesystem, symbolic links are
+  not resolved and any leading tilde is not expanded.  To compute a real path
+  with symbolic links resolved and leading tildes expanded, use the
+  :command:`file(REAL_PATH)` command instead.
 
 Native Conversion
 ^^^^^^^^^^^^^^^^^
@@ -710,89 +668,79 @@
 For commands in this section, *native* refers to the host platform, not the
 target platform when cross-compiling.
 
-.. _cmake_path-NATIVE_PATH:
-.. _NATIVE_PATH:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>)
 
-Converts a cmake-style ``<path-var>`` into a native path with
-platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
+  Converts a cmake-style ``<path-var>`` into a native path with
+  platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
 
-When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
-<Normalization>` before the conversion.
+  When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
+  <Normalization>` before the conversion.
 
 .. _CONVERT:
-.. _cmake_path-TO_CMAKE_PATH_LIST:
-.. _TO_CMAKE_PATH_LIST:
 
-.. code-block:: cmake
-
+.. signature::
   cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE])
+  :target:
+    CONVERT ... TO_CMAKE_PATH_LIST
 
-Converts a native ``<input>`` path into a cmake-style path with forward
-slashes (``/``).  On Windows hosts, the long filename marker is taken into
-account.  The input can be a single path or a system search path like
-``$ENV{PATH}``.  A search path will be converted to a cmake-style list
-separated by ``;`` characters (on non-Windows platforms, this essentially
-means ``:`` separators are replaced with ``;``).  The result of the
-conversion is stored in the ``<out-var>`` variable.
+  Converts a native ``<input>`` path into a cmake-style path with forward
+  slashes (``/``).  On Windows hosts, the long filename marker is taken into
+  account.  The input can be a single path or a system search path like
+  ``$ENV{PATH}``.  A search path will be converted to a cmake-style list
+  separated by ``;`` characters (on non-Windows platforms, this essentially
+  means ``:`` separators are replaced with ``;``).  The result of the
+  conversion is stored in the ``<out-var>`` variable.
 
-When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
-<Normalization>` before the conversion.
+  When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
+  <Normalization>` before the conversion.
 
-.. note::
-  Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
-  takes a literal string as input, not the name of a variable.
+  .. note::
+    Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
+    takes a literal string as input, not the name of a variable.
 
-.. _cmake_path-TO_NATIVE_PATH_LIST:
-.. _TO_NATIVE_PATH_LIST:
-
-.. code-block:: cmake
-
+.. signature::
   cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE])
+  :target:
+    CONVERT ... TO_NATIVE_PATH_LIST
 
-Converts a cmake-style ``<input>`` path into a native path with
-platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
-The input can be a single path or a cmake-style list.  A list will be
-converted into a native search path (``;``-separated on Windows,
-``:``-separated on other platforms).  The result of the conversion is
-stored in the ``<out-var>`` variable.
+  Converts a cmake-style ``<input>`` path into a native path with
+  platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
+  The input can be a single path or a cmake-style list.  A list will be
+  converted into a native search path (``;``-separated on Windows,
+  ``:``-separated on other platforms).  The result of the conversion is
+  stored in the ``<out-var>`` variable.
 
-When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
-<Normalization>` before the conversion.
+  When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
+  <Normalization>` before the conversion.
 
-.. note::
-  Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
-  takes a literal string as input, not the name of a variable.
+  .. note::
+    Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
+    takes a literal string as input, not the name of a variable.
 
-For example:
+  For example:
 
-.. code-block:: cmake
+  .. code-block:: cmake
 
-  set(paths "/a/b/c" "/x/y/z")
-  cmake_path(CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths)
-  message("Native path list is \"${native_paths}\"")
+    set(paths "/a/b/c" "/x/y/z")
+    cmake_path(CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths)
+    message("Native path list is \"${native_paths}\"")
 
-Output on Windows::
+  Output on Windows::
 
-  Native path list is "\a\b\c;\x\y\z"
+    Native path list is "\a\b\c;\x\y\z"
 
-Output on all other platforms::
+  Output on all other platforms::
 
-  Native path list is "/a/b/c:/x/y/z"
+    Native path list is "/a/b/c:/x/y/z"
 
 Hashing
 ^^^^^^^
 
-.. _HASH:
+.. signature::
+  cmake_path(HASH <path-var> <out-var>)
 
-.. code-block:: cmake
-
-    cmake_path(HASH <path-var> <out-var>)
-
-Compute a hash value of ``<path-var>`` such that for two paths ``p1`` and
-``p2`` that compare equal (:ref:`COMPARE ... EQUAL <COMPARE>`), the hash
-value of ``p1`` is equal to the hash value of ``p2``.  The path is always
-:ref:`normalized <Normalization>` before the hash is computed.
+  Computes a hash value of ``<path-var>`` such that for two paths ``p1`` and
+  ``p2`` that compare equal (:cref:`COMPARE ... EQUAL`), the hash value of
+  ``p1`` is equal to the hash value of ``p2``.  The path is always
+  :ref:`normalized <Normalization>` before the hash is computed.
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index c1862df..8cf7134 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -213,7 +213,7 @@
 <https://github.com/Kitware/CDash/blob/master/docs/test_measurements.md>`_
 for more information on the types of test measurements that CDash recognizes.
 
-.. versionadded: 3.22
+.. versionadded:: 3.22
   CTest can parse custom measurements from tags named
   ``<CTestMeasurement>`` or ``<CTestMeasurementFile>``. The older names
   ``<DartMeasurement>`` and ``<DartMeasurementFile>`` are still supported.
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index a2f9036..37f2b42 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -75,7 +75,8 @@
 
 ``WORKING_DIRECTORY``
  The named directory will be set as the current working directory of
- the child processes.
+ the child processes. If not given, the child processes' working directory is
+ unspecified.
 
 ``TIMEOUT``
  After the specified number of seconds (fractions allowed), all unfinished
diff --git a/Help/command/export.rst b/Help/command/export.rst
index 6668e97..9673869 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -141,7 +141,9 @@
           [VERSION_SCHEMA <string>]]
          [DEFAULT_TARGETS <target>...]
          [DEFAULT_CONFIGURATIONS <config>...]
-         [DESCRIPTION <project-description-string>]
+         [LICENSE <license-string>]
+         [DEFAULT_LICENSE <license-string>]
+         [DESCRIPTION <description-string>]
          [HOMEPAGE_URL <url-string>])
 
 .. versionadded:: 4.1
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 8a9f6e9..81f2a01 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -6,17 +6,16 @@
 This command is dedicated to file and path manipulation requiring access to the
 filesystem.
 
-For other path manipulation, handling only syntactic aspects, have a look at
+For other path manipulation, handling only syntactic aspects, see the
 :command:`cmake_path` command.
 
 .. note::
 
-  The sub-commands `RELATIVE_PATH`_, `TO_CMAKE_PATH`_ and `TO_NATIVE_PATH`_ has
-  been superseded, respectively, by sub-commands
-  :ref:`RELATIVE_PATH <cmake_path-RELATIVE_PATH>`,
-  :ref:`CONVERT ... TO_CMAKE_PATH_LIST <cmake_path-TO_CMAKE_PATH_LIST>` and
-  :ref:`CONVERT ... TO_NATIVE_PATH_LIST <cmake_path-TO_NATIVE_PATH_LIST>` of
-  :command:`cmake_path` command.
+  The sub-commands `RELATIVE_PATH`_, `TO_CMAKE_PATH`_, and `TO_NATIVE_PATH`_
+  have been superseded, respectively, by the sub-commands
+  :command:`cmake_path(RELATIVE_PATH)`,
+  :command:`cmake_path(CONVERT ... TO_CMAKE_PATH_LIST)`, and
+  :command:`cmake_path(CONVERT ... TO_NATIVE_PATH_LIST)`.
 
 Synopsis
 ^^^^^^^^
@@ -616,7 +615,9 @@
   emitted.
 
   Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if
-  creating the link fails.  It can be useful for handling situations such as
+  creating the link fails.  If the source is a directory, the destination
+  directory will be created if it does not exist, but no files will be copied
+  the from source one.  It can be useful for handling situations such as
   ``<original>`` and ``<linkname>`` being on different drives or mount points,
   which would make them unable to support a hard link.
 
diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst
index 9695ddf..a1dc5f9 100644
--- a/Help/command/find_file.rst
+++ b/Help/command/find_file.rst
@@ -4,7 +4,7 @@
 .. |FIND_XXX| replace:: find_file
 .. |NAMES| replace:: NAMES name1 [name2 ...]
 .. |SEARCH_XXX| replace:: full path to a file
-.. |SEARCH_XXX_DESC| replace:: full path to named file
+.. |SEARCH_XXX_DESC| replace:: full path to a named file
 .. |prefix_XXX_SUBDIR| replace:: ``<prefix>/include``
 .. |entry_XXX_SUBDIR| replace:: ``<entry>/include``
 
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 4dc9696..97390f7 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -141,7 +141,8 @@
                [REGISTRY_VIEW  (64|32|64_32|32_64|HOST|TARGET|BOTH)]
                [GLOBAL]
                [NO_POLICY_SCOPE]
-               [BYPASS_PROVIDER])
+               [BYPASS_PROVIDER]
+               [UNWIND_INCLUDE])
 
 The basic signature is supported by both Module and Config modes.
 The ``MODULE`` keyword implies that only Module mode can be used to find
@@ -249,6 +250,21 @@
   itself.  Future versions of CMake may detect attempts to use this keyword
   from places other than a dependency provider and halt with a fatal error.
 
+.. versionadded:: 4.2
+  The ``UNWIND_INCLUDE`` keyword is only allowed when ``find_package()`` is
+  being called within a parent call to ``find_package()``. When a call to
+  ``find_package(UNWIND_INCLUDE)`` fails to find the desired package, it begins
+  an "unwind" state. In this state further calls to ``find_package()`` and
+  :command:`include()` are forbidden, and all parent :command:`include()`
+  commands will immediately invoke :command:`return()` when their scope is
+  reached. This "unwinding" will continue until the parent ``find_package()``
+  is returned to.
+
+  ``UNWIND_INCLUDE`` is only intended to be used by calls to ``find_package()``
+  generated by :command:`install(EXPORT_PACKAGE_DEPENDENCIES)`, but may be
+  useful to those who wish to manually manage their dependencies in a similar
+  manner.
+
 .. _`full signature`:
 
 Full Signature
@@ -322,7 +338,9 @@
 specified.  If ``REQUIRED`` is specified and the package is not found, a
 fatal error is generated and the configure step stops executing.  If
 ``<PackageName>_DIR`` has been set to a directory not containing a
-configuration file, CMake will ignore it and search from scratch.
+configuration file, or if the requested version is not compatible
+with the package found in that directory (see :ref:`version selection`),
+CMake will ignore it and search from scratch.
 
 Package maintainers providing package configuration files are encouraged to
 name and install them such that the :ref:`search procedure` outlined below
@@ -581,12 +599,12 @@
 configuration file found is used, even if a newer version of the package
 resides later in the list of search paths.
 
-For search paths which contain glob expressions (``*``), the order in which
-directories matching the glob are searched is unspecified unless the
-:variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` variable is set.  This variable,
-along with the :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable,
-determines the order in which CMake considers glob matches.  For example, if
-the file system contains the package configuration files
+For search paths which contain glob expressions (``*``), directories matching
+the glob are searched in natural, descending order by default. This behavior
+can be overridden by setting variables :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`
+and :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` accordingly. Those variables
+determine the order in which CMake considers glob matches. For example, if the
+file system contains the package configuration files
 
 ::
 
@@ -594,21 +612,21 @@
   <prefix>/example-1.10/example-config.cmake
   <prefix>/share/example-2.0/example-config.cmake
 
-it is unspecified (when the aforementioned variables are unset) whether
-``find_package(example)`` will find ``example-1.2`` or ``example-1.10``
-(assuming that both are viable), but ``find_package`` will *not* find
-``example-2.0``, because one of the other two will be found first.
+then ``find_package(example)`` will (when the aforementioned variables are
+unset) pick ``example-1.10`` (assuming both ``example-1.2`` and ``example-1.10``
+are viable). Note however that ``find_package`` will *not* find ``example-2.0``,
+because one of the other two will be found first.
 
 To control the order in which ``find_package`` searches directories that match
 a glob expression, use :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` and
 :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`.
-For instance, to cause the above example to select ``example-1.10``,
+For instance, to cause the above example to select ``example-1.2``,
 one can set
 
 .. code-block:: cmake
 
   set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
-  set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
+  set(CMAKE_FIND_PACKAGE_SORT_DIRECTION ASC)
 
 before calling ``find_package``.
 
@@ -624,6 +642,15 @@
    and ``<prefix>/<name>.framework/Versions/*/Resources/CMake``.  In previous
    versions of CMake, this order was unspecified.
 
+.. versionchanged:: 4.2
+   When encountering multiple viable matches, ``find_package`` now picks the
+   one with the most recent version by default. In previous versions of CMake,
+   the result was unspecified. Accordingly, the default of
+   :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` has changed from ``NONE`` to
+   ``NATURAL`` and :variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION`
+   now defaults to ``DEC`` (descending) instead of ``ASC`` (ascending).
+
+
 .. include:: include/FIND_XXX_ROOT.rst
 .. include:: include/FIND_XXX_ORDER.rst
 
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index 52ce7f4..5984117 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -58,7 +58,8 @@
 The ``<items>`` following the ``ITEMS`` keyword are processed
 as in the first variant of the ``foreach`` command.
 The forms ``LISTS A`` and ``ITEMS ${A}`` are
-equivalent.
+equivalent. If no ``<lists>`` or ``<items>`` are given, the body
+of the loop will never be executed (i.e., it is processed as empty).
 
 The following example shows how the ``LISTS`` option is
 processed:
@@ -97,13 +98,18 @@
 command iterates over each list simultaneously setting the
 iteration variables as follows:
 
-- if the only ``loop_var`` given, then it sets a series of
+- if a single ``loop_var`` is given, then it sets a series of
   ``loop_var_N`` variables to the current item from the
   corresponding list;
-- if multiple variable names passed, their count should match
-  the lists variables count;
-- if any of the lists are shorter, the corresponding iteration
-  variable is not defined for the current iteration.
+- if multiple variable names are passed, it sets each variable to the
+  current item from the corresponding list. The number of iteration
+  variables must match the number of list variables.
+
+If no ``<lists>`` are given, the body of the loop will never be executed
+(i.e., it is processed as empty).
+
+The following example shows how the ``ZIP_LISTS`` option is
+processed:
 
 .. noqa: spellcheck off
 
diff --git a/Help/command/if.rst b/Help/command/if.rst
index 4fed570..c12ec12 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -264,7 +264,7 @@
   True if the given string or variable's value matches the given regular
   expression.  See :ref:`Regex Specification` for regex format.
 
-  .. versionadded:: 3.9
+  .. versionadded:: 2.6
    ``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
 
 .. signature:: if(<variable|string> LESS <variable|string>)
@@ -415,7 +415,7 @@
        ...
     endif()
 
-  See :ref:`cmake_path(COMPARE) <Path COMPARE>` for more details.
+  See :ref:`cmake_path(COMPARE) <Path Comparison>` for more details.
 
 Variable Expansion
 ^^^^^^^^^^^^^^^^^^
diff --git a/Help/command/include/FIND_XXX.rst b/Help/command/include/FIND_XXX.rst
index 9d063ad..194b6f8 100644
--- a/Help/command/include/FIND_XXX.rst
+++ b/Help/command/include/FIND_XXX.rst
@@ -32,11 +32,27 @@
             )
 
 This command is used to find a |SEARCH_XXX_DESC|.
-A cache entry, or a normal variable if ``NO_CACHE`` is specified,
-named by ``<VAR>`` is created to store the result of this command.
-If the |SEARCH_XXX| is found the result is stored in the variable
-and the search will not be repeated unless the variable is cleared.
-If nothing is found, the result will be ``<VAR>-NOTFOUND``.
+
+Prior to searching, |FIND_XXX| checks if variable ``<VAR>`` is defined. If
+the variable is not defined, the search will be performed. If the variable is
+defined and its value is ``NOTFOUND``, or ends in ``-NOTFOUND``, the search
+will be performed. If the variable contains any other value the search is not
+performed.
+
+  .. note::
+      ``VAR`` is considered defined if it is available in the current scope. See
+      the :ref:`cmake-language(7) variables <CMake Language Variables>`
+      documentation for details on scopes, and the interaction of normal
+      variables and cache entries.
+
+The results of the search will be stored in a cache entry named ``<VAR>``.
+Future calls to |FIND_XXX| will inspect this cache entry when specifying the
+same ``<VAR>``. This optimization ensures successful searches will not be
+repeated unless the cache entry is :command:`unset`.
+
+If the |SEARCH_XXX| is found the recorded value in cache entry ``<VAR>`` will
+be the result of the search. If nothing is found, the recorded value will be
+``<VAR>-NOTFOUND``.
 
 Options include:
 
@@ -103,8 +119,9 @@
 
   .. note::
 
-    If the variable is already set before the call (as a normal or cache
-    variable) then the search will not occur.
+    |FIND_XXX| will still check for ``<VAR>`` as usual, checking first for a
+    variable, and then a cache entry. If either indicate a previous successful
+    search, the search will not be performed.
 
   .. warning::
 
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 033c5c6..f3c4d2f 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -993,7 +993,9 @@
              [VERSION_SCHEMA <string>]]
             [DEFAULT_TARGETS <target>...]
             [DEFAULT_CONFIGURATIONS <config>...]
-            [DESCRIPTION <project-description-string>]
+            [LICENSE <license-string>]
+            [DEFAULT_LICENSE <license-string>]
+            [DESCRIPTION <description-string>]
             [HOMEPAGE_URL <url-string>]
             [PERMISSIONS <permission>...]
             [CONFIGURATIONS <config>...]
@@ -1051,7 +1053,25 @@
     configurations exists.  If not specified, CMake will fall back to the
     package's available configurations in an unspecified order.
 
-  ``DESCRIPTION <project-description-string>``
+  ``LICENSE <license-string>``
+    .. versionadded:: 4.2
+
+    A |SPDX|_ (SPDX) `License Expression`_ that describes the license(s) of the
+    project as a whole, including documentation, resources, or other materials
+    distributed with the project, in addition to software artifacts.  See the
+    SPDX `License List`_ for a list of commonly used licenses and their
+    identifiers.
+
+    The license of individual components is taken from the
+    :prop_tgt:`SPDX_LICENSE` property of their respective targets.
+
+  ``DEFAULT_LICENSE <license-string>``
+    .. versionadded:: 4.2
+
+    A |SPDX|_ (SPDX) `License Expression`_ that describes the license(s) of any
+    components which do not otherwise specify their license(s).
+
+  ``DESCRIPTION <description-string>``
     .. versionadded:: 4.1
 
     An informational description of the project.  It is recommended that this
@@ -1283,3 +1303,9 @@
 
 .. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
 .. |cps-version_schema| replace:: ``version_schema``
+
+.. _SPDX: https://spdx.dev/
+.. |SPDX| replace:: System Package Data Exchange
+
+.. _License Expression: https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/
+.. _License List: https://spdx.org/licenses/
diff --git a/Help/command/project.rst b/Help/command/project.rst
index bf0f171..a77e0b1 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -12,7 +12,8 @@
  project(<PROJECT-NAME>
          [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
          [COMPAT_VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
-         [DESCRIPTION <project-description-string>]
+         [SPDX_LICENSE <license-string>]
+         [DESCRIPTION <description-string>]
          [HOMEPAGE_URL <url-string>]
          [LANGUAGES <language-name>...])
 
@@ -106,7 +107,44 @@
     ``CMakeLists.txt``, then the compatibility version is also stored in the
     variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`.
 
-``DESCRIPTION <project-description-string>``
+``SPDX_LICENSE <license-string>``
+  .. versionadded:: 4.2
+  .. note::
+
+    Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+
+  Optional.
+  Sets the variables
+
+  * :variable:`PROJECT_SPDX_LICENSE`,
+    :variable:`<PROJECT-NAME>_SPDX_LICENSE`
+
+  to ``<license-string>``, which shall be a |SPDX|_ (SPDX)
+  `License Expression`_ that describes the license(s) of the project as a
+  whole, including documentation, resources, or other materials distributed
+  with the project, in addition to software artifacts. See the SPDX
+  `License List`_ for a list of commonly used licenses and their identifiers.
+  See the :prop_tgt:`SPDX_LICENSE` property for specifying the license(s) on
+  individual software artifacts.
+
+  .. note::
+    The project license is *not* used to initialize the
+    :prop_tgt:`SPDX_LICENSE` property of individual targets.  This allows the
+    package license and default component license, which are specified when
+    exporting package information, to be meaningful.  Only |CPS| exports make
+    use of this information.
+
+    The project license *is* inherited as the package license in some cases.
+    Refer to the ``PROJECT`` option and related documentation of the
+    :command:`export` and :command:`install` commands for more information.
+
+.. _SPDX: https://spdx.dev/
+.. |SPDX| replace:: System Package Data Exchange
+
+.. _License Expression: https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/
+.. _License List: https://spdx.org/licenses/
+
+``DESCRIPTION <description-string>``
   .. versionadded:: 3.9
 
   Optional.
@@ -114,7 +152,7 @@
 
   * :variable:`PROJECT_DESCRIPTION`, :variable:`<PROJECT-NAME>_DESCRIPTION`
 
-  to ``<project-description-string>``.
+  to ``<description-string>``.
   It is recommended that this description is a relatively short string,
   usually no more than a few words.
 
@@ -149,12 +187,11 @@
 Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
 to skip enabling any languages.
 
-The variables set through the ``VERSION``, ``COMPAT_VERSION``, ``DESCRIPTION``
-and ``HOMEPAGE_URL`` options are intended for use as default values in package
-metadata and documentation. The :command:`export` and :command:`install`
-commands use these accordingly when generating |CPS| package descriptions.
-
-.. |CPS| replace:: Common Package Specification
+The variables set through the ``VERSION``, ``COMPAT_VERSION``,
+``SPDX_LICENSE``, ``DESCRIPTION`` and ``HOMEPAGE_URL`` options are
+intended for use as default values in package metadata and documentation.
+The :command:`export` and :command:`install` commands use these accordingly
+when generating |CPS| package descriptions.
 
 .. _`Code Injection`:
 
@@ -224,3 +261,5 @@
   other commands whose behavior they may affect and for this reason the
   ``project()`` command will issue a warning if this order is not kept.
   See also policy :policy:`CMP0000`.
+
+.. |CPS| replace:: Common Package Specification
diff --git a/Help/command/set.rst b/Help/command/set.rst
index 6c1af47..12413f9 100644
--- a/Help/command/set.rst
+++ b/Help/command/set.rst
@@ -44,15 +44,16 @@
 ^^^^^^^^^^^^^^^
 
 .. signature::
-  set(<variable> <value>... CACHE <type> <docstring> [FORCE])
+  set(CACHE{<variable>} [TYPE <type>] [HELP <helpstring>...] [FORCE]
+                        VALUE [<value>...])
   :target: CACHE
 
-  Sets the given cache ``<variable>`` (cache entry).  Since cache entries
-  are meant to provide user-settable values this does not overwrite
-  existing cache entries by default.  Use the ``FORCE`` option to
-  overwrite existing entries.
+  .. versionadded:: 4.2
 
-  The ``<type>`` must be specified as one of:
+  Sets the given cache ``<variable>`` (cache entry). The options are:
+
+  ``TYPE <type>``
+    Specify the type of the cache entry. The ``<type>`` must be one of:
 
     ``BOOL``
       Boolean ``ON/OFF`` value.
@@ -77,9 +78,26 @@
       They may be used to store variables persistently across runs.
       Use of this type implies ``FORCE``.
 
-  The ``<docstring>`` must be specified as a line of text
-  providing a quick summary of the option
-  for presentation to :manual:`cmake-gui(1)` users.
+    If ``TYPE`` is not specified, if the cache variable already exist and its
+    type is not ``UNINITIALIZED``, the type previously specified will be kept
+    otherwise, ``STRING`` will be used.
+
+  ``HELP <helpstring>...``
+    The ``<helpstring>`` must be specified as a line of text providing a quick
+    summary of the option for presentation to :manual:`cmake-gui(1)` users. If
+    more than one string is given, they are concatenated into a single string
+    with no separator between them.
+
+    If ``HELP`` is not specified, an empty string will be used.
+
+  ``FORCE``
+    Since cache entries are meant to provide user-settable values this does not
+    overwrite existing cache entries by default.  Use the ``FORCE`` option to
+    overwrite existing entries.
+
+  ``VALUE <value>...``
+    List of values to be set to the cache ``<variable>``. This argument must be
+    always the last one.
 
   If the cache entry does not exist prior to the call or the ``FORCE``
   option is given then the cache entry will be set to the given value.
@@ -101,6 +119,13 @@
   then the ``set`` command will treat the path as relative to the
   current working directory and convert it to an absolute path.
 
+.. signature::
+  set(<variable> <value>... CACHE <type> <docstring> [FORCE])
+  :target: CACHE_legacy
+
+  This signature is supported for compatibility purpose. Use preferably the
+  other one.
+
 Set Environment Variable
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/command/string.rst b/Help/command/string.rst
index f540e1c..ae138e8 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -27,6 +27,7 @@
     string(`STRIP`_ <string> <out-var>)
     string(`GENEX_STRIP`_ <string> <out-var>)
     string(`REPEAT`_ <string> <count> <out-var>)
+    string(`REGEX QUOTE`_ <out-var> <input>...)
 
   `Comparison`_
     string(`COMPARE`_ <op> <string1> <string2> <out-var>)
@@ -290,6 +291,16 @@
   Produce the output string as the input ``<string>``
   repeated ``<count>`` times.
 
+.. signature::
+  string(REGEX QUOTE <out-var> <input>...)
+
+  .. versionadded:: 4.2
+
+  Store in an ``<out-var>`` a regular expression matching the ``<input>``.
+  All characters that have special meaning in a regular expression are
+  escaped, such that the output string can be used as part of a regular
+  expression to match the input literally.
+
 Comparison
 ^^^^^^^^^^
 
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
index f14a5c2..7973e1b 100644
--- a/Help/command/try_run.rst
+++ b/Help/command/try_run.rst
@@ -155,6 +155,20 @@
   the target platform.  This is created only if the
   ``RUN_OUTPUT_VARIABLE`` or ``OUTPUT_VARIABLE`` option was used.
 
+``<runResultVar>__TRYRUN_OUTPUT_STDOUT``
+  .. versionadded:: 3.25
+
+  Output from stdout if the executable were to be run on the target
+  platform.  This is created only if the ``RUN_OUTPUT_STDOUT_VARIABLE``
+  or ``RUN_OUTPUT_STDERR_VARIABLE`` option was used.
+
+``<runResultVar>__TRYRUN_OUTPUT_STDERR``
+  .. versionadded:: 3.25
+
+  Output from stderr if the executable were to be run on the target
+  platform.  This is created only if the ``RUN_OUTPUT_STDOUT_VARIABLE``
+  or ``RUN_OUTPUT_STDERR_VARIABLE`` option was used.
+
 In order to make cross compiling your project easier, use ``try_run``
 only if really required.  If you use ``try_run``, use the
 ``RUN_OUTPUT_STDOUT_VARIABLE``, ``RUN_OUTPUT_STDERR_VARIABLE``,
diff --git a/Help/command/unset.rst b/Help/command/unset.rst
index f78d01f..8512246 100644
--- a/Help/command/unset.rst
+++ b/Help/command/unset.rst
@@ -3,37 +3,54 @@
 
 Unset a variable, cache variable, or environment variable.
 
-Unset Normal Variable or Cache Entry
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Unset Normal Variable
+^^^^^^^^^^^^^^^^^^^^^
 
-.. code-block:: cmake
+.. signature::
+  unset(<variable> [PARENT_SCOPE])
+  :target: normal
 
-  unset(<variable> [CACHE | PARENT_SCOPE])
+  Removes a normal variable from the current scope, causing it
+  to become undefined.
 
-Removes a normal variable from the current scope, causing it
-to become undefined.  If ``CACHE`` is present, then a cache variable
-is removed instead of a normal variable.
-
-If ``PARENT_SCOPE`` is present then the variable is removed from the scope
-above the current scope.  See the same option in the :command:`set` command
-for further details.
+  If ``PARENT_SCOPE`` is present then the variable is removed from the scope
+  above the current scope.  See the same option in the :command:`set` command
+  for further details.
 
 .. include:: include/UNSET_NOTE.rst
 
+Unset Cache Entry
+^^^^^^^^^^^^^^^^^
+
+.. signature::
+  unset(CACHE{<variable>})
+  :target: CACHE
+
+  .. versionadded:: 4.2
+
+  Removes ``<variable>`` from the cache, causing it to become undefined.
+
+.. signature::
+  unset(<variable> CACHE)
+  :target: CACHE_legacy
+
+  This signature is supported for compatibility purpose. Use preferably the
+  other one.
+
 Unset Environment Variable
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code-block:: cmake
-
+.. signature::
   unset(ENV{<variable>})
+  :target: ENV
 
-Removes ``<variable>`` from the currently available
-:manual:`Environment Variables <cmake-env-variables(7)>`.
-Subsequent calls of ``$ENV{<variable>}`` will return the empty string.
+  Removes ``<variable>`` from the currently available
+  :manual:`Environment Variables <cmake-env-variables(7)>`.
+  Subsequent calls of ``$ENV{<variable>}`` will return the empty string.
 
-This command affects only the current CMake process, not the process
-from which CMake was called, nor the system environment at large,
-nor the environment of subsequent build or test processes.
+  This command affects only the current CMake process, not the process
+  from which CMake was called, nor the system environment at large,
+  nor the environment of subsequent build or test processes.
 
 See Also
 ^^^^^^^^
diff --git a/Help/cpack_gen/appimage.rst b/Help/cpack_gen/appimage.rst
new file mode 100644
index 0000000..42dec8e
--- /dev/null
+++ b/Help/cpack_gen/appimage.rst
@@ -0,0 +1,155 @@
+CPack AppImage Generator
+------------------------
+
+.. versionadded:: 4.2
+
+The CPack `AppImage`_ generator enables bundling an application into the
+AppImage format. It uses ``appimagetool`` to pack the application
+and ``patchelf`` to set the application ``RPATH`` to a relative path
+based on where the AppImage will be mounted.
+
+.. _`AppImage`: https://appimage.org
+
+The ``appimagetool`` does not scan for libraries dependencies.  It only
+packs the installed content and checks if the provided ``.desktop`` file
+was properly created.  For best compatibility, it's recommended to build on
+an old LTS distribution and to include any dependencies in the generated file.
+
+The snippet below can be added to your ``CMakeLists.txt`` file.
+Replace ``my_application_target`` with your application target.
+The example will do a best effort to identify the libraries your
+application links to and copy them to the install location.
+
+.. code-block:: cmake
+
+  install(CODE [[
+      file(GET_RUNTIME_DEPENDENCIES
+          EXECUTABLES $<TARGET_FILE:my_application_target>
+          RESOLVED_DEPENDENCIES_VAR resolved_deps
+      )
+
+      foreach(dep ${resolved_deps})
+          # copy the symlink
+          file(COPY ${dep} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
+
+          # Resolve the real path of the dependency (follows symlinks)
+          file(REAL_PATH ${dep} resolved_dep_path)
+
+          # Copy the resolved file to the destination
+          file(COPY ${resolved_dep_path} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
+      endforeach()
+  ]])
+
+The CPack AppImage generator will generate a default `AppRun`_ based on the
+provided ``.desktop`` entry.  Alternatively, if a custom ``AppRun`` is
+installed, e.g., via the :command:`install` command, it will be used instead
+of the generated one.
+
+.. _`AppRun`: https://docs.appimage.org/introduction/software-overview.html#apprun
+
+For Qt-based projects, it is recommended to call
+``qt_generate_deploy_app_script()`` or ``qt_generate_deploy_qml_app_script()``
+and install the files generated by the script.  This will install the
+Qt plugins.
+
+You must also set :variable:`CPACK_PACKAGE_ICON` with the same value
+listed in the Desktop file.
+
+Variables Specific to CPack AppImage Generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. variable:: CPACK_APPIMAGE_TOOL_EXECUTABLE
+
+  Name of the ``appimagetool`` executable.  If not given as an absolute path,
+  logic based on :command:`find_program` will be used internally with this
+  value to find the executable.
+
+  :Default: ``appimagetool``
+
+.. variable:: CPACK_APPIMAGE_PATCHELF_EXECUTABLE
+
+  Name of the ``patchelf`` executable.  If not given as an absolute path,
+  logic based on :command:`find_program` will be used internally with this
+  value to find the executable.
+
+  :Default: ``patchelf``
+
+.. variable:: CPACK_APPIMAGE_DESKTOP_FILE
+
+  Name of the freedesktop.org desktop file to be installed.  If not specified,
+  the first ``.desktop`` file found in the list of files to be installed will
+  be used.  There must be a valid ``.desktop`` file for the package, and it
+  must include an ``Icon`` entry that matches :variable:`CPACK_PACKAGE_ICON`
+  without the file extension.  The actual installed location of the icon
+  should follow the freedesktop.org specification.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_UPDATE_INFORMATION
+
+  Embed the value of this variable as the update information.  See the
+  ``appimagetool`` source code for the supported values and formats of the
+  ``--updateinformation`` option.  It is highly recommended to have
+  the ``zsyncmake`` tool installed if using ``zsync`` update information.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_GUESS_UPDATE_INFORMATION
+
+  When this variable is true, add the ``--guess`` option to the
+  ``appimagetool`` invocation.  This directs the tool to try to guess
+  appropriate update information based on GitHub or GitLab environment
+  variables.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_COMPRESSOR
+
+  Override the ``appimagetool``'s default type of squashfs compression (zstd).
+  This corresponds to the ``appimagetool --comp`` option.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_MKSQUASHFS_OPTIONS
+
+  List of arguments to pass through to ``mksquashfs``.  Each of these will be
+  preceded by ``--mksquashfs-opt`` on the ``appimagetool`` command line.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_NO_APPSTREAM
+
+  If set to true, do not check AppStream metadata.  This passes the
+  ``--no-appstream`` option to ``appimagetool``.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_EXCLUDE_FILE
+
+  Use the specified file as an exclude file for ``mksquashfs``,
+  in addition to ``.appimageignore``.  This uses the ``--exclude-file``
+  option to ``appimagetool``.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_RUNTIME_FILE
+
+  Specify a runtime file to use instead of letting the ``appimagetool``
+  download a runtime to embed in the generated AppImage.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_SIGN
+
+  When set to true, sign the generated AppImage with gpg[2].
+  :variable:`CPACK_APPIMAGE_SIGN_KEY` should also be specified if using this
+  option.
+
+  :Default: Unset
+
+.. variable:: CPACK_APPIMAGE_SIGN_KEY
+
+  Key ID to use for gpg[2] signatures when signing is enabled with
+  :variable:`CPACK_APPIMAGE_SIGN`.
+
+  :Default: Unset
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index 458ed93..53b1e9b 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -240,3 +240,12 @@
 
  where ``<preArgs>...`` is constructed from ``CPACK_NSIS_EXECUTABLE_PRE_ARGUMENTS``
  and ``<postArgs>...``  is constructed from ``CPACK_NSIS_EXECUTABLE_POST_ARGUMENTS``.
+
+.. variable:: CPACK_NSIS_CRC_CHECK
+
+ .. versionadded:: 4.2
+
+ Specifies whether or not the installer will perform a CRC on itself before
+ allowing an install.
+ Allowed values for this variable are ``on``, ``off``, and ``force``.
+ If not specified, the default behavior is ``on``.
diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst
index e2003ca..fce5c38 100644
--- a/Help/cpack_gen/wix.rst
+++ b/Help/cpack_gen/wix.rst
@@ -487,3 +487,13 @@
      first manually uninstall any older version.
 
  See https://docs.firegiant.com/wix3/xsd/wix/package/
+
+.. variable:: CPACK_WIX_CAB_PER_COMPONENT
+
+ .. versionadded:: 4.2
+
+ If this variable is set to true one ``.cab`` file per component is created.
+ The default is to create a single ``.cab`` file for all files in the installer.
+
+ WiX creates ``.cab`` files in parallel so multiple ``.cab`` files may be
+ desirable for faster packaging.
diff --git a/Help/dev/README.rst b/Help/dev/README.rst
index 2a2d32d..84766a6 100644
--- a/Help/dev/README.rst
+++ b/Help/dev/README.rst
@@ -40,11 +40,13 @@
 * The `CMake Documentation Guide`_.
 * The `CMake Testing Guide`_.
 * The `CMake Experimental Features Guide`_.
+* The `CMake Debugging Guide`_.
 
 .. _`CMake Source Code Guide`: source.rst
 .. _`CMake Documentation Guide`: documentation.rst
 .. _`CMake Testing Guide`: testing.rst
 .. _`CMake Experimental Features Guide`: experimental.rst
+.. _`CMake Debugging Guide`: debug.rst
 
 Maintainer Documentation
 ========================
diff --git a/Help/dev/debug.rst b/Help/dev/debug.rst
new file mode 100644
index 0000000..ded270f
--- /dev/null
+++ b/Help/dev/debug.rst
@@ -0,0 +1,197 @@
+CMake Debugging Guide
+*********************
+
+This guide explains how to attach a debugger to CMake's unit testing framework.
+We'll focus on using **GDB** on Linux for both command-line and IDE debugging.
+See documentation on `CMake Development`_ for more information.
+
+.. _`CMake Development`: README.rst
+
+Linux: Using GDB
+================
+
+On Linux, the GNU Debugger (**GDB**) is the standard tool for debugging the
+CMake test suite. The core process involves launching the ``cmake`` executable
+from within GDB with a specific set of arguments that configure and run the
+desired test.
+
+GDB Configuration
+-----------------
+
+For effective debugging, GDB must be configured to handle child processes
+correctly, which CMake tests often create. A good practice is to use a local
+``.gdbinit`` file in your build directory. This keeps CMake-specific settings
+separate from your global configuration.
+
+**1. Enable Local .gdbinit Files (One-Time Setup)**
+
+To allow GDB to automatically load configuration from your build directory,
+add the following line to your global GDB initialization file at
+``$HOME/.gdbinit``. This is a one-time setup that makes future projects easier
+to manage.
+
+.. code-block:: text
+
+  set auto-load local-gdbinit on
+
+**2. Create a Project-Specific .gdbinit**
+
+Next, create a ``.gdbinit`` file inside your CMake **build directory**.
+This file will contain settings specific to debugging CMake.
+To make this easier, you can symlink the template file provided in the CMake
+source tree:
+
+.. code-block:: bash
+
+  # Navigate to your build directory
+  cd /path/to/your/cmake/build
+
+  # Create a symlink to the template
+  ln -s $cmake_srcdir/Utilities/gdb/gdbinit-template .gdbinit
+
+The template contains the essential settings for debugging CMake tests:
+
+.. code-block:: gdb
+
+  # Allows GDB to follow child processes
+  set follow-fork-mode child
+
+  # Allows the parent process continue in parallel
+  set non-stop on
+
+Debugging from the Command Line
+-------------------------------
+
+To start debugging, first cd to the build directory. Then, launch the
+``cmake`` executable using ``gdb --args``, which passes the necessary test
+configuration arguments directly to CMake.
+
+.. note::
+
+  To get the launch command, run ``ctest -R "RunCMake.$TESTNAME" -VV -N``
+
+
+The following example runs the ``InstallPackageInfo`` test.
+
+.. code-block:: bash
+
+  # Define paths to your CMake source and build directories
+  CMAKE_SOURCE_DIR="$HOME/cmake"
+  CMAKE_BUILD_DIR="$CMAKE_SOURCE_DIR/build"
+
+  # Define the specific test to run
+  TEST_NAME="InstallPackageInfo"
+
+  # Navigate to the build directory
+  cd "$CMAKE_BUILD_DIR"
+
+  # Launch GDB with the appropriate arguments for the test
+  gdb --args ./bin/cmake \
+    "-DCMAKE_MODULE_PATH=$CMAKE_SOURCE_DIR/Tests/RunCMake" \
+    "-DRunCMake_GENERATOR=Ninja" \
+    "-DRunCMake_SOURCE_DIR=$CMAKE_SOURCE_DIR/Tests/RunCMake/$TEST_NAME" \
+    "-DRunCMake_BINARY_DIR=$CMAKE_BUILD_DIR/Tests/RunCMake/$TEST_NAME" \
+    "-P" "$CMAKE_SOURCE_DIR/Tests/RunCMake/RunCMakeTest.cmake"
+
+Once GDB loads, you may set breakpoints (e.g., ``b cmInstallCommand``) and
+then start the test by typing ``run``.
+
+Filtering Tests
+---------------
+
+Some test suites contain multiple sub-tests. To run only a specific one,
+you can use the ``RunCMake_TEST_FILTER`` environment variable.
+
+For example, to run only the "Metadata" test within the ``InstallPackageInfo``
+suite, you can set the variable before launching GDB:
+
+.. code-block:: bash
+
+  RunCMake_TEST_FILTER="Metadata" gdb --args ...
+
+Alternatively, you can set the environment variable from within the
+GDB session before running the test:
+
+.. code-block:: gdb-prompt
+
+  (gdb) set environment RunCMake_TEST_FILTER Metadata
+  (gdb) run
+
+
+IDE Integration
+---------------
+
+You can also debug CMake tests directly from your IDE.
+
+CLion
+=====
+
+If you have configured GDB to auto-load local ``.gdbinit`` files as described
+above, CLion will automatically pick up the necessary settings.
+
+A simple way to debug a test is to modify its ``CTest`` run configuration:
+
+#. **Select the Test**: In the "Run/Debug Configurations" dialog, find the
+   ``CTest`` entry for your test (e.g., ``RunCMake.InstallPackageInfo``).
+#. **Add CTest Arguments**: In the "CTest arguments" field, add
+   ``--extra-verbose``. This is helpful for debugging because it prints the
+   exact command ``CTest`` uses to run the test.
+#. **Set Working Directory**: Ensure the "Working Directory" field is set to
+   ``$CMakeCurrentLocalGenerationDir$``.
+
+You can now set breakpoints in your code and debug this configuration.
+
+Visual Studio Code
+==================
+
+Create a ``launch.json`` file in the ``.vscode`` directory of your
+CMake **source folder** with the following configuration. This configuration
+hardcodes the necessary GDB settings, so it does not depend on an external
+``.gdbinit`` file.
+
+.. code-block:: json
+
+  {
+   "version": "0.2.0",
+   "configurations": [
+     {
+       "name": "Debug CMake Test",
+       "type": "cppdbg",
+       "request": "launch",
+       "program": "${workspaceFolder}/build/bin/cmake",
+       "args": [
+         "-DCMAKE_MODULE_PATH=${workspaceFolder}/Tests/RunCMake",
+         "-DRunCMake_GENERATOR=Ninja",
+         "-DRunCMake_SOURCE_DIR=${workspaceFolder}/Tests/RunCMake/InstallPackageInfo",
+         "-DRunCMake_BINARY_DIR=${workspaceFolder}/build/Tests/RunCMake/InstallPackageInfo",
+         "-P",
+         "${workspaceFolder}/Tests/RunCMake/RunCMakeTest.cmake"
+       ],
+       "stopAtEntry": false,
+       "cwd": "${workspaceFolder}/build",
+       "environment": [],
+       "MIMode": "gdb",
+       "setupCommands": [
+         {
+           "description": "Enable pretty-printing for gdb",
+           "text": "-enable-pretty-printing",
+           "ignoreFailures": true
+         },
+         {
+           "description": "Follow child processes",
+           "text": "set follow-fork-mode child",
+           "ignoreFailures": true
+         },
+         {
+           "description": "Don't stop the parent process",
+           "text": "set non-stop on",
+           "ignoreFailures": true
+         }
+       ]
+     }
+   ]
+  }
+
+.. note::
+
+  Remember to change the test name (``InstallPackageInfo``) in the ``"args"`` section to the specific test you want to debug.
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index 81ddc8c..0c0e618 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -127,15 +127,15 @@
 set
 
 * variable ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` to
-* value ``a37d1069-1972-4901-b9c9-f194aaf2b6e0``.
+* value ``ec7aa2dc-b87f-45a3-8022-fe01c5f59984``.
 
 To enable instrumentation at the user-level, files should be placed under
 either
-``<CMAKE_CONFIG_DIR>/instrumentation-a37d1069-1972-4901-b9c9-f194aaf2b6e0`` or
-``<CMAKE_BINARY_DIR>/.cmake/instrumentation-a37d1069-1972-4901-b9c9-f194aaf2b6e0``.
+``<CMAKE_CONFIG_DIR>/instrumentation-ec7aa2dc-b87f-45a3-8022-fe01c5f59984`` or
+``<CMAKE_BINARY_DIR>/.cmake/instrumentation-ec7aa2dc-b87f-45a3-8022-fe01c5f59984``.
 
 To include instrumentation data in CTest XML files (for submission to CDash),
 you need to set the following environment variables:
 
 * ``CTEST_USE_INSTRUMENTATION=1``
-* ``CTEST_EXPERIMENTAL_INSTRUMENTATION=a37d1069-1972-4901-b9c9-f194aaf2b6e0``
+* ``CTEST_EXPERIMENTAL_INSTRUMENTATION=ec7aa2dc-b87f-45a3-8022-fe01c5f59984``
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 24ddb9a..33408c0 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -263,12 +263,12 @@
   set(CMake_VERSION_PATCH 0)
   set(CMake_VERSION_RC 0)
 
-Replace uses of ``DEVEL_CMAKE_VERSION`` in the source tree with
+Replace uses of ``CMake_VERSION_DEVEL`` in the source tree with
 the literal release version number string ``"$major.$minor.0"``:
 
 .. code-block:: shell
 
-  $EDITOR $(git grep -l DEVEL_CMAKE_VERSION)
+  $EDITOR $(git grep -l CMake_VERSION_DEVEL)
 
 Commit with a message such as::
 
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index fd8597d..d8de4e1 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -245,7 +245,7 @@
 
 * ``<cmext/iterator>``:
 
-  * ``cm::is_terator``:
+  * ``cm::is_iterator``:
     Checks if a type is an iterator type.
 
   * ``cm::is_input_iterator``:
diff --git a/Help/envvar/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst b/Help/envvar/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst
new file mode 100644
index 0000000..1aab196
--- /dev/null
+++ b/Help/envvar/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst
@@ -0,0 +1,10 @@
+CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
+---------------------------------------
+
+.. versionadded:: 4.2
+
+.. include:: include/ENV_VAR.rst
+
+``CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`` is a string specifying the
+strategy to use for autogen-related target intermediate directories. It
+initializes the :variable:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY` variable.
diff --git a/Help/envvar/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst b/Help/envvar/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst
new file mode 100644
index 0000000..4017e59
--- /dev/null
+++ b/Help/envvar/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst
@@ -0,0 +1,10 @@
+CMAKE_FASTBUILD_VERBOSE_GENERATOR
+---------------------------------
+
+.. versionadded:: 4.2
+
+.. include:: include/ENV_VAR.rst
+
+The ``CMAKE_FASTBUILD_VERBOSE_GENERATOR`` environment variable specifies a custom default
+value for the :variable:`CMAKE_FASTBUILD_VERBOSE_GENERATOR` variable in place of the
+default values specified by CMake itself.
diff --git a/Help/envvar/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst b/Help/envvar/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst
new file mode 100644
index 0000000..a3a01a7
--- /dev/null
+++ b/Help/envvar/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst
@@ -0,0 +1,10 @@
+CMAKE_INTERMEDIATE_DIR_STRATEGY
+-------------------------------
+
+.. versionadded:: 4.2
+
+.. include:: include/ENV_VAR.rst
+
+``CMAKE_INTERMEDIATE_DIR_STRATEGY`` is a string specifying the strategy to use
+for target intermediate directories. It initializes the
+:variable:`CMAKE_INTERMEDIATE_DIR_STRATEGY` variable.
diff --git a/Help/envvar/CTEST_PARALLEL_LEVEL.rst b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
index 798c79b..ba8ae4f 100644
--- a/Help/envvar/CTEST_PARALLEL_LEVEL.rst
+++ b/Help/envvar/CTEST_PARALLEL_LEVEL.rst
@@ -14,7 +14,6 @@
   parallelism, or unbounded parallelism, respectively, as documented by
   the :option:`ctest --parallel` option.
 
-  On Windows, environment variables cannot be set to an empty string.
   CTest will interpret a whitespace-only string as empty.
 
   In CMake 3.28 and earlier, an empty or ``0`` value was equivalent to ``1``.
diff --git a/Help/envvar/CTEST_USE_INSTRUMENTATION.rst b/Help/envvar/CTEST_USE_INSTRUMENTATION.rst
index 6e33845..b00c92d 100644
--- a/Help/envvar/CTEST_USE_INSTRUMENTATION.rst
+++ b/Help/envvar/CTEST_USE_INSTRUMENTATION.rst
@@ -10,6 +10,6 @@
    This feature is only available when experimental support for instrumentation
    has been enabled by the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` gate.
 
-Setting this environment variable enables
+Setting this environment variable to ``1``, ``True``, or ``ON`` enables
 :manual:`instrumentation <cmake-instrumentation(7)>` for CTest in
 :ref:`Dashboard Client` mode.
diff --git a/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst b/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst
index 95053e4..4a119aa 100644
--- a/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst
+++ b/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst
@@ -10,8 +10,9 @@
    This feature is only available when experimental support for instrumentation
    has been enabled by the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` gate.
 
-Setting this environment variable causes CTest to report the full
-command line (including arguments) to CDash for each instrumented command.
-By default, CTest truncates the command line at the first space.
+Setting this environment variable to ``1``, ``True``, or ``ON`` causes CTest to
+report the full command line (including arguments) to CDash for each
+instrumented command. By default, CTest truncates the command line at the first
+space.
 
 See also :envvar:`CTEST_USE_INSTRUMENTATION`
diff --git a/Help/generator/FASTBuild.rst b/Help/generator/FASTBuild.rst
new file mode 100644
index 0000000..f16b166
--- /dev/null
+++ b/Help/generator/FASTBuild.rst
@@ -0,0 +1,111 @@
+FASTBuild
+=========
+
+.. versionadded:: 4.2
+
+Generates a ``fbuild.bff`` file, which can be used to build the project with
+`FASTBuild <https://www.fastbuild.org/docs/home.html>`_.
+
+Usage
+-----
+
+Specify the generator when invoking :manual:`cmake(1)`:
+
+.. code-block:: shell
+
+  cmake [<options>] -G FASTBuild -B <path-to-build> [-S <path-to-source>]
+
+This writes a FASTBuild configuration file named ``fbuild.bff`` into
+``<path-to-build>``.
+
+.. note::
+
+   This generator also produces IDE project files for Visual Studio and Xcode,
+   which are placed under:
+
+   * ``<path-to-build>/VisualStudio`` – Visual Studio solution and projects
+   * ``<path-to-build>/XCode`` – Xcode workspace and projects
+
+   These IDE files can be generated by building ``xcode`` or ``solution`` targets
+   and will build using FASTBuild as the backend.
+
+Caching
+-------
+
+To enable FASTBuild caching, set the cache path using the
+:variable:`CMAKE_FASTBUILD_CACHE_PATH` variable or the
+``FASTBUILD_CACHE_PATH`` environment variable.
+
+Then build with the ``-cache`` flag:
+
+.. code-block:: console
+
+   cmake --build <path-to-build> -- -cache
+
+Compiler Behavior Variables
+---------------------------
+
+The following variables control how compiler nodes are emitted in the generated
+``fbuild.bff``. These settings may affect build determinism, debug info paths,
+include handling, and compiler argument formatting:
+
+* :variable:`CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE`
+* :variable:`CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG`
+* :variable:`CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES`
+* :variable:`CMAKE_FASTBUILD_COMPILER_EXTRA_FILES`
+* :variable:`CMAKE_FASTBUILD_FORCE_RESPONSE_FILE`
+* :variable:`CMAKE_FASTBUILD_SOURCE_MAPPING`
+* :variable:`CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS`
+* :variable:`CMAKE_FASTBUILD_USE_LIGHTCACHE`
+* :variable:`CMAKE_FASTBUILD_USE_RELATIVE_PATHS`
+
+Configuration Variables
+-----------------------
+
+The following variables can be used to configure this generator:
+
+* :variable:`CMAKE_FASTBUILD_CACHE_PATH`
+* :variable:`CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV`
+* :variable:`CMAKE_FASTBUILD_ENV_OVERRIDES`
+* :variable:`CMAKE_FASTBUILD_IDE_ARGS`
+* :variable:`CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT`
+* :variable:`CMAKE_FASTBUILD_VERBOSE_GENERATOR`
+
+Target Properties
+-----------------
+
+The following target properties can be used to fine-tune behavior on a
+per-target basis:
+
+* :prop_tgt:`FASTBUILD_CACHING` –
+  disables caching for a specific target.
+* :prop_tgt:`FASTBUILD_DISTRIBUTION` –
+  disables distributed compilation for a specific target.
+
+Notes
+-----
+
+* This generator does not support directories as outputs of custom commands.
+  If you do specify a directory as an output, it should be marked with the
+  ``SYMBOLIC`` property to avoid incorrect behavior.
+* It is highly advised to use custom commands with only one output.
+  If multiple outputs are specified, the generator will emit an additional
+  rule to check the outputs at build time. This adds overhead and is necessary
+  because FASTBuild natively supports only a single output per custom step.
+
+Example
+-------
+
+.. code-block:: shell
+
+  cmake [<options>] -G FASTBuild -B <path-to-build> -DCMAKE_BUILD_TYPE=Release
+  cmake --build <path-to-build> --target my_app
+
+This generates ``fbuild.bff`` in ``<path-to-build>`` and uses FASTBuild
+to build the ``my_app`` target.
+
+See Also
+--------
+
+* :manual:`cmake-generators(7)`
+* `FASTBuild Documentation <https://www.fastbuild.org/docs/documentation.html>`_
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
index 8b7e31d..08940d2 100644
--- a/Help/generator/Visual Studio 10 2010.rst
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -3,7 +3,7 @@
 
 Removed.  This once generated Visual Studio 10 2010 project files, but
 the generator has been removed since CMake 3.25.  It is still possible
-to build with the VS 10 2010 toolset by also installing VS 2015 (or above)
-and using the :generator:`Visual Studio 14 2015` (or above) generator with
+to build with the VS 10 2010 toolset by also installing VS 2017 (or above)
+and using the :generator:`Visual Studio 15 2017` (or above) generator with
 :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v100``,
 or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
index 99048bd..8c0f37c 100644
--- a/Help/generator/Visual Studio 11 2012.rst
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -3,7 +3,7 @@
 
 Removed.  This once generated Visual Studio 11 2012 project files, but
 the generator has been removed since CMake 3.28.  It is still possible
-to build with the VS 11 2012 toolset by also installing VS 2015 (or above)
-and using the :generator:`Visual Studio 14 2015` (or above) generator with
+to build with the VS 11 2012 toolset by also installing VS 2017 (or above)
+and using the :generator:`Visual Studio 15 2017` (or above) generator with
 :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v110``,
 or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
index 6589072..1724c0c 100644
--- a/Help/generator/Visual Studio 12 2013.rst
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -3,7 +3,7 @@
 
 Removed.  This once generated Visual Studio 12 2013 project files, but
 the generator has been removed since CMake 3.31.  It is still possible
-to build with the VS 12 2013 toolset by also installing VS 2015 (or above)
-and using the :generator:`Visual Studio 14 2015` (or above) generator with
+to build with the VS 12 2013 toolset by also installing VS 2017 (or above)
+and using the :generator:`Visual Studio 15 2017` (or above) generator with
 :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v120``,
 or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
index a491193..7e9035d 100644
--- a/Help/generator/Visual Studio 14 2015.rst
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -1,6 +1,14 @@
 Visual Studio 14 2015
 ---------------------
 
+.. deprecated:: 4.2
+
+  This generator is deprecated and will be removed in a future version
+  of CMake.  It will still be possible to build with VS 14 2015 tools
+  using the :generator:`Visual Studio 15 2017` (or above) generator
+  with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v140``, or by
+  using the :generator:`NMake Makefiles` generator.
+
 .. versionadded:: 3.1
 
 Generates Visual Studio 14 (VS 2015) project files.
diff --git a/Help/generator/Visual Studio 18 2026.rst b/Help/generator/Visual Studio 18 2026.rst
new file mode 100644
index 0000000..80127d0
--- /dev/null
+++ b/Help/generator/Visual Studio 18 2026.rst
@@ -0,0 +1,47 @@
+Visual Studio 18 2026
+---------------------
+
+.. versionadded:: 4.2
+
+Generates Visual Studio 18 (VS 2026) project files.
+
+Project Types
+^^^^^^^^^^^^^
+
+Only Visual C++ and C# projects may be generated (and Fortran with
+Intel compiler integration).  Other types of projects (JavaScript,
+Powershell, Python, etc.) are not supported.
+
+Instance Selection
+^^^^^^^^^^^^^^^^^^
+
+VS 2026 supports multiple installations on the same machine.  The
+:variable:`CMAKE_GENERATOR_INSTANCE` variable may be used to select one.
+
+Platform Selection
+^^^^^^^^^^^^^^^^^^
+
+The default target platform name (architecture) is that of the host
+and is provided in the :variable:`CMAKE_VS_PLATFORM_NAME_DEFAULT` variable.
+
+The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
+via the :option:`cmake -A` option, to specify a target platform
+name (architecture).  For example:
+
+* ``cmake -G "Visual Studio 18 2026" -A Win32``
+* ``cmake -G "Visual Studio 18 2026" -A x64``
+* ``cmake -G "Visual Studio 18 2026" -A ARM``
+* ``cmake -G "Visual Studio 18 2026" -A ARM64``
+
+Toolset Selection
+^^^^^^^^^^^^^^^^^
+
+The ``v145`` toolset that comes with VS 18 2026 is selected by default.
+The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
+via the :option:`cmake -T` option, to specify another toolset.
+
+.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
+   By default this generator uses the 64-bit variant on x64 hosts and
+   the 32-bit variant otherwise.
+
+.. include:: include/VS_TOOLSET_HOST_ARCH.rst
diff --git a/Help/generator/Visual Studio 9 2008.rst b/Help/generator/Visual Studio 9 2008.rst
index a5d953a..1e2730c 100644
--- a/Help/generator/Visual Studio 9 2008.rst
+++ b/Help/generator/Visual Studio 9 2008.rst
@@ -4,6 +4,6 @@
 Removed.  This once generated Visual Studio 9 2008 project files, but
 the generator has been removed since CMake 3.30.  It is still possible
 to build with the VS 9 2008 toolset by also installing VS 10 2010 and
-VS 2015 (or above) and using the :generator:`Visual Studio 14 2015`
+VS 2017 (or above) and using the :generator:`Visual Studio 15 2017`
 generator (or above) with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v90``,
 or by using the :generator:`NMake Makefiles` generator.
diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst
index 04ae7f9..f335e1f 100644
--- a/Help/guide/ide-integration/index.rst
+++ b/Help/guide/ide-integration/index.rst
@@ -147,7 +147,7 @@
 
 .. _CLion: https://www.jetbrains.com/clion/
 .. _KDevelop: https://kdevelop.org/
-.. _QtCreator: https://www.qt.io/product/development-tools
+.. _QtCreator: https://www.qt.io/development/tools
 .. _Vim: https://www.vim.org/
 .. _Visual Studio: https://visualstudio.microsoft.com/
 .. _VSCode: https://code.visualstudio.com/
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index b36e2e7..674bf52 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -1,473 +1,10 @@
 Step 1: A Basic Starting Point
 ==============================
 
-Where do I start with CMake? This step will provide an introduction to some of
-CMake's basic syntax, commands, and variables. As these concepts are
-introduced, we will work through three exercises and create a simple CMake
-project.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-Each exercise in this step will start with some background information. Then, a
-goal and list of helpful resources are provided. Each file in the
-``Files to Edit`` section is in the ``Step1`` directory and contains one or
-more ``TODO`` comments. Each ``TODO`` represents a line or two of code to
-change or add. The ``TODO`` s are intended to be completed in numerical order,
-first complete  ``TODO 1`` then ``TODO 2``, etc. The ``Getting Started``
-section will give some helpful hints and guide you through the exercise. Then
-the ``Build and Run`` section will walk step-by-step through how to build and
-test the exercise. Finally, at the end of each exercise the intended solution
-is discussed.
+.. only:: cmakeorg
 
-Also note that each step in the tutorial builds on the previous. For example,
-the starting code for ``Step2`` is the complete solution to ``Step1``.
-
-Exercise 1 - Building a Basic Project
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The most basic CMake project is an executable built from a single source code
-file. For simple projects like this, a ``CMakeLists.txt`` file with three
-commands is all that is required.
-
-**Note:** Although upper, lower and mixed case commands are supported by CMake,
-lower case commands are preferred and will be used throughout the tutorial.
-
-Any project's top most CMakeLists.txt must start by specifying a minimum CMake
-version using the :command:`cmake_minimum_required` command. This establishes
-policy settings and ensures that the following CMake functions are run with a
-compatible version of CMake.
-
-To start a project, we use the :command:`project` command to set the project
-name. This call is required with every project and should be called soon after
-:command:`cmake_minimum_required`. As we will see later, this command can
-also be used to specify other project level information such as the language
-or version number.
-
-Finally, the :command:`add_executable` command tells CMake to create an
-executable using the specified source code files.
-
-Goal
-----
-
-Understand how to create a simple CMake project.
-
-Helpful Resources
------------------
-
-* :command:`add_executable`
-* :command:`cmake_minimum_required`
-* :command:`project`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-
-Getting Started
-----------------
-
-The source code for ``tutorial.cxx`` is provided in the
-``Help/guide/tutorial/Step1`` directory and can be used to compute the square
-root of a number. This file does not need to be edited in this step.
-
-In the same directory is a ``CMakeLists.txt`` file which you will complete.
-Start with ``TODO 1`` and work through ``TODO 3``.
-
-Build and Run
--------------
-
-Once ``TODO 1`` through ``TODO 3`` have been completed, we are ready to build
-and run our project! First, run the :manual:`cmake <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool.
-
-For example, from the command line we could navigate to the
-``Help/guide/tutorial`` directory of the CMake source code tree and create a
-build directory:
-
-.. code-block:: console
-
-  mkdir Step1_build
-
-Next, navigate to that build directory and run
-:manual:`cmake <cmake(1)>` to configure the project and generate a native build
-system:
-
-.. code-block:: console
-
-  cd Step1_build
-  cmake ../Step1
-
-Then call that build system to actually compile/link the project:
-
-.. code-block:: console
-
-  cmake --build .
-
-For multi-config generators (e.g. Visual Studio), first navigate to the
-appropriate subdirectory, for example:
-
-.. code-block:: console
-
-  cd Debug
-
-Finally, try to use the newly built ``Tutorial``:
-
-.. code-block:: console
-
-  Tutorial 4294967296
-  Tutorial 10
-  Tutorial
-
-
-**Note:** Depending on the shell, the correct syntax may be ``Tutorial``,
-``./Tutorial`` or ``.\Tutorial``. For simplicity, the exercises will use
-``Tutorial`` throughout.
-
-Solution
---------
-
-As mentioned above, a three line ``CMakeLists.txt`` is all that we need to get
-up and running. The first line is to use :command:`cmake_minimum_required` to
-set the CMake version as follows:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 1: CMakeLists.txt
-  :name: CMakeLists.txt-cmake_minimum_required
-  :language: cmake
-  :end-before: # set the project name and version
-
-.. raw:: html
-
-  </details>
-
-The next step to make a basic project is to use the :command:`project`
-command as follows to set the project name:
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 2: CMakeLists.txt
-  :name: CMakeLists.txt-project
-
-  project(Tutorial)
-
-.. raw:: html
-
-  </details>
-
-The last command to call for a basic project is
-:command:`add_executable`. We call it as follows:
-
-.. raw:: html
-
-  <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 3: CMakeLists.txt
-  :name: CMakeLists.txt-add_executable
-  :language: cmake
-  :start-after: # add the executable
-  :end-before: # TODO 3:
-
-.. raw:: html
-
-  </details>
-
-Exercise 2 - Specifying the C++ Standard
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-CMake has some special variables that are either created behind the scenes or
-have meaning to CMake when set by project code. Many of these variables start
-with ``CMAKE_``. Avoid this naming convention when creating variables for your
-projects. Two of these special user settable variables are
-:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
-These may be used together to specify the C++ standard needed to build the
-project.
-
-Goal
-----
-
-Add a feature that requires C++11.
-
-Helpful Resources
------------------
-
-* :variable:`CMAKE_CXX_STANDARD`
-* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
-* :command:`set`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-* ``tutorial.cxx``
-
-Getting Started
----------------
-
-Continue editing files in the ``Step1`` directory. Start with ``TODO 4`` and
-complete through ``TODO 6``.
-
-First, edit ``tutorial.cxx`` by adding a feature that requires C++11. Then
-update ``CMakeLists.txt`` to require C++11.
-
-Build and Run
--------------
-
-Let's build our project again. Since we already created a build directory and
-ran CMake for Exercise 1, we can skip to the build step:
-
-.. code-block:: console
-
-  cd Step1_build
-  cmake --build .
-
-Now we can try to use the newly built ``Tutorial`` with same commands as
-before:
-
-.. code-block:: console
-
-  Tutorial 4294967296
-  Tutorial 10
-  Tutorial
-
-Solution
---------
-
-We start by adding some C++11 features to our project by replacing
-``atof`` with ``std::stod`` in ``tutorial.cxx``. This looks like
-the following:
-
-.. raw:: html
-
-  <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/tutorial.cxx
-  :caption: TODO 4: tutorial.cxx
-  :name: tutorial.cxx-cxx11
-  :language: c++
-  :start-after: // convert input to double
-  :end-before: // TODO 6:
-
-.. raw:: html
-
-  </details>
-
-To complete ``TODO 5``, simply remove ``#include <cstdlib>``.
-
-We will need to explicitly state in the CMake code that it should use the
-correct flags. One way to enable support for a specific C++ standard in CMake
-is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this tutorial, set
-the :variable:`CMAKE_CXX_STANDARD` variable in the ``CMakeLists.txt`` file to
-``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to ``True``. Make sure to
-add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
-:command:`add_executable`.
-
-.. raw:: html
-
-  <details><summary>TODO 6: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 6: CMakeLists.txt
-  :name: CMakeLists.txt-CXX_STANDARD
-  :language: cmake
-  :start-after: # specify the C++ standard
-  :end-before: # configure a header file
-
-.. raw:: html
-
-  </details>
-
-Exercise 3 - Adding a Version Number and Configured Header File
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Sometimes it may be useful to have a variable that is defined in your
-``CMakelists.txt`` file also be available in your source code. In this case, we
-would like to print the project version.
-
-One way to accomplish this is by using a configured header file. We create an
-input file with one or more variables to replace. These variables have special
-syntax which looks like ``@VAR@``.
-Then, we use the :command:`configure_file` command to copy the input file to a
-given output file and replace these variables with the current value of ``VAR``
-in the ``CMakelists.txt`` file.
-
-While we could edit the version directly in the source code, using this
-feature is preferred since it creates a single source of truth and avoids
-duplication.
-
-Goal
-----
-
-Define and report the project's version number.
-
-Helpful Resources
------------------
-
-* :variable:`<PROJECT-NAME>_VERSION_MAJOR`
-* :variable:`<PROJECT-NAME>_VERSION_MINOR`
-* :command:`configure_file`
-* :command:`target_include_directories`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-* ``tutorial.cxx``
-* ``TutorialConfig.h.in``
-
-Getting Started
----------------
-
-Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
-``TODO 12``. In this exercise, we start by adding a project version number in
-``CMakeLists.txt``. In that same file, use :command:`configure_file` to copy a
-given input file to an output file and substitute some variable values in the
-input file content.
-
-Next, create an input header file ``TutorialConfig.h.in`` defining version
-numbers which will accept variables passed from :command:`configure_file`.
-
-Finally, update ``tutorial.cxx`` to print out its version number.
-
-Build and Run
--------------
-
-Let's build our project again. As before, we already created a build directory
-and ran CMake so we can skip to the build step:
-
-.. code-block:: console
-
-  cd Step1_build
-  cmake --build .
-
-Verify that the version number is now reported when running the executable
-without any arguments.
-
-Solution
---------
-
-In this exercise, we improve our executable by printing a version number.
-While we could do this exclusively in the source code, using ``CMakeLists.txt``
-lets us maintain a single source of data for the version number.
-
-First, we modify the ``CMakeLists.txt`` file to use the
-:command:`project` command to set both the project name and version number.
-When the :command:`project` command is called, CMake defines
-``Tutorial_VERSION_MAJOR`` and ``Tutorial_VERSION_MINOR`` behind the scenes.
-
-.. raw:: html
-
-  <details><summary>TODO 7: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 7: CMakeLists.txt
-  :name: CMakeLists.txt-project-VERSION
-  :language: cmake
-  :start-after: # set the project name and version
-  :end-before: # specify the C++ standard
-
-.. raw:: html
-
-  </details>
-
-Then we used :command:`configure_file` to copy the input file with the
-specified CMake variables replaced:
-
-.. raw:: html
-
-  <details><summary>TODO 8: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 8: CMakeLists.txt
-  :name: CMakeLists.txt-configure_file
-  :language: cmake
-  :start-after: # to the source code
-  :end-before: # TODO 2:
-
-.. raw:: html
-
-  </details>
-
-Since the configured file will be written into the project binary
-directory, we must add that directory to the list of paths to search for
-include files.
-
-**Note:** Throughout this tutorial, we will refer to the project build and
-the project binary directory interchangeably. These are the same and are not
-meant to refer to a ``bin/`` directory.
-
-We used :command:`target_include_directories` to specify
-where the executable target should look for include files.
-
-.. raw:: html
-
-  <details><summary>TODO 9: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/CMakeLists.txt
-  :caption: TODO 9: CMakeLists.txt
-  :name: CMakeLists.txt-target_include_directories
-  :language: cmake
-  :start-after: # so that we will find TutorialConfig.h
-
-.. raw:: html
-
-  </details>
-
-``TutorialConfig.h.in`` is the input header file to be configured.
-When :command:`configure_file` is called from our ``CMakeLists.txt``, the
-values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will
-be replaced with the corresponding version numbers from the project in
-``TutorialConfig.h``.
-
-.. raw:: html
-
-  <details><summary>TODO 10: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/TutorialConfig.h.in
-  :caption: TODO 10: TutorialConfig.h.in
-  :name: TutorialConfig.h.in
-  :language: c++
-
-.. raw:: html
-
-  </details>
-
-Next, we need to modify ``tutorial.cxx`` to include the configured header file,
-``TutorialConfig.h``.
-
-.. raw:: html
-
-  <details><summary>TODO 11: Click to show/hide answer</summary>
-
-.. code-block:: c++
-  :caption: TODO 11: tutorial.cxx
-
-  #include "TutorialConfig.h"
-
-.. raw:: html
-
-  </details>
-
-Finally, we print out the executable name and version number by updating
-``tutorial.cxx`` as follows:
-
-.. raw:: html
-
-  <details><summary>TODO 12: Click to show/hide answer</summary>
-
-.. literalinclude:: Step2/tutorial.cxx
-  :caption: TODO 12 : tutorial.cxx
-  :name: tutorial.cxx-print-version
-  :language: c++
-  :start-after: {
-  :end-before: // convert input to double
-
-.. raw:: html
-
-  </details>
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/A%20Basic%20Starting%20Point.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding Export Configuration.rst b/Help/guide/tutorial/Adding Export Configuration.rst
index c4ab476..2708846 100644
--- a/Help/guide/tutorial/Adding Export Configuration.rst
+++ b/Help/guide/tutorial/Adding Export Configuration.rst
@@ -1,140 +1,10 @@
 Step 11: Adding Export Configuration
 ====================================
 
-During :guide:`tutorial/Installing and Testing` of the tutorial we added the
-ability for CMake to install the library and headers of the project. During
-:guide:`tutorial/Packaging an Installer` we added the ability to package up
-this information so it could be distributed to other people.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-The next step is to add the necessary information so that other CMake projects
-can use our project, be it from a build directory, a local install or when
-packaged.
+.. only:: cmakeorg
 
-The first step is to update our :command:`install(TARGETS)` commands to not
-only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword
-generates a CMake file containing code to import all targets listed in the
-install command from the installation tree. So let's go ahead and explicitly
-``EXPORT`` the ``MathFunctions`` library by updating the ``install`` command
-in ``MathFunctions/CMakeLists.txt`` to look like:
-
-.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-install-TARGETS-EXPORT
-  :language: cmake
-  :start-after: # install libs
-
-Now that we have ``MathFunctions`` being exported, we also need to explicitly
-install the generated ``MathFunctionsTargets.cmake`` file. This is done by
-adding the following to the bottom of the top-level ``CMakeLists.txt``:
-
-.. literalinclude:: Complete/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-install-EXPORT
-  :language: cmake
-  :start-after: # install the configuration targets
-  :end-before: include(CMakePackageConfigHelpers)
-
-At this point you should try and run CMake. If everything is setup properly
-you will see that CMake will generate an error that looks like:
-
-.. code-block:: console
-
-  Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains
-  path:
-
-    "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions"
-
-  which is prefixed in the source directory.
-
-CMake is telling you that during the generation of the export information
-it will export a path that is intrinsically tied to the current machine and
-will not be valid on other machines. The solution to this is to update the
-``MathFunctions`` :command:`target_include_directories` to understand that it
-needs different ``INTERFACE`` locations when being used from within the build
-directory and from an install / package. This means converting the
-:command:`target_include_directories` call for ``MathFunctions`` to look like:
-
-.. literalinclude:: Step12/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-target_include_directories
-  :language: cmake
-  :start-after: # to find MathFunctions.h, while we don't.
-  :end-before: # should we use our own math functions
-
-Once this has been updated, we can re-run CMake and verify that it doesn't
-warn anymore.
-
-At this point, we have CMake properly packaging the target information that is
-required but we will still need to generate a ``MathFunctionsConfig.cmake`` so
-that the CMake :command:`find_package` command can find our project. So let's go
-ahead and add a new file to the top-level of the project called
-``Config.cmake.in`` with the following contents:
-
-.. literalinclude:: Step12/Config.cmake.in
-  :caption: Config.cmake.in
-  :name: Config.cmake.in
-
-Then, to properly configure and install that file, add the following to the
-bottom of the top-level ``CMakeLists.txt``:
-
-.. literalinclude:: Step12/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-install-Config.cmake
-  :language: cmake
-  :start-after: # install the configuration targets
-  :end-before: # generate the config file
-
-
-Next, we execute the :command:`configure_package_config_file`.  This command
-will configure a provided file but with a few specific differences from the
-standard :command:`configure_file` way.
-To properly utilize this function, the input file should have a single line
-with the text ``@PACKAGE_INIT@`` in addition to the content that is desired.
-That variable will be replaced with a block of code which turns set values into
-relative paths.  These values which are new can be referenced by the same name
-but prepended with a ``PACKAGE_`` prefix.
-
-.. literalinclude:: Step12/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-configure-package-config.cmake
-  :language: cmake
-  :start-after: # install the configuration targets
-  :end-before: # generate the version file
-
-The :command:`write_basic_package_version_file` is next.  This command writes
-a file which is used by :command:`find_package`, documenting the version and
-compatibility of the desired package.  Here, we use the ``Tutorial_VERSION_*``
-variables and say that it is compatible with ``AnyNewerVersion``, which
-denotes that this version or any higher one are compatible with the requested
-version.
-
-.. literalinclude:: Step12/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-basic-version-file.cmake
-  :language: cmake
-  :start-after: # generate the version file
-  :end-before: # install the generated configuration files
-
-Finally, set both generated files to be installed:
-
-.. literalinclude:: Step12/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-install-configured-files.cmake
-  :language: cmake
-  :start-after: # install the generated configuration files
-  :end-before: # generate the export
-
-At this point, we have generated a relocatable CMake Configuration for our
-project that can be used after the project has been installed or packaged. If
-we want our project to also be used from a build directory we only have to add
-the following to the bottom of the top level ``CMakeLists.txt``:
-
-.. literalinclude:: Step12/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-export
-  :language: cmake
-  :start-after: # needs to be after the install(TARGETS) command
-
-With this export call we now generate a ``MathFunctionsTargets.cmake``, allowing the
-configured ``MathFunctionsConfig.cmake`` in the build directory to be used by
-other projects, without needing it to be installed.
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20Export%20Configuration.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index d2dddf7..f36f5b9 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -1,168 +1,10 @@
 Step 4: Adding Generator Expressions
-=====================================
+====================================
 
-:manual:`Generator expressions <cmake-generator-expressions(7)>` are evaluated
-during build system generation to produce information specific to each build
-configuration.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-:manual:`Generator expressions <cmake-generator-expressions(7)>` are allowed in
-the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`,
-:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others.
-They may also be used when using commands to populate those properties, such as
-:command:`target_link_libraries`, :command:`target_include_directories`,
-:command:`target_compile_definitions` and others.
+.. only:: cmakeorg
 
-:manual:`Generator expressions <cmake-generator-expressions(7)>`  may be used
-to enable conditional linking, conditional definitions used when compiling,
-conditional include directories and more. The conditions may be based on the
-build configuration, target properties, platform information or any other
-queryable information.
-
-There are different types of
-:manual:`generator expressions <cmake-generator-expressions(7)>` including
-Logical, Informational, and Output expressions.
-
-Logical expressions are used to create conditional output. The basic
-expressions are the ``0`` and ``1`` expressions. A ``$<0:...>`` results in the
-empty string, and ``$<1:...>`` results in the content of ``...``.  They can also
-be nested.
-
-Exercise 1 - Adding Compiler Warning Flags with Generator Expressions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A common usage of
-:manual:`generator expressions <cmake-generator-expressions(7)>` is to
-conditionally add compiler flags, such as those for language levels or
-warnings. A nice pattern is to associate this information to an ``INTERFACE``
-target allowing this information to propagate.
-
-Goal
-----
-
-Add compiler warning flags when building but not for installed versions.
-
-Helpful Resources
------------------
-
-* :manual:`cmake-generator-expressions(7)`
-* :command:`cmake_minimum_required`
-* :command:`set`
-* :command:`target_compile_options`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-
-Getting Started
----------------
-
-Open the file ``Step4/CMakeLists.txt`` and complete ``TODO 1`` through
-``TODO 4``.
-
-First, in the top level ``CMakeLists.txt`` file, we need to set the
-:command:`cmake_minimum_required` to ``3.15``. In this exercise we are going
-to use a generator expression which was introduced in CMake 3.15.
-
-Next we add the desired compiler warning flags that we want for our project.
-As warning flags vary based on the compiler, we use the
-``COMPILE_LANG_AND_ID`` generator expression to control which flags to apply
-given a language and a set of compiler ids.
-
-Build and Run
--------------
-
-Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
-executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
-and then build it with your chosen build tool or by using ``cmake --build .``
-from the build directory.
-
-.. code-block:: console
-
-  mkdir Step4_build
-  cd Step4_build
-  cmake ../Step4
-  cmake --build .
-
-Solution
---------
-
-Update the :command:`cmake_minimum_required` to require at least CMake
-version ``3.15``:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/CMakeLists.txt
-  :caption: TODO 1: CMakeLists.txt
-  :name: MathFunctions-CMakeLists.txt-minimum-required-step4
-  :language: cmake
-  :end-before: # set the project name and version
-
-.. raw:: html
-
-  </details>
-
-Next we determine which compiler our system is currently using to build
-since warning flags vary based on the compiler we use. This is done with
-the ``COMPILE_LANG_AND_ID`` generator expression. We set the result in the
-variables ``gcc_like_cxx`` and ``msvc_cxx`` as follows:
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/CMakeLists.txt
-  :caption: TODO 2: CMakeLists.txt
-  :name: CMakeLists.txt-compile_lang_and_id
-  :language: cmake
-  :start-after: # the BUILD_INTERFACE genex
-  :end-before: target_compile_options(tutorial_compiler_flags INTERFACE
-
-.. raw:: html
-
-  </details>
-
-Next we add the desired compiler warning flags that we want for our project.
-Using our variables ``gcc_like_cxx`` and ``msvc_cxx``, we can use another
-generator expression to apply the respective flags only when the variables are
-true. We use :command:`target_compile_options` to apply these flags to our
-interface library.
-
-.. raw:: html
-
-  <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 3: CMakeLists.txt
-  :name: CMakeLists.txt-compile_flags
-
-  target_compile_options(tutorial_compiler_flags INTERFACE
-    "$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
-    "$<${msvc_cxx}:-W3>"
-  )
-
-.. raw:: html
-
-  </details>
-
-Lastly, we only want these warning flags to be used during builds. Consumers
-of our installed project should not inherit our warning flags. To specify
-this, we wrap our flags from TODO 3 in a generator expression using the
-``BUILD_INTERFACE`` condition. The resulting full code looks like the following:
-
-.. raw:: html
-
-  <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/CMakeLists.txt
-  :caption: TODO 4: CMakeLists.txt
-  :name: CMakeLists.txt-target_compile_options-genex
-  :language: cmake
-  :start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-  :end-before: # configure a header file to pass some of the CMake settings
-
-.. raw:: html
-
-  </details>
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20Generator%20Expressions.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
index e91aa6a..e825a3b 100644
--- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
+++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
@@ -1,108 +1,10 @@
 Step 6: Adding Support for a Testing Dashboard
 ==============================================
 
-Adding support for submitting our test results to a dashboard is simple. We
-already defined a number of tests for our project in
-:ref:`Testing Support <Tutorial Testing Support>`. Now we just have to run
-those tests and submit them to CDash.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
+.. only:: cmakeorg
 
-Exercise 1 - Send Results to a Testing Dashboard
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Goal
-----
-
-Display our CTest results with CDash.
-
-Helpful Resources
------------------
-
-* :manual:`ctest(1)`
-* :command:`include`
-* :module:`CTest`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-
-Getting Started
----------------
-
-For this exercise, complete ``TODO 1`` in the top-level ``CMakeLists.txt`` by
-including the :module:`CTest` module. This will enable testing with CTest as
-well as dashboard submissions to CDash, so we can safely remove the call to
-:command:`enable_testing`.
-
-We will also need to acquire a ``CTestConfig.cmake`` file to be placed in the
-top-level directory. When run, the :manual:`ctest <ctest(1)>` executable will
-read this file to gather information about the testing dashboard. It contains:
-
-* The project "Nightly" start time
-
-  *  The time when a 24 hour "day" starts for this project.
-
-* The URL of the CDash instance where the submission's generated documents
-  will be sent
-
-For this tutorial, a public dashboard server is used and its corresponding
-``CTestConfig.cmake`` file is provided for you in this step's root directory.
-In practice, this file would be downloaded from a project's ``Settings`` page
-on the CDash instance intended to host the test results. Once downloaded from
-CDash, the file should not be modified locally.
-
-.. literalinclude:: Step7/CTestConfig.cmake
-  :caption: CTestConfig.cmake
-  :name: CTestConfig.cmake
-  :language: cmake
-
-
-Build and Run
--------------
-
-Note that as part of the CDash submission some information about your
-development system (e.g. site name or full pathnames) may displayed publicly.
-
-To create a simple test dashboard, run the :manual:`cmake <cmake(1)>`
-executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
-but do not build it yet. Instead, navigate to the build directory and run:
-
-.. code-block:: console
-
-  ctest [-VV] -D Experimental
-
-Remember, for multi-config generators (e.g. Visual Studio), the configuration
-type must be specified:
-
-.. code-block:: console
-
-  ctest [-VV] -C Debug -D Experimental
-
-Or, from an IDE, build the ``Experimental`` target.
-
-The :manual:`ctest <ctest(1)>` executable will build the project, run any
-tests, and submit the results to Kitware's public dashboard:
-https://my.cdash.org/index.php?project=CMakeTutorial.
-
-Solution
---------
-
-The only CMake code changed needed in this step was to enable dashboard
-submissions to CDash by including the :module:`CTest` module in our top-level
-``CMakeLists.txt``:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step7/CMakeLists.txt
-  :caption: TODO 1: CMakeLists.txt
-  :name: CMakeLists.txt-include-CTest
-  :language: cmake
-  :start-after: # enable testing
-  :end-before: # does the application run
-
-.. raw:: html
-
-  </details>
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20Support%20for%20a%20Testing%20Dashboard.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst
index 87070ed..b61dfba 100644
--- a/Help/guide/tutorial/Adding System Introspection.rst
+++ b/Help/guide/tutorial/Adding System Introspection.rst
@@ -1,163 +1,10 @@
 Step 7: Adding System Introspection
 ===================================
 
-Let us consider adding some code to our project that depends on features the
-target platform may not have. For this example, we will add some code that
-depends on whether or not the target platform has the ``log`` and ``exp``
-functions. Of course almost every platform has these functions but for this
-tutorial assume that they are not common.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-Exercise 1 - Assessing Dependency Availability
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. only:: cmakeorg
 
-Goal
-----
-
-Change implementation based on available system dependencies.
-
-Helpful Resources
------------------
-
-* :module:`CheckCXXSourceCompiles`
-* :command:`target_compile_definitions`
-
-Files to Edit
--------------
-
-* ``MathFunctions/CMakeLists.txt``
-* ``MathFunctions/mysqrt.cxx``
-
-Getting Started
----------------
-
-The starting source code is provided in the ``Step7`` directory. In this
-exercise, complete ``TODO 1`` through ``TODO 5``.
-
-Start by editing ``MathFunctions/CMakeLists.txt``. Include the
-:module:`CheckCXXSourceCompiles` module. Then, use
-``check_cxx_source_compiles()`` to determine whether ``log`` and ``exp`` are
-available from ``cmath``. If they are available, use
-:command:`target_compile_definitions` to specify ``HAVE_LOG`` and ``HAVE_EXP``
-as compile definitions.
-
-In the ``MathFunctions/mysqrt.cxx``, include ``cmath``. Then, if the system has
-``log`` and ``exp``, use them to compute the square root.
-
-Build and Run
--------------
-
-Make a new directory called ``Step7_build``. Run the
-:manual:`cmake  <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool and run the ``Tutorial`` executable.
-
-This can look like the following:
-
-.. code-block:: console
-
-  mkdir Step7_build
-  cd Step7_build
-  cmake ../Step7
-  cmake --build .
-
-Which function gives better results now, ``sqrt`` or ``mysqrt``?
-
-Solution
---------
-
-In this exercise we will use functions from the
-:module:`CheckCXXSourceCompiles` module so first we must include it in
-``MathFunctions/CMakeLists.txt``.
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
-  :caption: TODO 1: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-include-check_cxx_source_compiles
-  :language: cmake
-  :start-after: # does this system provide the log and exp functions?
-  :end-before: check_cxx_source_compiles
-
-.. raw:: html
-
-  </details>
-
-Then test for the availability of
-``log`` and ``exp`` using ``check_cxx_compiles_source``. This function
-lets us try compiling simple code with the required dependency prior to
-the true source code compilation. The resulting variables ``HAVE_LOG``
-and ``HAVE_EXP`` represent whether those dependencies are available.
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
-  :caption: TODO 2: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-check_cxx_source_compiles
-  :language: cmake
-  :start-after: include(CheckCXXSourceCompiles)
-  :end-before: # add compile definitions
-
-.. raw:: html
-
-  </details>
-
-Next, we need to pass these CMake variables to our source code. This way,
-our source code can tell what resources are available. If both ``log`` and
-``exp`` are available, use :command:`target_compile_definitions` to specify
-``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions.
-
-.. raw:: html
-
-  <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
-  :caption: TODO 3: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-target_compile_definitions
-  :language: cmake
-  :start-after: # add compile definitions
-  :end-before: # state
-
-.. raw:: html
-
-  </details>
-
-Since we may be using ``log`` and ``exp``, we need to modify
-``mysqrt.cxx`` to include ``cmath``.
-
-.. raw:: html
-
-  <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
-  :caption: TODO 4: MathFunctions/mysqrt.cxx
-  :name: MathFunctions/mysqrt.cxx-include-cmath
-  :language: c++
-  :start-after: #include "mysqrt.h"
-  :end-before: include <iostream>
-
-.. raw:: html
-
-  </details>
-
-If ``log`` and ``exp`` are available on the system, then use them to
-compute the square root in the ``mysqrt`` function. The ``mysqrt`` function in
-``MathFunctions/mysqrt.cxx`` will look as follows:
-
-.. raw:: html
-
-  <details><summary>TODO 5: Click to show/hide answer</summary>
-
-.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
-  :caption: TODO 5: MathFunctions/mysqrt.cxx
-  :name: MathFunctions/mysqrt.cxx-ifdef
-  :language: c++
-  :start-after: // if we have both log and exp then use them
-  :end-before: return result;
-
-.. raw:: html
-
-  </details>
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20System%20Introspection.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
index e7aff9c..81e8445 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -1,304 +1,10 @@
 Step 3: Adding Usage Requirements for a Library
 ===============================================
 
-Exercise 1 - Adding Usage Requirements for a Library
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-:ref:`Usage requirements <Target Usage Requirements>` of a target parameters
-allow for far better control over a library or executable's link and include
-line while also giving more control over the transitive property of targets
-inside CMake. The primary commands that
-leverage usage requirements are:
+.. only:: cmakeorg
 
-* :command:`target_compile_definitions`
-* :command:`target_compile_options`
-* :command:`target_include_directories`
-* :command:`target_link_directories`
-* :command:`target_link_options`
-* :command:`target_precompile_headers`
-* :command:`target_sources`
-
-
-Goal
-----
-
-Add usage requirements for a library.
-
-Helpful Materials
------------------
-
-* :variable:`CMAKE_CURRENT_SOURCE_DIR`
-
-Files to Edit
--------------
-
-* ``MathFunctions/CMakeLists.txt``
-* ``CMakeLists.txt``
-
-Getting Started
----------------
-
-In this exercise, we will refactor our code from
-:guide:`tutorial/Adding a Library` to use the modern CMake approach. We will
-let our library define its own usage requirements so they are passed
-transitively to other targets as necessary. In this case, ``MathFunctions``
-will specify any needed include directories itself. Then, the consuming target
-``Tutorial`` simply needs to link to ``MathFunctions`` and not worry about
-any additional include directories.
-
-The starting source code is provided in the ``Step3`` directory. In this
-exercise, complete ``TODO 1`` through ``TODO 3``.
-
-First, add a call to :command:`target_include_directories` in
-``MathFunctions/CMakeLists``. Remember that
-:variable:`CMAKE_CURRENT_SOURCE_DIR` is the path to the source directory
-currently being processed.
-
-Then, update (and simplify!) the call to
-:command:`target_include_directories` in the top-level ``CMakeLists.txt``.
-
-Build and Run
--------------
-
-Make a new directory called ``Step3_build``, run the :manual:`cmake
-<cmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>` to
-configure the project and then build it with your chosen build tool or by
-using :option:`cmake --build . <cmake --build>` from the build directory.
-Here's a refresher of what that looks like from the command line:
-
-.. code-block:: console
-
-  mkdir Step3_build
-  cd Step3_build
-  cmake ../Step3
-  cmake --build .
-
-Next, use the newly built ``Tutorial`` and verify that it is working as
-expected.
-
-Solution
---------
-
-Let's update the code from the previous step to use the modern CMake
-approach of usage requirements.
-
-We want to state that anybody linking to ``MathFunctions`` needs to include
-the current source directory, while ``MathFunctions`` itself doesn't. This
-can be expressed with an ``INTERFACE`` usage requirement. Remember
-``INTERFACE`` means things that consumers require but the producer doesn't.
-
-At the end of ``MathFunctions/CMakeLists.txt``, use
-:command:`target_include_directories` with the ``INTERFACE`` keyword, as
-follows:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
-  :caption: TODO 1: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
-  :language: cmake
-  :start-after: # to find MathFunctions.h
-  :end-before: # should we use our own
-
-.. raw:: html
-
-  </details>
-
-Now that we've specified usage requirements for ``MathFunctions`` we can
-safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
-``CMakeLists.txt``.
-
-Remove this line:
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: TODO 2: CMakeLists.txt
-  :name: CMakeLists.txt-remove-EXTRA_INCLUDES
-  :language: cmake
-  :start-after: add_subdirectory(MathFunctions)
-  :end-before: # add the executable
-
-.. raw:: html
-
-  </details>
-
-And remove ``EXTRA_INCLUDES`` from ``target_include_directories``:
-
-.. raw:: html
-
-  <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/CMakeLists.txt
-  :caption: TODO 3: CMakeLists.txt
-  :name: CMakeLists.txt-target_include_directories-remove-EXTRA_INCLUDES
-  :language: cmake
-  :start-after: # so that we will find TutorialConfig.h
-
-.. raw:: html
-
-  </details>
-
-Notice that with this technique, the only thing our executable target does to
-use our library is call :command:`target_link_libraries` with the name
-of the library target. In larger projects, the classic method of specifying
-library dependencies manually becomes very complicated very quickly.
-
-Exercise 2 - Setting the C++ Standard with Interface Libraries
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Now that we have switched our code to a more modern approach, let's demonstrate
-a modern technique to set properties to multiple targets.
-
-Let's refactor our existing code to use an ``INTERFACE`` library. We will
-use that library in the next step to demonstrate a common use for
-:manual:`generator expressions <cmake-generator-expressions(7)>`.
-
-Goal
-----
-
-Add an ``INTERFACE`` library target to specify the required C++ standard.
-
-Helpful Resources
------------------
-
-* :command:`add_library`
-* :command:`target_compile_features`
-* :command:`target_link_libraries`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-* ``MathFunctions/CMakeLists.txt``
-
-Getting Started
----------------
-
-In this exercise, we will refactor our code to use an ``INTERFACE`` library to
-specify the C++ standard.
-
-Start this exercise from what we left at the end of Step3 exercise 1. You will
-have to complete ``TODO 4`` through ``TODO 7``.
-
-Start by editing the top level ``CMakeLists.txt`` file. Construct an
-``INTERFACE`` library target called ``tutorial_compiler_flags`` and
-specify ``cxx_std_11`` as a target compiler feature.
-
-Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
-targets have a :command:`target_link_libraries` call to
-``tutorial_compiler_flags``.
-
-Build and Run
--------------
-
-Since we have our build directory already configured from Exercise 1, simply
-rebuild our code by calling the following:
-
-.. code-block:: console
-
-  cd Step3_build
-  cmake --build .
-
-Next, use the newly built ``Tutorial`` and verify that it is working as
-expected.
-
-Solution
---------
-
-Let's update our code from the previous step to use interface libraries
-to set our C++ requirements.
-
-To start, we need to remove the two :command:`set` calls on the variables
-:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
-The specific lines to remove are as follows:
-
-.. literalinclude:: Step3/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-CXX_STANDARD-variable-remove
-  :language: cmake
-  :start-after: # specify the C++ standard
-  :end-before: # configure a header file
-
-Next, we need to create an interface library, ``tutorial_compiler_flags``. And
-then use :command:`target_compile_features` to add the compiler feature
-``cxx_std_11``.
-
-
-.. raw:: html
-
-  <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/CMakeLists.txt
-  :caption: TODO 4: CMakeLists.txt
-  :name: CMakeLists.txt-cxx_std-feature
-  :language: cmake
-  :start-after: # specify the C++ standard
-  :end-before: # TODO 2: Create helper
-
-.. raw:: html
-
-  </details>
-
-Finally, with our interface library set up, we need to link our
-executable ``Tutorial``, our ``SqrtLibrary`` library and our ``MathFunctions``
-library to our new ``tutorial_compiler_flags`` library. Respectively, the code
-will look like this:
-
-.. raw:: html
-
-  <details><summary>TODO 5: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/CMakeLists.txt
-  :caption: TODO 5: CMakeLists.txt
-  :name: CMakeLists.txt-target_link_libraries-step4
-  :language: cmake
-  :start-after: add_executable(Tutorial tutorial.cxx)
-  :end-before: # add the binary tree to the search path for include file
-
-.. raw:: html
-
-  </details>
-
-this:
-
-.. raw:: html
-
-  <details><summary>TODO 6: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
-  :caption: TODO 6: MathFunctions/CMakeLists.txt
-  :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
-  :language: cmake
-  :start-after: # link SqrtLibrary to tutorial_compiler_flags
-  :end-before: target_link_libraries(MathFunctions
-
-.. raw:: html
-
-  </details>
-
-and this:
-
-.. raw:: html
-
-  <details><summary>TODO 7: Click to show/hide answer</summary>
-
-.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
-  :caption: TODO 7: MathFunctions/CMakeLists.txt
-  :name: MathFunctions-SqrtLibrary-target_link_libraries-step4
-  :language: cmake
-  :start-after: # link MathFunctions to tutorial_compiler_flags
-
-.. raw:: html
-
-  </details>
-
-
-With this, all of our code still requires C++ 11 to build. Notice
-though that with this method, it gives us the ability to be specific about
-which targets get specific requirements. In addition, we create a single
-source of truth in our interface library.
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20Usage%20Requirements%20for%20a%20Library.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
index c71a889..00d079d 100644
--- a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
+++ b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
@@ -1,103 +1,10 @@
 Step 8: Adding a Custom Command and Generated File
 ==================================================
 
-Suppose, for the purpose of this tutorial, we decide that we never want to use
-the platform ``log`` and ``exp`` functions and instead would like to
-generate a table of precomputed values to use in the ``mysqrt`` function.
-In this section, we will create the table as part of the build process,
-and then compile that table into our application.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-First, let's remove the check for the ``log`` and ``exp`` functions in
-``MathFunctions/CMakeLists.txt``. Then remove the check for ``HAVE_LOG`` and
-``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
-:code:`#include <cmath>`.
+.. only:: cmakeorg
 
-In the ``MathFunctions`` subdirectory, a new source file named
-``MakeTable.cxx`` has been provided to generate the table.
-
-After reviewing the file, we can see that the table is produced as valid C++
-code and that the output filename is passed in as an argument.
-
-The next step is to create ``MathFunctions/MakeTable.cmake``. Then, add the
-appropriate commands to the file to build the ``MakeTable`` executable and
-then run it as part of the build process. A few commands are needed to
-accomplish this.
-
-First, we add an executable for ``MakeTable``.
-
-.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
-  :caption: MathFunctions/MakeTable.cmake
-  :name: MathFunctions/MakeTable.cmake-add_executable-MakeTable
-  :language: cmake
-  :start-after: # first we add the executable that generates the table
-  :end-before: target_link_libraries
-
-After creating the executable, we add the ``tutorial_compiler_flags`` to our
-executable using :command:`target_link_libraries`.
-
-.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
-  :caption: MathFunctions/MakeTable.cmake
-  :name: MathFunctions/MakeTable.cmake-link-tutorial-compiler-flags
-  :language: cmake
-  :start-after: add_executable
-  :end-before: # add the command to generate
-
-Then we add a custom command that specifies how to produce ``Table.h``
-by running MakeTable.
-
-.. literalinclude:: Step9/MathFunctions/MakeTable.cmake
-  :caption: MathFunctions/MakeTable.cmake
-  :name: MathFunctions/MakeTable.cmake-add_custom_command-Table.h
-  :language: cmake
-  :start-after: # add the command to generate the source code
-
-Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
-file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
-of sources for the library ``SqrtLibrary``.
-
-.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-add_library-Table.h
-  :language: cmake
-  :start-after:   # library that just does sqrt
-  :end-before: # state that we depend on
-
-We also have to add the current binary directory to the list of include
-directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
-
-.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
-  :language: cmake
-  :start-after: # state that we depend on our bin
-  :end-before: target_link_libraries
-
-As the last step, we need to include
-``MakeTable.cmake`` at the top of the ``MathFunctions/CMakeLists.txt``.
-
-.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-include-MakeTable.cmake
-  :language: cmake
-  :start-after: # generate Table.h
-  :end-before: # library that just does sqrt
-
-Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
-``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
-
-.. literalinclude:: Step9/MathFunctions/mysqrt.cxx
-  :caption: MathFunctions/mysqrt.cxx
-  :name: MathFunctions/mysqrt.cxx
-  :language: c++
-  :start-after: // a hack square root calculation using simple operations
-
-Run the :manual:`cmake  <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool.
-
-When this project is built it will first build the ``MakeTable`` executable.
-It will then run ``MakeTable`` to produce ``Table.h``. Finally, it will
-compile ``mysqrt.cxx`` which includes ``Table.h`` to produce the
-``MathFunctions`` library.
-
-Run the Tutorial executable and verify that it is using the table.
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20a%20Custom%20Command%20and%20Generated%20File.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index 8f39da3..dffe081 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -1,455 +1,10 @@
 Step 2: Adding a Library
 ========================
 
-At this point, we have seen how to create a basic project using CMake. In this
-step, we will learn how to create and use a library in our project. We will
-also see how to make the use of our library optional.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-Exercise 1 - Creating a Library
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. only:: cmakeorg
 
-To add a library in CMake, use the :command:`add_library` command and specify
-which source files should make up the library.
-
-Rather than placing all of the source files in one directory, we can organize
-our project with one or more subdirectories. In this case, we will create a
-subdirectory specifically for our library. Here, we can add a new
-``CMakeLists.txt`` file and one or more source files. In the top level
-``CMakeLists.txt`` file, we will use the :command:`add_subdirectory` command
-to add the subdirectory to the build.
-
-Once the library is created, it is connected to our executable target with
-:command:`target_include_directories` and :command:`target_link_libraries`.
-
-Goal
-----
-
-Add and use a library.
-
-Helpful Resources
------------------
-
-* :command:`add_library`
-* :command:`add_subdirectory`
-* :command:`target_include_directories`
-* :command:`target_link_libraries`
-* :variable:`PROJECT_SOURCE_DIR`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-* ``tutorial.cxx``
-* ``MathFunctions/CMakeLists.txt``
-
-Getting Started
----------------
-
-In this exercise, we will add a library to our project that contains our own
-implementation for computing the square root of a number. The executable can
-then use this library instead of the standard square root function provided by
-the compiler.
-
-For this tutorial we will put the library into a subdirectory called
-``MathFunctions``. This directory already contains the header files
-``MathFunctions.h`` and ``mysqrt.h``. Their respective source files
-``MathFunctions.cxx`` and ``mysqrt.cxx`` are also provided. We will not need
-to modify any of these files. ``mysqrt.cxx`` has one function called
-``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
-function. ``MathFunctions.cxx`` contains one function ``sqrt`` which serves
-to hide the implementation details of ``sqrt``.
-
-From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
-complete through ``TODO 6``.
-
-First, fill in the one line ``CMakeLists.txt`` in the ``MathFunctions``
-subdirectory.
-
-Next, edit the top level ``CMakeLists.txt``.
-
-Finally, use the newly created ``MathFunctions`` library in ``tutorial.cxx``
-
-Build and Run
--------------
-
-Run the :manual:`cmake  <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool.
-
-Below is a refresher of what that looks like from the command line:
-
-.. code-block:: console
-
-  mkdir Step2_build
-  cd Step2_build
-  cmake ../Step2
-  cmake --build .
-
-Try to use the newly built ``Tutorial`` and ensure that it is still
-producing accurate square root values.
-
-Solution
---------
-
-In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
-a library target called ``MathFunctions`` with :command:`add_library`. The
-source files for the library are passed as an argument to
-:command:`add_library`. This looks like the following line:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 1: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-add_library
-
-  add_library(MathFunctions MathFunctions.cxx mysqrt.cxx)
-
-.. raw:: html
-
-  </details>
-
-To make use of the new library we will add an :command:`add_subdirectory`
-call in the top-level ``CMakeLists.txt`` file so that the library will get
-built.
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 2: CMakeLists.txt
-  :name: CMakeLists.txt-add_subdirectory
-
-  add_subdirectory(MathFunctions)
-
-.. raw:: html
-
-  </details>
-
-Next, the new library target is linked to the executable target using
-:command:`target_link_libraries`.
-
-.. raw:: html
-
-  <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 3: CMakeLists.txt
-  :name: CMakeLists.txt-target_link_libraries
-
-  target_link_libraries(Tutorial PUBLIC MathFunctions)
-
-.. raw:: html
-
-  </details>
-
-Finally we need to specify the library's header file location.
-Modify the existing :command:`target_include_directories` call
-to add the ``MathFunctions`` subdirectory as an include directory
-so that the ``MathFunctions.h`` header file can be found.
-
-.. raw:: html
-
-  <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 4: CMakeLists.txt
-  :name: CMakeLists.txt-target_include_directories-step2
-
-  target_include_directories(Tutorial PUBLIC
-                            "${PROJECT_BINARY_DIR}"
-                            "${PROJECT_SOURCE_DIR}/MathFunctions"
-                            )
-
-.. raw:: html
-
-  </details>
-
-Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
-
-.. raw:: html
-
-  <details><summary>TODO 5: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/tutorial.cxx
-  :caption: TODO 5: tutorial.cxx
-  :name: CMakeLists.txt-include-MathFunctions.h
-  :language: cmake
-  :start-after: #include <string>
-  :end-before: #include "TutorialConfig.h"
-
-.. raw:: html
-
-  </details>
-
-Lastly, replace ``sqrt`` with the wrapper function ``mathfunctions::sqrt``.
-
-.. raw:: html
-
-  <details><summary>TODO 6: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/tutorial.cxx
-  :caption: TODO 6: tutorial.cxx
-  :name: CMakeLists.txt-option
-  :language: cmake
-  :start-after:   double const inputValue = std::stod(argv[1]);
-  :end-before: std::cout
-
-.. raw:: html
-
-  </details>
-
-Exercise 2 - Adding an Option
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Now let us add an option in the MathFunctions library to allow developers to
-select either the custom square root implementation or the built in standard
-implementation. While for the tutorial
-there really isn't any need to do so, for larger projects this is a common
-occurrence.
-
-CMake can do this using the :command:`option` command. This gives users a
-variable which they can change when configuring their cmake build. This
-setting will be stored in the cache so that the user does not need to set
-the value each time they run CMake on a build directory.
-
-Goal
-----
-
-Add the option to build without ``MathFunctions``.
-
-
-Helpful Resources
------------------
-
-* :command:`if`
-* :command:`option`
-* :command:`target_compile_definitions`
-
-Files to Edit
--------------
-
-* ``MathFunctions/CMakeLists.txt``
-* ``MathFunctions/MathFunctions.cxx``
-
-Getting Started
----------------
-
-Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
-``TODO 14``.
-
-First create a variable ``USE_MYMATH`` using the :command:`option` command
-in ``MathFunctions/CMakeLists.txt``. In that same file, use that option
-to pass a compile definition to the ``MathFunctions`` library.
-
-Then, update ``MathFunctions.cxx`` to redirect compilation based on
-``USE_MYMATH``.
-
-Lastly, prevent ``mysqrt.cxx`` from being compiled when ``USE_MYMATH`` is on
-by making it its own library inside of the ``USE_MYMATH`` block of
-``MathFunctions/CMakeLists.txt``.
-
-Build and Run
--------------
-
-Since we have our build directory already configured from Exercise 1, we can
-rebuild by simply calling the following:
-
-.. code-block:: console
-
-  cd ../Step2_build
-  cmake --build .
-
-Next, run the ``Tutorial`` executable on a few numbers to verify that it's
-still correct.
-
-Now let's update the value of ``USE_MYMATH`` to ``OFF``. The easiest way is to
-use the :manual:`cmake-gui <cmake-gui(1)>` or  :manual:`ccmake <ccmake(1)>`
-if you're in the terminal. Or, alternatively, if you want to change the
-option from the command-line, try:
-
-.. code-block:: console
-
-  cmake ../Step2 -DUSE_MYMATH=OFF
-
-Now, rebuild the code with the following:
-
-.. code-block:: console
-
-  cmake --build .
-
-Then, run the executable again to ensure that it still works with
-``USE_MYMATH`` set to ``OFF``. Which function gives better results, ``sqrt``
-or ``mysqrt``?
-
-Solution
---------
-
-The first step is to add an option to ``MathFunctions/CMakeLists.txt``.
-This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
-:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
-changed by the user.
-
-.. raw:: html
-
-  <details><summary>TODO 7: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
-  :caption: TODO 7: MathFunctions/CMakeLists.txt
-  :name: CMakeLists.txt-option-library-level
-  :language: cmake
-  :start-after: # should we use our own math functions
-  :end-before: if (USE_MYMATH)
-
-.. raw:: html
-
-  </details>
-
-Next, make building and linking our library with ``mysqrt`` function
-conditional using this new option.
-
-Create an :command:`if` statement which checks the value of
-``USE_MYMATH``. Inside the :command:`if` block, put the
-:command:`target_compile_definitions` command with the compile
-definition ``USE_MYMATH``.
-
-.. raw:: html
-
-  <details><summary>TODO 8: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 8: MathFunctions/CMakeLists.txt
-  :name: CMakeLists.txt-USE_MYMATH
-
-  if (USE_MYMATH)
-    target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-  endif()
-
-.. raw:: html
-
-  </details>
-
-When ``USE_MYMATH`` is ``ON``, the compile definition ``USE_MYMATH`` will
-be set. We can then use this compile definition to enable or disable
-sections of our source code.
-
-The corresponding changes to the source code are fairly straightforward.
-In ``MathFunctions.cxx``, we make ``USE_MYMATH`` control which square root
-function is used:
-
-.. raw:: html
-
-  <details><summary>TODO 9: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
-  :caption: TODO 9: MathFunctions/MathFunctions.cxx
-  :name: MathFunctions-USE_MYMATH-if
-  :language: c++
-  :start-after: which square root function should we use?
-  :end-before: }
-
-.. raw:: html
-
-  </details>
-
-Next, we need to include ``mysqrt.h`` if ``USE_MYMATH`` is defined.
-
-.. raw:: html
-
-  <details><summary>TODO 10: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/MathFunctions.cxx
-  :caption: TODO 10: MathFunctions/MathFunctions.cxx
-  :name: MathFunctions-USE_MYMATH-if-include
-  :language: c++
-  :start-after: include <cmath>
-  :end-before: namespace mathfunctions
-
-.. raw:: html
-
-  </details>
-
-Finally, we need to include ``cmath`` now that we are using ``std::sqrt``.
-
-.. raw:: html
-
-  <details><summary>TODO 11: Click to show/hide answer</summary>
-
-.. code-block:: c++
-  :caption: TODO 11 : MathFunctions/MathFunctions.cxx
-  :name: tutorial.cxx-include_cmath
-
-  #include <cmath>
-
-.. raw:: html
-
-  </details>
-
-At this point, if ``USE_MYMATH`` is ``OFF``, ``mysqrt.cxx`` would not be used
-but it will still be compiled because the ``MathFunctions`` target has
-``mysqrt.cxx`` listed under sources.
-
-There are a few ways to fix this. The first option is to use
-:command:`target_sources` to add ``mysqrt.cxx`` from within the ``USE_MYMATH``
-block. Another option is to create an additional library within the
-``USE_MYMATH`` block which is responsible for compiling ``mysqrt.cxx``. For
-the sake of this tutorial, we are going to create an additional library.
-
-First, from within ``USE_MYMATH`` create a library called ``SqrtLibrary``
-that has sources ``mysqrt.cxx``.
-
-.. raw:: html
-
-  <details><summary>TODO 12: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
-  :caption: TODO 12 : MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-add_library-SqrtLibrary
-  :language: cmake
-  :start-after: # library that just does sqrt
-  :end-before: # TODO 7: Link
-
-.. raw:: html
-
-  </details>
-
-Next, we link ``SqrtLibrary`` onto ``MathFunctions`` when ``USE_MYMATH`` is
-enabled.
-
-.. raw:: html
-
-  <details><summary>TODO 13: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
-  :caption: TODO 13 : MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-target_link_libraries-SqrtLibrary
-  :language: cmake
-  :start-after: to tutorial_compiler_flags
-  :end-before: endif()
-
-.. raw:: html
-
-  </details>
-
-Finally, we can remove ``mysqrt.cxx`` from our ``MathFunctions`` library
-source list because it will be pulled in when ``SqrtLibrary`` is included.
-
-.. raw:: html
-
-  <details><summary>TODO 14: Click to show/hide answer</summary>
-
-.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
-  :caption: TODO 14 : MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-remove-mysqrt.cxx-MathFunctions
-  :language: cmake
-  :end-before: # TODO 1:
-
-.. raw:: html
-
-  </details>
-
-With these changes, the ``mysqrt`` function is now completely optional to
-whoever is building and using the ``MathFunctions`` library. Users can toggle
-``USE_MYMATH`` to manipulate what library is used in the build.
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Adding%20a%20Library.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Before You Begin.rst b/Help/guide/tutorial/Before You Begin.rst
new file mode 100644
index 0000000..d3d3a5b
--- /dev/null
+++ b/Help/guide/tutorial/Before You Begin.rst
@@ -0,0 +1,250 @@
+Step 0: Before You Begin
+========================
+
+The CMake tutorial consists of hands-on exercises writing and building a
+C++ project; solving progressively more complex build requirements such
+as libraries, code generators, tests, and external dependencies. Before we
+are ready to even begin the first step of that journey, we need to ensure we
+have the correct tools at hand and understand how to use them.
+
+.. note::
+  The tutorial material assumes the user has a C++20 compiler and toolchain
+  available, and at least a beginner understanding of the C++ language. It
+  is impossible to cover here all the possible ways one might acquire these
+  prerequisites.
+
+This prerequisite step provides recommendations for how to acquire and
+run CMake itself in order to carry out the rest of the tutorial. If you're
+already familiar with the basics of how to run CMake, you can feel free to move
+on to the rest of the tutorial.
+
+Getting the Tutorial Exercises
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. include:: include/source.rst
+
+|tutorial_source|
+Each step of the tutorial has a corresponding subfolder, which serves as the
+starting point for that step's exercises.
+
+Getting CMake
+^^^^^^^^^^^^^
+
+The most obvious way to get your hands on CMake is to download it from the
+CMake website. `The website's "Download" section <https://cmake.org/download/>`_
+contains the latest builds of CMake for all common (and some uncommon) desktop
+platforms.
+
+However, it is preferable to acquire CMake via the usual delivery mechanism for
+developer tools on your platform. CMake is available in most packaging
+repositories, as a Visual Studio component, and can even be installed from the
+Python package index. Additionally, CMake is often available as part of the base
+image of most CI/CD runners targeting C/C++. You should consult the documentation
+for your software build environment to see if CMake is already available.
+
+CMake can also be compiled from source using the instructions described by
+``README.rst``, found in the root of the CMake source tree.
+
+CMake, like any program, needs to be available in ``PATH`` in order to be run
+from a shell. You can verify CMake is available by running any CMake command.
+
+.. code-block:: shell
+
+  $ cmake --version
+  cmake version 3.23.5
+
+  CMake suite maintained and supported by Kitware (kitware.com/cmake).
+
+
+.. note::
+  If using a Visual Studio-provided development environment, it is best to run
+  CMake from inside a Developer Command Prompt or Developer Powershell. This
+  ensures CMake has access to all the required developer tooling and
+  environment variables.
+
+CMake Generators
+^^^^^^^^^^^^^^^^
+
+CMake is a configuration program, sometimes called a "meta" build system. As
+with other configuration systems, CMake is not ultimately responsible for
+running the commands which produce the software build. Instead, CMake generates
+a build system based on project, environment, and user-provided configuration
+information.
+
+CMake supports multiple build systems as the output of this configuration
+process. These output backends are called "generators", because they generate
+the build system. CMake supports many generators, the documentation for
+which can be found at :manual:`cmake-generators(7)`. Information about
+supported generators for your particular CMake installation can be found
+via :option:`cmake --help` under the "Generators" heading.
+
+Using CMake thus requires one of the build programs which consumes this
+generator output be available. The ``Unix Makefiles``, ``Ninja``, and
+``Visual Studio`` generators require a compatible ``make``, ``ninja``, and
+``Visual Studio`` installation respectively.
+
+.. note::
+  The default generator on Windows is typically the newest available Visual
+  Studio version on the machine running CMake, everywhere else it is
+  ``Unix Makefiles``.
+
+Which generator is used can be controlled via the :envvar:`CMAKE_GENERATOR`
+environment variable, or the :option:`cmake -G` option.
+
+Single and Multi-Configuration Generators
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In many cases, it is possible to treat the underlying build system as an
+implementation detail and not differentiate between, for example, ``ninja``
+and ``make`` when using CMake. However, there is one significant property
+of a given generator which we need to be aware of for even trivial workflows:
+if the generator supports single configuration builds, or if it supports
+multi-configuration builds.
+
+Software builds often have several variants which we might be interested in.
+These variants have names like ``Debug``, ``Release``, ``RelWithDebInfo``, and
+``MinSizeRel``, with properties corresponding to the name of the given variant.
+
+A single-configuration build system always builds the software the same way, if
+it is generated to produce ``Debug`` builds it will always produce
+a ``Debug`` build. A multi-configuration build system can produce different
+outputs depending on the configuration specified at build time.
+
+.. note::
+  The terms **build configuration** and **build type** are synonymous. When
+  dealing with single-configuration generators, which only support a single
+  variant, the generated variant is usually called the "build type".
+
+  When dealing with multi-configuration generators, the available variants are
+  usually called the "build configurations". Selecting a variant at build
+  time is usually called "selecting a configuration" and referred to by flags
+  and variables as the "config".
+
+  However, this convention is not universal. Both technical and colloquial
+  documentation often mix the two terms. *Configuration* and *config* are
+  considered the more correct in contexts which generically address both single
+  and multi-configuration generators.
+
+The commonly used generators are as follows:
+
++-----------------------------+---------------------------------+
+| Single-Configuration        | Multi-Configuration             |
++=============================+=================================+
+| :generator:`Ninja`          | :generator:`Ninja Multi-Config` |
++-----------------------------+---------------------------------+
+| :generator:`Unix Makefiles` | Visual Studio (all versions)    |
++-----------------------------+---------------------------------+
+| :generator:`FASTBuild`      | :generator:`Xcode`              |
++-----------------------------+---------------------------------+
+
+When using a single-configuration generator, the build type is selected based on
+the :envvar:`CMAKE_BUILD_TYPE` environment variable, or can be specified
+directly when invoking CMake via ``cmake -DCMAKE_BUILD_TYPE=<config>``.
+
+.. note::
+  For the purpose of the tutorial, it is generally unnecessary to specify a
+  build type when working with single-configuration generators. The
+  platform-specific default behavior will work for all exercises.
+
+When using a multi-configuration generator, the build configuration is specified
+at build time using either a build-system specific mechanism, or via the
+:option:`cmake --build --config <cmake--build --config>` option.
+
+Other Usage Basics
+^^^^^^^^^^^^^^^^^^
+
+The rest of the tutorial will cover the remaining usage basics in greater depth,
+but for the purpose of ensuring we have a working development environment a few
+more CMake option flags will be enumerated here.
+
+
+  :option:`cmake -S \<dir\> <cmake -S>`
+    Specifies the project root directory, where CMake will find the project
+    to be built. This contains the root ``CMakeLists.txt`` file which will
+    be discussed in Step 1 of the tutorial.
+
+    When unspecified, defaults to the current working directory.
+
+  :option:`cmake -B \<dir\> <cmake -B>`
+    Specifies the build directory, where CMake will output the files for the
+    generated build system, as well as artifacts of the build itself when
+    the build system is run.
+
+    When unspecified, defaults to the current working directory.
+
+  :option:`cmake --build \<dir\> <cmake --build>`
+    Runs the build system in the specified build directory. This is a generic
+    command for all generators. For multi-configuration generators, the desired
+    configuration can be requested via:
+
+    ``cmake --build <dir> --config <cfg>``
+
+Try It Out
+^^^^^^^^^^
+
+The ``Help/guide/tutorial/Step0`` directory contains a simple "Hello World"
+C++ project. The specifics of how CMake configures this project will be
+discussed in Step 1 of the tutorial, we need only concern ourselves with
+running the CMake program itself.
+
+As described above, there are many possible ways we could run CMake depending
+on which generator we want to use for the build. If we navigate to the
+``Help/guide/tutorial/Step0`` directory and run:
+
+.. code-block:: shell
+
+  cmake -B build
+
+CMake will generate a build system for the Step0 project into
+``Help/guide/tutorial/Step0/build`` using the default generator for the
+platform. Alternatively we can specify a specific generator, ``Ninja`` for
+example, with:
+
+.. code-block:: shell
+
+  cmake -G Ninja -B build
+
+The effect is similar, but will use the ``Ninja`` generator instead of the
+platform default.
+
+.. note::
+  We can't reuse the build directory with different generators. It is necessary
+  to delete the build directory between CMake runs if you want to switch to a
+  different generator using the same build directory.
+
+How we build and run the project after generating the build system depends on
+the kind of generator we're using. If it is a single-configuration generator on
+a non-Windows platform, we can simply do:
+
+.. code-block:: shell
+
+  cmake --build build
+  ./build/hello
+
+.. note::
+  On Windows we might need to specify the file extension depending on which
+  shell is in use, ie ``./build/hello.exe``
+
+If we're using a multi-configuration generator, we will want to specify the
+build configuration. The default configurations are ``Debug``, ``Release``,
+``RelWithDebInfo``, and ``MinRelSize``. The result of the build will be stored
+in a configuration-specific subdirectory of the build folder. So for example we
+could run:
+
+.. code-block:: shell
+
+  cmake --build build --config Debug
+  ./build/Debug/hello
+
+Getting Help and Additional Resources
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For help from the CMake community, you can reach out on
+`the CMake Discourse Forums <https://discourse.cmake.org/>`_.
+
+.. only:: cmakeorg
+
+  For professional training related to CMake, please see
+  `the CMake training landing page <https://www.kitware.com/courses/cmake-training/>`_.
+  For other professional CMake services,
+  `please reach out to us using our contact form <https://www.kitware.com/contact/>`_.
diff --git a/Help/guide/tutorial/CMake Language Fundamentals.rst b/Help/guide/tutorial/CMake Language Fundamentals.rst
new file mode 100644
index 0000000..e5dc68d
--- /dev/null
+++ b/Help/guide/tutorial/CMake Language Fundamentals.rst
@@ -0,0 +1,583 @@
+Step 2: CMake Language Fundamentals
+===================================
+
+In the previous step we rushed through and handwaved several aspects of the
+CMake language which is used within ``CMakeLists.txt`` in order to get useful,
+building programs as soon as possible. However, in the wild we encounter
+a great deal more complexity than simply describing lists of source and
+header files.
+
+To deal with this complexity CMake provides a Turing-complete domain-specific
+language for describing the process of building software. Understanding the
+fundamentals of this language will be necessary as we write more complex
+CMLs and other CMake files. The language is formally known as
+":manual:`CMake Language <cmake-language(7)>`", or more colloquially as CMakeLang.
+
+.. note::
+  The CMake Language is not well suited to describing things which are not
+  related to building software. While it has some features for general purpose
+  use, developers should use caution when solving problems not directly related
+  to their build in CMake Language.
+
+  Oftentimes the correct answer is to write a tool in a general purpose
+  programming language which solves the problem, and teach CMake how to invoke
+  that tool as part of the build process. Code generation, cryptographic
+  signature utilities, and even ray-tracers have been written in CMake Language,
+  but this is not a recommended practice.
+
+Because we want to fully explore the language features, this step is an
+exception to the tutorial sequencing. It neither builds on ``Step1``, nor is the
+starting point for ``Step3``. This will be a sandbox to explore language
+features without building any software. We'll pick back up with the Tutorial
+program in ``Step3``.
+
+.. note::
+  This tutorial endeavors to demonstrate best practices and solutions to real
+  problems. However, for this one step we're going to be re-implementing some
+  built-in CMake functions. In "real life", do not write your own
+  :command:`list(APPEND)`.
+
+Background
+^^^^^^^^^^
+
+The only fundamental types in CMakeLang are strings and lists. Every object in
+CMake is a string, and lists are themselves strings which contain semicolons
+as separators. Any command which appears to operate on something other than a
+string, whether they be booleans, numbers, JSON objects, or otherwise, is in
+fact consuming a string, doing some internal conversion logic (in a language
+other than CMakeLang), and then converting back to a string for any potential
+output.
+
+We can create a variable, which is to say a name for a string, using the
+:command:`set` command.
+
+.. code-block:: cmake
+
+  set(var "World!")
+
+A variable's value can be accessed using brace expansion, for example if we want
+to use the :command:`message` command to print the string named by ``var``.
+
+.. code-block:: cmake
+
+  set(var "World!")
+  message("Hello ${var}")
+
+.. code-block:: console
+
+  $ cmake -P CMakeLists.txt
+  Hello World!
+
+.. note::
+  :option:`cmake -P` is called "script mode", it informs CMake this file is not
+  intended to have a :command:`project` command. We're not building any
+  software, instead using CMake only as a command interpreter.
+
+Because CMakeLang has only strings, conditionals are entirely by convention of
+which strings are considered true and which are considered false. These are
+*supposed* to be intuitive, "True", "On", "Yes", and (strings representing)
+non-zero numbers are truthy, while "False" "Off", "No", "0", "Ignore",
+"NotFound", and the empty string are all considered false.
+
+However, some of the rules are more complex than that, so taking some time
+to consult the :command:`if` documentation on expressions is worthwhile. It's
+recommended to stick to a single pair for a given context, such as
+"True"/"False" or "On"/"Off".
+
+As mentioned, lists are strings containing semicolons. The :command:`list`
+command is useful for manipulating these, and many structures within CMake
+expect to operate with this convention. As an example, we can use the
+:command:`foreach` command to iterate over a list.
+
+.. code-block:: cmake
+
+  set(stooges "Moe;Larry")
+  list(APPEND stooges "Curly")
+
+  message("Stooges contains: ${stooges}")
+
+  foreach(stooge IN LISTS stooges)
+    message("Hello, ${stooge}")
+  endforeach()
+
+.. code-block:: console
+
+  $ cmake -P CMakeLists.txt
+  Stooges contains: Moe;Larry;Curly
+  Hello, Moe
+  Hello, Larry
+  Hello, Curly
+
+Exercise 1 - Macros, Functions, and Lists
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+CMake allows us to craft our own functions and macros. This can be very helpful
+when constructing lots of similar targets, like tests, for which we will want
+to call similar sets of commands over and over again. We do so with
+:command:`function` and :command:`macro`.
+
+.. code-block:: cmake
+
+  macro(MyMacro MacroArgument)
+    message("${MacroArgument}\n\t\tFrom Macro")
+  endmacro()
+
+  function(MyFunc FuncArgument)
+    MyMacro("${FuncArgument}\n\tFrom Function")
+  endfunction()
+
+  MyFunc("From TopLevel")
+
+.. code-block:: console
+
+  $ cmake -P CMakeLists.txt
+  From TopLevel
+        From Function
+                From Macro
+
+Like with many languages, the difference between functions and macros is one
+of scope. In CMakeLang, both :command:`function` and :command:`macro` can "see"
+all the variables created in all the frames above them. However, a
+:command:`macro` acts semantically like a text replacement, similar to C/C++
+macros, so any side effects the macro creates are visible in their calling
+context. If we create or change a variable in a macro, the caller will see the
+change.
+
+:command:`function` creates its own variable scope, so side effects are not
+visible to the caller. In order to propagate changes to the parent which called
+the function, we must use ``set(<var> <value> PARENT_SCOPE)``, which works the
+same as :command:`set` but for variables belonging to the caller's context.
+
+.. note::
+  In CMake 3.25, the :command:`return(PROPAGATE)` option was added, which
+  works the same as :command:`set(PARENT_SCOPE)` but provides slightly better
+  ergonomics.
+
+While not necessary for this exercise, it bears mentioning that :command:`macro`
+and :command:`function` both support variadic arguments via the ``ARGV``
+variable, a list containing all arguments passed to the command, and the
+``ARGN`` variable, containing all arguments past the last expected argument.
+
+We're not going to build any targets in this exercise, so instead we'll
+construct our own version of :command:`list(APPEND)`, which adds a value to a
+list.
+
+Goal
+----
+
+Implement a macro and a function which append a value to a list, without using
+the :command:`list(APPEND)` command.
+
+The desired usage of these commands is as follows:
+
+.. code-block:: cmake
+
+  set(Letters "Alpha;Beta")
+  MacroAppend(Letters "Gamma")
+  message("Letters contains: ${Letters}")
+
+.. code-block:: console
+
+  $ cmake -P Exercise1.cmake
+  Letters contains: Alpha;Beta;Gamma
+
+.. note::
+  The extension for these exercises is ``.cmake``, that's the standard extension
+  for CMakeLang files when not contained in a ``CMakeLists.txt``
+
+Helpful Resources
+-----------------
+
+* :command:`macro`
+* :command:`function`
+* :command:`set`
+* :command:`if`
+
+Files to Edit
+-------------
+
+* ``Exercise1.cmake``
+
+Getting Started
+----------------
+
+The source code for ``Exercise1.cmake`` is provided in the
+``Help/guide/tutorial/Step2`` directory. It contains tests to verify the
+append behavior described above.
+
+.. note::
+  You're not expected to handle the case of an empty or undefined list to
+  append to. However, as a bonus, the case is tested if you want to try out
+  your understanding of CMakeLang conditionals.
+
+Complete ``TODO 1`` and ``TODO 2``.
+
+Build and Run
+-------------
+
+We're going to use script mode to run these exercises. First navigate to the
+``Help/guide/tutorial/Step2`` folder then you can run the code with:
+
+.. code-block:: console
+
+  cmake -P Exercise1.cmake
+
+The script will report if the commands were implemented correctly.
+
+Solution
+--------
+
+This problem relies on an understanding of the mechanisms of CMake variables.
+CMake variables are names for strings; or put another way, a CMake variable
+is itself a string which can brace expand into a different string.
+
+This leads to a common pattern in CMake code where functions and macros aren't
+passed values, but rather, they are passed the names of variables which contain
+those values. Thus ``ListVar`` does not contain the *value* of the list we need
+to append to, it contains the *name* of a list, which contains the value we
+need to append to.
+
+When expanding the variable with ``${ListVar}``, we will get the name of the
+list. If we expand that name with ``${${ListVar}}``, we will get the values
+the list contains.
+
+To implement ``MacroAppend``, we need only combine this understanding of
+``ListVar`` with our knowledge of the :command:`set` command.
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 1: Exercise1.cmake
+  :name: Exercise1.cmake-MacroAppend
+
+  macro(MacroAppend ListVar Value)
+    set(${ListVar} "${${ListVar}};${Value}")
+  endmacro()
+
+.. raw:: html
+
+  </details>
+
+We don't need to worry about scope here, because a macro operates in the same
+scope as its parent.
+
+``FuncAppend`` is almost identical, in fact it could be implemented in the
+same one liner but with an added ``PARENT_SCOPE``, but the instructions ask
+us to implement it in terms of ``MacroAppend``.
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 2: Exercise1.cmake
+  :name: Exercise1.cmake-FuncAppend
+
+  function(FuncAppend ListVar Value)
+    MacroAppend(${ListVar} ${Value})
+    set(${ListVar} "${${ListVar}}" PARENT_SCOPE)
+  endfunction()
+
+.. raw:: html
+
+  </details>
+
+``MacroAppend`` transforms ``ListVar`` for us, but it won't propagate the result
+to the parent scope. Because this is a function, we need to do so ourselves
+with :command:`set(PARENT_SCOPE)`.
+
+Exercise 2 - Conditionals and Loops
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The two most common flow control elements in any structured programming
+language are conditionals and their close sibling loops. CMakeLang is no
+different. As previously mentioned, the truthiness of a given CMake string is a
+convention established by the :command:`if` command.
+
+When given a string, :command:`if` will first check if it is one of the known
+constant values previously discussed. If the string isn't one of those values
+the command assumes it is a variable, and checks the brace-expanded contents of
+that variable to determine the result of the conditional.
+
+.. code-block:: cmake
+
+  if(True)
+    message("Constant Value: True")
+  else()
+    message("Constant Value: False")
+  endif()
+
+  if(ConditionalValue)
+    message("Undefined Variable: True")
+  else()
+    message("Undefined Variable: False")
+  endif()
+
+  set(ConditionalValue True)
+
+  if(ConditionalValue)
+    message("Defined Variable: True")
+  else()
+    message("Defined Variable: False")
+  endif()
+
+.. code-block:: console
+
+  $ cmake -P ConditionalValue.cmake
+  Constant Value: True
+  Undefined Variable: False
+  Defined Variable: True
+
+.. note::
+    This is a good a time as any to discuss quoting in CMake. All objects in
+    CMake are strings, thus the double quote, ``"``, is often unnecessary.
+    CMake knows the object is a string, everything is a string.
+
+    However, it is needed in some contexts. Strings containing whitespace require
+    double quotes, else they are treated like lists; CMake will concatenate the
+    elements together with semicolons. The reverse is also true, when
+    brace-expanding lists it is necessary to do so inside quotes if we want to
+    *preserve* the semicolons. Otherwise CMake will expand the list items into
+    space-separate strings.
+
+    A handful of commands, such as :command:`if`, recognize the difference
+    between quoted and unquoted strings. :command:`if` will only check that the
+    given string represents a variable when the string is unquoted.
+
+Finally, :command:`if` provides several useful comparison modes such as
+``STREQUAL`` for string matching, ``DEFINED`` for checking the existence of
+a variable, and ``MATCHES`` for regular expression checks. It also supports the
+typical logical operators, ``NOT``, ``AND``, and ``OR``.
+
+In addition to conditionals CMake provides two loop structures,
+:command:`while`, which follows the same rules as :command:`if` for checking a
+loop variable, and the more useful :command:`foreach`, which iterates over lists
+of strings and was demonstrated in the `Background`_ section.
+
+For this exercise, we're going to use loops and conditionals to solve some
+simple problems. We'll be using the aforementioned ``ARGN`` variable from
+:command:`function` as the list to operate on.
+
+Goal
+----
+
+Loop over a list, and return all the strings containing the string ``Foo``.
+
+.. note::
+  Those who read the command documentation will be aware that this is
+  :command:`list(FILTER)`, resist the temptation to use it.
+
+Helpful Resources
+-----------------
+
+* :command:`function`
+* :command:`foreach`
+* :command:`if`
+* :command:`list`
+
+Files to Edit
+-------------
+
+* ``Exercise2.cmake``
+
+Getting Started
+----------------
+
+The source code for ``Exercise2.cmake`` is provided in the ``Help/guide/tutorial/Step2``
+directory. It contains tests to verify the append behavior described above.
+
+.. note::
+  You should use the :command:`list(APPEND)` command this time to collect your
+  final result into a list. The input can be consumed from the ``ARGN`` variable
+  of the provided function.
+
+Complete ``TODO 3``.
+
+Build and Run
+-------------
+
+Navigate to the ``Help/guide/tutorial/Step2`` folder then you can run the code with:
+
+.. code-block:: console
+
+  cmake -P Exercise2.cmake
+
+The script will report if the ``FilterFoo`` function was implemented correctly.
+
+Solution
+--------
+
+We need to do three things, loop over the ``ARGN`` list, check if a given
+item in that list matches ``"Foo"``, and if so append it to the ``OutVar``
+list.
+
+While there are a couple ways we could invoke :command:`foreach`, the
+recommended way is to allow the command to do the variable expansion for us
+via ``IN LISTS`` to access the ``ARGN`` list items.
+
+The :command:`if` comparison we need is ``MATCHES`` which will check if
+``"FOO"`` exists in the item. All that remains is to append the item to the
+``OutVar`` list.  The trickiest part is remembering that ``OutVar`` *names* a
+list, it is not the list itself, so we need to access it via ``${OutVar}``.
+
+.. raw:: html
+
+  <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 3: Exercise2.cmake
+  :name: Exercise2.cmake-FilterFoo
+
+  function(FilterFoo OutVar)
+
+    foreach(item IN LISTS ARGN)
+      if(item MATCHES Foo)
+        list(APPEND ${OutVar} ${item})
+      endif()
+    endforeach()
+
+    set(${OutVar} ${${OutVar}} PARENT_SCOPE)
+  endfunction()
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Organizing with Include
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We have already discussed how to incorporate subdirectories containing their
+own CMLs with :command:`add_subdirectory`. In later steps we will explore
+the various way CMake code can be packaged and shared across projects.
+
+However for small CMake functions and utilities, it is often beneficial for them
+to live in their own ``.cmake`` files outside the project CMLs and separate
+from the rest of the build system. This allows for separation of concerns,
+removing the project-specific elements from the utilities we are using to
+describe them.
+
+To incorporate these separate ``.cmake`` files into our project, we use the
+:command:`include` command. This command immediately begins interpreting the
+contents of the :command:`include`'d file in the scope of the parent CML. It
+is as if the entire file were being called as a macro.
+
+Traditionally, these kinds of ``.cmake`` files live in a folder named "cmake"
+inside the project root. For this exercise, we'll use the ``Step2`` folder instead.
+
+Goal
+----
+
+Use the functions from Exercises 1 and 2 to build and filter our own list of items.
+
+Helpful Resources
+-----------------
+
+* :command:`include`
+
+Files to Edit
+-------------
+
+* ``Exercise3.cmake``
+
+Getting Started
+----------------
+
+The source code for ``Exercise3.cmake`` is provided in the ``Help/guide/tutorial/Step2``
+directory. It contains tests to verify the correct usage of our functions
+from the previous two exercises.
+
+.. note::
+  Actually it reuses tests from Exercise2.cmake, reusable code is good for
+  everyone.
+
+Complete ``TODO 4`` through ``TODO 7``.
+
+Build and Run
+-------------
+
+Navigate to the ``Help/guide/tutorial/Step2`` folder then you can run the code with:
+
+.. code-block:: console
+
+  cmake -P Exercise3.cmake
+
+The script will report if the functions were invoked and composed correctly.
+
+Solution
+--------
+
+The :command:`include` command will interpret the included file completely,
+including the tests from the first two exercises. We don't want to run these
+tests again. Thanks to some forethought, these files check a variable called
+``SKIP_TESTS`` prior to running their tests, setting this to ``True`` will
+get us the behavior we want.
+
+.. raw:: html
+
+  <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 4: Exercise3.cmake
+  :name: Exercise3.cmake-SKIP_TESTS
+
+  set(SKIP_TESTS True)
+
+.. raw:: html
+
+  </details>
+
+Now we're ready to :command:`include` the previous exercises to grab their
+functions.
+
+.. raw:: html
+
+  <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 5: Exercise3.cmake
+  :name: Exercise3.cmake-include
+
+  include(Exercise1.cmake)
+  include(Exercise2.cmake)
+
+.. raw:: html
+
+  </details>
+
+Now that ``FuncAppend`` is available to us, we can use it to append new elements
+to the ``InList``.
+
+.. raw:: html
+
+  <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 6: Exercise3.cmake
+  :name: Exercise3.cmake-FuncAppend
+
+  FuncAppend(InList FooBaz)
+  FuncAppend(InList QuxBaz)
+
+.. raw:: html
+
+  </details>
+
+Finally, we can use ``FilterFoo`` to filter the full list. The tricky part to
+remember here is that our ``FilterFoo`` wants to operate on list values via
+``ARGN``, so we need to expand the ``InList`` when we call ``FilterFoo``.
+
+.. raw:: html
+
+  <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 7: Exercise3.cmake
+  :name: Exercise3.cmake-FilterFoo
+
+  FilterFoo(OutList ${InList})
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt
deleted file mode 100644
index 181c25e..0000000
--- a/Help/guide/tutorial/Complete/CMakeLists.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-cmake_minimum_required(VERSION 3.15)
-
-# set the project name and version
-project(Tutorial VERSION 1.0)
-
-set(CMAKE_DEBUG_POSTFIX d)
-
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
-
-# control where the static and shared libraries are built so that on windows
-# we don't need to tinker with the path to run the executable
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-
-option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
-
-if(APPLE)
-  set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
-elseif(UNIX)
-  set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
-endif()
-
-# configure a header file to pass the version number only
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
-add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-enable_testing()
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-# setup installer
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_GENERATOR "TGZ")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
-
-# install the configuration targets
-install(EXPORT MathFunctionsTargets
-  FILE MathFunctionsTargets.cmake
-  DESTINATION lib/cmake/MathFunctions
-)
-
-include(CMakePackageConfigHelpers)
-# generate the config file that is includes the exports
-configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
-  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
-  INSTALL_DESTINATION "lib/cmake/example"
-  NO_SET_AND_CHECK_MACRO
-  NO_CHECK_REQUIRED_COMPONENTS_MACRO
-  )
-# generate the version file for the config file
-write_basic_package_version_file(
-  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
-  VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
-  COMPATIBILITY AnyNewerVersion
-)
-
-# install the configuration file
-install(FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
-  DESTINATION lib/cmake/MathFunctions
-  )
-
-# generate the export targets for the build tree
-# needs to be after the install(TARGETS) command
-export(EXPORT MathFunctionsTargets
-  FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
-)
diff --git a/Help/guide/tutorial/Complete/CTestConfig.cmake b/Help/guide/tutorial/Complete/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Complete/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Complete/Config.cmake.in b/Help/guide/tutorial/Complete/Config.cmake.in
deleted file mode 100644
index 17cbabd..0000000
--- a/Help/guide/tutorial/Complete/Config.cmake.in
+++ /dev/null
@@ -1,4 +0,0 @@
-
-@PACKAGE_INIT@
-
-include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
diff --git a/Help/guide/tutorial/Complete/License.txt b/Help/guide/tutorial/Complete/License.txt
deleted file mode 100644
index 85760e5..0000000
--- a/Help/guide/tutorial/Complete/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
deleted file mode 100644
index 1654564..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-# add the library that runs
-add_library(MathFunctions MathFunctions.cxx)
-
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE
-                            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-                            $<INSTALL_INTERFACE:include>
-                           )
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if(USE_MYMATH)
-
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
-  include(MakeTable.cmake) # generates Table.h
-
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-              )
-
-  # state that we depend on our binary dir to find Table.h
-  target_include_directories(SqrtLibrary PRIVATE
-                             ${CMAKE_CURRENT_BINARY_DIR}
-                             )
-
-  # state that SqrtLibrary need PIC when the default is shared libraries
-  set_target_properties(SqrtLibrary PROPERTIES
-                        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
-                        )
-
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
-
-# define the symbol stating we are using the declspec(dllexport) when
-# building on windows
-target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
-
-# setup the version numbering
-set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
-set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
-
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
-endif()
-install(TARGETS ${installable_libs}
-        EXPORT MathFunctionsTargets
-        DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cmake b/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cmake
deleted file mode 100644
index 12865a9..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index c0991b9..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include "MathFunctions.h"
-
-#include <cmath>
-
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
-}
-}
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h
deleted file mode 100644
index 3fb547b..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/MathFunctions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#if defined(_WIN32)
-#  if defined(EXPORTING_MYMATH)
-#    define DECLSPEC __declspec(dllexport)
-#  else
-#    define DECLSPEC __declspec(dllimport)
-#  endif
-#else // non windows
-#  define DECLSPEC
-#endif
-
-namespace mathfunctions {
-double DECLSPEC sqrt(double x);
-}
diff --git a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 8153f18..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <iostream>
-
-#include "MathFunctions.h"
-
-// include the generated table
-#include "Table.h"
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // use the table to help find an initial value
-  double result = x;
-  if (x >= 1 && x < 10) {
-    std::cout << "Use the table to help find an initial value " << std::endl;
-    result = sqrtTable[static_cast<int>(x)];
-  }
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h b/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h
deleted file mode 100644
index e1c42ef..0000000
--- a/Help/guide/tutorial/Complete/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Complete/MultiCPackConfig.cmake b/Help/guide/tutorial/Complete/MultiCPackConfig.cmake
deleted file mode 100644
index c2583df..0000000
--- a/Help/guide/tutorial/Complete/MultiCPackConfig.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-include("release/CPackConfig.cmake")
-
-set(CPACK_INSTALL_CMAKE_PROJECTS
-    "debug;Tutorial;ALL;/"
-    "release;Tutorial;ALL;/"
-    )
diff --git a/Help/guide/tutorial/Complete/SimpleTest/CMakeLists.txt b/Help/guide/tutorial/Complete/SimpleTest/CMakeLists.txt
new file mode 100644
index 0000000..96ad781
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/CMakeLists.txt
@@ -0,0 +1,53 @@
+# A very simple test framework for demonstrating how dependencies work
+cmake_minimum_required(VERSION 3.23)
+
+project(SimpleTest
+  VERSION 0.0.1
+)
+
+add_library(SimpleTest INTERFACE)
+target_sources(SimpleTest
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      SimpleTest.h
+)
+target_compile_features(SimpleTest INTERFACE cxx_std_20)
+
+target_compile_definitions(SimpleTest INTERFACE "SIMPLETEST_CONFIG=$<CONFIG>")
+
+find_package(TransitiveDep REQUIRED)
+target_link_libraries(SimpleTest
+  INTERFACE
+    TransitiveDep::TransitiveDep
+)
+
+include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+
+install(
+  TARGETS SimpleTest
+  EXPORT SimpleTestTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT SimpleTestTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+  NAMESPACE SimpleTest::
+)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+  ARCH_INDEPENDENT
+)
+
+install(
+  FILES
+    cmake/simpletest_discover_impl.cmake
+    cmake/simpletest_discover_tests.cmake
+    cmake/SimpleTestConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+)
diff --git a/Help/guide/tutorial/Complete/SimpleTest/CMakePresets.json b/Help/guide/tutorial/Complete/SimpleTest/CMakePresets.json
new file mode 100644
index 0000000..816d8a3
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "SimpleTest Preset",
+      "description": "Preset to use with the tutorial's SimpleTest library",
+      "binaryDir": "${sourceDir}/build",
+      "installDir": "${sourceParentDir}/install",
+      "cacheVariables": {
+        "CMAKE_CXX_STANDARD": "20",
+        "CMAKE_PREFIX_PATH": "${sourceParentDir}/install"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Complete/SimpleTest/SimpleTest.h b/Help/guide/tutorial/Complete/SimpleTest/SimpleTest.h
new file mode 100644
index 0000000..ced6562
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/SimpleTest.h
@@ -0,0 +1,155 @@
+#pragma once
+
+#include <cstdio>
+#include <map>
+#include <string_view>
+
+namespace SimpleTest {
+
+using TestFunc = void (*)();
+
+using Registry = std::map<std::string_view, TestFunc, std::less<>>;
+inline Registry g_registry;
+
+inline Registry& registry()
+{
+  return g_registry;
+}
+
+struct failure
+{
+  char const* file;
+  int line;
+  char const* expr;
+};
+
+struct Registrar
+{
+  template <std::size_t N>
+  Registrar(char const (&name)[N], TestFunc f)
+  {
+    auto [it, inserted] =
+      registry().emplace(std::string_view{ name, N ? (N - 1) : 0 }, f);
+    if (!inserted) {
+      std::printf("[  WARN    ] duplicate test name: %.*s\n",
+                  int(it->first.size()), it->first.data());
+    }
+  }
+};
+
+inline Registry const& all()
+{
+  return registry();
+}
+inline TestFunc find(std::string_view name)
+{
+  auto it = registry().find(name);
+  return it == registry().end() ? nullptr : it->second;
+}
+
+}
+
+#define SIMPLETEST_STRINGIFY(a) #a
+#define SIMPLETEST_XSTRINGIFY(a) SIMPLETEST_STRINGIFY(a)
+#define SIMPLETEST_CONCAT_(a, b) a##b
+#define SIMPLETEST_CONCAT(a, b) SIMPLETEST_CONCAT_(a, b)
+
+#define TEST(name_literal)                                                    \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)();                 \
+  static ::SimpleTest::Registrar SIMPLETEST_CONCAT(_simpletest_reg_,          \
+                                                   __LINE__)(                 \
+    name_literal, &SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__));             \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)()
+
+// Minimal assertion
+#define REQUIRE(expr)                                                         \
+  do {                                                                        \
+    if (!(expr))                                                              \
+      throw ::SimpleTest::failure{ __FILE__, __LINE__, #expr };               \
+  } while (0)
+
+int main(int argc, char** argv)
+{
+  using namespace ::SimpleTest;
+
+  std::string_view arg1 =
+    (argc >= 2) ? std::string_view{ argv[1] } : std::string_view{};
+
+  if (arg1 == "--list") {
+    bool first = true;
+    for (auto const& [name, _] : registry()) {
+      if (!first)
+        std::printf(",");
+      std::printf("%.*s", int(name.size()), name.data());
+      first = false;
+    }
+    std::printf("\n");
+    return 0;
+  }
+
+  if (arg1 == "--test") {
+    if (argc < 3) {
+      std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+      return 2;
+    }
+
+#ifdef SIMPLETEST_CONFIG
+    std::printf("SimpleTest built with config: " SIMPLETEST_XSTRINGIFY(
+      SIMPLETEST_CONFIG) "\n");
+#endif
+
+    std::string_view name{ argv[2] };
+    auto it = registry().find(name);
+    if (it == registry().end()) {
+      std::printf("[ NOTFOUND ] %s\n", argv[2]);
+      return 2;
+    }
+
+    int failed = 0;
+    std::printf("[ RUN      ] %.*s\n", int(it->first.size()),
+                it->first.data());
+    try {
+      it->second();
+      std::printf("[       OK] %.*s\n", int(it->first.size()),
+                  it->first.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(it->first.size()),
+                  it->first.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n",
+                  int(it->first.size()), it->first.data());
+      failed = 1;
+    }
+    return failed;
+  }
+
+  if (argc > 1) {
+    std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+    return 2;
+  }
+
+#ifdef SIMPLETEST_CONFIG
+  std::printf("SimpleTest built with config: " SIMPLETEST_XSTRINGIFY(
+    SIMPLETEST_CONFIG) "\n");
+#endif
+
+  // Default: run all tests.
+  int failed = 0;
+  for (auto const& [name, func] : all()) {
+    std::printf("[ RUN      ] %.*s\n", int(name.size()), name.data());
+    try {
+      func();
+      std::printf("[       OK ] %.*s\n", int(name.size()), name.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(name.size()),
+                  name.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n", int(name.size()),
+                  name.data());
+      failed = 1;
+    }
+  }
+  return failed;
+}
diff --git a/Help/guide/tutorial/Complete/SimpleTest/cmake/SimpleTestConfig.cmake b/Help/guide/tutorial/Complete/SimpleTest/cmake/SimpleTestConfig.cmake
new file mode 100644
index 0000000..6c7ffb5
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/cmake/SimpleTestConfig.cmake
@@ -0,0 +1,5 @@
+include(CMakeFindDependencyMacro)
+find_dependency(TransitiveDep)
+
+include(${CMAKE_CURRENT_LIST_DIR}/SimpleTestTargets.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_tests.cmake)
diff --git a/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_impl.cmake b/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_impl.cmake
new file mode 100644
index 0000000..7d3a22b
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_impl.cmake
@@ -0,0 +1,32 @@
+if(NOT DEFINED TEST_EXE OR NOT DEFINED OUT_FILE)
+# noqa: spellcheck off
+  message(FATAL_ERROR "simpletest_discover: need -DTEST_EXE and -DOUT_FILE")
+# noqa: spellcheck on
+endif()
+
+execute_process(
+  COMMAND ${TEST_EXE} --list
+  RESULT_VARIABLE _rc
+  OUTPUT_VARIABLE _out
+  ERROR_VARIABLE _err
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+if(NOT _rc EQUAL 0)
+  file(WRITE ${OUT_FILE} "# simpletest: --list failed (rc=${_rc})\n")
+  message(FATAL_ERROR "simpletest_discover: '${TEST_EXE} --list' failed (${_rc})\n${_err}")
+endif()
+
+if(_out STREQUAL "")
+  file(WRITE ${OUT_FILE} "# simpletest: no tests\n")
+  return()
+endif()
+
+string(REPLACE "," ";" _names "${_out}")
+
+file(WRITE ${OUT_FILE} "# Auto-generated by simpletest_discover_impl.cmake\n")
+foreach(_name IN LISTS _names)
+  file(APPEND ${OUT_FILE}
+    "add_test([=[${_name}]=] \"${TEST_EXE}\" \"--test\" \"${_name}\")\n"
+  )
+endforeach()
diff --git a/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_tests.cmake b/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_tests.cmake
new file mode 100644
index 0000000..e5cf059
--- /dev/null
+++ b/Help/guide/tutorial/Complete/SimpleTest/cmake/simpletest_discover_tests.cmake
@@ -0,0 +1,27 @@
+set(_simpletest_impl_script ${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_impl.cmake)
+
+function(simpletest_discover_tests target)
+  if(NOT TARGET ${target})
+    message(FATAL_ERROR "simpletest_discover_tests: no such target '${target}'")
+  endif()
+
+  set(_out ${CMAKE_CURRENT_BINARY_DIR}/${target}_ctests.cmake)
+
+  if(NOT EXISTS ${_out})
+    file(WRITE ${_out} "# Populated after building ${target}\n")
+  endif()
+
+# noqa: spellcheck off
+  add_custom_command(TARGET ${target} POST_BUILD
+    COMMAND ${CMAKE_COMMAND}
+      -DTEST_EXE=$<TARGET_FILE:${target}>
+      -DOUT_FILE=${_out}
+      -P ${_simpletest_impl_script}
+    BYPRODUCTS ${_out}
+    COMMENT "SimpleTest: Discovering tests in ${target}"
+    VERBATIM
+  )
+# noqa: spellcheck on
+
+  set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES ${_out})
+endfunction()
diff --git a/Help/guide/tutorial/Complete/TutorialConfig.h.in b/Help/guide/tutorial/Complete/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Complete/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Complete/TutorialProject/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/CMakeLists.txt
new file mode 100644
index 0000000..4091638
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required(VERSION 3.23)
+
+project(Tutorial
+  VERSION 1.0.0
+)
+
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
+option(BUILD_TESTING "Enable testing and build tests" ON)
+
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
+
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
+
+if(BUILD_TESTING)
+  enable_testing()
+  add_subdirectory(Tests)
+endif()
+
+add_subdirectory(MathFunctions)
+
+include(GNUInstallDirs)
+
+install(
+  TARGETS MathFunctions OpAdd OpMul OpSub MathLogger SqrtTable
+  EXPORT TutorialTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT TutorialTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+  NAMESPACE Tutorial::
+)
+
+include(CMakePackageConfigHelpers)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+)
+
+install(
+  FILES
+    cmake/TutorialConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/CMakePresets.json b/Help/guide/tutorial/Complete/TutorialProject/CMakePresets.json
new file mode 100644
index 0000000..fee177b
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "CMAKE_PREFIX_PATH": "${sourceParentDir}/install",
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..e0f3ba2
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/CMakeLists.txt
@@ -0,0 +1,55 @@
+add_library(MathFunctions)
+add_library(Tutorial::MathFunctions ALIAS MathFunctions)
+
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
+
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
+
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
+    SqrtTable
+
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
+
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
+
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
+endif()
+
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
+
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
+endif()
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+add_subdirectory(MakeTable)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..6aa2a32
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_executable(MakeTable)
+
+target_sources(MakeTable
+  PRIVATE
+    MakeTable.cxx
+)
+
+add_custom_command(
+  OUTPUT SqrtTable.h
+  COMMAND MakeTable SqrtTable.h
+  DEPENDS MakeTable
+  VERBATIM
+)
+
+add_custom_target(RunMakeTable DEPENDS SqrtTable.h)
+
+add_library(SqrtTable INTERFACE)
+
+target_sources(SqrtTable
+  INTERFACE
+    FILE_SET HEADERS
+    BASE_DIRS
+      ${CMAKE_CURRENT_BINARY_DIR}
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SqrtTable.h
+)
+
+add_dependencies(SqrtTable RunMakeTable)
diff --git a/Help/guide/tutorial/Complete/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
rename from Help/guide/tutorial/Complete/MathFunctions/MakeTable.cxx
rename to Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..4bf8051
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,101 @@
+#include <cmath>
+#include <format>
+
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
+#endif
+
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+#include <SqrtTable.h>
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+#ifdef TUTORIAL_USE_STD_SQRT
+  return std::sqrt(x);
+#else
+  return mysqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.h
new file mode 100644
index 0000000..91cb176
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathFunctions.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/Tests/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/Tests/CMakeLists.txt
new file mode 100644
index 0000000..9b5bcd1
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/Tests/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_executable(TestMathFunctions)
+
+target_sources(TestMathFunctions
+  PRIVATE
+    TestMathFunctions.cxx
+)
+
+find_package(SimpleTest REQUIRED)
+
+target_link_libraries(TestMathFunctions
+  PRIVATE
+    MathFunctions
+    SimpleTest::SimpleTest
+)
+
+simpletest_discover_tests(TestMathFunctions)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/Tests/TestMathFunctions.cxx b/Help/guide/tutorial/Complete/TutorialProject/Tests/TestMathFunctions.cxx
new file mode 100644
index 0000000..166fd5d
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/Tests/TestMathFunctions.cxx
@@ -0,0 +1,22 @@
+#include <MathFunctions.h>
+#include <SimpleTest.h>
+
+TEST("add")
+{
+  REQUIRE(mathfunctions::OpAdd(2.0, 2.0) == 4.0);
+}
+
+TEST("sub")
+{
+  REQUIRE(mathfunctions::OpSub(4.0, 2.0) == 2.0);
+}
+
+TEST("mul")
+{
+  REQUIRE(mathfunctions::OpMul(5.0, 5.0) == 25.0);
+}
+
+TEST("sqrt")
+{
+  REQUIRE(mathfunctions::sqrt(25.0) == 5.0);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Complete/TutorialProject/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..79b232b
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/Tutorial/CMakeLists.txt
@@ -0,0 +1,39 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
+
+find_path(UnpackagedIncludeFolder Unpackaged.h REQUIRED
+  PATH_SUFFIXES
+    Unpackaged
+)
+
+target_include_directories(Tutorial
+  PRIVATE
+    ${UnpackagedIncludeFolder}
+)
diff --git a/Help/guide/tutorial/Complete/TutorialProject/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Complete/TutorialProject/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..ac133d4
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/Tutorial/Tutorial.cxx
@@ -0,0 +1,27 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+#include <Unpackaged.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Complete/TutorialProject/cmake/TutorialConfig.cmake b/Help/guide/tutorial/Complete/TutorialProject/cmake/TutorialConfig.cmake
new file mode 100644
index 0000000..d13caa4
--- /dev/null
+++ b/Help/guide/tutorial/Complete/TutorialProject/cmake/TutorialConfig.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/TutorialTargets.cmake)
diff --git a/Help/guide/tutorial/Complete/install/include/Unpackaged/Unpackaged.h b/Help/guide/tutorial/Complete/install/include/Unpackaged/Unpackaged.h
new file mode 100644
index 0000000..9782b0a
--- /dev/null
+++ b/Help/guide/tutorial/Complete/install/include/Unpackaged/Unpackaged.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define UNPACKAGED_HEADER_FOUND
diff --git a/Help/guide/tutorial/Complete/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake b/Help/guide/tutorial/Complete/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
new file mode 100644
index 0000000..ef51145
--- /dev/null
+++ b/Help/guide/tutorial/Complete/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
@@ -0,0 +1,50 @@
+# Abridged import written for the Tutorial
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+if(CMAKE_VERSION VERSION_LESS "3.0.0")
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 3.0.0...3.30)
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_cmake_targets_defined "")
+set(_cmake_targets_not_defined "")
+set(_cmake_expected_targets "")
+foreach(_cmake_expected_target IN ITEMS TransitiveDep::TransitiveDep)
+  list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
+  if(TARGET "${_cmake_expected_target}")
+    list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
+  else()
+    list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
+  endif()
+endforeach()
+unset(_cmake_expected_target)
+if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
+  unset(_cmake_targets_defined)
+  unset(_cmake_targets_not_defined)
+  unset(_cmake_expected_targets)
+  unset(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT _cmake_targets_defined STREQUAL "")
+  string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
+  string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
+endif()
+unset(_cmake_targets_defined)
+unset(_cmake_targets_not_defined)
+unset(_cmake_expected_targets)
+
+# Create imported target TransitiveDep::TransitiveDep
+add_library(TransitiveDep::TransitiveDep INTERFACE IMPORTED)
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/Help/guide/tutorial/Complete/tutorial.cxx b/Help/guide/tutorial/Complete/tutorial.cxx
deleted file mode 100644
index 78641b1..0000000
--- a/Help/guide/tutorial/Complete/tutorial.cxx
+++ /dev/null
@@ -1,26 +0,0 @@
-// A simple program that computes the square root of a number
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Configuration and Cache Variables.rst b/Help/guide/tutorial/Configuration and Cache Variables.rst
new file mode 100644
index 0000000..250748b
--- /dev/null
+++ b/Help/guide/tutorial/Configuration and Cache Variables.rst
@@ -0,0 +1,606 @@
+Step 3: Configuration and Cache Variables
+=========================================
+
+CMake projects often have some project-specific configuration variables which
+users and packagers are interested in. CMake has many ways that an invoking
+user or process can communicate these configuration choices, but the most
+fundamental of them are :option:`-D <cmake -D>` flags.
+
+In this step we'll explore the ins and out of how to provide project
+configuration options from within a CML, and how to invoke CMake to take
+advantage of configuration options provided by both CMake and individual
+projects.
+
+Background
+^^^^^^^^^^
+
+If we had a CMake project for compression software which supported multiple
+compression algorithms, we might want to let the packager of the project decide
+which algorithms to enable when they build our software. We can do so by
+consuming variables set via :option:`-D <cmake -D>` flags.
+
+.. code-block:: cmake
+
+  if(COMPRESSION_SOFTWARE_USE_ZLIB)
+    message("I will use Zlib!")
+    # ...
+  endif()
+
+  if(COMPRESSION_SOFTWARE_USE_ZSTD)
+    message("I will use Zstd!")
+    # ...
+  endif()
+
+.. code-block:: console
+
+  $ cmake -B build \
+      -DCOMPRESSION_SOFTWARE_USE_ZLIB=ON \
+      -DCOMPRESSION_SOFTWARE_USE_ZSTD=OFF
+  ...
+  I will use Zlib!
+
+Of course, we will want to provide reasonable defaults for these configuration
+choices, and a way to communicate the purpose of a given option. This function
+is provided by the :command:`option` command.
+
+.. code-block:: cmake
+
+  option(COMPRESSION_SOFTWARE_USE_ZLIB "Support Zlib compression" ON)
+  option(COMPRESSION_SOFTWARE_USE_ZSTD "Support Zstd compression" ON)
+
+  if(COMPRESSION_SOFTWARE_USE_ZLIB)
+    # Same as before
+  # ...
+
+.. code-block:: console
+
+  $ cmake -B build \
+      -DCOMPRESSION_SOFTWARE_USE_ZLIB=OFF
+  ...
+  I will use Zstd!
+
+The names created by :option:`-D <cmake -D>` flags and :command:`option` are
+not normal variables, they are **cache** variables. Cache variables are globally
+visible variables which are *sticky*, their value is difficult to change after
+it is initially set. In fact they are so sticky that, in project mode, CMake
+will save and restore cache variables across multiple configurations. If a
+cache variable is set once, it will remain until another :option:`-D <cmake -D>`
+flag preempts the saved variable.
+
+.. note::
+  CMake itself has dozens of normal and cache variables used for configuration.
+  These are documented at :manual:`cmake-variables(7)` and operate in the same
+  manner as project-provided variables for configuration.
+
+:command:`set` can also be used to manipulate cache variables, but will not
+change a variable which has already been created.
+
+.. code-block:: cmake
+
+  set(StickyCacheVariable "I will not change" CACHE STRING "")
+  set(StickyCacheVariable "Overwrite StickyCache" CACHE STRING "")
+
+  message("StickyCacheVariable: ${StickyCacheVariable}")
+
+.. code-block:: console
+
+  $ cmake -P StickyCacheVariable.cmake
+  StickyCacheVariable: I will not change
+
+Because :option:`-D <cmake -D>` flags are processed before any other commands,
+they take precedence for setting the value of a cache variable.
+
+.. code-block:: console
+
+  $ cmake \
+    -DStickyCacheVariable="Commandline always wins" \
+    -P StickyCacheVariable.cmake
+  StickyCacheVariable: Commandline always wins
+
+While cache variables cannot ordinarily be changed, they can be *shadowed* by
+normal variables. We can observe this by :command:`set`'ing a variable to have
+the same name as a cache variable, and then using :command:`unset` to remove
+the normal variable.
+
+.. code-block:: cmake
+
+  set(ShadowVariable "In the shadows" CACHE STRING "")
+  set(ShadowVariable "Hiding the cache variable")
+  message("ShadowVariable: ${ShadowVariable}")
+
+  unset(ShadowVariable)
+  message("ShadowVariable: ${ShadowVariable}")
+
+.. code-block:: console
+
+  $ cmake -P ShadowVariable.cmake
+  ShadowVariable: Hiding the cache variable
+  ShadowVariable: In the shadows
+
+Exercise 1 - Using Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We can imagine a scenario where consumers really want our ``MathFunctions``
+library, and the ``Tutorial`` utility is a "take it or leave it" add-on. In
+that case, we might want to add an option to allow consumers to disable
+building our ``Tutorial`` binary, building only the ``MathFunctions`` library.
+
+With our knowledge of options, conditionals, and cache variables we have all
+the pieces we need to make this configuration available.
+
+Goal
+----
+
+Add an option named ``TUTORIAL_BUILD_UTILITIES`` to control if the ``Tutorial``
+binary is configured and built.
+
+.. note::
+  CMake allows us to determine which targets are built after configuration. Our
+  users could ask for the ``MathFunctions`` library alone without ``Tutorial``.
+  CMake also has mechanisms to exclude targets from ``ALL``, the default target
+  which builds all the other available targets.
+
+  However, options which completely exclude targets from the configuration are
+  convenient and popular, especially if configuring those targets involves
+  heavy-weight steps which might take some time.
+
+  It also simplifies :command:`install()` logic, which we'll discuss in later
+  steps, if targets the packager is uninterested in are completely excluded.
+
+Helpful Resources
+-----------------
+
+* :command:`option`
+* :command:`if`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+The ``Help/guide/tutorial/Step3`` folder contains the complete, recommended
+solution to ``Step1`` and the relevant ``TODOs`` for this step. Take a minute
+to review and refamiliarize yourself with the ``Tutorial`` project.
+
+When you feel you have an understanding of the current code, start with
+``TODO 1`` and complete through ``TODO 2``.
+
+Build and Run
+-------------
+
+We can now reconfigure our project. However, this time we want to control the
+configuration via :option:`-D <cmake -D>` flags. We again start by navigating
+to ``Help/guide/tutorial/Step3`` and invoking CMake, but this time with our
+configuration options.
+
+.. code-block:: console
+
+  cmake -B build -DTUTORIAL_BUILD_UTILITIES=OFF
+
+We can now build as usual.
+
+.. code-block:: console
+
+  cmake --build build
+
+After the build we should observe no Tutorial executable is produced. Because
+cache variables are sticky even a reconfigure shouldn't change this, despite
+the default-``ON`` option.
+
+.. code-block:: console
+
+  cmake -B build
+  cmake --build build
+
+Will not produce the Tutorial executable, the cache variables are "locked in".
+To change this we have two options. First, we can edit the file which stores
+the cache variables between CMake configuration runs, the "CMake Cache". This
+file is ``build/CMakeCache.txt``, in it we can find the option cache variable.
+
+.. code-block:: text
+
+  //Build the Tutorial executable
+  TUTORIAL_BUILD_UTILITIES:BOOL=OFF
+
+We can change this from ``OFF`` to ``ON``, rerun the build, and we will get
+our ``Tutorial`` executable.
+
+.. note::
+  ``CMakeCache.txt`` entries are of the form ``<Name>:<Type>=<Value>``, however
+  the "type" is only a hint. All objects in CMake are strings, regardless of
+  what the cache says.
+
+Alternatively, we can change the value of the cache variable on the command
+line, because the command line runs before ``CMakeCache.txt`` is loaded its
+value take precedence over those in the cache file.
+
+.. code-block:: console
+
+  cmake -B build -DTUTORIAL_BUILD_UTILITIES=ON
+  cmake --build build
+
+Doing so we observe the value in ``CMakeCache.txt`` has flipped from ``OFF``
+to ``ON``, and that the ``Tutorial`` executable is built.
+
+Solution
+--------
+
+First we create our :command:`option` to provide our cache variable with a
+reasonable default value.
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+  :caption: TODO 1: CMakeLists.txt
+  :name: CMakeLists.txt-option-TUTORIAL_BUILD_UTILITIES
+  :language: cmake
+  :start-at: option(TUTORIAL_BUILD_UTILITIES
+  :end-at: option(TUTORIAL_BUILD_UTILITIES
+
+.. raw:: html
+
+  </details>
+
+Then we can check the cache variable to conditionally enable the ``Tutorial``
+executable (by way of adding its subdirectory).
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+  :caption: TODO 2: CMakeLists.txt
+  :name: CMakeLists.txt-if-TUTORIAL_BUILD_UTILITIES
+  :language: cmake
+  :start-at: if(TUTORIAL_BUILD_UTILITIES)
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
+
+Exercise 2 - ``CMAKE`` Variables
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+CMake has several important normal and cache variables provided to allow
+packagers to control the build. Decisions such as compilers, default flags,
+search locations for packages, and much more are all controlled by CMake's
+own configuration variables.
+
+Among the most important are language standards. As the language standard can
+have significant impact on the ABI presented by a given package. For example,
+it's quite common for libraries to use standard C++ templates on later
+standards, and provide polyfills on earlier standards. If a library is consumed
+under different standards then ABI incompatibilities between the standard
+templates and the polyfills can result in incomprehensible errors and runtime
+crashes.
+
+Ensuring all of our targets are built under the same language standard is
+achieved with the :variable:`CMAKE_<LANG>_STANDARD` cache variables. For C++,
+this is ``CMAKE_CXX_STANDARD``.
+
+.. note::
+  Because these variables are so important, it is equally important that
+  developers not override or shadow them in their CMLs. Shadowing
+  :variable:`CMAKE_<LANG>_STANDARD` in a CML because the library wants C++20,
+  when the packager has decided to build the rest of their libraries and
+  applications with C++23, can lead to the aforementioned terrible,
+  incomprehensible errors.
+
+  Do not :command:`set` ``CMAKE_`` globals without very strong reasons for
+  doing so. We'll discuss better methods for targets to communicate
+  requirements like definitions and minimum standards in later steps.
+
+In this exercise, we'll introduce some C++20 code into our library and
+executable and build them with C++20 by setting the appropriate cache variable.
+
+Goal
+----
+
+Use ``std::format`` to format printed strings instead of stream operators. To
+ensure availability of ``std::format``, configure CMake to use the C++20
+standard for C++ targets.
+
+Helpful Resources
+-----------------
+
+* :option:`cmake -D`
+* :variable:`CMAKE_<LANG>_STANDARD`
+* :variable:`CMAKE_CXX_STANDARD`
+* :prop_tgt:`CXX_STANDARD`
+* `cppreference \<format\> <https://en.cppreference.com/w/cpp/utility/format/format.html>`_
+
+Files to Edit
+-------------
+
+* ``Tutorial/Tutorial.cxx``
+* ``MathFunctions/MathFunctions.cxx``
+
+Getting Started
+---------------
+
+Continue to edit files from ``Step3``. Complete ``TODO 3`` through ``TODO 7``.
+We'll be modifying our prints to use ``std::format`` instead of stream
+operators.
+
+Ensure your cache variables are set such that the Tutorial executable will be
+built, using any of the methods discussed in the previous exercise.
+
+Build and Run
+-------------
+
+We need to reconfigure our project with the new standard, we can do this
+using the same method as our ``TUTORIAL_BUILD_UTILITIES`` cache variable.
+
+.. code-block:: console
+
+  cmake -B build -DCMAKE_CXX_STANDARD=20
+
+.. note::
+  Configuration variables are, by convention, prefixed with the provider of the
+  variable. CMake configuration variables are prefixed with ``CMAKE_``, while
+  projects should prefix their variables with ``<PROJECT>_``.
+
+  The tutorial configuration variables follow this convention, and are prefixed
+  with ``TUTORIAL_``.
+
+Now that we've configured with C++20, we can build as usual.
+
+.. code-block:: console
+
+  cmake --build build
+
+Solution
+--------
+
+We need to include ``<format>`` and then use it.
+
+.. raw:: html
+
+  <details><summary>TODO 3-5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/Tutorial/Tutorial.cxx
+  :caption: TODO 3: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-include-format
+  :language: c++
+  :start-at: #include <format>
+  :end-at: #include <string>
+
+.. literalinclude:: Step4/Tutorial/Tutorial.cxx
+  :caption: TODO 4: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-format1
+  :language: c++
+  :start-at: if (argc < 2) {
+  :end-at: return 1;
+  :append: }
+  :dedent: 2
+
+.. literalinclude:: Step4/Tutorial/Tutorial.cxx
+  :caption: TODO 5: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-format3
+  :language: c++
+  :start-at: // calculate square root
+  :end-at: outputValue);
+  :dedent: 2
+
+.. raw:: html
+
+  </details>
+
+And again for the ``MathFunctions`` library.
+
+.. raw:: html
+
+  <details><summary>TODO 6-7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/MathFunctions/MathFunctions.cxx
+  :caption: TODO 6: MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-include-format
+  :language: c++
+  :start-at: #include <format>
+  :end-at: #include <iostream>
+
+.. literalinclude:: Step4/MathFunctions/MathFunctions.cxx
+  :caption: TODO 7: MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-format
+  :language: c++
+  :start-at: double delta
+  :end-at: std::format
+  :dedent: 4
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - CMakePresets.json
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Managing these configuration values can quickly become overwhelming. In CI
+systems it is appropriate to record these as part of a given CI step. For
+example in a Github Actions CI step we might see something akin to the
+following:
+
+.. code-block:: yaml
+
+  - name: Configure and Build
+    run: |
+      cmake \
+        -B build \
+        -DCMAKE_BUILD_TYPE=Release \
+        -DCMAKE_CXX_STANDARD=20 \
+        -DCMAKE_CXX_EXTENSIONS=ON \
+        -DTUTORIAL_BUILD_UTILITIES=OFF \
+        # Possibly many more options
+        # ...
+
+      cmake --build build
+
+When developing code locally, typing all these options even once might be error
+prone. If a fresh configuration is needed for any reason, doing so multiple
+times could be exhausting.
+
+There are many and varied solutions to this problem, and your choice is
+ultimately up to your preferences as a developer. CLI-oriented developers
+commonly use task runners to invoke CMake with their desired options for a
+project. Most IDEs also have a custom mechanism for controlling CMake
+configuration.
+
+It would be impossible to fully enumerate every possible configuration workflow
+here. Instead we will explore CMake's built-in solution, known as
+:manual:`CMake Presets <cmake-presets(7)>`. Presets give us a format to name
+and express collections of CMake configuration options.
+
+.. note::
+    Presets are capable of expressing entire CMake workflows, from
+    configuration, through building, all the way to installing the software
+    package.
+
+    They are far more flexible than can we have room for here. We'll limit
+    ourselves to using them for configuration.
+
+CMake Presets come in two standard files, ``CMakePresets.json``, which is
+intended to be a part of the project and tracked in source control; and
+``CMakeUserPresets.json``, which is intended for local user configuration
+and should not be tracked in source control.
+
+The simplest preset which would be of use to a developer does nothing more
+than configure variables.
+
+.. code-block:: json
+
+  {
+    "version": 4,
+    "configurePresets": [
+      {
+        "name": "example-preset",
+        "cacheVariables": {
+          "EXAMPLE_FOO": "Bar",
+          "EXAMPLE_QUX": "Baz"
+        }
+      }
+    ]
+  }
+
+When invoking CMake, where previously we would have done:
+
+.. code-block:: console
+
+  cmake -B build -DEXAMPLE_FOO=Bar -DEXAMPLE_QUX=Baz
+
+We can now use the preset:
+
+.. code-block:: console
+
+  cmake -B build --preset example-preset
+
+CMake will search for files named ``CMakePresets.json`` and
+``CMakeUserPresets.json``, and load the named configuration from them if
+available.
+
+.. note::
+  Command line flags can be mixed with presets. Command line flags have
+  precedence over values found in a preset.
+
+Presets also support limited macros, variables that can be brace-expanded
+inside the preset. The only one of interest to us is the ``${sourceDir}`` macro,
+which expands to the root directory of the project. We can use this to set our
+build directory, skipping the :option:`-B <cmake -B>` flag when configuring
+the project.
+
+.. code-block:: json
+
+  {
+    "name": "example-preset",
+    "binaryDir": "${sourceDir}/build"
+  }
+
+Goal
+----
+
+Configure and build the tutorial using a CMake Preset instead of command line
+flags.
+
+Helpful Resources
+-----------------
+
+* :manual:`cmake-presets(7)`
+
+Files to Edit
+-------------
+
+* ``CMakePresets.json``
+
+Getting Started
+---------------
+
+Continue to edit files from ``Step3``. Complete ``TODO 8`` and ``TODO 9``.
+
+.. note::
+  ``TODOs`` inside ``CMakePresets.json`` need to be *replaced*. There should
+  be no ``TODO`` keys left inside the file when you have completed the exercise.
+
+You can verify the preset is working correctly by deleting the existing build
+folder before you configure, this will ensure you're not reusing the existing
+CMake Cache for configuration.
+
+.. note::
+  On CMake 3.24 and newer, the same effect can be achieved by configuring with
+  :option:`cmake --fresh`.
+
+All future configuration changes will be via the ``CMakePresets.json`` file.
+
+Build and Run
+-------------
+
+We can now use the preset file to manage our configuration.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+
+Presets are capable of running the build step for us, but for this tutorial
+we'll continue to run the build ourselves.
+
+.. code-block:: console
+
+  cmake --build build
+
+Solution
+--------
+
+There are two changes we need to make, first we want to set the build
+directory (also called the "binary directory") to the ``build`` subdirectory
+of our project folder, and second we need to set the ``CMAKE_CXX_STANDARD`` to
+``20``.
+
+.. raw:: html
+
+  <details><summary>TODO 8-9: Click to show/hide answer</summary>
+
+.. code-block:: json
+  :caption: TODO 8-9: CMakePresets.json
+  :name: CMakePresets.json-initial
+
+  {
+    "version": 4,
+    "configurePresets": [
+      {
+        "name": "tutorial",
+        "displayName": "Tutorial Preset",
+        "description": "Preset to use with the tutorial",
+        "binaryDir": "${sourceDir}/build",
+        "cacheVariables": {
+          "CMAKE_CXX_STANDARD": "20"
+        }
+      }
+    ]
+  }
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Custom Commands and Generated Files.rst b/Help/guide/tutorial/Custom Commands and Generated Files.rst
new file mode 100644
index 0000000..49c6c07
--- /dev/null
+++ b/Help/guide/tutorial/Custom Commands and Generated Files.rst
@@ -0,0 +1,279 @@
+Step 7: Custom Commands and Generated Files
+===========================================
+
+Code generation is a ubiquitous mechanism for extending programming languages
+beyond the bounds of their language model. CMake has first-class support for
+Qt's Meta-Object Compiler, but very few other code generators are notable
+enough to warrant that kind of effort.
+
+Instead, code generators tend to be bespoke and usage specific. CMake provides
+facilities for describing the usage of a code generator, so projects can
+add support for their individual needs.
+
+In this step, we will use :command:`add_custom_command` to add support for a
+code generator within the tutorial project.
+
+Background
+^^^^^^^^^^
+
+Any step in the build process can generally be described in terms of its inputs
+and outputs. CMake assumes that code generators and other custom processes
+operate on the same principle. In this way, the code generator acts identically
+to compilers, linkers, and other elements of the toolchain; when the inputs are
+newer than the outputs (or the outputs don't exist), a user-specified command
+will be run to update the outputs.
+
+.. note::
+  This model assumes the outputs of a process are known before it is run. CMake
+  lacks the ability to describe code generators where the name and location of
+  the outputs depends on the *content* of the input. Various hacks exist to
+  shim this functionality into CMake, but they are outside the scope of this
+  tutorial.
+
+Describing a code generator (or any custom process) is usually performed in
+two parts. First, the inputs and outputs are described independently of the
+CMake target model, concerned only with the generation process itself. Second,
+the outputs are associated with a CMake target to insert them into the CMake
+target model.
+
+For sources, this is as simple as adding the generated files to the source list
+of a ``STATIC``, ``SHARED``, or ``OBJECT`` library. For header-only generators,
+it's often necessary to use an intermediary target created via
+:command:`add_custom_target` to add the header file generation to the
+build stage (because ``INTERFACE`` libraries have no build step).
+
+Exercise 1 - Using a Code Generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The primary mechanism for describing a code generator is the
+:command:`add_custom_command` command. A "command", for the purpose of
+:command:`add_custom_command` is either an executable available in the build
+environment or a CMake executable target name.
+
+.. code-block:: cmake
+
+  add_executable(Tool)
+  # ...
+  add_custom_command(
+    OUTPUT Generated.cxx
+    COMMAND Tool -i input.txt -o Generated.cxx
+    DEPENDS Tool input.txt
+    VERBATIM
+  )
+  # ...
+  add_library(GeneratedObject OBJECT)
+  target_sources(GeneratedObject
+    PRIVATE
+      Generated.cxx
+  )
+
+Most of the keywords are self-explanatory, with the exception of ``VERBATIM``.
+This argument is effectively mandatory for legacy reasons that are uninteresting
+to explain in a modern context. The curious should consult the
+:command:`add_custom_command` documentation for additional details.
+
+The ``Tool`` executable target appears both in the ``COMMAND`` and ``DEPENDS``
+parameters. While ``COMMAND`` is sufficient for the code to build correctly,
+adding the ``Tool`` itself as a dependency of the custom command ensure that
+if ``Tool`` is updated, the custom command will be rerun.
+
+For header-only file generation, additional commands are necessary because the
+library itself has no build step. We can use :command:`add_custom_target` to
+create an "artificial" build step for the library. We then force the custom
+target to be run before any targets which link the library with the command
+:command:`add_dependencies`.
+
+.. code-block:: cmake
+
+  add_custom_target(RunGenerator DEPENDS Generated.h)
+
+  add_library(GeneratedLib INTERFACE)
+  target_sources(GeneratedLib
+    INTERFACE
+      FILE_SET HEADERS
+      BASE_DIRS
+        ${CMAKE_CURRENT_BINARY_DIR}
+      FILES
+        ${CMAKE_CURRENT_BINARY_DIR}/Generated.h
+  )
+
+  add_dependencies(GeneratedLib RunGenerator)
+
+.. note::
+  We add the :variable:`CMAKE_CURRENT_BINARY_DIR`, a variable which names the
+  current location in the build tree where our artifacts are being placed, to
+  the base directories because that's the working directory our code generator
+  will be run inside of. Listing the ``FILES`` is unnecessary for the build and
+  done so here only for clarity.
+
+Goal
+----
+
+Add a generated table of pre-computed square roots to the ``MathFunctions``
+library.
+
+Helpful Resources
+-----------------
+
+* :command:`add_executable`
+* :command:`add_library`
+* :command:`target_sources`
+* :command:`add_custom_command`
+* :command:`add_custom_target`
+* :command:`add_dependencies`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MakeTable/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
+
+Getting Started
+---------------
+
+The ``MathFunctions`` library has been edited to use a pre-computed table when
+given a number less than 10. However, the hardcoded table is not particularly
+accurate, containing only the nearest truncated integer value.
+
+The ``MakeTable.cxx`` source file describes a program which will generate a
+better table. It takes a single argument as input, the file name of the table
+to be generated.
+
+Complete ``TODO 1`` through ``TODO 10``.
+
+Build and Run
+-------------
+
+No special configuration is needed, configure and build as usual. Note that
+the ``MakeTable`` executable is sequenced before ``MathFunctions``.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+Verify the output of ``Tutorial`` now uses the pre-computed table for values
+less than 10.
+
+Solution
+--------
+
+First we add a new executable to generate the tables, adding the
+``MakeTable.cxx`` file as a source.
+
+.. raw:: html
+
+  <details><summary>TODO 1-2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/MakeTable/CMakeLists.txt
+  :caption: TODO 1-2: MathFunctions/MakeTable/CMakeLists.txt
+  :name: MathFunctions/MakeTable/CMakeLists.txt-add_executable
+  :language: cmake
+  :start-at: add_executable
+  :end-at: MakeTable.cxx
+  :append: )
+
+.. raw:: html
+
+  </details>
+
+Then we add a custom command which produces the table, and custom target which
+depends on the table.
+
+.. raw:: html
+
+  <details><summary>TODO 3-4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/MakeTable/CMakeLists.txt
+  :caption: TODO 3-4: MathFunctions/MakeTable/CMakeLists.txt
+  :name: MathFunctions/MakeTable/CMakeLists.txt-add_custom_command
+  :language: cmake
+  :start-at: add_custom_command
+  :end-at: add_custom_target
+
+.. raw:: html
+
+  </details>
+
+We need to add an interface library which describes the output which will
+appear in :variable:`CMAKE_CURRENT_BINARY_DIR`. The ``FILES`` parameter is
+optional.
+
+.. raw:: html
+
+  <details><summary>TODO 5-6: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/MakeTable/CMakeLists.txt
+  :caption: TODO 5-6: MathFunctions/MakeTable/CMakeLists.txt
+  :name: MathFunctions/MakeTable/CMakeLists.txt-add_library
+  :language: cmake
+  :start-at: add_library
+  :end-at: SqrtTable.h
+  :append: )
+
+.. raw:: html
+
+  </details>
+
+Now that all the targets are described, we can force the custom target to run
+before any dependents of the interface library by associating them with
+:command:`add_dependencies`.
+
+.. raw:: html
+
+  <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/MakeTable/CMakeLists.txt
+  :caption: TODO 7: MathFunctions/MakeTable/CMakeLists.txt
+  :name: MathFunctions/MakeTable/CMakeLists.txt-add_dependencies
+  :language: cmake
+  :start-at: add_dependencies
+  :end-at: add_dependencies
+
+.. raw:: html
+
+  </details>
+
+We are ready to add the interface library to the linked libraries of
+``MathFunctions``, and add the entire ``MakeTable`` folder to the project.
+
+.. raw:: html
+
+  <details><summary>TODO 8-9: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
+  :caption: TODO 8: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-link-sqrttable
+  :language: cmake
+  :start-at: target_link_libraries(MathFunctions
+  :end-at: )
+
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
+  :caption: TODO 9: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-add-maketable
+  :language: cmake
+  :start-at: add_subdirectory(MakeTable
+  :end-at: add_subdirectory(MakeTable
+
+.. raw:: html
+
+  </details>
+
+Finally, we update the ``MathFunctions`` library itself to take advantage of
+the generated table.
+
+.. raw:: html
+
+  <details><summary>TODO 10: Click to show/hide answer</summary>
+
+.. literalinclude:: Step8/MathFunctions/MathFunctions.cxx
+  :caption: TODO 10: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-include-sqrttable
+  :language: c++
+  :start-at: #include <SqrtTable.h>
+  :end-at: {
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Finding Dependencies.rst b/Help/guide/tutorial/Finding Dependencies.rst
new file mode 100644
index 0000000..0ad3abc
--- /dev/null
+++ b/Help/guide/tutorial/Finding Dependencies.rst
@@ -0,0 +1,529 @@
+Step 10: Finding Dependencies
+=============================
+
+In C/C++ software development, managing build dependencies is consistently
+one of the highest ranked challenges facing modern developers. CMake provides
+an extensive toolset for discovering and validating dependencies of different
+kinds.
+
+However, for correctly packaged projects there is no need to use these advanced
+tools. Many popular library and utility projects today produce correct install
+trees, like the one we set up in ``Step 9``, which are easy is to integrate
+into CMake.
+
+In this best-case scenario, we only need the :command:`find_package` to
+import dependencies into our project.
+
+Background
+^^^^^^^^^^
+
+There are five principle commands used for discovering dependencies with
+CMake, the first four are:
+
+  :command:`find_file`
+    Finds and reports the full path to a named file, this tends to be the
+    most flexible of the ``find`` commands.
+
+  :command:`find_library`
+    Finds and reports the full path to a static archive or shared object
+    suitable for use with :command:`target_link_libraries`.
+
+  :command:`find_path`
+    Finds and reports the full path to a directory *containing* a file. This
+    is most commonly used for headers in combination with
+    :command:`target_include_directories`.
+
+  :command:`find_program`
+    Finds and reports and invocable name or path for a program. Often used in
+    combination with :command:`execute_process` or :command:`add_custom_command`.
+
+These commands should be considered "backup", used when the primary find command
+is unsuitable. The primary find command is :command:`find_package`. It uses
+comprehensive built-in heuristics and upstream-provided packaging files to
+provide the best interface to the requested dependency.
+
+Exercise 1 - Using ``find_package()``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The search paths and behaviors used by :command:`find_package` are fully
+described in its documentation, but much too verbose to replicate here. Suffice
+to say it searches well known, lesser known, obscure, and user-provided
+locations attempting to find a package which meets the requirements given to it.
+
+.. code-block:: cmake
+
+  find_package(ForeignLibrary)
+
+The best way to use :command:`find_package` is to ensure all dependencies have
+been installed to a single install tree prior to the build, and then make the
+location of that install tree known to :command:`find_package` via the
+:variable:`CMAKE_PREFIX_PATH` variable.
+
+.. note::
+  Building and installing dependencies can itself be an immense amount of labor.
+  While this tutorial will do so for illustration purposes, it is **extremely**
+  recommended that a package manager be used for project-local dependency
+  management.
+
+:command:`find_package` accepts several parameters besides the package to be
+found. The most notable are:
+
+* A positional ``<version>`` argument, for describing a version to be checked
+  against the package's config version file. This should be used sparingly,
+  it is better to control the version of the dependency being installed via
+  a package manager than possibly break the build on otherwise innocuous
+  version updates.
+
+  If the package is known to rely on an older version of a dependency, it
+  may be appropriate to use a version requirement.
+
+* ``REQUIRED`` for non-optional dependencies which should abort the build
+  if not found.
+
+* ``QUIET`` for optional dependencies which should not report anything to
+  users when not found.
+
+:command:`find_package` reports its results via ``<PackageName>_FOUND``
+variables, which will be set to a true or false value for found and not found
+packages respectively.
+
+Goal
+----
+
+Integrate an externally installed test framework into the Tutorial project.
+
+Helpful Resources
+-----------------
+
+* :command:`find_package`
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``TutorialProject/CMakePresets.json``
+* ``TutorialProject/Tests/CMakeLists.txt``
+* ``TutorialProject/Tests/TestMathFunctions.cxx``
+
+Getting Started
+---------------
+
+The ``Step10`` folder is organized differently than previous steps. The tutorial
+project we need to edit is under ``Step10/TutorialProject``. Another project
+is now present, ``SimpleTest``, as well as a partially populated install tree
+which we will use in later exercises. You do not need to edit anything in these
+other directories for this exercise, all ``TODOs`` and solution steps are for
+``TutorialProject``.
+
+The ``SimpleTest`` package provides two useful constructs, the
+``SimpleTest::SimpleTest`` target to be linked into a test binary, and the
+``simpletest_discover_tests`` function for automatically adding tests to
+CTest.
+
+Similar to other test frameworks, ``simpletest_discover_tests`` only needs
+to be passed the name of the executable target containing the tests.
+
+.. code-block:: cmake
+
+  simpletest_discover_tests(MyTestExe)
+
+The ``TestMathFunctions.cxx`` file has been updated to use the ``SimpleTest``
+framework in the vein of GoogleTest or Catch2. Perform ``TODO 1`` through
+``TODO 5`` in order to use the new test framework.
+
+.. note::
+  It may go without saying, but ``SimpleTest`` is a very poor test framework
+  which only facially resembles a functional testing library. While much of
+  the CMake code in this tutorial could be used unaltered in other projects,
+  you should not use ``SimpleTest`` outside this tutorial, or try to learn from
+  the CMake code it provides.
+
+Build and Run
+-------------
+
+First we must install the ``SimpleTest`` framework. Navigate to the
+``Help/guide/Step10/SimpleTest`` directory and run the following commands
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --install build
+
+.. note::
+  The ``SimpleTest`` preset sets up everything needed to install ``SimpleTest``
+  for the tutorial. For reasons that are beyond the scope of this tutorial,
+  there is no need to build or provide any other configuration for
+  ``SimpleTest``.
+
+We can observe that the ``Step10/install`` directory has now been populated by
+the ``SimpleTest`` header and package files.
+
+Now we can configure and build the Tutorial project as per usual, navigating to
+the ``Help/guide/Step10/TutorialProject`` and running:
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+Verify that the ``SimpleTest`` framework has been consumed correctly by running
+the tests with CTest.
+
+Solution
+--------
+
+First we call :command:`find_package` to discover the ``SimpleTest`` package.
+We do this with ``REQUIRED`` because the tests cannot build without
+``SimpleTest``.
+
+.. raw:: html
+
+  <details><summary>TODO 1 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tests/CMakeLists.txt
+  :caption: TODO 1: TutorialProject/Tests/CMakeLists.txt
+  :name: TutorialProject/Tests/CMakeLists.txt-find_package
+  :language: cmake
+  :start-at: find_package
+  :end-at: find_package
+
+.. raw:: html
+
+  </details>
+
+Next we add the ``SimpleTest::SimpleTest`` target to ``TestMathFunctions``
+
+.. raw:: html
+
+  <details><summary>TODO 2 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tests/CMakeLists.txt
+  :caption: TODO 2: TutorialProject/Tests/CMakeLists.txt
+  :name: TutorialProject/Tests/CMakeLists.txt-link-simple-test
+  :language: cmake
+  :start-at: target_link_libraries(TestMathFunctions
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Now we can replace our test description code with a call to
+``simpletest_discover_tests``.
+
+.. raw:: html
+
+  <details><summary>TODO 3 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tests/CMakeLists.txt
+  :caption: TODO 3: TutorialProject/Tests/CMakeLists.txt
+  :name: TutorialProject/Tests/CMakeLists.txt-simpletest_discover_tests
+  :language: cmake
+  :start-at: simpletest_discover_tests
+  :end-at: simpletest_discover_tests
+
+.. raw:: html
+
+  </details>
+
+We ensure :command:`find_package` can discover ``SimpleTest`` by
+adding the install tree to :variable:`CMAKE_PREFIX_PATH`.
+
+.. raw:: html
+
+  <details><summary>TODO 4 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/CMakePresets.json
+  :caption: TODO 4: TutorialProject/CMakePresets.json
+  :name: TutorialProject/CMakePresets.json-CMAKE_PREFIX_PATH
+  :language: json
+  :start-at: cacheVariables
+  :end-at: TUTORIAL_ENABLE_IPO
+  :dedent: 6
+  :append: }
+
+.. raw:: html
+
+  </details>
+
+Finally, we update the tests to use the macros provided by ``SimpleTest`` by
+removing the placeholders and including the appropriate header.
+
+.. raw:: html
+
+  <details><summary>TODO 5 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tests/TestMathFunctions.cxx
+  :caption: TODO 5: TutorialProject/Tests/TestMathFunctions.cxx
+  :name: TutorialProject/Tests/TestMathFunctions.cxx-simpletest
+  :language: c++
+  :start-at: #include <MathFunctions.h>
+  :end-at: {
+
+.. raw:: html
+
+  </details>
+
+Exercise 2 - Transitive Dependencies
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Libraries often build on one another. A multimedia application may depend on a
+library which provides support for various container formats, which may in turn
+rely on one or more other libraries for compression algorithms.
+
+We need to express these transitive requirements inside the package config
+files we place in the install tree. We do so with the
+:module:`CMakeFindDependencyMacro` module, which provides a safe mechanism for
+installed packages to recursively discover one another.
+
+.. code-block:: cmake
+
+  include(CMakeFindDependencyMacro)
+  find_dependency(zlib)
+
+:module:`find_dependency() <CMakeFindDependencyMacro>` also forwards arguments
+from the top-level :command:`find_package` call. If :command:`find_package` is
+called with ``QUIET`` or ``REQUIRED``,
+:module:`find_dependency() <CMakeFindDependencyMacro>` will also use ``QUIET``
+and/or ``REQUIRED``.
+
+Goal
+----
+
+Add a dependency to ``SimpleTest`` and ensure that packages which rely on
+``SimpleTest`` also discover this transitive dependency.
+
+Helpful Resources
+-----------------
+
+* :module:`CMakeFindDependencyMacro`
+* :command:`find_package`
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``SimpleTest/CMakeLists.txt``
+* ``SimpleTest/cmake/SimpleTestConfig.cmake``
+
+Getting Started
+---------------
+
+For this step we will only be editing the ``SimpleTest`` project. The transitive
+dependency, ``TransitiveDep``, is a dummy dependency which provides no behavior.
+However CMake doesn't know this and the ``TutorialProject`` tests will fail to
+configure and build if CMake cannot find all required dependencies.
+
+The ``TransitiveDep`` package has already been installed to the
+``Step10/install`` tree. We do not need to install it as we did with
+``SimpleTest``.
+
+Complete ``TODO 6`` through ``TODO 8``.
+
+Build and Run
+-------------
+
+We need to reinstall the SimpleTest framework. Navigate to the
+``Help/guide/Step10/SimpleTest`` directory and run the same commands as before.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --install build
+
+Now we can reconfigure and rebuild the ``TutorialProject``, navigate to
+``Help/guide/Step10/TutorialProject`` and perform the usual steps to do so.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+If the build passed we have likely successfully propagated the transitive
+dependency. Verify this by searching the ``CMakeCache.txt`` of
+``TutorialProject`` for an entry named ``TransitiveDep_DIR``. This demonstrates
+the ``TutorialProject`` searched for an found ``TransitiveDep`` even though it
+has no direct requirement for it.
+
+Solution
+--------
+
+First we call :command:`find_package` to discover the ``TransitiveDep`` package.
+We use ``REQUIRED`` to verify we have found ``TransitiveDep``.
+
+.. raw:: html
+
+  <details><summary>TODO 6 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/SimpleTest/CMakeLists.txt
+  :caption: TODO 6: SimpleTest/CMakeLists.txt
+  :name: SimpleTest/CMakeLists.txt-find_package
+  :language: cmake
+  :start-at: find_package
+  :end-at: find_package
+
+.. raw:: html
+
+  </details>
+
+Next we add the ``TransitiveDep::TransitiveDep`` target to ``SimpleTest``.
+
+.. raw:: html
+
+  <details><summary>TODO 7 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/SimpleTest/CMakeLists.txt
+  :caption: TODO 7: SimpleTest/CMakeLists.txt
+  :name: SimpleTest/CMakeLists.txt-link-transitive-dep
+  :language: cmake
+  :start-at: target_link_libraries(SimpleTest
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+.. note::
+  If we built ``TutorialProject`` at this point, we would expect the
+  configuration to fail due to the ``TransitiveDep::TransitiveDep`` target
+  being unavailable inside that project.
+
+Finally, we include the :module:`CMakeFindDependencyMacro` and call
+:module:`find_dependency() <CMakeFindDependencyMacro>` inside the ``SimpleTest``
+package config file to propagate the transitive dependency.
+
+.. raw:: html
+
+  <details><summary>TODO 8 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/SimpleTest/cmake/SimpleTestConfig.cmake
+  :caption: TODO 8: SimpleTest/cmake/SimpleTestConfig.cmake
+  :name: SimpleTest/cmake/SimpleTestConfig.cmake-find_dependency
+  :language: cmake
+  :start-at: include
+  :end-at: find_dependency
+
+.. raw:: html
+
+  </details>
+
+  </details>
+
+Exercise 3 - Finding Other Kinds of Files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In a perfect world every dependency we care about would be packaged correctly,
+or at least some other developer would have written a module that discovers it
+for us. We do not live in a perfect world, and sometimes we will have to get
+our hands dirty and discover build requirements manually.
+
+For this we have the other find commands enumerated earlier in the step, such
+as :command:`find_path`.
+
+.. code-block:: cmake
+
+  find_path(PackageIncludeFolder Package.h REQUIRED
+    PATH_SUFFIXES
+      Package
+  )
+  target_include_directories(MyApp
+    PRIVATE
+      ${PackageIncludeFolder}
+  )
+
+Goal
+----
+
+Add an unpackaged header to the ``Tutorial`` executable of the
+``TutorialProject``.
+
+Helpful Resources
+-----------------
+
+* :command:`find_path`
+* :command:`target_include_directories`
+
+Files to Edit
+-------------
+
+* ``TutorialProject/Tutorial/CMakeLists.txt``
+* ``TutorialProject/Tutorial/Tutorial.cxx``
+
+Getting Started
+---------------
+
+For this step we will only be editing the ``TutorialProject`` project. The
+unpackaged header, ``Unpackaged/Unpackaged.h`` has already been installed to the
+``Step10/install`` tree.
+
+Complete ``TODO 9`` through ``TODO 11``.
+
+Build and Run
+-------------
+
+There are no special build steps for this exercise, navigate to
+``Help/guide/Step10/TutorialProject`` and perform the usual build.
+
+.. code-block:: console
+
+  cmake --build build
+
+If the build passed we have successfully added the ``Unpackaged`` include
+directory to the project.
+
+Solution
+--------
+
+First we call :command:`find_path` to discover the ``Unpackaged`` include
+directory. We use ``REQUIRED`` because building ``Tutorial`` will fail if
+we cannot locate the ``Unpackaged.h`` header.
+
+.. raw:: html
+
+  <details><summary>TODO 9 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tutorial/CMakeLists.txt
+  :caption: TODO 9: TutorialProject/Tutorial/CMakeLists.txt
+  :name: TutorialProject/Tutorial/CMakeLists.txt-find_path
+  :language: cmake
+  :start-at: find_path
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Next we add the discovered path to ``Tutorial`` using
+:command:`target_include_directories`.
+
+.. raw:: html
+
+  <details><summary>TODO 10 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tutorial/CMakeLists.txt
+  :caption: TODO 10: TutorialProject/Tutorial/CMakeLists.txt
+  :name: TutorialProject/Tutorial/CMakeLists.txt-target_include_directories
+  :language: cmake
+  :start-at: target_include_directories
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Finally, we edit ``Tutorial.cxx`` to include the discovered header.
+
+.. raw:: html
+
+  <details><summary>TODO 11 Click to show/hide answer</summary>
+
+.. literalinclude:: Step11/TutorialProject/Tutorial/Tutorial.cxx
+  :caption: TODO 11: TutorialProject/Tutorial/Tutorial.cxx
+  :name: TutorialProject/Tutorial/Tutorial.cxx-include-unpackaged
+  :language: c++
+  :start-at: #include <MathFunctions.h>
+  :end-at: #include <Unpackaged.h>
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Getting Started with CMake.rst b/Help/guide/tutorial/Getting Started with CMake.rst
new file mode 100644
index 0000000..d72acb0
--- /dev/null
+++ b/Help/guide/tutorial/Getting Started with CMake.rst
@@ -0,0 +1,805 @@
+Step 1: Getting Started with CMake
+==================================
+
+This first step in the CMake tutorial is intended as a quick-start into writing
+useful builds for small projects with CMake. By the end, you will be able to
+describe executables, libraries, source and header files, and the linkage
+relationships between them using CMake.
+
+Each exercise in this step will start with a discussion of the concepts and
+commands needed for the exercise. Then, a goal and list of helpful resources are
+provided. Each file in the ``Files to Edit`` section is in the ``Step1``
+directory and contains one or more ``TODO`` comments. Each ``TODO`` represents
+a line or two of code to change or add. The ``TODOs`` are intended to be
+completed in numerical order, first complete  ``TODO 1`` then ``TODO 2``, etc.
+
+.. note::
+  Each step in the tutorial builds on the previous, but the steps are not
+  strictly contiguous. Code not relevant to learning CMake, such as C++
+  function implementations or CMake code outside the scope of the tutorial,
+  will sometimes be added between steps.
+
+The ``Getting Started`` section will give some helpful hints and guide you
+through the exercise. Then the ``Build and Run`` section will walk step-by-step
+through how to build and test the exercise. Finally, at the end of each exercise
+the intended solution is reviewed.
+
+Background
+^^^^^^^^^^
+
+Typical usage of CMake revolves around one or more files named
+``CMakeLists.txt``. This file is sometimes referred to as a "lists file" or
+"CML". Within a given software project, a ``CMakeLists.txt`` will exist within
+any directory where we want to provide instructions to CMake on how to handle
+files and operations local to that directory or subdirectories. Each consists of
+a set of commands which describe some information or actions relevant to
+building the software project.
+
+Not every directory in a software project needs a CML, but it's strongly
+recommended that the project root contains one. This will serve as the entry
+point for CMake for its initial setup during configuration. This *root* CML
+should always contain the same two commands at or near the top the file.
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.23)
+
+  project(MyProjectName)
+
+The :command:`cmake_minimum_required` is a compatibility guarantee provided by
+CMake to the project developer. When called, it ensures that CMake will adopt
+the behavior of the listed version. If a later version of CMake is invoked on a
+CML containing the above code, it will act exactly as if it were CMake 3.23.
+
+The :command:`project` command is a conceptually simple command which provides a
+complex function. It informs CMake that what follows is the description of a
+distinct software project of a given name (as opposed to a shell-like script).
+When CMake sees the :command:`project` command it performs various checks to
+ensure the environment is suitable for building software; such as checking for
+compilers and other build tooling, and discovering properties like the
+endianness of the host and target machines.
+
+.. note::
+  While links to complete documentation are provided for every command, it is
+  not intended the reader understand the full semantics of each CMake command
+  they use. Effectively learning CMake, like any piece of software, is an
+  incremental process.
+
+The rest of this tutorial step will be chiefly concerned with the usage of four
+more commands. The :command:`add_executable` and :command:`add_library` commands
+for describing output artifacts the software project wants to produce, the
+:command:`target_sources` command for associating input files with their
+respective output artifacts, and the :command:`target_link_libraries` command
+for associating output artifacts with one another.
+
+These four commands are the backbone of most CMake usage. As we'll learn, they
+are sufficient for describing the majority of a typical project's requirements.
+
+Exercise 1 - Building an Executable
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most basic CMake project is an executable built from a single source code
+file. For simple projects like this, a ``CMakeLists.txt`` file with only
+four commands is needed.
+
+.. note::
+  Although upper, lower and mixed case commands are supported by CMake,
+  lower case commands are preferred and will be used throughout the tutorial.
+
+The first two commands we have already introduced, :command:`cmake_minimum_required`
+and :command:`project`. There is no usage of CMake where the first command in a
+root CML will be anything other than :command:`cmake_minimum_required`. There
+are some advanced usages where :command:`project` might not be the second
+command in a CML, but for our purposes it always will be.
+
+The next command we need is :command:`add_executable`.
+This command creates a *target*. In CMake lingo, a target is a name the
+developer gives to a collection of properties.
+
+Some examples of properties a target might want to keep track of are:
+  - The artifact kind (executable, library, header collection, etc)
+  - Source files
+  - Include directories
+  - Output name of an executable or library
+  - Dependencies
+  - Compiler and linker flags
+
+The mechanisms of CMake are often best understood as describing and manipulating
+targets and their properties. There are many more properties than those listed
+here. Documentation of CMake commands will often discuss their function in terms
+of the target properties they operate on.
+
+Targets themselves are simply names, a handle to this collection of properties.
+Using the :command:`add_executable` command is as easy as specifying the name
+we want to use for the target.
+
+.. code-block:: cmake
+
+  add_executable(MyProgram)
+
+Now that we have a name for our target, we can start associating properties
+with it like source files we want to build and link. The primary command for
+this is :command:`target_sources`, which takes as arguments a target name
+followed by one or more collections of files.
+
+.. code-block:: cmake
+
+  target_sources(MyProgram
+    PRIVATE
+      main.cxx
+  )
+
+.. note::
+  Paths in CMake are generally either absolute, or relative to the
+  :variable:`CMAKE_CURRENT_SOURCE_DIR`. We haven't talked about variables like
+  that yet, so you can read this as "relative to the location of the current
+  CML".
+
+Each collection of files is prefixed by a :ref:`scope keyword <Target Command Scope>`.
+We'll discuss the complete semantics of these keywords when we talk about
+linking targets together, but the quick explanation is these describe how a
+property should be inherited by dependents of our target.
+
+Typically, nothing depends on an executable. Other programs and libraries don't
+need to link to an executable, or inherit headers, or anything of that nature.
+So the appropriate scope to use here is ``PRIVATE``, which informs CMake that
+this property only belongs to ``MyProgram`` and is not inheritable.
+
+.. note::
+  This rule is true almost everywhere. Outside advanced and esoteric usages,
+  the scope keyword for executables should *always* be ``PRIVATE``. The same
+  holds for implementation files generally, regardless of whether the target
+  is an executable or a library. The only target which needs to "see" the
+  ``.cxx`` files is the target building them.
+
+Goal
+----
+
+Understand how to create a simple CMake project with a single executable.
+
+Helpful Resources
+-----------------
+
+* :command:`project`
+* :command:`cmake_minimum_required`
+* :command:`add_executable`
+* :command:`target_sources`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+----------------
+
+The source code for ``Tutorial.cxx`` is provided in the
+``Help/guide/tutorial/Step1/Tutorial`` directory and can be used to compute the
+square root of a number. This file does not need to be edited in this exercise.
+
+In the parent directory, ``Help/guide/tutorial/Step1``, is a ``CMakeLists.txt``
+file which you will complete. Start with ``TODO 1`` and work through ``TODO 4``.
+
+Build and Run
+-------------
+
+Once ``TODO 1`` through ``TODO 4`` have been completed, we are ready to build
+and run our project! First, run the :manual:`cmake <cmake(1)>` executable or the
+:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
+with your chosen build tool.
+
+For example, from the command line we could navigate to the
+``Help/guide/tutorial/Step1`` directory and invoke CMake for configuration
+as follows:
+
+.. code-block:: console
+
+  cmake -B build
+
+The :option:`-B <cmake -B>` flag tells CMake to use the given relative
+path as the location to generate files and store artifacts during the build
+process. If it is omitted, the current working directory is used. It is
+generally considered bad practice to do "in-source" builds, placing these
+generated files in the source tree itself.
+
+Next, tell CMake to build the project with
+:option:`cmake --build <cmake --build>`, passing it the same relative path
+we did with the :option:`-B <cmake -B>` flag.
+
+.. code-block:: console
+
+  cmake --build build
+
+The ``Tutorial`` executable will be built into the ``build`` directory. For
+multi-config generators (e.g. Visual Studio), it might be placed in a
+subdirectory such as ``build/Debug``.
+
+Finally, try to use the newly built ``Tutorial``:
+
+.. code-block:: console
+
+  Tutorial 4294967296
+  Tutorial 10
+  Tutorial
+
+.. note::
+  Depending on the shell, the correct syntax may be ``Tutorial``,
+  ``./Tutorial``, ``.\Tutorial``, or even ``.\Tutorial.exe``. For simplicity,
+  the exercises will use ``Tutorial`` throughout.
+
+Solution
+--------
+
+As mentioned above, a four command ``CMakeLists.txt`` is all that we need to get
+up and running. The first line should be :command:`cmake_minimum_required`, to
+set the CMake version as follows:
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/CMakeLists.txt
+  :caption: TODO 1: CMakeLists.txt
+  :name: CMakeLists.txt-cmake_minimum_required
+  :language: cmake
+  :start-at: cmake_minimum_required
+  :end-at: cmake_minimum_required
+
+.. raw:: html
+
+  </details>
+
+The next step to make a basic project is to use the :command:`project`
+command as follows to set the project name and inform CMake we intend to build
+software with this ``CMakeLists.txt``.
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/CMakeLists.txt
+  :caption: TODO 2: CMakeLists.txt
+  :name: CMakeLists.txt-project
+  :language: cmake
+  :start-at: project
+  :end-at: project
+
+.. raw:: html
+
+  </details>
+
+Now we can setup our executable target for the Tutorial with :command:`add_executable`.
+
+.. raw:: html
+
+  <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/Tutorial/CMakeLists.txt
+  :caption: TODO 3: CMakeLists.txt
+  :name: CMakeLists.txt-add_executable
+  :language: cmake
+  :start-at: add_executable
+  :end-at: add_executable
+
+.. raw:: html
+
+  </details>
+
+Finally, we can associate our source file with the Tutorial executable target
+using :command:`target_sources`.
+
+.. raw:: html
+
+  <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 4: CMakeLists.txt
+  :name: CMakeLists.txt-target_sources
+
+  target_sources(Tutorial
+    PRIVATE
+      Tutorial/Tutorial.cxx
+  )
+
+
+.. raw:: html
+
+  </details>
+
+Exercise 2 - Building a Library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We only need to introduce one more command to build a library,
+:command:`add_library`. This works exactly like :command:`add_executable`, but
+for libraries.
+
+.. code-block:: cmake
+
+  add_library(MyLibrary)
+
+However, now is a good time to introduce header files. Header files are not
+directly built as translation units, which is to say they are not a *build*
+requirement. They are a *usage* requirement. We need to know about header files
+in order to build other parts of a given target.
+
+As such, header files are described slightly differently than implementation
+files like ``tutorial.cxx``. They're also going to need different
+:ref:`scope keywords <Target Command Scope>` than the ``PRIVATE`` keyword we
+have used so far.
+
+To describe a collection of header files, we're going to use what's known as a
+``FILE_SET``.
+
+.. code-block:: cmake
+
+  target_sources(MyLibrary
+    PRIVATE
+      library_implementation.cxx
+
+    PUBLIC
+      FILE_SET myHeaders
+      TYPE HEADERS
+      BASE_DIRS
+        include
+      FILES
+        include/library_header.h
+  )
+
+This is a lot of complexity, but we'll go through it point by point. First,
+note that we have our implementation file as a ``PRIVATE`` source, same as
+with the executable previously. However, we now use ``PUBLIC`` for our
+header file. This allows consumers of our library to "see" the library's
+header files.
+
+.. note::
+  We're not quite ready to discuss the full semantics of scope keywords. We'll
+  cover them more completely in Exercise 3.
+
+Following the scope keyword is a ``FILE_SET``, a collection of files to be
+described as a single unit. A ``FILE_SET`` consists of the following parts:
+
+* ``FILE_SET <name>`` is the name of the ``FILE_SET``. This is a handle which
+  we can use to describe the collection in other contexts.
+
+* ``TYPE <type>`` is the kind of files we are describing. Most commonly this
+  will be headers, but newer versions of CMake support other types like C++20
+  modules.
+
+* ``BASE_DIRS`` is the "base" locations for the files. This can be most easily
+  understood as the locations that will be described to compilers for header
+  discovery via ``-I`` flags.
+
+* ``FILES`` is the list of files, same as with the implementation sources list
+  earlier.
+
+This is a lot of information to describe, so there are some useful shortcuts
+we can take. Notably, if the ``FILE_SET`` name is the same as the type, we
+don't need to provide the ``TYPE`` field.
+
+.. code-block:: cmake
+
+  target_sources(MyLibrary
+    PRIVATE
+      library_implementation.cxx
+
+    PUBLIC
+      FILE_SET HEADERS
+      BASE_DIRS
+        include
+      FILES
+        include/library_header.h
+  )
+
+There are other shortcuts we can take, but we'll discuss those more in later
+steps.
+
+Goal
+----
+
+Build a library.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+* :command:`target_sources`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+Continue editing files in the ``Step1`` directory. Start with ``TODO 5`` and
+complete through ``TODO 6``.
+
+Build and Run
+-------------
+
+Let's build our project again. Since we already created a build directory and
+ran CMake for Exercise 1, we can skip to the build step:
+
+.. code-block:: console
+
+  cmake --build build
+
+We should be able to see our library created alongside the Tutorial executable.
+
+Solution
+--------
+
+We start by adding the library target in the same manner as the the Tutorial
+executable.
+
+.. raw:: html
+
+  <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+  :caption: TODO 5: CMakeLists.txt
+  :name: CMakeLists.txt-add_library
+  :language: cmake
+  :start-at: add_library
+  :end-at: add_library
+
+.. raw:: html
+
+  </details>
+
+Next we need to describe the source files. For the implementation file,
+``MathFunctions.cxx``, this is straight-forward; for the header file
+``MathFunctions.h`` we will need to use a ``FILE_SET``.
+
+We can either give this ``FILE_SET`` its own name, or use the shortcut of naming
+it ``HEADERS``. For this tutorial, we'll be using the shortcut, but either
+solution is valid.
+
+For ``BASE_DIRS`` we need to determine the directory which will allow for the
+desired ``#include <MathFunctions.h>`` directive. To achieve this, the
+``MathFunctions`` folder itself will be a base directory. We would make a
+different choice if the desired include directive were
+``#include <MathFunctions/MathFunctions.h>`` or similar.
+
+.. raw:: html
+
+  <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 6: CMakeLists.txt
+  :name: CMakeLists.txt-library_sources
+
+  target_sources(MathFunctions
+    PRIVATE
+      MathFunctions/MathFunctions.cxx
+
+    PUBLIC
+      FILE_SET HEADERS
+      BASE_DIRS
+        MathFunctions
+      FILES
+        MathFunctions/MathFunctions.h
+  )
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Linking Together Libraries and Executables
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We're ready to combine our library with our executable, for this we must
+introduce a new command, :command:`target_link_libraries`. The name of this
+command can be somewhat misleading, as it does a great deal more than just
+invoke linkers. It describes relationships between targets generally.
+
+.. code-block:: cmake
+
+  target_link_libraries(MyProgram
+    PRIVATE
+      MyLibrary
+  )
+
+We're finally ready to discuss the :ref:`scope keywords <Target Command Scope>`.
+There are three of them, ``PRIVATE``, ``INTERFACE``, and ``PUBLIC``. These
+describe how properties are made available to targets.
+
+* A ``PRIVATE`` property (also called a "non-interface" property) is only
+  available to the target which owns it, for example ``PRIVATE`` headers will
+  only be visible to the target they're attached to.
+
+* An ``INTERFACE`` property is only available to targets *which link* the
+  owning target. The owning target does not have access to these properties. A
+  header-only library is an example of a collection of ``INTERFACE`` properties,
+  as header-only libraries do not build anything themselves and do not need to
+  access their own files.
+
+* ``PUBLIC`` is not a distinct kind of property, but rather is the union of the
+  ``PRIVATE`` and ``INTERFACE`` properties. Thus requirements described with
+  ``PUBLIC`` are available to both the owning target and consuming targets.
+
+Consider the following concrete example:
+
+.. code-block:: cmake
+
+  target_sources(MyLibrary
+    PRIVATE
+      FILE_SET internalOnlyHeaders
+      TYPE HEADERS
+      FILES
+        InternalOnlyHeader.h
+
+    INTERFACE
+      FILE_SET consumerOnlyHeaders
+      TYPE HEADERS
+      FILES
+        ConsumerOnlyHeader.h
+
+    PUBLIC
+      FILE_SET publicHeaders
+      TYPE HEADERS
+      FILES
+        PublicHeader.h
+  )
+
+.. note::
+  We excluded ``BASE_DIRS`` for each file set here, that's another shortcut.
+  When excluded, ``BASE_DIRS`` defaults to the current source directory.
+
+The ``MyLibrary`` target has several properties which will be modified by this
+call to :command:`target_sources`. Until now we've used the term "properties"
+generically, but properties are themselves named values we can reason about.
+Two specific properties which will be modified here are :prop_tgt:`HEADER_SETS`
+and :prop_tgt:`INTERFACE_HEADER_SETS`, which both contain lists of header file
+sets added via :command:`target_sources`.
+
+The value ``internalOnlyHeaders`` will be added to :prop_tgt:`HEADER_SETS`,
+``consumerOnlyHeaders`` to :prop_tgt:`INTERFACE_HEADER_SETS`, and
+``publicHeaders`` will be added to both.
+
+When a given target is being built, it will use its own *non-interface*
+properties (eg, :prop_tgt:`HEADER_SETS`), combined with the *interface*
+properties of any targets it links to (eg, :prop_tgt:`INTERFACE_HEADER_SETS`).
+
+.. note::
+  **It is not necessary to reason about CMake properties at this level of
+  detail.** The above is described for completeness. Most of the time you don't
+  need to be concerned with the specific properties a command is modifying.
+
+  Scope keywords have a simple intuition associated with them, when considering
+  a command from the point of view of the target it is being applied to:
+  **PRIVATE** is for me, **INTERFACE** is for others, **PUBLIC** is for all of
+  us.
+
+Goal
+----
+
+In the Tutorial executable, use the ``sqrt()`` function provided by the
+``MathFunctions`` library.
+
+Helpful Resources
+-----------------
+
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``Tutorial/Tutorial.cxx``
+
+Getting Started
+---------------
+
+Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
+``TODO 9``. In this exercise, we need to add the ``MathFunctions`` target to
+the ``Tutorial`` target's linked libraries using :command:`target_link_libraries`.
+
+After modifying the CML, update ``tutorial.cxx`` to use the
+``mathfunctions::sqrt()`` function instead of ``std::sqrt``.
+
+Build and Run
+-------------
+
+Let's build our project again. As before, we already created a build directory
+and ran CMake so we can skip to the build step:
+
+.. code-block:: console
+
+  cmake --build build
+
+Verify that the output matches what you would expect from the ``MathFunctions``
+library.
+
+Solution
+--------
+
+In this exercise, we are describing the ``Tutorial`` executable as a consumer
+of the ``MathFunctions`` target by adding ``MathFunctions`` to the linked
+libraries of the ``Tutorial``.
+
+To achieve this, we modify ``CMakeLists.txt`` file to use the
+:command:`target_link_libraries` command, using ``Tutorial`` as the target to
+be modified and ``MathFunctions`` as the library we want to add.
+
+.. raw:: html
+
+  <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/Tutorial/CMakeLists.txt
+  :caption: TODO 7: CMakeLists.txt
+  :name: CMakeLists.txt-target_link_libraries
+  :language: cmake
+  :start-at: target_link_libraries(Tutorial
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+.. note::
+  The order here is only loosely relevant. That we call
+  :command:`target_link_libraries` prior to defining ``MathFunctions`` with
+  :command:`add_library` doesn't matter to CMake. We are recording that
+  ``Tutorial`` has a dependency on something named ``MathFunctions``, but what
+  ``MathFunctions`` means isn't resolved at this stage.
+
+  The only target which needs to be defined when calling a CMake command like
+  :command:`target_sources` or :command:`target_link_libraries` is the target
+  being modified.
+
+Finally, all that's left to do is modify ``Tutorial.cxx`` to use the newly
+provided ``mathfunctions::sqrt`` function. That means adding the appropriate
+header file and modifying our ``sqrt()`` call.
+
+.. raw:: html
+
+  <details><summary>TODO 8-9: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/Tutorial/Tutorial.cxx
+  :caption: TODO 8: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-MathFunctions-headers
+  :language: c++
+  :start-at: iostream
+  :end-at: MathFunctions.h
+
+.. literalinclude:: Step3/Tutorial/Tutorial.cxx
+  :caption: TODO 9: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-MathFunctions-code
+  :language: c++
+  :start-at: calculate square root
+  :end-at: mathfunctions::sqrt
+  :dedent: 2
+
+.. raw:: html
+
+  </details>
+
+Exercise 4 - Subdirectories
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+As we move through the tutorial, we will be adding more commands to manipulate
+the ``Tutorial`` executable and the ``MathFunctions`` library. We want to make
+sure we keep commands local to the files they are dealing with. While not a
+major concern for a small project like this, it can be very useful for large
+projects with many targets and thousands of files.
+
+The :command:`add_subdirectory` command allows us to incorporate CMLs located
+in subdirectories of the project.
+
+.. code-block:: cmake
+
+  add_subdirectory(SubdirectoryName)
+
+When a ``CMakeLists.txt`` in a subdirectory is being processed by CMake all
+relative paths described in the subdirectory CML are relative to that
+subdirectory, not the top-level CML.
+
+Goal
+----
+
+Use :command:`add_subdirectory` to organize the project.
+
+Helpful Resources
+-----------------
+
+* :command:`add_subdirectory`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``Tutorial/CMakeLists.txt``
+* ``MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+The ``TODOs`` for this step are spread across three ``CMakeLists.txt`` files.
+Be sure to pay attention to the path changes necessary when moving the
+:command:`target_sources` commands into subdirectories.
+
+.. note::
+  Previously we said that ``BASE_DIRS`` defaults to the current source
+  directory. As the desired include directory for ``MathFunctions`` will now be
+  the same directory as the CML calling :command:`target_sources`, we should
+  remove the ``BASE_DIRS`` keyword and argument entirely.
+
+Complete ``TODO 10`` through ``TODO 13``.
+
+Build and Run
+-------------
+
+Because of the reorganization, we'll need to clean the original build
+directory prior to rebuilding (otherwise our new ``Target`` build folder would
+conflict with our previously created ``Target`` executable). We can achieve
+this with the :option:`--clean-first <cmake--build --clean-first>` flag.
+
+There's no need for a reconfiguration. CMake will automatically
+re-configure itself due to the changes in the CMLs.
+
+.. code-block:: console
+
+  cmake --build build --clean-first
+
+.. note::
+  Our executable and library will be output to a new location in the build tree.
+  A subdirectory which mirrors where :command:`add_executable` and
+  :command:`add_library` were called in the source tree. You will need to
+  navigate to this subdirectory in the build tree to run the tutorial
+  executable in future steps.
+
+  You can verify this behavior by deleting the old ``Tutorial`` executable,
+  and observing that the new one is produced at ``Tutorial/Tutorial``.
+
+Solution
+--------
+
+We need to move all the commands concerning the ``Tutorial`` executable into
+``Tutorial/CMakeLists.txt``, and replace them with an
+:command:`add_subdirectory` command. We also need to update the path for
+``Tutorial.cxx``.
+
+.. raw:: html
+
+  <details><summary>TODO 10-11: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/Tutorial/CMakeLists.txt
+  :caption: TODO 10: Tutorial/CMakeLists.txt
+  :name: Tutorial/CMakeLists.txt-moved
+  :language: cmake
+
+.. code-block:: cmake
+  :caption: TODO 11: CMakeLists.txt
+  :name: CMakeLists.txt-add_subdirectory-Tutorial
+
+  add_subdirectory(Tutorial)
+
+.. raw:: html
+
+  </details>
+
+We need to do the same with the commands for ``MathFunctions``, changing the
+relative paths as appropriate and removing ``BASE_DIRS`` as it is no longer
+necessary, the default value will work.
+
+.. raw:: html
+
+  <details><summary>TODO 12-13: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
+  :caption: TODO 12: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-moved
+  :language: cmake
+
+.. literalinclude:: Step3/CMakeLists.txt
+  :caption: TODO 13: CMakeLists.txt
+  :name: CMakeLists.txt-add_subdirectory-MathFunctions
+  :language: cmake
+  :start-at: add_subdirectory(MathFunctions
+  :end-at: add_subdirectory(MathFunctions
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/In-Depth CMake Library Concepts.rst b/Help/guide/tutorial/In-Depth CMake Library Concepts.rst
new file mode 100644
index 0000000..d59ab93
--- /dev/null
+++ b/Help/guide/tutorial/In-Depth CMake Library Concepts.rst
@@ -0,0 +1,446 @@
+Step 5: In-Depth CMake Library Concepts
+=======================================
+
+While executables are mostly one-size-fits-all, libraries come in many
+different forms. There are static archives, shared objects, modules,
+object libraries, header-only libraries, and libraries which describe advanced
+CMake properties to be inherited by other targets, just to name a few.
+
+In this step you will learn about some of the most common kinds of libraries
+that CMake can describe. This will cover most of the in-project uses of
+:command:`add_library`. Libraries which are imported from dependencies (or
+exported by the project to be consumed as a dependency) will be covered in
+later steps.
+
+Background
+^^^^^^^^^^
+
+As we learned in ``Step1``, the :command:`add_library` command accepts the name
+of the library target to be created as its first argument. The second
+argument is an optional ``<type>`` for which the following values are valid:
+
+  ``STATIC``
+    A :ref:`Static Library <Static Libraries>`:
+    an archive of object files for use when linking other targets.
+
+  ``SHARED``
+    A :ref:`Shared Library <Shared Libraries>`:
+    a dynamic library that may be linked by other targets and loaded
+    at runtime.
+
+  ``MODULE``
+    A :ref:`Module Library <Module Libraries>`:
+    a plugin that may not be linked by other targets, but may be
+    dynamically loaded at runtime using dlopen-like functionality.
+
+  ``OBJECT``
+    An :ref:`Object Library <Object Libraries>`:
+    a collection of object files which have not been archived or linked
+    into a library.
+
+  ``INTERFACE``
+    An :ref:`Interface Library <Interface Libraries>`:
+    a library target which specifies usage requirements for dependents but
+    does not compile sources and does not produce a library artifact on disk.
+
+In addition, there are ``IMPORTED`` libraries which describe library targets
+from foreign projects or modules, imported into the current project. We will
+cover these briefly in later steps.
+
+``MODULE`` libraries are most commonly found in plugin systems, or as extensions
+to runtime-loading languages like Python or Javascript. They act very similar to
+normal shared libraries, except they cannot be directly linked by other targets.
+They are sufficiently similar that we won't cover them in further depth here.
+
+Exercise 1 - Static and Shared
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+While the :command:`add_library` command supports explicitly setting ``STATIC``
+or ``SHARED``, and this is sometimes necessary, it is best to leave the second
+argument empty for most "normal" libraries which can operate as either.
+
+When not given a type, :command:`add_library` will create either a ``STATIC``
+or ``SHARED`` library depending on the value of :variable:`BUILD_SHARED_LIBS`.
+If :variable:`BUILD_SHARED_LIBS` is true, a ``SHARED`` library will be created,
+otherwise it will be ``STATIC``.
+
+.. code-block:: cmake
+
+  add_library(MyLib-static STATIC)
+  add_library(MyLib-shared SHARED)
+
+  # Depends on BUILD_SHARED_LIBS
+  add_library(MyLib)
+
+This is desirable behavior, as it allows packagers to determine what kind of
+library will be produced, and ensure dependents link to that version of the
+library without needing to modify their source code. In some contexts, fully
+static builds are appropriate, and in others shared libraries are desirable.
+
+.. note::
+  CMake does not define the :variable:`BUILD_SHARED_LIBS` variable by default,
+  meaning without project or user intervention :command:`add_library` will
+  produce ``STATIC`` libraries.
+
+By leaving the second argument to :command:`add_library()` blank, projects
+provide additional flexibility to their packagers and downstream dependents.
+
+Goal
+----
+
+Build ``MathFunctions`` as a shared library.
+
+.. note::
+  On Windows, you might see warnings about an empty DLL, as ``MathFunctions``
+  doesn't export any symbols.
+
+Helpful Resources
+-----------------
+
+* :variable:`BUILD_SHARED_LIBS`
+
+Files to Edit
+-------------
+
+There are no files to edit.
+
+Getting Started
+---------------
+
+The ``Help/guide/tutorial/Step5`` directory contains the complete, recommended
+solution to ``Step4``. This step is about building the ``MathFunctions``
+library, there are no ``TODOs`` necessary. You can proceed directly to the
+build step.
+
+Build and Run
+-------------
+
+We can configure using our preset, turning on :variable:`BUILD_SHARED_LIBS` with
+a :option:`-D <cmake -D>` flag.
+
+.. code-block:: console
+
+  cmake --preset tutorial -DBUILD_SHARED_LIBS=ON
+
+Then we can build only the ``MathFunctions`` library with
+:option:`-t <cmake--build -t>`.
+
+.. code-block:: console
+
+  cmake --build build -t MathFunctions
+
+Verify a shared library is produced for ``MathFunctions`` then reset
+:variable:`BUILD_SHARED_LIBS`, either by reconfiguring with
+``-DBUILD_SHARED_LIBS=OFF`` or deleting the ``CMakeCache.txt``.
+
+Solution
+--------
+
+There are no changes to the project for this exercise.
+
+Exercise 2 - Interface Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Interface libraries are those which only communicate usage requirements for
+other targets, they do not build or produce any artifacts of their own. As such
+all the properties of an interface library must themselves be interface
+properties, specified with the ``INTERFACE`` :ref:`scope keywords <Target Command Scope>`.
+
+.. code-block:: cmake
+
+  add_library(MyInterface INTERFACE)
+  target_compile_definitions(MyInterface INTERFACE MYINTERFACE_COMPILE_DEF)
+
+The most common kind of interface library in C++ development is a header-only
+library. Such libraries do not build anything, only providing the flags
+necessary to discover their headers.
+
+Goal
+----
+
+Add a header-only library to the tutorial project, and use it inside the
+``Tutorial`` executable.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+* :command:`target_sources`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/MathLogger/CMakeLists.txt``
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
+
+Getting Started
+---------------
+
+In our previous discussions of :command:`target_sources(FILE_SET)`, we noted
+we can omit the ``TYPE`` parameter if the file set's name is the same as the
+file set's type. We also said we can omit the ``BASE_DIRS`` parameter if
+we want to use the current source directory as the only base directory.
+
+We're ready to introduce a third shortcut, we only need to include the ``FILES``
+parameter if the headers are intended to be installed, such as public headers
+of a library.
+
+The ``MathLogger`` headers in this exercise are only used internally by the
+``MathFunctions`` implementation. They will not be installed. This should
+make for a very abbreviated call to :command:`target_sources(FILE_SET)`.
+
+.. note::
+  The headers will be discovered by the compiler's dependency scanner to ensure
+  correct incremental builds. It can be useful to list header files in these
+  contexts anyway, as the list can be used to generate metadata some IDEs
+  rely on.
+
+You can begin editing the ``Step5`` directory. Complete ``TODO 1`` through
+``TODO 7``.
+
+Build and Run
+-------------
+
+The preset has already been updated to use ``mathfunctions::sqrt`` instead of
+``std::sqrt``. We can build and configure as usual.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+Verify that the ``Tutorial`` output now uses the logging framework.
+
+Solution
+--------
+
+First we add a new ``INTERFACE`` library named ``MathLogger``.
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/MathLogger/CMakeLists.txt
+  :caption: TODO 1: MathFunctions/MathLogger/CMakeLists.txt
+  :name: MathFunctions/MathLogger/CMakeLists.txt-add_library
+  :language: cmake
+  :start-at: add_library
+  :end-at: add_library
+
+.. raw:: html
+
+  </details>
+
+Then we add the appropriate :command:`target_sources` call to capture the
+header information. We give this file set the name ``HEADERS`` so we can
+omit the ``TYPE``, we don't need ``BASE_DIRS`` as we will use the default
+of the current source directory, and we can exclude the ``FILES`` list because
+we don't intend to install the library.
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/MathLogger/CMakeLists.txt
+  :caption: TODO 2: MathFunctions/MathLogger/CMakeLists.txt
+  :name: MathFunctions/MathLogger/CMakeLists.txt-target_sources
+  :language: cmake
+  :start-at: target_sources(
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Now we can add the ``MathLogger`` library to the ``MathFunctions`` linked
+libraries, and at the ``MathLogger`` folder to the project.
+
+.. raw:: html
+
+  <details><summary>TODO 3-4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+  :caption: TODO 3: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-link-mathlogger
+  :language: cmake
+  :start-at: target_link_libraries(
+  :end-at: MathLogger
+  :append: )
+
+.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+  :caption: TODO 4: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-add-mathlogger
+  :language: cmake
+  :start-at: add_subdirectory(MathLogger
+  :end-at: add_subdirectory(MathLogger
+
+.. raw:: html
+
+  </details>
+
+Finally we can update ``MathFunctions.cxx`` to take advantage of the new logger.
+
+.. raw:: html
+
+  <details><summary>TODO 5-7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/MathFunctions.cxx
+  :caption: TODO 5: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-mathlogger-header
+  :language: c++
+  :start-at: cmath
+  :end-at: MathLogger
+
+.. literalinclude:: Step6/MathFunctions/MathFunctions.cxx
+  :caption: TODO 6: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-mathlogger-logger
+  :language: c++
+  :start-at: mathlogger::Logger Logger
+  :end-at: mathlogger::Logger Logger
+
+.. literalinclude:: Step6/MathFunctions/MathFunctions.cxx
+  :caption: TODO 7: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-mathlogger-code
+  :language: c++
+  :start-at: Logger.Log(std::format("Computing sqrt of {} to be {}\n"
+  :end-at: std::format
+  :dedent: 4
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Object Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Object libraries have several advanced uses, but also tricky nuances which
+are difficult to fully enumerate in the scope of this tutorial.
+
+.. code-block:: cmake
+
+  add_library(MyObjects OBJECT)
+
+The most obvious drawback to object libraries is the objects themselves cannot
+be transitively linked. If an object library appears in the
+:prop_tgt:`INTERFACE_LINK_LIBRARIES` of a target, the dependents which link that
+target will not "see" the objects. The object library will act like an
+``INTERFACE`` library in such contexts. In the general case, object libraries
+are only suitable for ``PRIVATE`` or ``PUBLIC`` consumption via
+:command:`target_link_libraries`.
+
+A common use case for object libraries is coalescing several library targets
+into a single archive or shared library object. Even within a single project
+libraries may be maintained as different targets for a variety of reasons, such
+as belonging to different teams within an organization. However, it may be
+desirable to distribute these as a single consumer-facing binary. Object
+libraries make this possible.
+
+Goal
+----
+
+Add several object libraries to the ``MathFunctions`` library.
+
+Helpful Resources
+-----------------
+
+* :command:`target_link_libraries`
+* :command:`add_subdirectory`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.h``
+* ``Tutorial/Tutorial.cxx``
+
+Getting Started
+---------------
+
+Several extensions for our ``MathFunctions`` library have been made available
+(we can imagine these coming from other teams in our organization). Take
+a minute to look at the targets made available in ``MathFunctions/MathExtensions``.
+Then complete ``TODO 8`` through ``TODO 11``.
+
+Build and Run
+-------------
+
+There's no reconfiguration needed, we can build as usual.
+
+.. code-block:: console
+
+  cmake --build build
+
+Verify the output of ``Tutorial`` now includes the verification message. Also
+take a minute to inspect the build directory under
+``build/MathFunctions/MathExtensions``. You should find that, unlike
+``MathFunctions``, no archives are produced for any of the object libraries.
+
+Solution
+--------
+
+First we will add links for all the object libraries to ``MathFunctions``.
+These are ``PUBLIC``, because we want the objects to be added to the
+``MathFunctions`` library as part of its own build step, and we want the
+headers to be available to consumers of the library.
+
+Then we add the ``MathExtensions`` subdirectoy to the project.
+
+.. raw:: html
+
+  <details><summary>TODO 8-9: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+  :caption: TODO 8: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-link-objects
+  :language: cmake
+  :start-at: target_link_libraries(
+  :end-at: )
+
+.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+  :caption: TODO 9: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-add-objs
+  :language: cmake
+  :start-at: add_subdirectory(MathExtensions
+  :end-at: add_subdirectory(MathExtensions
+
+.. raw:: html
+
+  </details>
+
+
+To make the extensions available to consumers, we include their headers in the
+``MathFunctions.h`` header.
+
+.. raw:: html
+
+  <details><summary>TODO 10: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/MathFunctions/MathFunctions.h
+  :caption: TODO 10: MathFunctions/MathFunctions.h
+  :name: MathFunctions/MathFunctions.h-include-objects
+  :language: c++
+  :start-at: OpAdd
+  :end-at: OpSub
+
+.. raw:: html
+
+  </details>
+
+Finally we can take advantage of the extensions in the ``Tutorial`` program.
+
+.. raw:: html
+
+  <details><summary>TODO 11: Click to show/hide answer</summary>
+
+.. literalinclude:: Step6/Tutorial/Tutorial.cxx
+  :caption: TODO 11: Tutorial/Tutorial.cxx
+  :name: Tutorial/Tutorial.cxx-use-objects
+  :language: c++
+  :start-at: OpMul
+  :end-at: checkValue);
+  :dedent: 2
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/In-Depth CMake Target Commands.rst b/Help/guide/tutorial/In-Depth CMake Target Commands.rst
new file mode 100644
index 0000000..842b0d5
--- /dev/null
+++ b/Help/guide/tutorial/In-Depth CMake Target Commands.rst
@@ -0,0 +1,544 @@
+Step 4: In-Depth CMake Target Commands
+======================================
+
+There are several target commands within CMake we can use to describe
+requirements. As a reminder, a target command is one which modifies the
+properties of the target it is applied to. These properties describe
+requirements needed to build the software, such as sources, compile flags,
+and output names; or properties necessary to consume the target, such as header
+includes, library directories, and linkage rules.
+
+.. note::
+  As discussed in ``Step1``, properties required to build a target should be
+  described with the ``PRIVATE`` :ref:`scope keyword <Target Command Scope>`,
+  those required to consume the target with ``INTERFACE``, and properties needed
+  for both are described with ``PUBLIC``.
+
+In this step we will go over all the available target commands in CMake. Not all
+target commands are created equal. We have already discussed the two most
+important target commands, :command:`target_sources` and
+:command:`target_link_libraries`. Of the remaining commands, some are almost
+as common as these two, others have more advanced applications, and a couple
+should only be used as a last resort when other options are not available.
+
+Background
+^^^^^^^^^^
+
+Before going any further, let's name all of the CMake target commands. We'll
+split these into three groups: the recommended and generally useful commands,
+the advanced and cautionary commands, and the "footgun" commands which should
+be avoided unless necessary.
+
++-----------------------------------------+--------------------------------------+---------------------------------------+
+| Common/Recommended                      | Advanced/Caution                     | Esoteric/Footguns                     |
++=========================================+======================================+=======================================+
+| :command:`target_compile_definitions`   | :command:`get_target_property`       | :command:`target_include_directories` |
+| :command:`target_compile_features`      | :command:`set_target_properties`     | :command:`target_link_directories`    |
+| :command:`target_link_libraries`        | :command:`target_compile_options`    |                                       |
+| :command:`target_sources`               | :command:`target_link_options`       |                                       |
+|                                         | :command:`target_precompile_headers` |                                       |
++-----------------------------------------+--------------------------------------+---------------------------------------+
+
+.. note::
+    There's no such thing as a "bad" CMake target command. They all have valid
+    use cases. This categorization is provided to give newcomers a simple
+    intuition about which commands they should consider first when tackling
+    a problem.
+
+We'll demonstrate most of these in the following exercises. The three we won't
+be using are :command:`get_target_property`, :command:`set_target_properties`
+and :command:`target_precompile_headers`, so we will briefly discuss their
+purpose here.
+
+The :command:`get_target_property` and :command:`set_target_properties` commands
+give direct access to a target's properties by name. They can even be used
+to attach arbitrary property names to a target.
+
+.. code-block:: cmake
+
+  add_library(Example)
+  set_target_properties(Example
+    PROPERTIES
+      Key Value
+      Hello World
+  )
+
+  get_target_property(KeyVar Example Key)
+  get_target_property(HelloVar Example Hello)
+
+  message("Key: ${KeyVar}")
+  message("Hello: ${HelloVar}")
+
+.. code-block:: console
+
+  $ cmake -B build
+  ...
+  Key: Value
+  Hello: World
+
+The full list of target properties which are semantically meaningful to CMake
+are documented at :manual:`cmake-properties(7)`, however most of these should
+be modified with their dedicated commands. For example, it is unnecessary to
+directly manipulate ``LINK_LIBRARIES`` and ``INTERFACE_LINK_LIBRARIES``, as
+these are handled by :command:`target_link_libraries`.
+
+Conversely, some lesser-used properties are only accessible via these commands.
+The :prop_tgt:`DEPRECATION` property, used to attach deprecation notices to
+targets, can only be set via :command:`set_target_properties`; as can the
+:prop_tgt:`ADDITIONAL_CLEAN_FILES`, for describing additional files to be
+removed by CMake's ``clean`` target; and other properties of this sort.
+
+The :command:`target_precompile_headers` command takes a list of header files,
+similar to :command:`target_sources`, and creates a precompiled header from
+them. This precompiled header is then force included into all translation
+units in the target. This can be useful for build performance.
+
+Exercise 1 - Features and Definitions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In earlier steps we cautioned against globally setting
+:variable:`CMAKE_<LANG>_STANDARD` and overriding packagers' decision concerning
+which language standard to use. On the other hand, many libraries have a
+minimum required feature set they need in order to build, and for these it
+is appropriate to use the :command:`target_compile_features` command to
+communicate those requirements.
+
+.. code-block:: cmake
+
+  target_compile_features(MyApp PRIVATE cxx_std_20)
+
+The :command:`target_compile_features` command describes a minimum language
+standard as a target property. If the :variable:`CMAKE_<LANG>_STANDARD` is above
+this version, or the compiler default already provides this language standard,
+no action is taken. If additional flags are necessary to enable the standard,
+these will be added by CMake.
+
+.. note::
+  :command:`target_compile_features` manipulates the same style of interface and
+  non-interface properties as the other target commands. This means it is
+  possible to *inherit* a language standard requirement specified with
+  ``INTERFACE`` or ``PUBLIC`` scope keywords.
+
+  If language features are used only in implementation files, then the
+  respective compile features should be ``PRIVATE``. If the target's headers
+  use the features, then ``PUBLIC`` or ``INTERFACE`` should be used.
+
+For C++, the compile features are of the form ``cxx_std_YY`` where ``YY`` is
+the standardization year, e.g. ``14``, ``17``, ``20``, etc.
+
+The :command:`target_compile_definitions` command describes compile definitions
+as target properties. It is the most common mechanism for communicating build
+configuration information to the source code itself. As with all properties,
+the scope keywords apply as we have discussed.
+
+.. code-block:: cmake
+
+  target_compile_definitions(MyLibrary
+    PRIVATE
+      MYLIBRARY_USE_EXPERIMENTAL_IMPLEMENTATION
+
+    PUBLIC
+      MYLIBRARY_EXCLUDE_DEPRECATED_FUNCTIONS
+  )
+
+It is neither required nor desired that we attach ``-D`` prefixes to compile
+definitions described with :command:`target_compile_definitions`. CMake will
+determine the correct flag for the current compiler.
+
+Goal
+----
+
+Use :command:`target_compile_features` and :command:`target_compile_definitions`
+to communicate language standard and compile definition requirements.
+
+Helpful Resources
+-----------------
+
+* :command:`target_compile_features`
+* :command:`target_compile_definitions`
+* :command:`option`
+* :command:`if`
+
+Files to Edit
+-------------
+
+* ``Tutorial/CMakeLists.txt``
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
+* ``CMakePresets.json``
+
+Getting Started
+---------------
+
+The ``Help/guide/tutorial/Step4`` directory contains the complete, recommended
+solution to ``Step3`` and relevant ``TODOs`` for this step. Complete ``TODO 1``
+through ``TODO 8``.
+
+Build and Run
+-------------
+
+We can run CMake using our ``tutorial`` preset, and then build as usual.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+Verify that the output of ``Tutorial`` is what we would expect for ``std::sqrt``.
+
+Solution
+--------
+
+First we add a new option to the top-level CML.
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/CMakeLists.txt
+  :caption: TODO 1: CMakeLists.txt
+  :name: CMakeLists.txt-TUTORIAL_USE_STD_SQRT
+  :language: cmake
+  :start-at: option(TUTORIAL_BUILD_UTILITIES
+  :end-at: option(TUTORIAL_USE_STD_SQRT
+
+.. raw:: html
+
+  </details>
+
+Then we add the compile feature and definitions to ``MathFunctions``.
+
+.. raw:: html
+
+  <details><summary>TODO 2-3: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
+  :caption: TODO 2-3: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-target_compile_features
+  :language: cmake
+  :start-at: target_compile_features
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
+
+And the compile feature for ``Tutorial``.
+
+.. raw:: html
+
+  <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/Tutorial/CMakeLists.txt
+  :caption: TODO 4: Tutorial/CMakeLists.txt
+  :name: Tutorial/CMakeLists.txt-target_compile_features
+  :language: cmake
+  :start-at: target_compile_features
+  :end-at: target_compile_features
+
+.. raw:: html
+
+  </details>
+
+Now we can modify ``MathFunctions`` to take advantage of the new definition.
+
+.. raw:: html
+
+  <details><summary>TODO 5-6: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/MathFunctions/MathFunctions.cxx
+  :caption: TODO 5: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-cmath
+  :language: c++
+  :start-at: cmath
+  :end-at: format
+  :append: #include <iostream>
+
+.. literalinclude:: Step5/MathFunctions/MathFunctions.cxx
+  :caption: TODO 6: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-std-sqrt
+  :language: c++
+  :start-at: double sqrt(double x)
+  :end-at: }
+
+.. raw:: html
+
+  </details>
+
+Finally we can update our ``CMakePresets.json``. We don't need to set
+``CMAKE_CXX_STANDARD`` anymore, but we do want to try out our new
+compile definition.
+
+.. raw:: html
+
+  <details><summary>TODO 7-8: Click to show/hide answer</summary>
+
+.. code-block:: json
+  :caption: TODO 7-8: CMakePresets.json
+  :name: CMakePresets.json-std-sqrt
+
+  "cacheVariables": {
+    "TUTORIAL_USE_STD_SQRT": "ON"
+  }
+
+.. raw:: html
+
+  </details>
+
+Exercise 2 - Compile and Link Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes, we need to exercise specific control over the exact options being
+passed on the compile and link line. These situations are addressed by
+:command:`target_compile_options` and :command:`target_link_options`.
+
+.. code:: cmake
+
+  target_compile_options(MyApp PRIVATE -Wall -Werror)
+  target_link_options(MyApp PRIVATE -T LinksScript.ld)
+
+There are several problems with unconditionally calling
+:command:`target_compile_options` or :command:`target_link_options`. The primary
+problem is compiler flags are specific to the compiler frontend being used. In
+order to ensure that our project supports multiple compiler frontends, we must
+only pass compatible flags to the compiler.
+
+We can achieve this by checking the :variable:`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT`
+variable which tells us the style of flags supported by the compiler frontend.
+
+.. note::
+  Prior to CMake 3.26, :variable:`CMAKE_<LANG>_COMPILER_FRONTEND_VARIANT` was
+  only set for compilers with multiple frontend variants. In versions after
+  CMake 3.26 checking this variable alone is sufficient.
+
+  However this tutorial targets CMake 3.23. As such, the logic is more
+  complicated than we have time for here. This tutorial step already includes
+  correct logic for checking the compiler variant for MSVC, GCC, Clang, and
+  AppleClang on CMake 3.23.
+
+Even if a compiler accepts the flags we pass, the semantics of compiler flags
+change over time. This is especially true with regards to warnings. Projects
+should not turn warnings-as-error flags by default, as this can break their
+build on otherwise innocuous compiler warnings included in later releases.
+
+.. note::
+  For errors and warnings, consider placing flags in :variable:`CMAKE_<LANG>_FLAGS`
+  for local development builds and during CI runs (via preset or
+  :option:`-D <cmake -D>` flags). We know exactly which compiler and
+  toolchain are being used in these contexts, so we can customize the behavior
+  precisely without risking build breakages on other platforms.
+
+Goal
+----
+
+Add appropriate warning flags to the ``Tutorial`` executable for MSVC-style and
+GNU-style compiler frontends.
+
+Helpful Resources
+-----------------
+
+* :command:`target_compile_options`
+
+Files to Edit
+-------------
+
+* ``Tutorial/CMakeLists.txt``
+
+Getting Started
+---------------
+
+Continue editing files in the ``Step4`` directory. The conditional for checking
+the frontend variant has already been written. Complete ``TODO 9`` and
+``TODO 10`` to add warning flags to ``Tutorial``.
+
+Build and Run
+-------------
+
+Since we have already configured for this step, we can build with the usual
+command.
+
+.. code-block:: cmake
+
+  cmake --build build
+
+This should reveal a simple warning in the build. You can go ahead and fix it.
+
+Solution
+--------
+
+We need to add two compile options to ``Tutorial``, one MSVC-style flag and
+one GNU-style flag.
+
+.. raw:: html
+
+  <details><summary>TODO 9-10: Click to show/hide answer</summary>
+
+.. literalinclude:: Step5/Tutorial/CMakeLists.txt
+  :caption: TODO 9-10: Tutorial/CMakeLists.txt
+  :name: Tutorial/CMakeLists.txt-target_compile_options
+  :language: cmake
+  :start-at: if(
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Include and Link Directories
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+  This exercise requires building an archive using a compiler directly on the
+  command line. It is not used in later steps. It is included only to
+  demonstrate a use case for :command:`target_include_directories` and
+  :command:`target_link_directories`.
+
+  If you cannot complete this exercise for whatever reason feel free to treat
+  it as informational-only, or skip it entirely.
+
+It is generally unnecessary to directly describe include and link directories,
+as these requirements are inherited when linking together targets generated
+within CMake, or from external dependencies imported into CMake with commands
+we will cover in later steps.
+
+If we happen to have some libraries or header files which are not described
+by a CMake target which we need to bring into the build, perhaps pre-compiled
+binaries provided by a vendor, we can incorporate with the
+:command:`target_link_directories` and :command:`target_include_directories`
+commands.
+
+.. code-block:: cmake
+
+  target_link_directories(MyApp PRIVATE Vendor/lib)
+  target_include_directories(MyApp PRIVATE Vendor/include)
+
+
+These commands use properties which map to the ``-L`` and ``-I`` compiler flags
+(or whatever flags the compiler uses for link and include directories).
+
+Of course, passing a link directory doesn't tell the compiler to link anything
+into the build. For that we need :command:`target_link_libraries`. When
+:command:`target_link_libraries` is given an argument which does not map to
+a target name, it will add the string directly to the link line as a library
+to be linked into the build (prepending any appropriate flags, such a ``-l``).
+
+Goal
+----
+
+Describe a pre-compiled, vendored, static library and its headers inside a
+project using :command:`target_link_directories` and
+:command:`target_include_directories`.
+
+Helpful Resources
+-----------------
+
+* :command:`target_link_directories`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``Vendor/CMakeLists.txt``
+* ``Tutorial/CMakeLists.txt``
+
+Getting Started
+---------------
+
+You will need to build the vendor library into a static archive to complete this
+exercise. Navigate to the ``Help/guide/tutorial/Step4/Vendor/lib`` directory
+and build the code as appropriate for your platform.
+
+Typical commands for a GCC toolchain on Unix-like systems are:
+
+.. code-block:: console
+
+  g++ -c Vendor.cxx
+  ar rvs libVendor.a Vendor.o
+
+Likewise, sample commands for an MSVC toolchain on Windows are:
+
+.. code-block:: console
+
+  cl -c Vendor.cxx
+  lib -out:Vendor.lib Vendor.obj
+
+Here, since you're directly invoking ``cl`` and ``lib``, make sure to use a
+Developer Command Prompt for your version of Visual Studio with the same
+target architecture used by this CMake project.
+
+Then complete ``TODO 11`` through ``TODO 14``.
+
+.. note::
+  ``VendorLib`` is an ``INTERFACE`` library, meaning it has no build requirements
+  (because it has already been built). All of its properties should also be
+  interface properties.
+
+  We'll discuss ``INTERFACE`` libraries in greater depth during the next step.
+
+
+Build and Run
+-------------
+
+If you have successfully built ``libVendor``, you can rebuild ``Tutorial``
+using the normal command.
+
+.. code-block:: console
+
+  cmake --build build
+
+Running ``Tutorial`` should now output a message about the acceptability of the
+result to the vendor.
+
+Solution
+--------
+
+We need to use the target link and include commands to describe the archive
+and its headers as ``INTERFACE`` requirements of ``VendorLib``.
+
+.. raw:: html
+
+  <details><summary>TODO 11-13: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 11-13: Vendor/CMakeLists.txt
+  :name: Vendor/CMakeLists.txt
+
+  target_include_directories(VendorLib
+    INTERFACE
+      include
+  )
+
+  target_link_directories(VendorLib
+    INTERFACE
+      lib
+  )
+
+  target_link_libraries(VendorLib
+    INTERFACE
+      Vendor
+  )
+
+.. raw:: html
+
+  </details>
+
+Then we can add ``VendorLib`` to ``Tutorial``'s linked libraries.
+
+.. raw:: html
+
+  <details><summary>TODO 14: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 14: Tutorial/CMakeLists.txt
+  :name: Tutorial/CMakeLists.txt-VendorLib
+
+  target_link_libraries(Tutorial
+    PRIVATE
+      MathFunctions
+      VendorLib
+  )
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/In-Depth System Introspection.rst b/Help/guide/tutorial/In-Depth System Introspection.rst
new file mode 100644
index 0000000..f872c56
--- /dev/null
+++ b/Help/guide/tutorial/In-Depth System Introspection.rst
@@ -0,0 +1,418 @@
+Step 6: In-Depth System Introspection
+=====================================
+
+In order to discover information about the system environment and the toolchain,
+CMake will often compile small test programs to verify the availability of
+compiler flags, headers, and builtins or other language constructs.
+
+In this step, we will take advantage of the same test program mechanisms that
+CMake uses in our own project code.
+
+Background
+^^^^^^^^^^
+
+An old trick going back to the oldest days of configuration and build systems
+is to verify the availability of some feature by compiling a small program
+which uses that feature.
+
+CMake makes this unnecessary for many contexts. As we will address in later
+steps, if CMake can find a library dependency, we can rely on it having all
+the facilities (headers, code generators, test utilities, etc) we expect it to
+have. Conversely, if CMake can't find a dependency, attempting to use the
+dependency anyway will almost certainly fail.
+
+However, there are other kinds of information about the toolchain which CMake
+doesn't communicate readily. For these advanced cases, we can write our own
+test programs and compile commands to check for availability.
+
+CMake provides modules to simplify these checks. These are documented at
+:manual:`cmake-modules(7)`. Any module that begins with ``Check`` is a system
+introspection module we can use to interrogate the toolchain and system
+environment. Some notable ones include:
+
+  ``CheckIncludeFiles``
+    Check one or more C/C++ header files.
+
+  ``CheckCompilerFlag``
+    Check whether the compiler supports a given flag.
+
+  ``CheckSourceCompiles``
+    Checks whether source code can be built for a given language.
+
+  ``CheckIPOSupported``
+    Check whether the compiler supports interprocedural optimization (IPO/LTO).
+
+
+Exercise 1 - Check Include File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A fast and easy check to perform is if a given header file is available on
+a certain platform, for which CMake provides :module:`CheckIncludeFiles`. This
+is most appropriate for system and intrinsic headers, which may not be provided
+by a specific package by are expected to be available in many build environments.
+
+.. code-block:: cmake
+
+  include(CheckIncludeFiles)
+  check_include_files(sys/socket.h HAVE_SYS_SOCKET_H LANGUAGE CXX)
+
+.. note::
+  These functions are not immediately available in CMake, they must be added via
+  :command:`include`'ing their associated module (aka, a CMakeLang file). Many
+  modules live inside CMake's own ``Modules`` folder. This built-in ``Modules``
+  folder is one of the places CMake searches when evaluating an :command:`include`
+  command. You can think of these modules like standard library headers, they're
+  expected to be available.
+
+Once a header file is known to exist, we can communicate that to our code using
+the same mechanisms of conditionals and target commands already covered.
+
+Goal
+----
+
+Check if the x86 SSE2 intrinsic header is available, and if so use it to
+improve ``mathfunctions::sqrt``.
+
+Helpful Resources
+-----------------
+
+* :module:`CheckIncludeFiles`
+* :command:`target_compile_definitions`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``MathFunctions/MathFunctions.cxx``
+
+Getting Started
+---------------
+
+The ``Help/guide/tutorial/Step6`` directory contains the complete, recommended
+solution to ``Step5`` and relevant ``TODOs`` for this step. It also contains
+specialized implementations of the ``sqrt`` function for various conditions,
+which you will find in ``MathFunctions/MathFunctions.cxx``.
+
+Complete ``TODO 1`` through ``TODO 3``. Note that some ``#ifdef`` directives
+have already been added to the library, which will change its operation as we
+work through the step.
+
+Build and Run
+-------------
+
+We can use our usual commands to configure.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+In the output of the configuration step we should observe CMake checking for
+the ``emmintrin.h`` header.
+
+.. code-block:: console
+
+  -- Looking for include file emmintrin.h
+  -- Looking for include file emmintrin.h - found
+
+If the header is available on your system, verify the ``Tutorial`` output
+contains the message about using SSE2. Conversely, if the header is not
+available you should see the usual behavior from ``Tutorial``.
+
+Solution
+--------
+
+First we include and use the ``CheckIncludeFiles`` module, verifying the
+``emmintrin.h`` header is available.
+
+.. raw:: html
+
+  <details><summary>TODO 1: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :caption: TODO 1: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-check-include-files
+  :language: cmake
+  :start-at: include(CheckIncludeFiles
+  :end-at: check_include_files(
+
+.. raw:: html
+
+  </details>
+
+Then we use the result of the check to conditionally set a compile definition
+on ``MathFunctions``.
+
+.. raw:: html
+
+  <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :caption: TODO 2: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-define-use-sse2
+  :language: cmake
+  :start-at: if(HAS_EMMINTRIN)
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
+
+Finally we can conditionally include the header in the ``MathFunctions`` library.
+
+.. raw:: html
+
+  <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/MathFunctions/MathFunctions.cxx
+  :caption: TODO 3: MathFunctions/MathFunctions.cxx
+  :name: MathFunctions/MathFunctions.cxx-include-sse2
+  :language: c++
+  :start-at: #ifdef TUTORIAL_USE_SSE2
+  :end-at: #endif
+
+.. raw:: html
+
+  </details>
+
+
+Exercise 2 - Check Source Compiles
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes it is insufficient to merely check for a header. This is especially
+true when no header is available to check, such is the case with
+compiler-builtins. For these scenarios we have :module:`CheckSourceCompiles`.
+
+.. code-block:: cmake
+
+  include(CheckSourceCompiles)
+  check_source_compiles(CXX
+    "
+      int main() {
+        int a, b, c;
+        __builtin_add_overflow(a, b, &c);
+      }
+    "
+    HAS_CHECKED_ADDITION
+  )
+
+.. note::
+  By default :module:`CheckSourceCompiles` builds and links an executable. The
+  code to be check must provide a valid ``int main()`` in order to succeed.
+
+After performing the check, this system introspection can be applied identically
+to how we discussed with header files.
+
+Goal
+----
+
+Check if the GNU SSE2 builtins are available, and if so use them to improve
+``mathfunctions::sqrt``.
+
+Helpful Resources
+-----------------
+
+* :module:`CheckSourceCompiles`
+* :command:`target_compile_definitions`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+Complete ``TODO 4`` and ``TODO 5``. No code changes to the ``MathFunctions``
+implementation are necessary, as these have already been provided.
+
+Build and Run
+-------------
+
+We need only rebuild the tutorial.
+
+.. code-block:: console
+
+  cmake --build build
+
+.. note::
+  If a check fails and you think it should succeed, you will need to clear the
+  CMake Cache by deleting the ``CMakeCache.txt`` file. CMake will not rerun
+  compile checks on subsequent runs if it has a cached result.
+
+In the output of the configuration step we should observe CMake checking if the
+provided source code compiles, which will be reported under the variable name
+we provided to ``check_source_compiles()``.
+
+.. code-block:: console
+
+  -- Performing Test HAS_GNU_BUILTIN
+  -- Performing Test HAS_GNU_BUILTIN - Success
+
+If the builtins are available on your compiler, verify the ``Tutorial`` output
+contains the message about using GNU-builting. Conversely, if the builtins are
+not available you should see the previous behavior from ``Tutorial``.
+
+Solution
+--------
+
+First we include and use the ``CheckSourceCompiles`` module, verifying the
+provided source code can be built.
+
+..
+  pygments doesn't like the [=[ <string> ]=] literals in the following
+  literalinclude, so use :language: none
+
+.. raw:: html
+
+  <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :caption: TODO 4: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-check-source-compiles
+  :language: none
+  :start-at: include(CheckSourceCompiles
+  :end-at: HAS_GNU_BUILTIN
+  :append: )
+
+.. raw:: html
+
+  </details>
+
+Then we use the result of the check to conditionally set a compile definition
+on ``MathFunctions``.
+
+.. raw:: html
+
+  <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+  :caption: TODO 5: MathFunctions/CMakeLists.txt
+  :name: MathFunctions/CMakeLists.txt-define-use-gnu-builtin
+  :language: cmake
+  :start-at: if(HAS_GNU_BUILTIN)
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Check Interprocedural Optimization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Interprocedural and link time optimizations can provide significant performance
+improvements to some software. CMake has the capacity to check for the
+availability of IPO flags via :module:`CheckIPOSupported`.
+
+.. code-block:: cmake
+
+  include(CheckIPOSupported)
+  check_ipo_supported() # fatal error if IPO is not supported
+  set_target_properties(MyApp
+    PROPERTIES
+      INTERPROCEDURAL_OPTIMIZATION TRUE
+  )
+
+.. note::
+  There a couple important caveats with regard to in-project IPO configuration:
+
+  * CMake does not know about every IPO/LTO flag on every compiler, better
+    results can often be achieved with individual tuning for a known toolchain.
+  * Setting the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` property on a target
+    does not alter any of the targets it links to, or dependencies from other
+    projects. IPO can only "see" into other targets which are also compiled
+    appropriately.
+
+  For these reasons, serious consideration should be given to manually setting
+  up IPO/LTO flags across all projects in the dependency tree via external
+  mechanisms (presets, :option:`-D <cmake -D>` flags,
+  :manual:`toolchain files <cmake-toolchains(7)>`, etc) instead of in-project
+  control.
+
+However, especially for extremely large projects, it can be useful to have
+an in-project mechanism to use IPO whenever it is available.
+
+Goal
+----
+
+Enable IPO for the entire tutorial project when it is available from the
+toolchain.
+
+Helpful Resources
+-----------------
+
+* :module:`CheckIPOSupported`
+* :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+Continue editing the files in ``Step6``. Complete ``TODO 6`` and ``TODO 7``.
+
+Build and Run
+-------------
+
+We need only rebuild the tutorial.
+
+.. code-block:: console
+
+  cmake --build build
+
+If IPO is unavailable, we will see an error message during configuration.
+Otherwise nothing will change.
+
+.. note::
+  Regardless of the result of the IPO check, we shouldn't expect any change
+  in behavior from ``Tutorial`` or ``MathFunctions``.
+
+Solution
+--------
+
+The first ``TODO`` is easy, we add another option to our project.
+
+.. raw:: html
+
+  <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/CMakeLists.txt
+  :caption: TODO 6: CMakeLists.txt
+  :name: CMakeLists.txt-enable-ipo
+  :language: cmake
+  :start-at: option(TUTORIAL_ENABLE_IPO
+  :end-at: option(TUTORIAL_ENABLE_IPO
+
+.. raw:: html
+
+  </details>
+
+The next step is involved, however the documentation for :module:`CheckIPOSupported`
+has an almost complete example of what we need to do. The only difference is
+we are going to enable IPO project-wide instead of for a single target.
+
+.. raw:: html
+
+  <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step7/CMakeLists.txt
+  :caption: TODO 7: CMakeLists.txt
+  :name: CMakeLists.txt-check-ipo
+  :language: cmake
+  :start-at: if(TUTORIAL_ENABLE_IPO)
+  :end-at: endif()
+  :append: endif()
+
+.. raw:: html
+
+  </details>
+
+.. note::
+  Normally we have discouraged setting ``CMAKE_`` variables inside the project.
+  Here, we are controlling that behavior with an :command:`option()`. This
+  allows packagers to opt-out of our override. This is an imperfect, but
+  acceptable solution to situations where we want to provide options to control
+  project-wide behavior controlled by ``CMAKE_`` variables.
diff --git a/Help/guide/tutorial/Installation Commands and Concepts.rst b/Help/guide/tutorial/Installation Commands and Concepts.rst
new file mode 100644
index 0000000..c2422a5
--- /dev/null
+++ b/Help/guide/tutorial/Installation Commands and Concepts.rst
@@ -0,0 +1,596 @@
+Step 9: Installation Commands and Concepts
+==========================================
+
+Projects need to do more than build and test their code, they need to make it
+available to consumers. The layout of files in the build tree is unsuitable
+for consumption by other projects, binaries are in unexpected places, header
+files are located far away in the source tree, and there's no clear way
+to discover what targets are provided or how to use them.
+
+This translation, moving artifacts from the source and build trees into a final
+layout suitable for consumption, is known as installation. CMake supports a
+complete installation workflow as part of the project description, controlling
+both the layout of artifacts in the install tree, and reconstructing targets
+for other CMake projects which want to consume the libraries provided by the
+install tree.
+
+Background
+^^^^^^^^^^
+
+All CMake installation goes through a single command, :command:`install`, which
+is split into many subcommands responsible for various aspects of the
+installation process. For target-based CMake workflows, it is mostly sufficient
+to rely on installing targets themselves with :command:`install(TARGETS)`
+instead of resorting to manually moving files with :command:`install(FILES)`
+or :command:`install(DIRECTORY)`.
+
+.. note::
+  This is why we need to add ``FILES`` to header sets which are intended to be
+  installed. CMake needs to be able to locate the files when their associated
+  target is installed.
+
+CMake divides target-based installation into various artifact kinds. The
+available artifact kinds (in CMake 3.23) are:
+
+  ``ARCHIVE``
+    Static libraries (``.a`` / ``.lib``), DLL import libraries (``.lib``), and
+    a handful of other "archive-like" objects.
+
+  ``LIBRARY``
+    Shared libraries (``.so``), modules, and other dynamically loadable
+    objects. **Not** Window's DLL files (``.dll``) or MacOS frameworks.
+
+  ``RUNTIME``
+    Executables of all kinds except MacOS bundles; and Window's DLLs (``.dll``).
+
+  ``OBJECT``
+    Objects from ``OBJECT`` libraries.
+
+  ``FRAMEWORK``
+    Both static and shared MacOS frameworks
+
+  ``BUNDLE``
+    MacOS bundle executables
+
+  ``PUBLIC_HEADER`` / ``PRIVATE_HEADER`` / ``RESOURCE``
+    Files described by the :prop_tgt:`PUBLIC_HEADER`, :prop_tgt:`PRIVATE_HEADER`
+    and :prop_tgt:`RESOURCE` target properties, typically used with MacOS
+    frameworks
+
+  ``FILE_SET <set-name>``
+    A file set associated with the target. This is how headers are typically
+    installed.
+
+Most important artifact kinds have known destinations which CMake will default
+to unless instructed to do otherwise. For example, ``RUNTIME`` will be installed
+to the location named by :module:`CMAKE_INSTALL_BINDIR <GNUInstallDirs>`, if
+the variable is available, otherwise they default to ``bin``.
+
+The full list of artifact kind default destinations is described in the
+following table.
+
+=============================== =============================== ======================
+    Target Type                              Variable           Built-In Default
+=============================== =============================== ======================
+``RUNTIME``                     ``${CMAKE_INSTALL_BINDIR}``     ``bin``
+``LIBRARY``                     ``${CMAKE_INSTALL_LIBDIR}``     ``lib``
+``ARCHIVE``                     ``${CMAKE_INSTALL_LIBDIR}``     ``lib``
+``PRIVATE_HEADER``              ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+``PUBLIC_HEADER``               ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+``FILE_SET`` (type ``HEADERS``) ``${CMAKE_INSTALL_INCLUDEDIR}`` ``include``
+=============================== =============================== ======================
+
+For the most part, projects should leave the defaults alone unless they need to
+install to a specific subdirectory of a default location.
+
+CMake does not define the ``CMAKE_INSTALL_<dir>`` variables by default. If a
+project wishes to dictate installing to a subdirectory of one of these
+locations, it is necessary to include the :module:`GNUInstallDirs` module, which
+will provide values for all ``CMAKE_INSTALL_<dir>`` variables that have not
+already been defined.
+
+Exercise 1 - Installing Artifacts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For modern, target-based CMake projects installation of artifacts is trivial
+and consists of a single call to :command:`install(targets)`.
+
+.. code-block:: cmake
+
+  install(
+    TARGETS MyApp MyLib
+
+    FILE_SET HEADERS
+    FILE_SET anotherHeaderFileSet
+  )
+
+Most artifact kinds are installed by default and do not need to be listed in
+the :command:`install` command. However, ``FILE_SET``\ s must be named to let
+CMake know you want to install. In the above example we install two file
+sets, one named ``HEADERS`` and another named ``anotherHeaderFileSet``.
+
+When named, an artifact kind can be given various options, such as a destination.
+
+.. code-block:: cmake
+
+  include(GNUInstallDirs)
+
+  install(
+    TARGETS MyApp MyLib
+
+    RUNTIME
+      DESTINATION ${CMAKE_INSTALL_BINDIR}/Subfolder
+
+    FILE_SET HEADERS
+  )
+
+This will install the ``MyApp`` target to ``bin/Subfolder`` (if the packager
+hasn't changed :module:`CMAKE_INSTALL_BINDIR <GNUInstallDirs>`).
+
+Importantly, if the ``OBJECT`` artifact kind is never given a destination, it
+will act like an ``INTERFACE`` library, only installing its headers.
+
+Goal
+----
+
+Install the artifacts for the libraries and executables (except tests) described
+in the tutorial project.
+
+Helpful Resources
+-----------------
+
+* :command:`install`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+The ``Help/guide/tutorial/Step9`` directory contains the complete, recommended
+solution to ``Step8``. Complete ``TODO 1`` and ``TODO 2``.
+
+Build and Run
+-------------
+
+No special configuration is needed, configure and build as usual.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+We can verify the installation is correct with :option:`cmake --install`.
+
+.. code-block:: console
+
+  cmake --install build --prefix install
+
+The ``install`` folder should be populated correctly for our artifacts.
+
+Solution
+--------
+
+First we add an :command:`install(TARGETS)` for the conditionally built,
+thus conditionally installed, ``Tutorial`` executable.
+
+.. raw:: html
+
+  <details><summary>TODO 1 Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 1: CMakeLists.txt
+  :name: CMakeLists.txt-install-tutorial
+
+  if(TUTORIAL_BUILD_UTILITIES)
+    add_subdirectory(Tutorial)
+    install(
+      TARGETS Tutorial
+    )
+  endif()
+
+.. raw:: html
+
+  </details>
+
+Then we can install the rest of the targets.
+
+.. raw:: html
+
+  <details><summary>TODO 2 Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 2: CMakeLists.txt
+  :name: CMakeLists.txt-install-libs
+
+  install(
+    TARGETS MathFunctions OpAdd OpMul OpSub MathLogger SqrtTable
+    FILE_SET HEADERS
+  )
+
+.. raw:: html
+
+  </details>
+
+.. note::
+  We could add :command:`install(TARGETS)` commands locally to each subfolder
+  where the targets are defined. This would be typical in very large projects
+  where keeping track of all the installable targets is difficult.
+
+It might seem unnecessary to install the ``SqrtTable`` and ``MathLogger``,
+and it is at this stage. Due to how CMake models target relationships, when we
+reconstruct the target model in the next exercise we will need these targets to
+be available.
+
+Exercise 2 - Exporting Targets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This raw collection of installed files is a good start, but we lose the CMake
+target model. These are effectively no better than the pre-compiled vendored
+libraries we discussed in ``Step 4``. We need some way for other projects to
+reconstruct our targets from what we have provided in the install tree.
+
+The mechanism CMake provides to solve this is a CMakeLang file known as a
+"target export file". It is created by the :command:`install(EXPORT)`
+command.
+
+.. code-block:: cmake
+
+  install(
+    TARGETS MyApp MyLib
+    EXPORT MyProjectTargets
+  )
+
+  include(GNUInstallDirs)
+
+  install(
+    EXPORT MyProjectTargets
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProject
+    NAMESPACE MyProject::
+  )
+
+There are several parts to the above example. Firstly the
+:command:`install(TARGETS)` command takes an export name, basically a list to
+add the installed targets to.
+
+Later, the :command:`install(EXPORT)` command consumes this list of targets
+to generate the target export file. This will be a file named
+``<ExportName>.cmake`` located in the provided ``DESTINATION``. The
+``DESTINATION`` provided in this example is the conventional one, but any
+location searched by the :command:`find_package` command is valid.
+
+Finally, the targets created by the target export file will be prefixed with the
+``NAMESPACE`` string, ie they will be of the form ``<NAMESPACE><TargetName>``.
+It is conventional for this to be the project name followed by two colons.
+
+For reasons that will become more obvious in future steps, we typically don't
+consume this file directly. Instead we have a file named
+``<ProjectName>Config.cmake`` consume it via :command:`include()`.
+
+.. code-block:: cmake
+
+  include(${CMAKE_CURRENT_LIST_DIR}/MyProjectTargets.cmake)
+
+.. note::
+  The :variable:`CMAKE_CURRENT_LIST_DIR` variable names the directory that the
+  currently running CMake Language file is inside of, regardless of how that
+  file was included or launched.
+
+Then this file is installed alongside the target export with
+:command:`install(FILES)`.
+
+.. code-block:: cmake
+
+  install(
+    FILES
+      cmake/MyProjectConfig.cmake
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyProject
+  )
+
+.. note::
+  The name of this file and its location are dictated by the discovery
+  semantics of the :command:`find_package` command, which we will discuss more
+  in the next step.
+
+Goal
+----
+
+Export the Tutorial project targets so other projects may consume them.
+
+Helpful Resources
+-----------------
+
+* :command:`install`
+* :module:`GNUInstallDirs`
+* :variable:`CMAKE_CURRENT_LIST_DIR`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``cmake/TutorialConfig.cmake``
+
+Getting Started
+---------------
+
+Continue editing the files in the ``Help/guide/tutorial/Step9`` directory.
+Complete ``TODO 3`` through ``TODO 8``.
+
+Build and Run
+-------------
+
+The build command is sufficient to reconfigure the project.
+
+.. code-block:: console
+
+  cmake --build build
+
+We can verify the installation is correct with :option:`cmake --install`.
+
+.. note::
+
+  As with CTest, when using multi-config generator, eg Visual Studio, it will be
+  necessary to specify a configuration with
+  ``cmake --install --config <config> <remaining flags>``, where
+  ``<config>`` is a value like ``Debug`` or ``Release``. This is true whenever
+  using a multi-config generator, and won't be called out specifically in
+  future commands.
+
+.. code-block:: console
+
+  cmake --install build --prefix install
+
+.. note::
+  CMake won't update files which have not changed, only installing new or
+  updated files from the build and source trees.
+
+The ``install`` folder should be populated correctly for our artifacts and
+export files. We'll demonstrate how to use these files in the next step.
+
+Solution
+--------
+
+First we add the ``Tutorial`` target to the ``TutorialTargets`` export.
+
+.. raw:: html
+
+  <details><summary>TODO 3 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 3: CMakeLists.txt
+  :name: CMakeLists.txt-install-tutorial-export
+  :language: cmake
+  :start-at: install(
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Soon we will need access to the ``CMAKE_INSTALL_<dir>`` variables, so next
+we include the :module:`GNUInstallDirs` module.
+
+.. raw:: html
+
+  <details><summary>TODO 4 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 4: CMakeLists.txt
+  :name: CMakeLists.txt-gnuinstalldirss
+  :language: cmake
+  :start-at: include(GNUInstallDirs)
+  :end-at: include(GNUInstallDirs)
+
+.. raw:: html
+
+  </details>
+
+Now we add the rest of our targets to the ``TutorialTargets`` export.
+
+.. raw:: html
+
+  <details><summary>TODO 5 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 5: CMakeLists.txt
+  :name: CMakeLists.txt-install-libs-export
+  :language: cmake
+  :start-at: TARGETS MathFunctions
+  :end-at: )
+  :prepend: install(
+
+.. raw:: html
+
+  </details>
+
+Next we install the export itself, to generate our target export file.
+
+.. raw:: html
+
+  <details><summary>TODO 6 Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 6: CMakeLists.txt
+  :name: CMakeLists.txt-install-export
+
+  install(
+    EXPORT TutorialTargets
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+    NAMESPACE Tutorial::
+  )
+
+.. raw:: html
+
+  </details>
+
+And then we install our "config" file, which we will use to include our target
+export file.
+
+.. raw:: html
+
+  <details><summary>TODO 7 Click to show/hide answer</summary>
+
+.. code-block:: cmake
+  :caption: TODO 7: CMakeLists.txt
+  :name: CMakeLists.txt-install-config
+
+  install(
+    FILES
+      cmake/TutorialConfig.cmake
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+  )
+
+.. raw:: html
+
+  </details>
+
+Finally we can add the necessary :command:`include` command to the config file.
+
+.. raw:: html
+
+  <details><summary>TODO 8 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/cmake/TutorialConfig.cmake
+  :caption: TODO 8: cmake/TutorialConfig.cmake
+  :name: cmake/TutorialConfig.cmake
+  :language: cmake
+  :start-at: include
+  :end-at: include
+
+.. raw:: html
+
+  </details>
+
+Exercise 3 - Exporting a Version File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When importing CMake targets from a target export file, there is no way to
+"bail out" or "undo" the operation. If it turns out a package is a wrong or
+incompatible version for the one we requested, we'll be stuck with any
+side-effects incurred while we learned that version information.
+
+The answer CMake provides for this problem is a light-weight version file which
+only describes this version compatibility information, which can be checked
+before CMake commits to fully importing the file.
+
+CMake provides helper modules and scripts for generating these version files,
+namely the :module:`CMakePackageConfigHelpers` module.
+
+.. code-block:: cmake
+
+  include(CMakePackageConfigHelpers)
+
+  write_basic_package_version_file(
+    ${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfigVersion.cmake
+    COMPATIBILITY ExactVersion
+  )
+
+The available versions are:
+
+* ``AnyNewerVersion``
+* ``SameMajorVersion``
+* ``SameMinorVersion``
+* ``ExactVersion``
+
+Additionally packages can mark themselves as ``ARCH_INDEPENDENT``, intended for
+packages which ship no binaries which would tie them to a specific machine
+architecture.
+
+By default, the ``VERSION`` used by ``write_basic_package_version_file()`` is
+the ``VERSION`` number given to the :command:`project` command.
+
+Goal
+----
+
+Export a version file for the Tutorial project.
+
+Helpful Resources
+-----------------
+
+* :command:`project`
+* :command:`install`
+* :module:`CMakePackageConfigHelpers`
+* :variable:`PROJECT_VERSION`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+Continue editing the files in the ``Help/guide/tutorial/Step9`` directory.
+Complete ``TODO 9`` through ``TODO 12``.
+
+Build and Run
+-------------
+
+Rebuild and install as done previously.
+
+.. code-block:: console
+
+  cmake --build build
+  cmake --install build --prefix install
+
+The ``install`` folder should be populated correctly with our newly generated
+and installed version file.
+
+Solution
+--------
+
+First we add a ``VERSION`` parameter to the :command:`project` command.
+
+.. raw:: html
+
+  <details><summary>TODO 9 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 9: CMakeLists.txt
+  :name: CMakeLists.txt-project-version
+  :language: cmake
+  :start-at: project(
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+Next we include the :module:`CMakePackageConfigHelpers` modules and use it
+to generate the config version file.
+
+.. raw:: html
+
+  <details><summary>TODO 10-11 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 10-11: CMakeLists.txt
+  :name: CMakeLists.txt-write_basic_package_version_file
+  :language: cmake
+  :start-at: include(CMakePackageConfigHelpers
+  :end-at: COMPATIBILITY ExactVersion
+  :append: )
+
+.. raw:: html
+
+  </details>
+
+Finally we add the config version file to the list of files to be installed.
+
+.. raw:: html
+
+  <details><summary>TODO 12 Click to show/hide answer</summary>
+
+.. literalinclude:: Step10/TutorialProject/CMakeLists.txt
+  :caption: TODO 12: CMakeLists.txt
+  :name: CMakeLists.txt-install-version-config
+  :language: cmake
+  :start-at: FILES
+  :end-at: )
+  :prepend: install(
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst
index 7a59fcb..0adf131 100644
--- a/Help/guide/tutorial/Installing and Testing.rst
+++ b/Help/guide/tutorial/Installing and Testing.rst
@@ -1,311 +1,10 @@
 Step 5: Installing and Testing
 ==============================
 
-Exercise 1 - Install Rules
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-Often, it is not enough to only build an executable, it should also be
-installable. With CMake, we can specify install rules using the
-:command:`install` command. Supporting local installations for your builds in
-CMake is often as simple as specifying an install location and the targets and
-files to be installed.
+.. only:: cmakeorg
 
-Goal
-----
-
-Install the ``Tutorial`` executable and the ``MathFunctions`` library.
-
-Helpful Materials
------------------
-
-* :command:`install`
-
-Files to Edit
--------------
-
-* ``MathFunctions/CMakeLists.txt``
-* ``CMakeLists.txt``
-
-Getting Started
----------------
-
-The starting code is provided in the ``Step5`` directory. In this
-exercise, complete ``TODO 1`` through ``TODO 4``.
-
-First, update ``MathFunctions/CMakeLists.txt`` to install the
-``MathFunctions`` and ``tutorial_compiler_flags`` libraries to the ``lib``
-directory. In that same file, specify the install rules needed to install
-``MathFunctions.h`` to the ``include`` directory.
-
-Then, update the top level ``CMakeLists.txt`` to install
-the ``Tutorial`` executable to the ``bin`` directory. Lastly, any header files
-should be installed to the ``include`` directory. Remember that
-``TutorialConfig.h`` is in the :variable:`PROJECT_BINARY_DIR`.
-
-Build and Run
--------------
-
-Make a new directory called ``Step5_build``. Run the
-:manual:`cmake <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool.
-
-Then, run the install step by using the :option:`--install <cmake --install>`
-option of the :manual:`cmake  <cmake(1)>` command (introduced in 3.15, older
-versions of CMake must use ``make install``) from the command line. This step
-will install the appropriate header files, libraries, and executables.
-For example:
-
-.. code-block:: console
-
-  cmake --install .
-
-For multi-configuration tools, don't forget to use the
-:option:`--config <cmake--build --config>` argument to specify the configuration.
-
-.. code-block:: console
-
-  cmake --install . --config Release
-
-If using an IDE, simply build the ``INSTALL`` target. You can build the same
-install target from the command line like the following:
-
-.. code-block:: console
-
-  cmake --build . --target install --config Debug
-
-The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
-root of where the files will be installed. If using the :option:`cmake --install`
-command, the installation prefix can be overridden via the
-:option:`--prefix <cmake--install --prefix>` argument. For example:
-
-.. code-block:: console
-
-  cmake --install . --prefix "/home/myuser/installdir"
-
-Navigate to the install directory and verify that the installed ``Tutorial``
-runs.
-
-Solution
---------
-
-The install rules for our project are fairly simple:
-
-* For ``MathFunctions``, we want to install the libraries and header file to
-  the ``lib`` and ``include`` directories respectively.
-
-* For the ``Tutorial`` executable, we want to install the executable and
-  configured header file to the ``bin`` and ``include`` directories
-  respectively.
-
-So to the end of ``MathFunctions/CMakeLists.txt`` we add:
-
-.. raw:: html
-
-  <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
-  :caption: TODO 1: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-install-TARGETS
-  :language: cmake
-  :start-after: # install libs
-  :end-before: # install include headers
-
-.. raw:: html
-
-  </details>
-
-and
-
-.. raw:: html
-
-  <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
-  :caption: TODO 2: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-install-headers
-  :language: cmake
-  :start-after: # install include headers
-
-.. raw:: html
-
-  </details>
-
-The install rules for the ``Tutorial`` executable and configured header file
-are similar. To the end of the top-level ``CMakeLists.txt`` we add:
-
-.. raw:: html
-
-  <details><summary>TODO 3,4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: TODO 3,4: CMakeLists.txt-install-TARGETS
-  :language: cmake
-  :start-after: # add the install targets
-  :end-before: # TODO 1: Replace enable_testing() with include(CTest)
-
-.. raw:: html
-
-  </details>
-
-That is all that is needed to create a basic local
-install of the tutorial.
-
-.. _`Tutorial Testing Support`:
-
-Exercise 2 - Testing Support
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-CTest offers a way to easily manage tests for your project. Tests can be
-added through the :command:`add_test` command. Although it is not
-explicitly covered in this tutorial, there is a lot of compatibility
-between CTest and other testing frameworks such as :module:`GoogleTest`.
-
-Goal
-----
-
-Create unit tests for our executable using CTest.
-
-Helpful Materials
------------------
-
-* :command:`enable_testing`
-* :command:`add_test`
-* :command:`function`
-* :command:`set_tests_properties`
-* :manual:`ctest <ctest(1)>`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-
-Getting Started
----------------
-
-The starting source code is provided in the ``Step5`` directory. In this
-exercise, complete ``TODO 5`` through ``TODO 9``.
-
-First, we need to enable testing. Next, begin adding tests to our project
-using :command:`add_test`. We will work through adding 3 simple tests and
-then you can add additional testing as you see fit.
-
-Build and Run
--------------
-
-Navigate to the build directory and rebuild the application. Then, run the
-:program:`ctest` executable: :option:`ctest -N` and :option:`ctest -VV`. For
-multi-config generators (e.g. Visual Studio), the configuration type must be
-specified with the :option:`-C \<mode\> <ctest -C>` flag.  For example, to run tests in Debug
-mode use ``ctest -C Debug -VV`` from the build directory
-(not the Debug subdirectory!). Release mode would be executed from the same
-location but with a ``-C Release``. Alternatively, build the ``RUN_TESTS``
-target from the IDE.
-
-Solution
---------
-
-Let's test our application. At the end of the top-level ``CMakeLists.txt``
-file we first need to enable testing with the
-:command:`enable_testing` command.
-
-.. raw:: html
-
-  <details><summary>TODO 5: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/CMakeLists.txt
-  :caption: TODO 5: CMakeLists.txt
-  :name: CMakeLists.txt-enable_testing
-  :language: cmake
-  :start-after: # enable testing
-  :end-before: # does the application run
-
-.. raw:: html
-
-  </details>
-
-With testing enabled, we will add a number of basic tests to verify
-that the application is working correctly. First, we create a test using
-:command:`add_test` which runs the ``Tutorial`` executable with the
-parameter 25 passed in. For this test, we are not going to check the
-executable's computed answer. This test will verify that
-application runs, does not segfault or otherwise crash, and has a zero
-return value. This is the basic form of a CTest test.
-
-.. raw:: html
-
-  <details><summary>TODO 6: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/CMakeLists.txt
-  :caption: TODO 6: CMakeLists.txt
-  :name: CMakeLists.txt-test-runs
-  :language: cmake
-  :start-after: # does the application run
-  :end-before: # does the usage message work
-
-.. raw:: html
-
-  </details>
-
-Next, let's use the :prop_test:`PASS_REGULAR_EXPRESSION` test property to
-verify that the output of the test contains certain strings. In this case,
-verifying that the usage message is printed when an incorrect number of
-arguments are provided.
-
-.. raw:: html
-
-  <details><summary>TODO 7: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/CMakeLists.txt
-  :caption: TODO 7: CMakeLists.txt
-  :name: CMakeLists.txt-test-usage
-  :language: cmake
-  :start-after: # does the usage message work?
-  :end-before: # define a function to simplify adding tests
-
-.. raw:: html
-
-  </details>
-
-The next test we will add verifies the computed value is truly the
-square root.
-
-.. raw:: html
-
-  <details><summary>TODO 8: Click to show/hide answer</summary>
-
-.. code-block:: cmake
-  :caption: TODO 8: CMakeLists.txt
-  :name: CMakeLists.txt-test-standard
-
-  add_test(NAME StandardUse COMMAND Tutorial 4)
-  set_tests_properties(StandardUse
-    PROPERTIES PASS_REGULAR_EXPRESSION "4 is 2"
-    )
-
-.. raw:: html
-
-  </details>
-
-This one test is not enough to give us confidence that it will
-work for all values passed in. We should add more tests to verify this.
-To easily add more tests, we make a function called ``do_test`` that runs the
-application and verifies that the computed square root is correct for
-given input. For each invocation of ``do_test``, another test is added to
-the project with a name, input, and expected results based on the passed
-arguments.
-
-.. raw:: html
-
-  <details><summary>TODO 9: Click to show/hide answer</summary>
-
-.. literalinclude:: Step6/CMakeLists.txt
-  :caption: TODO 9: CMakeLists.txt
-  :name: CMakeLists.txt-generalized-tests
-  :language: cmake
-  :start-after: # define a function to simplify adding tests
-
-.. raw:: html
-
-  </details>
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Installing%20and%20Testing.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Miscellaneous Features.rst b/Help/guide/tutorial/Miscellaneous Features.rst
new file mode 100644
index 0000000..51fbe8e
--- /dev/null
+++ b/Help/guide/tutorial/Miscellaneous Features.rst
@@ -0,0 +1,188 @@
+Step 11: Miscellaneous Features
+===============================
+
+Some features don't fit well or aren't important enough to receive attention
+in the main tutorial, but deserve mention. These exercises collect some of those
+features. They should be considered "bonuses".
+
+There are many CMake features that are not covered by the tutorial, some of
+which are considered essential to the projects which use them. Others are
+in common use by packagers but see little discussion among software developers
+producing local builds.
+
+This list is not an exhaustive discussion of what remains of CMake's
+capabilities. It may grow or shrink with time and relevance.
+
+Exercise 1: Target Aliases
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This tutorial focuses on installing dependencies and consuming them from an
+install tree. It also recommends the use of package managers to facilitate
+this process. However, for a variety of reasons both historical and
+contemporary this is not always how CMake projects are consumed.
+
+It is possible to vendor a dependency's source code entirely in a parent project
+and consume it with :command:`add_subdirectory`. When performed, the target
+names exposed are those used within the project, not those exported via
+:command:`install(EXPORT)`. The target names will not have the namespace string
+that command prefixes to targets.
+
+Some projects wish to support this workflow with an interface consistent with
+the one presented to :command:`find_package` consumers. CMake supports this via
+:command:`add_library(ALIAS)` and :command:`add_executable(ALIAS)`.
+
+.. code-block:: cmake
+
+  add_library(MyLib INTERFACE)
+  add_library(MyProject::MyLib ALIAS MyLib)
+
+Goal
+----
+
+Add a library alias for the ``MathFunctions`` library.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+
+Files to Edit
+-------------
+
+* ``TutorialProject/MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+For this step we will only be editing the ``TutorialProject`` project in the
+``Step11`` folder. Complete ``TODO 1``.
+
+Build and Run
+-------------
+
+To build the project we first need configure and install ``SimpleTest``.
+Navigate to ``Help/guide/Step11/SimpleTest`` and run the appropriate commands.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --install build
+
+Then navigate to ``Help/guide/Step11/TutorialProject`` and perform the usual build.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+There should be no observable change in behavior from adding the alias.
+
+Solution
+--------
+
+We add a single line to the ``MathFunctions`` CML.
+
+.. raw:: html
+
+  <details><summary>TODO 1 Click to show/hide answer</summary>
+
+.. literalinclude:: Complete/TutorialProject/MathFunctions/CMakeLists.txt
+  :caption: TODO 1: TutorialProject/MathFunctions/CMakeLists.txt
+  :name: TutorialProject/MathFunctions/CMakeLists.txt-alias
+  :language: cmake
+  :start-at: ALIAS
+  :end-at: ALIAS
+
+.. raw:: html
+
+  </details>
+
+Exercise 2: Generator Expressions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are a
+complicated domain-specific language supported in some contexts within CMake.
+They are most easily understood as deferred-evaluation conditionals, they
+express requirements where the inputs to determine the correct behavior are not
+known during the CMake configuration stage.
+
+.. note::
+  This is where generator expressions get their name, they are evaluated when
+  the underlying build system is being generated.
+
+Generator expressions were commonly used in combination with
+:command:`target_include_directories` to express include directory requirements
+across the build and install tree, but file sets have superseded this use case.
+Their most common applications now are in multi-config generators and
+intricate dependency injection systems.
+
+.. code-block:: cmake
+
+  target_compile_definitions(MyApp PRIVATE "MYAPP_BUILD_CONFIG=$<CONFIG>")
+
+Goal
+----
+
+Add a generator expression to ``SimpleTest`` that checks the build configuration
+inside a compile definition.
+
+Helpful Resources
+-----------------
+
+* :command:`target_compile_definitions`
+* :manual:`cmake-generator-expressions(7)`
+
+Files to Edit
+-------------
+
+* ``SimpleTest/CMakeLists.txt``
+
+Getting Started
+---------------
+
+For this step we will only be editing the ``SimpleTest`` project in the
+``Step11`` folder. Complete ``TODO 2``.
+
+Build and Run
+-------------
+
+To build the project we first need configure and install ``SimpleTest``.
+Navigate to ``Help/guide/Step11/SimpleTest`` and run the appropriate commands.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --install build
+
+Then navigate to ``Help/guide/Step11/TutorialProject`` and perform the usual build.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+When running the ``TestMathFunctions`` binary directly, we should a message
+naming the build configuration used to build the executable (not necessarily the
+same as configuration used to configure ``SimpleTest``). On single configuration
+generators, the build configuration can be changed by setting
+:variable:`CMAKE_BUILD_TYPE`.
+
+Solution
+--------
+
+We add a single line to the ``SimpleTest`` CML.
+
+.. raw:: html
+
+  <details><summary>TODO 2 Click to show/hide answer</summary>
+
+.. literalinclude:: Complete/SimpleTest/CMakeLists.txt
+  :caption: TODO 2: SimpleTest/CMakeLists.txt
+  :name: SimpleTest/CMakeLists.txt-target_compile_definitions
+  :language: cmake
+  :start-at: target_compile_definitions
+  :end-at: target_compile_definitions
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/Packaging Debug and Release.rst b/Help/guide/tutorial/Packaging Debug and Release.rst
index 6036969..c6bfdf5 100644
--- a/Help/guide/tutorial/Packaging Debug and Release.rst
+++ b/Help/guide/tutorial/Packaging Debug and Release.rst
@@ -1,86 +1,10 @@
 Step 12: Packaging Debug and Release
 ====================================
 
-**Note:** This example is valid for single-configuration generators and will
-not work for multi-configuration generators (e.g. Visual Studio).
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-By default, CMake's model is that a build directory only contains a single
-configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is
-possible, however, to setup CPack to bundle multiple build directories and
-construct a package that contains multiple configurations of the same project.
+.. only:: cmakeorg
 
-First, we want to ensure that the debug and release builds use different names
-for the libraries that will be installed. Let's use ``d`` as the
-postfix for the debug libraries.
-
-Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
-``CMakeLists.txt`` file:
-
-.. literalinclude:: Complete/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-CMAKE_DEBUG_POSTFIX-variable
-  :language: cmake
-  :start-after: project(Tutorial VERSION 1.0)
-  :end-before: target_compile_features(tutorial_compiler_flags
-
-And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:
-
-.. literalinclude:: Complete/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-DEBUG_POSTFIX-property
-  :language: cmake
-  :start-after: # add the executable
-  :end-before: # add the binary tree to the search path for include files
-
-Let's also add version numbering to the ``MathFunctions`` library. In
-``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and
-:prop_tgt:`SOVERSION` properties:
-
-.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-VERSION-properties
-  :language: cmake
-  :start-after: # setup the version numbering
-  :end-before: # install libs
-
-From the ``Step12`` directory, create ``debug`` and ``release``
-subdirectories. The layout will look like:
-
-.. code-block:: none
-
-  - Step12
-     - debug
-     - release
-
-Now we need to setup debug and release builds. We can use
-:variable:`CMAKE_BUILD_TYPE` to set the configuration type:
-
-.. code-block:: console
-
-  cd debug
-  cmake -DCMAKE_BUILD_TYPE=Debug ..
-  cmake --build .
-  cd ../release
-  cmake -DCMAKE_BUILD_TYPE=Release ..
-  cmake --build .
-
-Now that both the debug and release builds are complete, we can use a custom
-configuration file to package both builds into a single release. In the
-``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this
-file, first include the default configuration file that was created by the
-:manual:`cmake  <cmake(1)>` executable.
-
-Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
-projects to install. In this case, we want to install both debug and release.
-
-.. literalinclude:: Complete/MultiCPackConfig.cmake
-  :caption: MultiCPackConfig.cmake
-  :name: MultiCPackConfig.cmake
-  :language: cmake
-
-From the ``Step12`` directory, run :manual:`cpack <cpack(1)>` specifying our
-custom configuration file with the ``config`` option:
-
-.. code-block:: console
-
-  cpack --config MultiCPackConfig.cmake
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Packaging%20Debug%20and%20Release.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Packaging an Installer.rst b/Help/guide/tutorial/Packaging an Installer.rst
index 4cca679..82c8a72 100644
--- a/Help/guide/tutorial/Packaging an Installer.rst
+++ b/Help/guide/tutorial/Packaging an Installer.rst
@@ -1,64 +1,10 @@
 Step 9: Packaging an Installer
 ==============================
 
-Next suppose that we want to distribute our project to other people so that
-they can use it. We want to provide both binary and source distributions on a
-variety of platforms. This is a little different from the install we did
-previously in :guide:`tutorial/Installing and Testing`, where we were
-installing the binaries that we had built from the source code. In this
-example we will be building installation packages that support binary
-installations and package management features. To accomplish this we will use
-CPack to create platform specific installers. Specifically we need to add a
-few lines to the bottom of our top-level ``CMakeLists.txt`` file.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-.. literalinclude:: Step10/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-include-CPack
-  :language: cmake
-  :start-after: # setup installer
+.. only:: cmakeorg
 
-That is all there is to it. We start by including
-:module:`InstallRequiredSystemLibraries`. This module will include any runtime
-libraries that are needed by the project for the current platform. Next we set
-some CPack variables to where we have stored the license and version
-information for this project. The version information was set earlier in this
-tutorial and the ``License.txt`` has been included in the top-level source
-directory for this step.  The :variable:`CPACK_GENERATOR` and
-:variable:`CPACK_SOURCE_GENERATOR` variables select the generators used for
-binary and source installations, respectively.
-
-Finally we include the :module:`CPack module <CPack>` which will use these
-variables and some other properties of the current system to setup an
-installer.
-
-The next step is to build the project in the usual manner and then run the
-:manual:`cpack <cpack(1)>` executable. To build a binary distribution, from the
-binary directory run:
-
-.. code-block:: console
-
-  cpack
-
-To specify the binary generator, use the :option:`-G <cpack -G>` option. For
-multi-config builds, use :option:`-C <cpack -C>` to specify the configuration.
-For example:
-
-.. code-block:: console
-
-  cpack -G ZIP -C Debug
-
-For a list of available generators, see :manual:`cpack-generators(7)` or call
-:option:`cpack --help`. An :cpack_gen:`archive generator <CPack Archive Generator>`
-like ZIP creates a compressed archive of all *installed* files.
-
-To create an archive of the *full* source tree you would type:
-
-.. code-block:: console
-
-  cpack --config CPackSourceConfig.cmake
-
-Alternatively, run ``make package`` or right click the ``Package`` target and
-``Build Project`` from an IDE.
-
-Run the installer found in the binary directory. Then run the installed
-executable and verify that it works.
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Packaging%20an%20Installer.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
index a2f5e2a..738b572 100644
--- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
+++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
@@ -1,61 +1,10 @@
 Step 10: Selecting Static or Shared Libraries
 =============================================
 
-In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can
-be used to control the default behavior of :command:`add_library`,
-and allow control over how libraries without an explicit type (``STATIC``,
-``SHARED``, ``MODULE`` or ``OBJECT``) are built.
+This page was once part of an older version of the CMake tutorial which
+last appeared in CMake 4.1.  See the current tutorial version :guide:`here <CMake Tutorial>`.
 
-To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
-top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
-users to optionally select if the value should be ``ON`` or ``OFF``.
+.. only:: cmakeorg
 
-.. literalinclude:: Step11/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-option-BUILD_SHARED_LIBS
-  :language: cmake
-  :start-after: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY
-  :end-before: # configure a header file to pass the version number only
-
-Next, we need to specify output directories for our static and shared
-libraries.
-
-.. literalinclude:: Step11/CMakeLists.txt
-  :caption: CMakeLists.txt
-  :name: CMakeLists.txt-cmake-output-directories
-  :language: cmake
-  :start-after: # we don't need to tinker with the path to run the executable
-  :end-before: # configure a header file to pass the version number only
-
-Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
-
-.. literalinclude:: Step11/MathFunctions/MathFunctions.h
-  :caption: MathFunctions/MathFunctions.h
-  :name: MathFunctions/MathFunctions.h
-  :language: c++
-
-At this point, if you build everything, you may notice that linking fails
-as we are combining a static library without position independent code with a
-library that has position independent code. The solution to this is to
-explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
-SqrtLibrary to be ``True`` when building shared libraries.
-
-.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-POSITION_INDEPENDENT_CODE
-  :language: cmake
-  :start-at: # state that SqrtLibrary need PIC when the default is shared libraries
-  :end-at:  )
-
-Define ``EXPORTING_MYMATH`` stating we are using ``declspec(dllexport)`` when
-building on Windows.
-
-.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
-  :caption: MathFunctions/CMakeLists.txt
-  :name: MathFunctions/CMakeLists.txt-dll-export
-  :language: cmake
-  :start-at: # define the symbol stating we are using the declspec(dllexport) when
-  :end-at: target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
-
-**Exercise**: We modified ``MathFunctions.h`` to use dll export defines.
-Using CMake documentation can you find a helper module to simplify this?
+  To see the older version, follow `this link <https://cmake.org/cmake/help/v4.1/guide/tutorial/Selecting%20Static%20or%20Shared%20Libraries.html>`_
+  or select the drop-down in the page header.
diff --git a/Help/guide/tutorial/Step0/CMakeLists.txt b/Help/guide/tutorial/Step0/CMakeLists.txt
new file mode 100644
index 0000000..35c4cbc
--- /dev/null
+++ b/Help/guide/tutorial/Step0/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.23)
+
+project(Tutorial)
+
+add_executable(hello)
+target_sources(hello
+  PRIVATE
+    HelloWorld.cxx
+)
diff --git a/Help/guide/tutorial/Step0/HelloWorld.cxx b/Help/guide/tutorial/Step0/HelloWorld.cxx
new file mode 100644
index 0000000..b936ae8
--- /dev/null
+++ b/Help/guide/tutorial/Step0/HelloWorld.cxx
@@ -0,0 +1,6 @@
+#include <cstdio>
+
+int main()
+{
+  std::printf("Hello World\n");
+}
diff --git a/Help/guide/tutorial/Step1/CMakeLists.txt b/Help/guide/tutorial/Step1/CMakeLists.txt
index 6fcce90..19020c2 100644
--- a/Help/guide/tutorial/Step1/CMakeLists.txt
+++ b/Help/guide/tutorial/Step1/CMakeLists.txt
@@ -1,16 +1,21 @@
-# TODO 1: Set the minimum required version of CMake to be 3.10
+# TODO1: Set the minimum required version of CMake to be 3.23
 
-# TODO 2: Create a project named Tutorial
+# TODO2: Create a project named Tutorial
 
-# TODO 7: Set the project version number as 1.0 in the above project command
+# TODO3: Add an executable target called Tutorial to the project
 
-# TODO 6: Set the variable CMAKE_CXX_STANDARD to 11
-#         and the variable CMAKE_CXX_STANDARD_REQUIRED to True
+# TODO4: Add the Tutorial/Tutorial.cxx source file to the Tutorial target
 
-# TODO 8: Use configure_file to configure and copy TutorialConfig.h.in to
-#         TutorialConfig.h
+# TODO7: Add the MathFunctions library as a linked dependency
+#        to the Tutorial target
 
-# TODO 3: Add an executable called Tutorial to the project
-# Hint: Be sure to specify the source file as tutorial.cxx
+# TODO11: Add the Tutorial subdirectory to the project
 
-# TODO 9: Use target_include_directories to include ${PROJECT_BINARY_DIR}
+# TODO5: Add a library target called MathFunctions to the project
+
+# TODO6: Add the source and header file located in Step1/MathFunctions to the
+#        MathFunctions target, note that the intended way to include the
+#        MathFunctions header is:
+#          #include <MathFunctions.h>
+
+# TODO13: Add the MathFunctions subdirectory to the project
diff --git a/Help/guide/tutorial/Step1/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step1/MathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..0816408
--- /dev/null
+++ b/Help/guide/tutorial/Step1/MathFunctions/CMakeLists.txt
@@ -0,0 +1,2 @@
+# TODO12: Move all the MathFunctions target commands to this CMakeLists.txt.
+#         Ensure that all paths are updated to be relative to this new location.
diff --git a/Help/guide/tutorial/Step1/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step1/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..4bce912
--- /dev/null
+++ b/Help/guide/tutorial/Step1/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,31 @@
+#include <iostream>
+
+namespace {
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
+  }
+  return result;
+}
+}
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+  return mysqrt(x);
+}
+}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step1/MathFunctions/MathFunctions.h
similarity index 100%
rename from Help/guide/tutorial/Step2/MathFunctions/MathFunctions.h
rename to Help/guide/tutorial/Step1/MathFunctions/MathFunctions.h
diff --git a/Help/guide/tutorial/Step1/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step1/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..93d5b5f
--- /dev/null
+++ b/Help/guide/tutorial/Step1/Tutorial/CMakeLists.txt
@@ -0,0 +1,2 @@
+# TODO10: Move all the Tutorial target commands to this CMakeLists.txt. Ensure
+#          that all paths are updated to be relative to this new location.
diff --git a/Help/guide/tutorial/Step1/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step1/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..8cc0f2a
--- /dev/null
+++ b/Help/guide/tutorial/Step1/Tutorial/Tutorial.cxx
@@ -0,0 +1,23 @@
+// A simple program that computes the square root of a number
+#include <cmath>
+#include <iostream>
+#include <string>
+
+// TODO8: Include the MathFunctions header
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << "Usage: " << argv[0] << " number" << std::endl;
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // TODO9: Use the mathfunctions::sqrt function
+  // calculate square root
+  double const outputValue = std::sqrt(inputValue);
+  std::cout << "The square root of " << inputValue << " is " << outputValue
+            << std::endl;
+}
diff --git a/Help/guide/tutorial/Step1/TutorialConfig.h.in b/Help/guide/tutorial/Step1/TutorialConfig.h.in
deleted file mode 100644
index 990bfbd..0000000
--- a/Help/guide/tutorial/Step1/TutorialConfig.h.in
+++ /dev/null
@@ -1,2 +0,0 @@
-// the configured options and settings for Tutorial
-// TODO 10: Define Tutorial_VERSION_MAJOR and Tutorial_VERSION_MINOR
diff --git a/Help/guide/tutorial/Step1/tutorial.cxx b/Help/guide/tutorial/Step1/tutorial.cxx
deleted file mode 100644
index 18077b6..0000000
--- a/Help/guide/tutorial/Step1/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <cstdlib> // TODO 5: Remove this line
-#include <iostream>
-#include <string>
-
-// TODO 11: Include TutorialConfig.h
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // TODO 12: Create a print statement using Tutorial_VERSION_MAJOR
-    //          and Tutorial_VERSION_MINOR
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  // TODO 4: Replace atof(argv[1]) with std::stod(argv[1])
-  double const inputValue = atof(argv[1]);
-
-  // calculate square root
-  double const outputValue = sqrt(inputValue);
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt
deleted file mode 100644
index 40fee8d..0000000
--- a/Help/guide/tutorial/Step10/CMakeLists.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-cmake_minimum_required(VERSION 3.15)
-
-# set the project name and version
-project(Tutorial VERSION 1.0)
-
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
-
-# configure a header file to pass the version number only
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
-add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-include(CTest)
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-# setup installer
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_GENERATOR "TGZ")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
diff --git a/Help/guide/tutorial/Step10/CTestConfig.cmake b/Help/guide/tutorial/Step10/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step10/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step10/License.txt b/Help/guide/tutorial/Step10/License.txt
deleted file mode 100644
index 85760e5..0000000
--- a/Help/guide/tutorial/Step10/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
deleted file mode 100644
index 210563a..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# add the library that runs
-add_library(MathFunctions MathFunctions.cxx)
-
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if(USE_MYMATH)
-
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
-  include(MakeTable.cmake) # generates Table.h
-
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-              )
-
-  # state that we depend on our binary dir to find Table.h
-  target_include_directories(SqrtLibrary PRIVATE
-                             ${CMAKE_CURRENT_BINARY_DIR}
-                             )
-
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
-
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
-endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cmake b/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cmake
deleted file mode 100644
index 12865a9..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index c0991b9..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include "MathFunctions.h"
-
-#include <cmath>
-
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
-}
-}
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
deleted file mode 100644
index 1e916e1..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace mathfunctions {
-double sqrt(double x);
-}
diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 8153f18..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <iostream>
-
-#include "MathFunctions.h"
-
-// include the generated table
-#include "Table.h"
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // use the table to help find an initial value
-  double result = x;
-  if (x >= 1 && x < 10) {
-    std::cout << "Use the table to help find an initial value " << std::endl;
-    result = sqrtTable[static_cast<int>(x)];
-  }
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h
deleted file mode 100644
index e1c42ef..0000000
--- a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step10/SimpleTest/CMakeLists.txt b/Help/guide/tutorial/Step10/SimpleTest/CMakeLists.txt
new file mode 100644
index 0000000..6a73ff4
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/CMakeLists.txt
@@ -0,0 +1,52 @@
+# A very simple test framework for demonstrating how dependencies work
+cmake_minimum_required(VERSION 3.23)
+
+project(SimpleTest
+  VERSION 0.0.1
+)
+
+add_library(SimpleTest INTERFACE)
+target_sources(SimpleTest
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      SimpleTest.h
+)
+target_compile_features(SimpleTest INTERFACE cxx_std_20)
+
+# TODO6: Find the TransitiveDep package with find_package. The SimpleTest
+#        build should fail if TransitiveDep cannot be found.
+
+# TODO7: Add the TransitiveDep::TransitiveDep target to the SimpleTest interface
+#        library's links. Remember that interface libraries can only have
+#        interface properties.
+
+include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+
+install(
+  TARGETS SimpleTest
+  EXPORT SimpleTestTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT SimpleTestTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+  NAMESPACE SimpleTest::
+)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+  ARCH_INDEPENDENT
+)
+
+install(
+  FILES
+    cmake/simpletest_discover_impl.cmake
+    cmake/simpletest_discover_tests.cmake
+    cmake/SimpleTestConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+)
diff --git a/Help/guide/tutorial/Step10/SimpleTest/CMakePresets.json b/Help/guide/tutorial/Step10/SimpleTest/CMakePresets.json
new file mode 100644
index 0000000..816d8a3
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "SimpleTest Preset",
+      "description": "Preset to use with the tutorial's SimpleTest library",
+      "binaryDir": "${sourceDir}/build",
+      "installDir": "${sourceParentDir}/install",
+      "cacheVariables": {
+        "CMAKE_CXX_STANDARD": "20",
+        "CMAKE_PREFIX_PATH": "${sourceParentDir}/install"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step10/SimpleTest/SimpleTest.h b/Help/guide/tutorial/Step10/SimpleTest/SimpleTest.h
new file mode 100644
index 0000000..ca290d3
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/SimpleTest.h
@@ -0,0 +1,151 @@
+#pragma once
+
+#include <cstdio>
+#include <map>
+#include <string_view>
+
+namespace SimpleTest {
+
+using TestFunc = void (*)();
+
+using Registry = std::map<std::string_view, TestFunc, std::less<>>;
+inline Registry g_registry;
+
+inline Registry& registry()
+{
+  return g_registry;
+}
+
+struct failure
+{
+  char const* file;
+  int line;
+  char const* expr;
+};
+
+struct Registrar
+{
+  template <std::size_t N>
+  Registrar(char const (&name)[N], TestFunc f)
+  {
+    auto [it, inserted] =
+      registry().emplace(std::string_view{ name, N ? (N - 1) : 0 }, f);
+    if (!inserted) {
+      std::printf("[  WARN    ] duplicate test name: %.*s\n",
+                  int(it->first.size()), it->first.data());
+    }
+  }
+};
+
+inline Registry const& all()
+{
+  return registry();
+}
+inline TestFunc find(std::string_view name)
+{
+  auto it = registry().find(name);
+  return it == registry().end() ? nullptr : it->second;
+}
+
+}
+
+#define SIMPLETEST_CONCAT_(a, b) a##b
+#define SIMPLETEST_CONCAT(a, b) SIMPLETEST_CONCAT_(a, b)
+
+#define TEST(name_literal)                                                    \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)();                 \
+  static ::SimpleTest::Registrar SIMPLETEST_CONCAT(_simpletest_reg_,          \
+                                                   __LINE__)(                 \
+    name_literal, &SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__));             \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)()
+
+// Minimal assertion
+#define REQUIRE(expr)                                                         \
+  do {                                                                        \
+    if (!(expr))                                                              \
+      throw ::SimpleTest::failure{ __FILE__, __LINE__, #expr };               \
+  } while (0)
+
+int main(int argc, char** argv)
+{
+  using namespace ::SimpleTest;
+
+  std::string_view arg1 =
+    (argc >= 2) ? std::string_view{ argv[1] } : std::string_view{};
+
+  if (arg1 == "--list") {
+    bool first = true;
+    for (auto const& [name, _] : registry()) {
+      if (!first)
+        std::printf(",");
+      std::printf("%.*s", int(name.size()), name.data());
+      first = false;
+    }
+    std::printf("\n");
+    return 0;
+  }
+
+  if (arg1 == "--test") {
+    if (argc < 3) {
+      std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+      return 2;
+    }
+
+#ifdef SIMPLETEST_CONFIG
+    std::printf("SimpleTest built with config: %s\n", SIMPLETEST_CONFIG);
+#endif
+
+    std::string_view name{ argv[2] };
+    auto it = registry().find(name);
+    if (it == registry().end()) {
+      std::printf("[ NOTFOUND ] %s\n", argv[2]);
+      return 2;
+    }
+
+    int failed = 0;
+    std::printf("[ RUN      ] %.*s\n", int(it->first.size()),
+                it->first.data());
+    try {
+      it->second();
+      std::printf("[       OK] %.*s\n", int(it->first.size()),
+                  it->first.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(it->first.size()),
+                  it->first.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n",
+                  int(it->first.size()), it->first.data());
+      failed = 1;
+    }
+    return failed;
+  }
+
+  if (argc > 1) {
+    std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+    return 2;
+  }
+
+#ifdef SIMPLETEST_CONFIG
+  std::printf("SimpleTest built with config: %s\n", SIMPLETEST_CONFIG);
+#endif
+
+  // Default: run all tests.
+  int failed = 0;
+  for (auto const& [name, func] : all()) {
+    std::printf("[ RUN      ] %.*s\n", int(name.size()), name.data());
+    try {
+      func();
+      std::printf("[       OK ] %.*s\n", int(name.size()), name.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(name.size()),
+                  name.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n", int(name.size()),
+                  name.data());
+      failed = 1;
+    }
+  }
+  return failed;
+}
diff --git a/Help/guide/tutorial/Step10/SimpleTest/cmake/SimpleTestConfig.cmake b/Help/guide/tutorial/Step10/SimpleTest/cmake/SimpleTestConfig.cmake
new file mode 100644
index 0000000..aba0f75
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/cmake/SimpleTestConfig.cmake
@@ -0,0 +1,6 @@
+# TODO8: Include the CMakeFindDependencyMacro and use find_dependency to find
+#        the TransitiveDep package.
+
+
+include(${CMAKE_CURRENT_LIST_DIR}/SimpleTestTargets.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_tests.cmake)
diff --git a/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_impl.cmake b/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_impl.cmake
new file mode 100644
index 0000000..7d3a22b
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_impl.cmake
@@ -0,0 +1,32 @@
+if(NOT DEFINED TEST_EXE OR NOT DEFINED OUT_FILE)
+# noqa: spellcheck off
+  message(FATAL_ERROR "simpletest_discover: need -DTEST_EXE and -DOUT_FILE")
+# noqa: spellcheck on
+endif()
+
+execute_process(
+  COMMAND ${TEST_EXE} --list
+  RESULT_VARIABLE _rc
+  OUTPUT_VARIABLE _out
+  ERROR_VARIABLE _err
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+if(NOT _rc EQUAL 0)
+  file(WRITE ${OUT_FILE} "# simpletest: --list failed (rc=${_rc})\n")
+  message(FATAL_ERROR "simpletest_discover: '${TEST_EXE} --list' failed (${_rc})\n${_err}")
+endif()
+
+if(_out STREQUAL "")
+  file(WRITE ${OUT_FILE} "# simpletest: no tests\n")
+  return()
+endif()
+
+string(REPLACE "," ";" _names "${_out}")
+
+file(WRITE ${OUT_FILE} "# Auto-generated by simpletest_discover_impl.cmake\n")
+foreach(_name IN LISTS _names)
+  file(APPEND ${OUT_FILE}
+    "add_test([=[${_name}]=] \"${TEST_EXE}\" \"--test\" \"${_name}\")\n"
+  )
+endforeach()
diff --git a/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_tests.cmake b/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_tests.cmake
new file mode 100644
index 0000000..e5cf059
--- /dev/null
+++ b/Help/guide/tutorial/Step10/SimpleTest/cmake/simpletest_discover_tests.cmake
@@ -0,0 +1,27 @@
+set(_simpletest_impl_script ${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_impl.cmake)
+
+function(simpletest_discover_tests target)
+  if(NOT TARGET ${target})
+    message(FATAL_ERROR "simpletest_discover_tests: no such target '${target}'")
+  endif()
+
+  set(_out ${CMAKE_CURRENT_BINARY_DIR}/${target}_ctests.cmake)
+
+  if(NOT EXISTS ${_out})
+    file(WRITE ${_out} "# Populated after building ${target}\n")
+  endif()
+
+# noqa: spellcheck off
+  add_custom_command(TARGET ${target} POST_BUILD
+    COMMAND ${CMAKE_COMMAND}
+      -DTEST_EXE=$<TARGET_FILE:${target}>
+      -DOUT_FILE=${_out}
+      -P ${_simpletest_impl_script}
+    BYPRODUCTS ${_out}
+    COMMENT "SimpleTest: Discovering tests in ${target}"
+    VERBATIM
+  )
+# noqa: spellcheck on
+
+  set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES ${_out})
+endfunction()
diff --git a/Help/guide/tutorial/Step10/TutorialConfig.h.in b/Help/guide/tutorial/Step10/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step10/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step10/TutorialProject/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/CMakeLists.txt
new file mode 100644
index 0000000..d153893
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/CMakeLists.txt
@@ -0,0 +1,64 @@
+cmake_minimum_required(VERSION 3.23)
+
+project(Tutorial
+  VERSION 1.0.0
+)
+
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
+option(BUILD_TESTING "Enable testing and build tests" ON)
+
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
+
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+  install(
+    TARGETS Tutorial
+    EXPORT TutorialTargets
+  )
+endif()
+
+if(BUILD_TESTING)
+  enable_testing()
+  add_subdirectory(Tests)
+endif()
+
+add_subdirectory(MathFunctions)
+
+include(GNUInstallDirs)
+
+install(
+  TARGETS MathFunctions OpAdd OpMul OpSub MathLogger SqrtTable
+  EXPORT TutorialTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT TutorialTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+  NAMESPACE Tutorial::
+)
+
+include(CMakePackageConfigHelpers)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+)
+
+install(
+  FILES
+    cmake/TutorialConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/CMakePresets.json b/Help/guide/tutorial/Step10/TutorialProject/CMakePresets.json
new file mode 100644
index 0000000..3926cac
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TODO4": "Add ${sourceParentDir}/install to CMAKE_PREFIX_PATH",
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..8673342
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/CMakeLists.txt
@@ -0,0 +1,54 @@
+add_library(MathFunctions)
+
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
+
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
+
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
+    SqrtTable
+
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
+
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
+
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
+endif()
+
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
+
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
+endif()
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+add_subdirectory(MakeTable)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..6aa2a32
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_executable(MakeTable)
+
+target_sources(MakeTable
+  PRIVATE
+    MakeTable.cxx
+)
+
+add_custom_command(
+  OUTPUT SqrtTable.h
+  COMMAND MakeTable SqrtTable.h
+  DEPENDS MakeTable
+  VERBATIM
+)
+
+add_custom_target(RunMakeTable DEPENDS SqrtTable.h)
+
+add_library(SqrtTable INTERFACE)
+
+target_sources(SqrtTable
+  INTERFACE
+    FILE_SET HEADERS
+    BASE_DIRS
+      ${CMAKE_CURRENT_BINARY_DIR}
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SqrtTable.h
+)
+
+add_dependencies(SqrtTable RunMakeTable)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
copy from Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx
copy to Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..4bf8051
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,101 @@
+#include <cmath>
+#include <format>
+
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
+#endif
+
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+#include <SqrtTable.h>
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+#ifdef TUTORIAL_USE_STD_SQRT
+  return std::sqrt(x);
+#else
+  return mysqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.h
new file mode 100644
index 0000000..91cb176
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathFunctions.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/Tests/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/Tests/CMakeLists.txt
new file mode 100644
index 0000000..1f4482c
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/Tests/CMakeLists.txt
@@ -0,0 +1,31 @@
+add_executable(TestMathFunctions)
+
+target_sources(TestMathFunctions
+  PRIVATE
+    TestMathFunctions.cxx
+)
+
+# TODO1: Find the SimpleTest package. This should be a required dependency when
+#        building tests.
+
+# TODO2: Add the SimpleTest::SimpleTest target to Test MathFunctions
+
+target_link_libraries(TestMathFunctions
+  PRIVATE
+    MathFunctions
+)
+
+# TODO3: Replace MathFunctionTest and all the calls to it with
+#        simpletest_discover_tests called on TestMathFunctions
+
+function(MathFunctionTest op)
+  add_test(
+    NAME ${op}
+    COMMAND TestMathFunctions ${op}
+  )
+endfunction()
+
+MathFunctionTest(add)
+MathFunctionTest(mul)
+MathFunctionTest(sqrt)
+MathFunctionTest(sub)
diff --git a/Help/guide/tutorial/Step10/TutorialProject/Tests/TestMathFunctions.cxx b/Help/guide/tutorial/Step10/TutorialProject/Tests/TestMathFunctions.cxx
new file mode 100644
index 0000000..68a3419
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/Tests/TestMathFunctions.cxx
@@ -0,0 +1,28 @@
+#include <MathFunctions.h>
+
+// TODO5: Replace the following 5 lines with #include <SimpleTest.h>
+#define TEST(x) namespace
+#define REQUIRE(x)
+int main()
+{
+}
+
+TEST("add")
+{
+  REQUIRE(mathfunctions::OpAdd(2.0, 2.0) == 4.0);
+}
+
+TEST("sub")
+{
+  REQUIRE(mathfunctions::OpSub(4.0, 2.0) == 2.0);
+}
+
+TEST("mul")
+{
+  REQUIRE(mathfunctions::OpMul(5.0, 5.0) == 25.0);
+}
+
+TEST("sqrt")
+{
+  REQUIRE(mathfunctions::sqrt(25.0) == 5.0);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step10/TutorialProject/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..05eac5c
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/Tutorial/CMakeLists.txt
@@ -0,0 +1,36 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
+
+# TODO9: Find the path to the folder containing Unpackaged.h. The build should
+#        fail if this path is not discovered. Note that Unpackaged.h is stored
+#        in a subdirectory named "Unpackaged".
+
+# TODO10: Add the discovered path to the Tutorial executable target's
+#         include directories.
diff --git a/Help/guide/tutorial/Step10/TutorialProject/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step10/TutorialProject/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..3b8f911
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/Tutorial/Tutorial.cxx
@@ -0,0 +1,28 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+// TODO11: Include the Unpackaged.h header
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step10/TutorialProject/cmake/TutorialConfig.cmake b/Help/guide/tutorial/Step10/TutorialProject/cmake/TutorialConfig.cmake
new file mode 100644
index 0000000..d13caa4
--- /dev/null
+++ b/Help/guide/tutorial/Step10/TutorialProject/cmake/TutorialConfig.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/TutorialTargets.cmake)
diff --git a/Help/guide/tutorial/Step10/install/include/Unpackaged/Unpackaged.h b/Help/guide/tutorial/Step10/install/include/Unpackaged/Unpackaged.h
new file mode 100644
index 0000000..9782b0a
--- /dev/null
+++ b/Help/guide/tutorial/Step10/install/include/Unpackaged/Unpackaged.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define UNPACKAGED_HEADER_FOUND
diff --git a/Help/guide/tutorial/Step10/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake b/Help/guide/tutorial/Step10/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
new file mode 100644
index 0000000..ef51145
--- /dev/null
+++ b/Help/guide/tutorial/Step10/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
@@ -0,0 +1,50 @@
+# Abridged import written for the Tutorial
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+if(CMAKE_VERSION VERSION_LESS "3.0.0")
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 3.0.0...3.30)
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_cmake_targets_defined "")
+set(_cmake_targets_not_defined "")
+set(_cmake_expected_targets "")
+foreach(_cmake_expected_target IN ITEMS TransitiveDep::TransitiveDep)
+  list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
+  if(TARGET "${_cmake_expected_target}")
+    list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
+  else()
+    list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
+  endif()
+endforeach()
+unset(_cmake_expected_target)
+if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
+  unset(_cmake_targets_defined)
+  unset(_cmake_targets_not_defined)
+  unset(_cmake_expected_targets)
+  unset(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT _cmake_targets_defined STREQUAL "")
+  string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
+  string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
+endif()
+unset(_cmake_targets_defined)
+unset(_cmake_targets_not_defined)
+unset(_cmake_expected_targets)
+
+# Create imported target TransitiveDep::TransitiveDep
+add_library(TransitiveDep::TransitiveDep INTERFACE IMPORTED)
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/Help/guide/tutorial/Step10/tutorial.cxx b/Help/guide/tutorial/Step10/tutorial.cxx
deleted file mode 100644
index ca5110c..0000000
--- a/Help/guide/tutorial/Step10/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step11/CMakeLists.txt b/Help/guide/tutorial/Step11/CMakeLists.txt
deleted file mode 100644
index 9214c88..0000000
--- a/Help/guide/tutorial/Step11/CMakeLists.txt
+++ /dev/null
@@ -1,85 +0,0 @@
-cmake_minimum_required(VERSION 3.15)
-
-# set the project name and version
-project(Tutorial VERSION 1.0)
-
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
-
-# control where the static and shared libraries are built so that on windows
-# we don't need to tinker with the path to run the executable
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-
-option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
-
-# configure a header file to pass the version number only
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
-add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-include(CTest)
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-# setup installer
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_GENERATOR "TGZ")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
diff --git a/Help/guide/tutorial/Step11/CTestConfig.cmake b/Help/guide/tutorial/Step11/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step11/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step11/License.txt b/Help/guide/tutorial/Step11/License.txt
deleted file mode 100644
index 85760e5..0000000
--- a/Help/guide/tutorial/Step11/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
deleted file mode 100644
index eacc538..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-# add the library that runs
-add_library(MathFunctions MathFunctions.cxx)
-
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if(USE_MYMATH)
-
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
-  include(MakeTable.cmake) # generates Table.h
-
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-              )
-
-  # state that we depend on our binary dir to find Table.h
-  target_include_directories(SqrtLibrary PRIVATE
-                             ${CMAKE_CURRENT_BINARY_DIR}
-                             )
-
-  # state that SqrtLibrary need PIC when the default is shared libraries
-  set_target_properties(SqrtLibrary PROPERTIES
-                        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
-                        )
-
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
-
-# define the symbol stating we are using the declspec(dllexport) when
-# building on windows
-target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
-
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
-endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cmake b/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cmake
deleted file mode 100644
index 12865a9..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index c0991b9..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include "MathFunctions.h"
-
-#include <cmath>
-
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
-}
-}
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h
deleted file mode 100644
index 3fb547b..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/MathFunctions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#if defined(_WIN32)
-#  if defined(EXPORTING_MYMATH)
-#    define DECLSPEC __declspec(dllexport)
-#  else
-#    define DECLSPEC __declspec(dllimport)
-#  endif
-#else // non windows
-#  define DECLSPEC
-#endif
-
-namespace mathfunctions {
-double DECLSPEC sqrt(double x);
-}
diff --git a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 8153f18..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <iostream>
-
-#include "MathFunctions.h"
-
-// include the generated table
-#include "Table.h"
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // use the table to help find an initial value
-  double result = x;
-  if (x >= 1 && x < 10) {
-    std::cout << "Use the table to help find an initial value " << std::endl;
-    result = sqrtTable[static_cast<int>(x)];
-  }
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h
deleted file mode 100644
index e1c42ef..0000000
--- a/Help/guide/tutorial/Step11/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step11/SimpleTest/CMakeLists.txt b/Help/guide/tutorial/Step11/SimpleTest/CMakeLists.txt
new file mode 100644
index 0000000..866640e
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/CMakeLists.txt
@@ -0,0 +1,54 @@
+# A very simple test framework for demonstrating how dependencies work
+cmake_minimum_required(VERSION 3.23)
+
+project(SimpleTest
+  VERSION 0.0.1
+)
+
+add_library(SimpleTest INTERFACE)
+target_sources(SimpleTest
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      SimpleTest.h
+)
+target_compile_features(SimpleTest INTERFACE cxx_std_20)
+
+# TODO2: Add a compile definition that sets SIMPLETEST_CONFIG=$<CONFIG>
+#        on the SimpleTest target
+
+find_package(TransitiveDep REQUIRED)
+target_link_libraries(SimpleTest
+  INTERFACE
+    TransitiveDep::TransitiveDep
+)
+
+include(GNUInstallDirs)
+include(CMakePackageConfigHelpers)
+
+install(
+  TARGETS SimpleTest
+  EXPORT SimpleTestTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT SimpleTestTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+  NAMESPACE SimpleTest::
+)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+  ARCH_INDEPENDENT
+)
+
+install(
+  FILES
+    cmake/simpletest_discover_impl.cmake
+    cmake/simpletest_discover_tests.cmake
+    cmake/SimpleTestConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/SimpleTestConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SimpleTest
+)
diff --git a/Help/guide/tutorial/Step11/SimpleTest/CMakePresets.json b/Help/guide/tutorial/Step11/SimpleTest/CMakePresets.json
new file mode 100644
index 0000000..816d8a3
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "SimpleTest Preset",
+      "description": "Preset to use with the tutorial's SimpleTest library",
+      "binaryDir": "${sourceDir}/build",
+      "installDir": "${sourceParentDir}/install",
+      "cacheVariables": {
+        "CMAKE_CXX_STANDARD": "20",
+        "CMAKE_PREFIX_PATH": "${sourceParentDir}/install"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step11/SimpleTest/SimpleTest.h b/Help/guide/tutorial/Step11/SimpleTest/SimpleTest.h
new file mode 100644
index 0000000..ced6562
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/SimpleTest.h
@@ -0,0 +1,155 @@
+#pragma once
+
+#include <cstdio>
+#include <map>
+#include <string_view>
+
+namespace SimpleTest {
+
+using TestFunc = void (*)();
+
+using Registry = std::map<std::string_view, TestFunc, std::less<>>;
+inline Registry g_registry;
+
+inline Registry& registry()
+{
+  return g_registry;
+}
+
+struct failure
+{
+  char const* file;
+  int line;
+  char const* expr;
+};
+
+struct Registrar
+{
+  template <std::size_t N>
+  Registrar(char const (&name)[N], TestFunc f)
+  {
+    auto [it, inserted] =
+      registry().emplace(std::string_view{ name, N ? (N - 1) : 0 }, f);
+    if (!inserted) {
+      std::printf("[  WARN    ] duplicate test name: %.*s\n",
+                  int(it->first.size()), it->first.data());
+    }
+  }
+};
+
+inline Registry const& all()
+{
+  return registry();
+}
+inline TestFunc find(std::string_view name)
+{
+  auto it = registry().find(name);
+  return it == registry().end() ? nullptr : it->second;
+}
+
+}
+
+#define SIMPLETEST_STRINGIFY(a) #a
+#define SIMPLETEST_XSTRINGIFY(a) SIMPLETEST_STRINGIFY(a)
+#define SIMPLETEST_CONCAT_(a, b) a##b
+#define SIMPLETEST_CONCAT(a, b) SIMPLETEST_CONCAT_(a, b)
+
+#define TEST(name_literal)                                                    \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)();                 \
+  static ::SimpleTest::Registrar SIMPLETEST_CONCAT(_simpletest_reg_,          \
+                                                   __LINE__)(                 \
+    name_literal, &SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__));             \
+  static void SIMPLETEST_CONCAT(_simpletest_fn_, __LINE__)()
+
+// Minimal assertion
+#define REQUIRE(expr)                                                         \
+  do {                                                                        \
+    if (!(expr))                                                              \
+      throw ::SimpleTest::failure{ __FILE__, __LINE__, #expr };               \
+  } while (0)
+
+int main(int argc, char** argv)
+{
+  using namespace ::SimpleTest;
+
+  std::string_view arg1 =
+    (argc >= 2) ? std::string_view{ argv[1] } : std::string_view{};
+
+  if (arg1 == "--list") {
+    bool first = true;
+    for (auto const& [name, _] : registry()) {
+      if (!first)
+        std::printf(",");
+      std::printf("%.*s", int(name.size()), name.data());
+      first = false;
+    }
+    std::printf("\n");
+    return 0;
+  }
+
+  if (arg1 == "--test") {
+    if (argc < 3) {
+      std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+      return 2;
+    }
+
+#ifdef SIMPLETEST_CONFIG
+    std::printf("SimpleTest built with config: " SIMPLETEST_XSTRINGIFY(
+      SIMPLETEST_CONFIG) "\n");
+#endif
+
+    std::string_view name{ argv[2] };
+    auto it = registry().find(name);
+    if (it == registry().end()) {
+      std::printf("[ NOTFOUND ] %s\n", argv[2]);
+      return 2;
+    }
+
+    int failed = 0;
+    std::printf("[ RUN      ] %.*s\n", int(it->first.size()),
+                it->first.data());
+    try {
+      it->second();
+      std::printf("[       OK] %.*s\n", int(it->first.size()),
+                  it->first.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(it->first.size()),
+                  it->first.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n",
+                  int(it->first.size()), it->first.data());
+      failed = 1;
+    }
+    return failed;
+  }
+
+  if (argc > 1) {
+    std::printf("usage: %s [--list] [--test <name>]\n", argv[0]);
+    return 2;
+  }
+
+#ifdef SIMPLETEST_CONFIG
+  std::printf("SimpleTest built with config: " SIMPLETEST_XSTRINGIFY(
+    SIMPLETEST_CONFIG) "\n");
+#endif
+
+  // Default: run all tests.
+  int failed = 0;
+  for (auto const& [name, func] : all()) {
+    std::printf("[ RUN      ] %.*s\n", int(name.size()), name.data());
+    try {
+      func();
+      std::printf("[       OK ] %.*s\n", int(name.size()), name.data());
+    } catch (failure const& f) {
+      std::printf("[  FAILED  ] %.*s at %s:%d : %s\n", int(name.size()),
+                  name.data(), f.file, f.line, f.expr);
+      failed = 1;
+    } catch (...) {
+      std::printf("[  FAILED  ] %.*s : unknown exception\n", int(name.size()),
+                  name.data());
+      failed = 1;
+    }
+  }
+  return failed;
+}
diff --git a/Help/guide/tutorial/Step11/SimpleTest/cmake/SimpleTestConfig.cmake b/Help/guide/tutorial/Step11/SimpleTest/cmake/SimpleTestConfig.cmake
new file mode 100644
index 0000000..6c7ffb5
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/cmake/SimpleTestConfig.cmake
@@ -0,0 +1,5 @@
+include(CMakeFindDependencyMacro)
+find_dependency(TransitiveDep)
+
+include(${CMAKE_CURRENT_LIST_DIR}/SimpleTestTargets.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_tests.cmake)
diff --git a/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_impl.cmake b/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_impl.cmake
new file mode 100644
index 0000000..7d3a22b
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_impl.cmake
@@ -0,0 +1,32 @@
+if(NOT DEFINED TEST_EXE OR NOT DEFINED OUT_FILE)
+# noqa: spellcheck off
+  message(FATAL_ERROR "simpletest_discover: need -DTEST_EXE and -DOUT_FILE")
+# noqa: spellcheck on
+endif()
+
+execute_process(
+  COMMAND ${TEST_EXE} --list
+  RESULT_VARIABLE _rc
+  OUTPUT_VARIABLE _out
+  ERROR_VARIABLE _err
+  OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+if(NOT _rc EQUAL 0)
+  file(WRITE ${OUT_FILE} "# simpletest: --list failed (rc=${_rc})\n")
+  message(FATAL_ERROR "simpletest_discover: '${TEST_EXE} --list' failed (${_rc})\n${_err}")
+endif()
+
+if(_out STREQUAL "")
+  file(WRITE ${OUT_FILE} "# simpletest: no tests\n")
+  return()
+endif()
+
+string(REPLACE "," ";" _names "${_out}")
+
+file(WRITE ${OUT_FILE} "# Auto-generated by simpletest_discover_impl.cmake\n")
+foreach(_name IN LISTS _names)
+  file(APPEND ${OUT_FILE}
+    "add_test([=[${_name}]=] \"${TEST_EXE}\" \"--test\" \"${_name}\")\n"
+  )
+endforeach()
diff --git a/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_tests.cmake b/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_tests.cmake
new file mode 100644
index 0000000..e5cf059
--- /dev/null
+++ b/Help/guide/tutorial/Step11/SimpleTest/cmake/simpletest_discover_tests.cmake
@@ -0,0 +1,27 @@
+set(_simpletest_impl_script ${CMAKE_CURRENT_LIST_DIR}/simpletest_discover_impl.cmake)
+
+function(simpletest_discover_tests target)
+  if(NOT TARGET ${target})
+    message(FATAL_ERROR "simpletest_discover_tests: no such target '${target}'")
+  endif()
+
+  set(_out ${CMAKE_CURRENT_BINARY_DIR}/${target}_ctests.cmake)
+
+  if(NOT EXISTS ${_out})
+    file(WRITE ${_out} "# Populated after building ${target}\n")
+  endif()
+
+# noqa: spellcheck off
+  add_custom_command(TARGET ${target} POST_BUILD
+    COMMAND ${CMAKE_COMMAND}
+      -DTEST_EXE=$<TARGET_FILE:${target}>
+      -DOUT_FILE=${_out}
+      -P ${_simpletest_impl_script}
+    BYPRODUCTS ${_out}
+    COMMENT "SimpleTest: Discovering tests in ${target}"
+    VERBATIM
+  )
+# noqa: spellcheck on
+
+  set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES ${_out})
+endfunction()
diff --git a/Help/guide/tutorial/Step11/TutorialConfig.h.in b/Help/guide/tutorial/Step11/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step11/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step11/TutorialProject/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/CMakeLists.txt
new file mode 100644
index 0000000..4091638
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required(VERSION 3.23)
+
+project(Tutorial
+  VERSION 1.0.0
+)
+
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
+option(BUILD_TESTING "Enable testing and build tests" ON)
+
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
+
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
+
+if(BUILD_TESTING)
+  enable_testing()
+  add_subdirectory(Tests)
+endif()
+
+add_subdirectory(MathFunctions)
+
+include(GNUInstallDirs)
+
+install(
+  TARGETS MathFunctions OpAdd OpMul OpSub MathLogger SqrtTable
+  EXPORT TutorialTargets
+  FILE_SET HEADERS
+)
+
+install(
+  EXPORT TutorialTargets
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+  NAMESPACE Tutorial::
+)
+
+include(CMakePackageConfigHelpers)
+
+write_basic_package_version_file(
+  ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  COMPATIBILITY ExactVersion
+)
+
+install(
+  FILES
+    cmake/TutorialConfig.cmake
+    ${CMAKE_CURRENT_BINARY_DIR}/TutorialConfigVersion.cmake
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/CMakePresets.json b/Help/guide/tutorial/Step11/TutorialProject/CMakePresets.json
new file mode 100644
index 0000000..fee177b
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "CMAKE_PREFIX_PATH": "${sourceParentDir}/install",
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..c3ea012
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/CMakeLists.txt
@@ -0,0 +1,55 @@
+add_library(MathFunctions)
+# TODO1: Add an alias for the MathFunctions library to match the exported target
+
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
+
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
+
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
+    SqrtTable
+
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
+
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
+
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
+endif()
+
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
+
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
+endif()
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+add_subdirectory(MakeTable)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..6aa2a32
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_executable(MakeTable)
+
+target_sources(MakeTable
+  PRIVATE
+    MakeTable.cxx
+)
+
+add_custom_command(
+  OUTPUT SqrtTable.h
+  COMMAND MakeTable SqrtTable.h
+  DEPENDS MakeTable
+  VERBATIM
+)
+
+add_custom_target(RunMakeTable DEPENDS SqrtTable.h)
+
+add_library(SqrtTable INTERFACE)
+
+target_sources(SqrtTable
+  INTERFACE
+    FILE_SET HEADERS
+    BASE_DIRS
+      ${CMAKE_CURRENT_BINARY_DIR}
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SqrtTable.h
+)
+
+add_dependencies(SqrtTable RunMakeTable)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
rename from Help/guide/tutorial/Step11/MathFunctions/MakeTable.cxx
rename to Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.cxx
new file mode 100644
index 0000000..4bf8051
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.cxx
@@ -0,0 +1,101 @@
+#include <cmath>
+#include <format>
+
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
+#endif
+
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+#include <SqrtTable.h>
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
+namespace mathfunctions {
+double sqrt(double x)
+{
+#ifdef TUTORIAL_USE_STD_SQRT
+  return std::sqrt(x);
+#else
+  return mysqrt(x);
+#endif
+}
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.h
new file mode 100644
index 0000000..91cb176
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathFunctions.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
+namespace mathfunctions {
+double sqrt(double x);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/Tests/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/Tests/CMakeLists.txt
new file mode 100644
index 0000000..9b5bcd1
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/Tests/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_executable(TestMathFunctions)
+
+target_sources(TestMathFunctions
+  PRIVATE
+    TestMathFunctions.cxx
+)
+
+find_package(SimpleTest REQUIRED)
+
+target_link_libraries(TestMathFunctions
+  PRIVATE
+    MathFunctions
+    SimpleTest::SimpleTest
+)
+
+simpletest_discover_tests(TestMathFunctions)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/Tests/TestMathFunctions.cxx b/Help/guide/tutorial/Step11/TutorialProject/Tests/TestMathFunctions.cxx
new file mode 100644
index 0000000..166fd5d
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/Tests/TestMathFunctions.cxx
@@ -0,0 +1,22 @@
+#include <MathFunctions.h>
+#include <SimpleTest.h>
+
+TEST("add")
+{
+  REQUIRE(mathfunctions::OpAdd(2.0, 2.0) == 4.0);
+}
+
+TEST("sub")
+{
+  REQUIRE(mathfunctions::OpSub(4.0, 2.0) == 2.0);
+}
+
+TEST("mul")
+{
+  REQUIRE(mathfunctions::OpMul(5.0, 5.0) == 25.0);
+}
+
+TEST("sqrt")
+{
+  REQUIRE(mathfunctions::sqrt(25.0) == 5.0);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step11/TutorialProject/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..79b232b
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/Tutorial/CMakeLists.txt
@@ -0,0 +1,39 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
+
+find_path(UnpackagedIncludeFolder Unpackaged.h REQUIRED
+  PATH_SUFFIXES
+    Unpackaged
+)
+
+target_include_directories(Tutorial
+  PRIVATE
+    ${UnpackagedIncludeFolder}
+)
diff --git a/Help/guide/tutorial/Step11/TutorialProject/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step11/TutorialProject/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..ac133d4
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/Tutorial/Tutorial.cxx
@@ -0,0 +1,27 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+#include <Unpackaged.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step11/TutorialProject/cmake/TutorialConfig.cmake b/Help/guide/tutorial/Step11/TutorialProject/cmake/TutorialConfig.cmake
new file mode 100644
index 0000000..d13caa4
--- /dev/null
+++ b/Help/guide/tutorial/Step11/TutorialProject/cmake/TutorialConfig.cmake
@@ -0,0 +1 @@
+include(${CMAKE_CURRENT_LIST_DIR}/TutorialTargets.cmake)
diff --git a/Help/guide/tutorial/Step11/install/include/Unpackaged/Unpackaged.h b/Help/guide/tutorial/Step11/install/include/Unpackaged/Unpackaged.h
new file mode 100644
index 0000000..9782b0a
--- /dev/null
+++ b/Help/guide/tutorial/Step11/install/include/Unpackaged/Unpackaged.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define UNPACKAGED_HEADER_FOUND
diff --git a/Help/guide/tutorial/Step11/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake b/Help/guide/tutorial/Step11/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
new file mode 100644
index 0000000..ef51145
--- /dev/null
+++ b/Help/guide/tutorial/Step11/install/lib/cmake/TransitiveDep/TransitiveDepConfig.cmake
@@ -0,0 +1,50 @@
+# Abridged import written for the Tutorial
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+if(CMAKE_VERSION VERSION_LESS "3.0.0")
+   message(FATAL_ERROR "CMake >= 3.0.0 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 3.0.0...3.30)
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_cmake_targets_defined "")
+set(_cmake_targets_not_defined "")
+set(_cmake_expected_targets "")
+foreach(_cmake_expected_target IN ITEMS TransitiveDep::TransitiveDep)
+  list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
+  if(TARGET "${_cmake_expected_target}")
+    list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
+  else()
+    list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
+  endif()
+endforeach()
+unset(_cmake_expected_target)
+if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
+  unset(_cmake_targets_defined)
+  unset(_cmake_targets_not_defined)
+  unset(_cmake_expected_targets)
+  unset(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT _cmake_targets_defined STREQUAL "")
+  string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
+  string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
+endif()
+unset(_cmake_targets_defined)
+unset(_cmake_targets_not_defined)
+unset(_cmake_expected_targets)
+
+# Create imported target TransitiveDep::TransitiveDep
+add_library(TransitiveDep::TransitiveDep INTERFACE IMPORTED)
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)
diff --git a/Help/guide/tutorial/Step11/tutorial.cxx b/Help/guide/tutorial/Step11/tutorial.cxx
deleted file mode 100644
index ca5110c..0000000
--- a/Help/guide/tutorial/Step11/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step12/CMakeLists.txt b/Help/guide/tutorial/Step12/CMakeLists.txt
deleted file mode 100644
index a84590f..0000000
--- a/Help/guide/tutorial/Step12/CMakeLists.txt
+++ /dev/null
@@ -1,124 +0,0 @@
-cmake_minimum_required(VERSION 3.15)
-
-# set the project name and version
-project(Tutorial VERSION 1.0)
-
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
-
-# control where the static and shared libraries are built so that on windows
-# we don't need to tinker with the path to run the executable
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-
-option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
-
-if(APPLE)
-  set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
-elseif(UNIX)
-  set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
-endif()
-
-# configure a header file to pass the version number only
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
-add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-enable_testing()
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-# setup installer
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_GENERATOR "TGZ")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
-
-# install the configuration targets
-install(EXPORT MathFunctionsTargets
-  FILE MathFunctionsTargets.cmake
-  DESTINATION lib/cmake/MathFunctions
-)
-
-include(CMakePackageConfigHelpers)
-# generate the config file that includes the exports
-configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
-  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
-  INSTALL_DESTINATION "lib/cmake/MathFunctions"
-  NO_SET_AND_CHECK_MACRO
-  NO_CHECK_REQUIRED_COMPONENTS_MACRO
-  )
-# generate the version file for the config file
-write_basic_package_version_file(
-  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
-  VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
-  COMPATIBILITY AnyNewerVersion
-)
-
-# install the generated configuration files
-install(FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
-  ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake
-  DESTINATION lib/cmake/MathFunctions
-  )
-
-# generate the export targets for the build tree
-# needs to be after the install(TARGETS) command
-export(EXPORT MathFunctionsTargets
-  FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
-)
diff --git a/Help/guide/tutorial/Step12/CTestConfig.cmake b/Help/guide/tutorial/Step12/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step12/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step12/Config.cmake.in b/Help/guide/tutorial/Step12/Config.cmake.in
deleted file mode 100644
index 17cbabd..0000000
--- a/Help/guide/tutorial/Step12/Config.cmake.in
+++ /dev/null
@@ -1,4 +0,0 @@
-
-@PACKAGE_INIT@
-
-include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
diff --git a/Help/guide/tutorial/Step12/License.txt b/Help/guide/tutorial/Step12/License.txt
deleted file mode 100644
index 85760e5..0000000
--- a/Help/guide/tutorial/Step12/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
deleted file mode 100644
index 8aa5904..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
+++ /dev/null
@@ -1,58 +0,0 @@
-# add the library that runs
-add_library(MathFunctions MathFunctions.cxx)
-
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE
-                            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-                            $<INSTALL_INTERFACE:include>
-                           )
-
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if(USE_MYMATH)
-
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
-  include(MakeTable.cmake) # generates Table.h
-
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-              )
-
-  # state that we depend on our binary dir to find Table.h
-  target_include_directories(SqrtLibrary PRIVATE
-                             ${CMAKE_CURRENT_BINARY_DIR}
-                             )
-
-  # state that SqrtLibrary need PIC when the default is shared libraries
-  set_target_properties(SqrtLibrary PROPERTIES
-                        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
-                        )
-
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
-
-# define the symbol stating we are using the declspec(dllexport) when
-# building on windows
-target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
-
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
-endif()
-install(TARGETS ${installable_libs}
-        EXPORT MathFunctionsTargets
-        DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cmake b/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cmake
deleted file mode 100644
index 12865a9..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx
deleted file mode 100644
index f85b278..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx
+++ /dev/null
@@ -1,25 +0,0 @@
-// A simple program that builds a sqrt table
-#include <cmath>
-#include <fstream>
-#include <iostream>
-
-int main(int argc, char* argv[])
-{
-  // make sure we have enough arguments
-  if (argc < 2) {
-    return 1;
-  }
-
-  std::ofstream fout(argv[1], std::ios_base::out);
-  bool const fileOpen = fout.is_open();
-  if (fileOpen) {
-    fout << "double sqrtTable[] = {" << std::endl;
-    for (int i = 0; i < 10; ++i) {
-      fout << sqrt(static_cast<double>(i)) << "," << std::endl;
-    }
-    // close the table with a zero
-    fout << "0};" << std::endl;
-    fout.close();
-  }
-  return fileOpen ? 0 : 1; // return 0 if wrote the file
-}
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index c0991b9..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include "MathFunctions.h"
-
-#include <cmath>
-
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
-}
-}
diff --git a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h
deleted file mode 100644
index 3fb547b..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#if defined(_WIN32)
-#  if defined(EXPORTING_MYMATH)
-#    define DECLSPEC __declspec(dllexport)
-#  else
-#    define DECLSPEC __declspec(dllimport)
-#  endif
-#else // non windows
-#  define DECLSPEC
-#endif
-
-namespace mathfunctions {
-double DECLSPEC sqrt(double x);
-}
diff --git a/Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 8153f18..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <iostream>
-
-#include "MathFunctions.h"
-
-// include the generated table
-#include "Table.h"
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // use the table to help find an initial value
-  double result = x;
-  if (x >= 1 && x < 10) {
-    std::cout << "Use the table to help find an initial value " << std::endl;
-    result = sqrtTable[static_cast<int>(x)];
-  }
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step12/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.h
deleted file mode 100644
index e1c42ef..0000000
--- a/Help/guide/tutorial/Step12/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step12/TutorialConfig.h.in b/Help/guide/tutorial/Step12/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step12/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step12/tutorial.cxx b/Help/guide/tutorial/Step12/tutorial.cxx
deleted file mode 100644
index 78641b1..0000000
--- a/Help/guide/tutorial/Step12/tutorial.cxx
+++ /dev/null
@@ -1,26 +0,0 @@
-// A simple program that computes the square root of a number
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt
deleted file mode 100644
index 0a06ed7..0000000
--- a/Help/guide/tutorial/Step2/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-
-# set the project name and version
-project(Tutorial VERSION 1.0)
-
-# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
-
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# TODO 2: Use add_subdirectory() to add MathFunctions to this project
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-# TODO 3: Use target_link_libraries to link the library to our executable
-
-# TODO 4: Add MathFunctions to Tutorial's target_include_directories()
-# Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
diff --git a/Help/guide/tutorial/Step2/Exercise1.cmake b/Help/guide/tutorial/Step2/Exercise1.cmake
new file mode 100644
index 0000000..3816de6
--- /dev/null
+++ b/Help/guide/tutorial/Step2/Exercise1.cmake
@@ -0,0 +1,72 @@
+cmake_minimum_required(VERSION 3.23)
+
+
+# TODO1: Implement MacroAppend
+macro(MacroAppend ListVar Value)
+
+endmacro()
+
+# TODO2: Call MacroAppend, then return the value from FuncAppend
+function(FuncAppend ListVar Value)
+
+endfunction()
+
+
+
+# Testing for the above, final expected value is "Alpha;Beta;Gamma;Delta"
+if(SKIP_TESTS)
+  return()
+endif()
+
+set(Original "Beta;Gamma")
+set(Expected "Alpha;Beta;Gamma;Delta")
+
+set(BeginList ${Original})
+set(EndList "Alpha")
+
+MacroAppend(BeginList "Delta")
+foreach(value IN LISTS BeginList)
+  MacroAppend(EndList ${value})
+endforeach()
+
+if(BeginList STREQUAL Original)
+  message("MacroAppend unimplemented or did nothing")
+elseif(NOT EndList STREQUAL Expected)
+  message(WARNING "MacroAppend error, final value: ${EndList}")
+else()
+  message("MacroAppend correct")
+endif()
+
+set(BeginList ${Original})
+set(EndList "Alpha")
+
+FuncAppend(BeginList "Delta")
+foreach(value IN LISTS BeginList)
+  FuncAppend(EndList ${value})
+endforeach()
+
+if(BeginList STREQUAL Original)
+  message("FuncAppend unimplemented or did nothing")
+elseif(NOT EndList STREQUAL Expected)
+  message(WARNING "FuncAppend error, final value: ${EndList}")
+else()
+  message("FuncAppend correct")
+endif()
+
+# Bonus Tests
+
+FuncAppend(UndefinedList "Test")
+
+set(EmptyList "")
+FuncAppend(EmptyList "Test")
+
+set(FalseList "False")
+FuncAppend(FalseList "Test")
+
+if(
+  (UndefinedList STREQUAL "Test") AND
+  (EmptyList STREQUAL "Test") AND
+  (FalseList STREQUAL "False;Test")
+)
+  message("You implemented the empty list case, well done!")
+endif()
diff --git a/Help/guide/tutorial/Step2/Exercise2.cmake b/Help/guide/tutorial/Step2/Exercise2.cmake
new file mode 100644
index 0000000..ee4e9e8
--- /dev/null
+++ b/Help/guide/tutorial/Step2/Exercise2.cmake
@@ -0,0 +1,51 @@
+cmake_minimum_required(VERSION 3.23)
+
+
+function(FilterFoo OutVar)
+# TODO3: Search all the variables in the argument list passed to FilterFoo,
+#        and place those containing "Foo" into the list named by "OutVar"
+
+  set(${OutVar} ${${OutVar}} PARENT_SCOPE)
+endfunction()
+
+
+
+# Testing for the above
+function(check_contains var)
+  if(NOT var IN_LIST OutList)
+    message(WARNING "OutList does not contain: ${var}")
+    set(Failed True PARENT_SCOPE)
+  endif()
+endfunction()
+
+function(check_nonfoo)
+  list(FILTER ARGN EXCLUDE REGEX Foo)
+  if(NOT ARGN STREQUAL "")
+    message(WARNING "OutList contains extra item(s): ${ARGN}")
+    set(Failed True PARENT_SCOPE)
+  endif()
+endfunction()
+
+if(SKIP_TESTS)
+  return()
+endif()
+
+set(InList FooBar BarBaz FooBaz BazBar QuxFoo BazQux)
+
+FilterFoo(OutList ${InList})
+
+if(NOT DEFINED OutList)
+  message("FilterFoo unimplemented or does nothing")
+  return()
+endif()
+
+set(Failed False)
+
+check_contains(FooBar)
+check_contains(FooBaz)
+check_contains(QuxFoo)
+check_nonfoo(${OutList})
+
+if(NOT Failed)
+  message("Success!")
+endif()
diff --git a/Help/guide/tutorial/Step2/Exercise3.cmake b/Help/guide/tutorial/Step2/Exercise3.cmake
new file mode 100644
index 0000000..439aa25
--- /dev/null
+++ b/Help/guide/tutorial/Step2/Exercise3.cmake
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.23)
+
+
+# TODO4: Set the SKIP_TESTS variable to a true value, so that the tests from
+#        Exercise1 and Exercise2 are skipped
+
+
+# TODO5: Include Exercise1.cmake and Exercise2.cmake
+
+
+set(InList FooBar QuxBar)
+
+# TODO6: Append FooBaz and QuxBaz to InList with FuncAppend
+
+
+if(NOT InList STREQUAL "FooBar;QuxBar;FooBaz;QuxBaz")
+  message(WARNING "Append failed, InList contains: ${InList}")
+endif()
+
+
+# TODO7: Filter InList with FilterFoo, use OutList as the output variable
+
+
+check_contains(FooBar)
+check_contains(FooBaz)
+check_nonfoo(${OutList})
+
+if(NOT Failed)
+  message("Success!")
+endif()
diff --git a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
deleted file mode 100644
index c3cd806..0000000
--- a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# TODO 14: Remove mysqrt.cxx from the list of sources
-
-# TODO 1: Add a library called MathFunctions with sources MathFunctions.cxx
-# and mysqrt.cxx
-# Hint: You will need the add_library command
-
-# TODO 7: Create a variable USE_MYMATH using option and set default to ON
-
-# TODO 8: If USE_MYMATH is ON, use target_compile_definitions to pass
-# USE_MYMATH as a precompiled definition to our source files
-
-# TODO 12: When USE_MYMATH is ON, add a library for SqrtLibrary with
-# source mysqrt.cxx
-
-# TODO 13: When USE_MYMATH is ON, link SqrtLibrary to the MathFunctions Library
diff --git a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index 781d0ec..0000000
--- a/Help/guide/tutorial/Step2/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "MathFunctions.h"
-
-// TODO 11: include cmath
-
-// TODO 10: Wrap the mysqrt include in a precompiled ifdef based on USE_MYMATH
-#include "mysqrt.h"
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-  // TODO 9: If USE_MYMATH is defined, use detail::mysqrt.
-  // Otherwise, use std::sqrt.
-  return detail::mysqrt(x);
-}
-}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
deleted file mode 100644
index ba0ac64..0000000
--- a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step2/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step2/TutorialConfig.h.in b/Help/guide/tutorial/Step2/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step2/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step2/tutorial.cxx b/Help/guide/tutorial/Step2/tutorial.cxx
deleted file mode 100644
index b4063c8..0000000
--- a/Help/guide/tutorial/Step2/tutorial.cxx
+++ /dev/null
@@ -1,29 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-// TODO 5: Include MathFunctions.h
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  // TODO 6: Replace sqrt with mathfunctions::sqrt
-
-  // calculate square root
-  double const outputValue = sqrt(inputValue);
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index ac3e9f1..916ad08 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -1,40 +1,18 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+project(Tutorial)
 
-# TODO 4: Replace the following code by:
-# * Creating an interface library called tutorial_compiler_flags
-#   Hint: use add_library() with the INTERFACE signature
-# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
-#   Hint: Use target_compile_features()
+# TODO1: Add a default ON option for a cache variable named:
+#          TUTORIAL_BUILD_UTILITIES.
+#        option() requires a doc string as its second argument, set this to
+#        something like:
+#          "Build the Tutorial executable"
 
-# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
+# TODO2: Add a conditional statement around add_subdirectory(Tutorial). Only
+#        build the Tutorial target if TUTORIAL_BUILD_UTILITIES is ON (or
+#        otherwise truthy).
 
-# TODO 2: Remove EXTRA_INCLUDES list
+add_subdirectory(Tutorial)
 
-# add the MathFunctions library
 add_subdirectory(MathFunctions)
-list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-# TODO 5: Link Tutorial to tutorial_compiler_flags
-
-target_link_libraries(Tutorial PUBLIC MathFunctions)
-
-# TODO 3: Remove use of EXTRA_INCLUDES
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           ${EXTRA_INCLUDES}
-                           )
diff --git a/Help/guide/tutorial/Step3/CMakePresets.json b/Help/guide/tutorial/Step3/CMakePresets.json
new file mode 100644
index 0000000..33f5968
--- /dev/null
+++ b/Help/guide/tutorial/Step3/CMakePresets.json
@@ -0,0 +1,14 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "TODO8": "Set the build directory",
+      "cacheVariables": {
+        "TODO9": "Set the C++ standard version"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 74c553f..dbc7f95 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -1,22 +1,11 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# TODO 1: State that anybody linking to MathFunctions needs to include the
-# current source directory, while MathFunctions itself doesn't.
-# Hint: Use target_include_directories with the INTERFACE keyword
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
-
-  # TODO 6: Link SqrtLibrary to tutorial_compiler_flags
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# TODO 7: Link MathFunctions to tutorial_compiler_flags
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
diff --git a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
index dc28b4b..5f519b4 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step3/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,35 @@
-#include "MathFunctions.h"
+#include <iostream>
 
-#include <cmath>
+// TODO6: Include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
+namespace {
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    // TODO7: Convert the print to use std::format
+    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
+  }
+  return result;
+}
+}
 
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
+  return mysqrt(x);
 }
 }
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
deleted file mode 100644
index ba0ac64..0000000
--- a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step3/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step3/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step3/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..0dc1f58
--- /dev/null
+++ b/Help/guide/tutorial/Step3/Tutorial/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
diff --git a/Help/guide/tutorial/Step3/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step3/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..c630f30
--- /dev/null
+++ b/Help/guide/tutorial/Step3/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+
+// TODO3: Include <format>
+
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    // TODO4: Convert the print to use std::format
+    std::cout << "Usage: " << argv[0] << " number" << std::endl;
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  // TODO5: Convert the print to use std::format
+  std::cout << "The square root of " << inputValue << " is " << outputValue
+            << std::endl;
+}
diff --git a/Help/guide/tutorial/Step3/TutorialConfig.h.in b/Help/guide/tutorial/Step3/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step3/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step3/tutorial.cxx b/Help/guide/tutorial/Step3/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step3/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index fba9766..7d09051 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -1,44 +1,15 @@
-# TODO 1: Update the minimum required version to 3.15
+cmake_minimum_required(VERSION 3.23)
 
-cmake_minimum_required(VERSION 3.10)
+project(Tutorial)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+# TODO1: Add a default-OFF option named TUTORIAL_USE_STD_SQRT, with a doc
+#        string of "Use std::sqrt"
 
-# TODO 2: Create helper variables to determine which compiler we are using:
-# * Create a new variable gcc_like_cxx that is true if we are using CXX and
-#   any of the following compilers: ARMClang, AppleClang, Clang, GNU, LCC
-# * Create a new variable msvc_cxx that is true if we are using CXX and MSVC
-# Hint: Use set() and COMPILE_LANG_AND_ID
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
 
-# TODO 3: Add warning flag compile options to the interface library
-# tutorial_compiler_flags.
-# * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused
-# * For msvc_cxx, add flags -W3
-# Hint: Use target_compile_options()
-
-# TODO 4: With nested generator expressions, only use the flags for the
-# build-tree
-# Hint: Use BUILD_INTERFACE
-
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
 add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
+add_subdirectory(Vendor)
diff --git a/Help/guide/tutorial/Step4/CMakePresets.json b/Help/guide/tutorial/Step4/CMakePresets.json
new file mode 100644
index 0000000..6c47447
--- /dev/null
+++ b/Help/guide/tutorial/Step4/CMakePresets.json
@@ -0,0 +1,16 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TODO7": "Remove the CMAKE_CXX_STANDARD (and this TODO)",
+        "CMAKE_CXX_STANDARD": "20",
+        "TODO8": "Set TUTORIAL_USE_STD_SQRT to ON"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index 6931898..213aafb 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -1,27 +1,16 @@
-# create the MathFunctions library
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
+# TODO2: Add a compile feature for C++20 support to MathFunctions
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+# TODO3: Add a conditional which checks TUTORIAL_USE_STD_SQRT and if
+#        ON, set a compile definition on MathFunctions of the same name
diff --git a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
index dc28b4b..4635cc4 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step4/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,38 @@
-#include "MathFunctions.h"
+// TODO5: Include <cmath>
 
-#include <cmath>
+#include <format>
+#include <iostream>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
+namespace {
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    std::cout << std::format("Computing sqrt of {} to be {}\n", x, result);
+  }
+  return result;
+}
+}
 
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
-  return std::sqrt(x);
-#endif
+  // TODO6: Check if TUTORIAL_USE_STD_SQRT is defined, if so use std::sqrt
+  //        instead of mysqrt
+
+  return mysqrt(x);
 }
 }
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
deleted file mode 100644
index ba0ac64..0000000
--- a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step4/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step4/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step4/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..65a1e74
--- /dev/null
+++ b/Help/guide/tutorial/Step4/Tutorial/CMakeLists.txt
@@ -0,0 +1,33 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+# TODO14: Add VendorLib to Tutorial
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+# TODO4: Add a compile feature for C++20 support to Tutorial
+
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  # TODO9: Add the /W3 compile flag to Tutorial
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  # TODO10: Add the -Wall compile flag to Tutorial
+
+
+endif()
diff --git a/Help/guide/tutorial/Step4/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step4/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..2bb79bf
--- /dev/null
+++ b/Help/guide/tutorial/Step4/Tutorial/Tutorial.cxx
@@ -0,0 +1,36 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+#ifdef TUTORIAL_USE_VENDORLIB
+#  include <Vendor.h>
+#endif
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  int unused;
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+#ifdef TUTORIAL_USE_VENDORLIB
+  if (CheckSqrt(inputValue, outputValue)) {
+    std::cout << "Sqrt verified by vendor\n";
+  } else {
+    std::cout << "Sqrt rejected by vendor\n";
+  }
+#endif
+}
diff --git a/Help/guide/tutorial/Step4/TutorialConfig.h.in b/Help/guide/tutorial/Step4/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step4/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step4/Vendor/CMakeLists.txt b/Help/guide/tutorial/Step4/Vendor/CMakeLists.txt
new file mode 100644
index 0000000..5850a8c
--- /dev/null
+++ b/Help/guide/tutorial/Step4/Vendor/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_library(VendorLib INTERFACE)
+target_compile_definitions(VendorLib INTERFACE TUTORIAL_USE_VENDORLIB)
+
+# TODO11: Add the include directory to VendorLib
+
+# TODO12: Add the lib directory to VendorLib
+
+# TODO13: Add the Vendor archive to VendorLib
diff --git a/Help/guide/tutorial/Step4/Vendor/include/Vendor.h b/Help/guide/tutorial/Step4/Vendor/include/Vendor.h
new file mode 100644
index 0000000..78742c4
--- /dev/null
+++ b/Help/guide/tutorial/Step4/Vendor/include/Vendor.h
@@ -0,0 +1,3 @@
+#pragma once
+
+bool CheckSqrt(double val, double sqrt);
diff --git a/Help/guide/tutorial/Step4/Vendor/lib/Vendor.cxx b/Help/guide/tutorial/Step4/Vendor/lib/Vendor.cxx
new file mode 100644
index 0000000..a6e6c9a
--- /dev/null
+++ b/Help/guide/tutorial/Step4/Vendor/lib/Vendor.cxx
@@ -0,0 +1,8 @@
+bool CheckSqrt(double val, double sqrt)
+{
+  double pow2 = sqrt * sqrt;
+  double delta = val > pow2 ? val - pow2 : pow2 - val;
+
+  // Close enough!
+  return delta < 0.1;
+}
diff --git a/Help/guide/tutorial/Step4/tutorial.cxx b/Help/guide/tutorial/Step4/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step4/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt
index ad814f6..f5ed532 100644
--- a/Help/guide/tutorial/Step5/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/CMakeLists.txt
@@ -1,59 +1,12 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+project(Tutorial)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
 
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
-
-# add the MathFunctions library
 add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# TODO 3: Install Tutorial in the bin directory
-# Hint: Use the TARGETS and DESTINATION parameters
-
-# TODO 4: Install TutorialConfig.h to the include directory
-# Hint: Use the FILES and DESTINATION parameters
-
-# TODO 5: Enable testing
-
-# TODO 6: Add a test called Runs which runs the following command:
-# $ Tutorial 25
-
-# TODO 7: Add a test called Usage which runs the following command:
-# $ Tutorial
-# Make sure the expected output is displayed.
-# Hint: Use the PASS_REGULAR_EXPRESSION property with "Usage.*number"
-
-# TODO 8: Add a test which runs the following command:
-# $ Tutorial 4
-# Make sure the result is correct.
-# Hint: Use the PASS_REGULAR_EXPRESSION property with "4 is 2"
-
-# TODO 9: Add more tests. Create a function called do_test to avoid copy +
-# paste. Test the following values: 4, 9, 5, 7, 25, -25 and 0.0001.
diff --git a/Help/guide/tutorial/Step5/CMakePresets.json b/Help/guide/tutorial/Step5/CMakePresets.json
new file mode 100644
index 0000000..b8ca15f
--- /dev/null
+++ b/Help/guide/tutorial/Step5/CMakePresets.json
@@ -0,0 +1,14 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TUTORIAL_USE_STD_SQRT": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index 61b3899..7aebf48 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -1,34 +1,29 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
+# TODO3: Add a link to MathLogger for the MathFunctions library. Note that
+#        MathLogger will only be used in the MathFunctions implementation,
+#        not the headers
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+# TODO8: Add links to MathLogger for the OpAdd, OpMul, and OpSub libraries.
+#        Note that their headers will be exposed in the MathFunctions.h
+#        header, and must be available to consumers.
 
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
+
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
 endif()
 
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+# TODO4: Add the MathLogger subdirectory
 
-# TODO 1: Create a variable called installable_libs that is a list of all
-# libraries we want to install (e.g. MathFunctions and tutorial_compiler_flags)
-# Then install the installable libraries to the lib folder.
-# Hint: Use the TARGETS and DESTINATION parameters
-
-# TODO 2: Install the library headers to the include folder.
-# Hint: Use the FILES and DESTINATION parameters
+# TODO9: Add the MathExtensions subdirectory
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
index dc28b4b..811209f 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,45 @@
-#include "MathFunctions.h"
-
 #include <cmath>
+#include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
-#endif
+// TODO5: Replace <iostream> with <MathLogger.h>
+
+#include <iostream>
+
+namespace {
+
+// TODO6: Instantiate a logger inside the anonymous namespace
+
+// a hack square root calculation using simple operations
+double mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    // TODO7: Use the logger to log the message
+    std::cout << std::format("Computing sqrt of {} to be {}\n", x, result);
+  }
+  return result;
+}
+}
 
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
+#ifdef TUTORIAL_USE_STD_SQRT
   return std::sqrt(x);
+#else
+  return mysqrt(x);
 #endif
 }
 }
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
index d5c2f22..fcc469b 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathFunctions.h
@@ -1,5 +1,7 @@
 #pragma once
 
+// TODO10: Include <OpAdd.h>, <OpMul.h>, and <OpSub.h>
+
 namespace mathfunctions {
 double sqrt(double x);
 }
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..1077c7f
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+# TODO1: Add an INTERFACE library called MathLogger
+
+
+# TODO2: Add an appropriate FILE_SET to MathLogger to capture the headers in
+#        this directory
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step5/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
deleted file mode 100644
index ba0ac64..0000000
--- a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step5/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step5/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step5/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..3daa5ea
--- /dev/null
+++ b/Help/guide/tutorial/Step5/Tutorial/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
diff --git a/Help/guide/tutorial/Step5/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step5/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..e3e3604
--- /dev/null
+++ b/Help/guide/tutorial/Step5/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  // TODO11: Check the calculated square root using mathfunctions::OpMul to
+  //         square the outputValue. Output the result with the format:
+  //           "The square of {} is {}\n"
+}
diff --git a/Help/guide/tutorial/Step5/TutorialConfig.h.in b/Help/guide/tutorial/Step5/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step5/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step5/tutorial.cxx b/Help/guide/tutorial/Step5/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step5/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index a86d60a..c07a1ac 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -1,71 +1,24 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+project(Tutorial)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
 
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
+# TODO6: Add a default-ON option named TUTORIAL_ENABLE_IPO with a doc string:
+#          "Check for and use IPO support"
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
+# TODO7: Include and use the CheckIPOSupported module to enable IPO if
+#        TUTORIAL_ENABLE_IPO is True. To enable IPO, use:
+#          set(CMAKE_INTERPROCEDURAL_OPTIMIZATION True)
+#        Otherwise, follow the examples in the CheckIPOSupported documentation.
+#        Specifically, follow the documentation example to emit an error message
+#        if IPO is unavailable. Additionally, when IPO is available, emit a
+#        message indicating so (otherwise IPO has no easily visible change in
+#        the logs or build).
 
-# add the MathFunctions library
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
+
 add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# TODO 1: Replace enable_testing() with include(CTest)
-# enable testing
-enable_testing()
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
diff --git a/Help/guide/tutorial/Step6/CMakePresets.json b/Help/guide/tutorial/Step6/CMakePresets.json
new file mode 100644
index 0000000..b8ca15f
--- /dev/null
+++ b/Help/guide/tutorial/Step6/CMakePresets.json
@@ -0,0 +1,14 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TUTORIAL_USE_STD_SQRT": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step6/CTestConfig.cmake b/Help/guide/tutorial/Step6/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step6/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 8499a51..bac1e65 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -1,35 +1,49 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
 
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
+
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
 endif()
 
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+# TODO1: Include the CheckIncludeFiles module and use it to check for
+#        the emmintrin.h header.
 
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
-endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
+# TODO2: If emmintrin.h is available, add a compile definition to MathFunctions
+#        named TUTORIAL_USE_SSE2. This will only be needed by the MathFunctions
+#        implementation file.
+
+# TODO4: Include the CheckSourceCompiles module and use it to check if the
+#        following program compiles:
+#
+#           typedef double v2df __attribute__((vector_size(16)));
+#           int main() {
+#             __builtin_ia32_sqrtsd(v2df{});
+#           }
+
+# TODO5: If the GNU builtins are available, add a compile definition to
+#        MathFunctions named TUTORIAL_USE_GNU_BUILTIN. This will only be needed
+#        by the MathFunctions implementation file.
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
index dc28b4b..eae6c32 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,79 @@
-#include "MathFunctions.h"
-
 #include <cmath>
+#include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
+#include <MathLogger.h>
+
+// TODO3: If the TUTORIAL_USE_SSE2 definition is set, include
+//        the <emmintrin.h> header
+
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
 #endif
 
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+double mysqrt(double x)
+{
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+
+}
+
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
+#ifdef TUTORIAL_USE_STD_SQRT
   return std::sqrt(x);
+#else
+  return mysqrt(x);
 #endif
 }
 }
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
index d5c2f22..91cb176 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathFunctions.h
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
 namespace mathfunctions {
 double sqrt(double x);
 }
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step6/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
deleted file mode 100644
index ba0ac64..0000000
--- a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step6/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step6/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..3daa5ea
--- /dev/null
+++ b/Help/guide/tutorial/Step6/Tutorial/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
diff --git a/Help/guide/tutorial/Step6/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step6/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..44b7831
--- /dev/null
+++ b/Help/guide/tutorial/Step6/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step6/TutorialConfig.h.in b/Help/guide/tutorial/Step6/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step6/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step6/tutorial.cxx b/Help/guide/tutorial/Step6/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step6/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt
index 97ec6aa..0b486f0 100644
--- a/Help/guide/tutorial/Step7/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/CMakeLists.txt
@@ -1,70 +1,25 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+project(Tutorial)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
 
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
 
-# add the MathFunctions library
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
+
 add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-include(CTest)
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
diff --git a/Help/guide/tutorial/Step7/CMakePresets.json b/Help/guide/tutorial/Step7/CMakePresets.json
new file mode 100644
index 0000000..f393977
--- /dev/null
+++ b/Help/guide/tutorial/Step7/CMakePresets.json
@@ -0,0 +1,15 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step7/CTestConfig.cmake b/Help/guide/tutorial/Step7/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step7/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index a0b3037..3782f66 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -1,55 +1,54 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
+# TODO8: Add the interface library to MathFunctions
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
 
-  # TODO 1: Include CheckCXXSourceCompiles
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
 
-  # TODO 2: Use check_cxx_source_compiles with simple C++ code to verify
-  # availability of:
-  # * std::log
-  # * std::exp
-  # Store the results in HAVE_LOG and HAVE_EXP respectively.
-
-  # Hint: Sample C++ code which uses log:
-  # #include <cmath>
-  # int main() {
-  #   std::log(1.0);
-  #   return 0;
-  # }
-
-  # TODO 3: Conditionally on HAVE_LOG and HAVE_EXP, add private compile
-  # definitions "HAVE_LOG" and "HAVE_EXP" to the SqrtLibrary target.
-
-  # Hint: Use target_compile_definitions()
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
 endif()
 
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
 
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
 endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+# TODO9: Add the MakeTable subdirectory to the project
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..cef2be7
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,15 @@
+# TODO1: Add a MakeTable executable
+
+# TODO2: Add MakeTable.cxx to the MakeTable executable
+
+# TODO3: Add a custom command which invokes MakeTable to generate SqrtTable.h
+
+# TODO4: Add a custom target which depends on SqrtTable.h
+
+# TODO5: Add an INTERFACE library to describe the SqrtTable header
+
+# TODO6: Add the current binary directory (and optionally the SqrtTable.h FILE)
+#        to a header file set of the interface library
+
+# TODO7: Use add_dependencies to ensure the custom target always runs before
+#        targets that depend on the interface library
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step7/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
rename from Help/guide/tutorial/Step10/MathFunctions/MakeTable.cxx
rename to Help/guide/tutorial/Step7/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
index dc28b4b..9da2656 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,102 @@
-#include "MathFunctions.h"
-
 #include <cmath>
+#include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
 #endif
 
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+// TODO10: Replace this hardcoded sqrtTable with #include <SqrtTable.h>
+double sqrtTable[] = { 0, 1, 1, 2, 2, 2, 2, 3, 3, 3 };
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
+#ifdef TUTORIAL_USE_STD_SQRT
   return std::sqrt(x);
+#else
+  return mysqrt(x);
 #endif
 }
 }
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
index d5c2f22..91cb176 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathFunctions.h
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
 namespace mathfunctions {
 double sqrt(double x);
 }
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step7/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 465b43a..0000000
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "mysqrt.h"
-
-// TODO 4: include cmath
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // TODO 5: If both HAVE_LOG and HAVE_EXP are defined,  use the following:
-  //// double result = std::exp(std::log(x) * 0.5);
-  //// std::cout << "Computing sqrt of " << x << " to be " << result
-  ////        << " using log and exp" << std::endl;
-  // else, use the existing logic.
-
-  // Hint: Don't forget the #endif before returning the result!
-
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step7/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step7/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..3daa5ea
--- /dev/null
+++ b/Help/guide/tutorial/Step7/Tutorial/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
diff --git a/Help/guide/tutorial/Step7/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step7/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..44b7831
--- /dev/null
+++ b/Help/guide/tutorial/Step7/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step7/TutorialConfig.h.in b/Help/guide/tutorial/Step7/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step7/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step7/tutorial.cxx b/Help/guide/tutorial/Step7/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step7/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt
index 97ec6aa..79f78f5 100644
--- a/Help/guide/tutorial/Step8/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/CMakeLists.txt
@@ -1,70 +1,30 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+project(Tutorial)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
 
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
+# TODO6: Add a default-ON option named BUILD_TESTING with a doc string of:
+#          "Enable testing and build tests"
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
 
-# add the MathFunctions library
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+endif()
+
+# TODO7: Conditional on the value of BUILD_TESTING, enable testing and add the
+#        Tests subdirectory to the project
+
 add_subdirectory(MathFunctions)
-
-# add the executable
-add_executable(Tutorial tutorial.cxx)
-
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
-
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
-
-# enable testing
-include(CTest)
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
diff --git a/Help/guide/tutorial/Step8/CMakePresets.json b/Help/guide/tutorial/Step8/CMakePresets.json
new file mode 100644
index 0000000..f393977
--- /dev/null
+++ b/Help/guide/tutorial/Step8/CMakePresets.json
@@ -0,0 +1,15 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step8/CTestConfig.cmake b/Help/guide/tutorial/Step8/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step8/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index b14d180..8673342 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -1,59 +1,54 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              )
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
+    SqrtTable
 
-  # does this system provide the log and exp functions?
-  include(CheckCXXSourceCompiles)
-  check_cxx_source_compiles("
-    #include <cmath>
-    int main() {
-      std::log(1.0);
-      return 0;
-    }
-  " HAVE_LOG)
-  check_cxx_source_compiles("
-    #include <cmath>
-    int main() {
-      std::exp(1.0);
-      return 0;
-    }
-  " HAVE_EXP)
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
 
-  # add compile definitions
-  if(HAVE_LOG AND HAVE_EXP)
-    target_compile_definitions(SqrtLibrary
-                               PRIVATE "HAVE_LOG" "HAVE_EXP"
-                               )
-  endif()
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
 
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
 endif()
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
 
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
-
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
 endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+add_subdirectory(MakeTable)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..6aa2a32
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_executable(MakeTable)
+
+target_sources(MakeTable
+  PRIVATE
+    MakeTable.cxx
+)
+
+add_custom_command(
+  OUTPUT SqrtTable.h
+  COMMAND MakeTable SqrtTable.h
+  DEPENDS MakeTable
+  VERBATIM
+)
+
+add_custom_target(RunMakeTable DEPENDS SqrtTable.h)
+
+add_library(SqrtTable INTERFACE)
+
+target_sources(SqrtTable
+  INTERFACE
+    FILE_SET HEADERS
+    BASE_DIRS
+      ${CMAKE_CURRENT_BINARY_DIR}
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SqrtTable.h
+)
+
+add_dependencies(SqrtTable RunMakeTable)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step8/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
rename from Help/guide/tutorial/Step8/MathFunctions/MakeTable.cxx
rename to Help/guide/tutorial/Step8/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
index dc28b4b..4bf8051 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,101 @@
-#include "MathFunctions.h"
-
 #include <cmath>
+#include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
 #endif
 
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+#include <SqrtTable.h>
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
+#ifdef TUTORIAL_USE_STD_SQRT
   return std::sqrt(x);
+#else
+  return mysqrt(x);
 #endif
 }
 }
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
index d5c2f22..91cb176 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathFunctions.h
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
 namespace mathfunctions {
 double sqrt(double x);
 }
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step8/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 28ab042..0000000
--- a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,36 +0,0 @@
-#include "mysqrt.h"
-
-#include <cmath>
-#include <iostream>
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // if we have both log and exp then use them
-#if defined(HAVE_LOG) && defined(HAVE_EXP)
-  double result = std::exp(std::log(x) * 0.5);
-  std::cout << "Computing sqrt of " << x << " to be " << result
-            << " using log and exp" << std::endl;
-#else
-  double result = x;
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-#endif
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step8/Tests/CMakeLists.txt b/Help/guide/tutorial/Step8/Tests/CMakeLists.txt
new file mode 100644
index 0000000..ce2ca46
--- /dev/null
+++ b/Help/guide/tutorial/Step8/Tests/CMakeLists.txt
@@ -0,0 +1,13 @@
+# TODO1: Add an executable target for the tests
+
+# TODO2: Add the TestMathFunctions.cxx file to the test target's sources
+
+# TODO3: Add the MathFunctions library to the test target's link libraries
+
+# TODO4: Write a function that takes a single operation name as an argument.
+#        The function will call add_test() with the operation name as the NAME
+#        of the test, and a COMMAND of the form: <TestTarget> <operation name>
+
+
+# TODO5: Call the function for all four supported operations:
+#          add, mul, sqrt, sub
diff --git a/Help/guide/tutorial/Step8/Tests/TestMathFunctions.cxx b/Help/guide/tutorial/Step8/Tests/TestMathFunctions.cxx
new file mode 100644
index 0000000..bda0bba
--- /dev/null
+++ b/Help/guide/tutorial/Step8/Tests/TestMathFunctions.cxx
@@ -0,0 +1,24 @@
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    return -1;
+  }
+
+  std::string op(argv[1]);
+
+  if (op == "add") {
+    return mathfunctions::OpAdd(1.0, 1.0) != 2.0;
+  } else if (op == "mul") {
+    return mathfunctions::OpMul(5.0, 5.0) != 25.0;
+  } else if (op == "sqrt") {
+    return mathfunctions::sqrt(25.0) != 5.0;
+  } else if (op == "sub") {
+    return mathfunctions::OpSub(5.0, 1.0) != 4.0;
+  }
+
+  return -1;
+}
diff --git a/Help/guide/tutorial/Step8/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step8/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..3daa5ea
--- /dev/null
+++ b/Help/guide/tutorial/Step8/Tutorial/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
diff --git a/Help/guide/tutorial/Step8/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step8/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..44b7831
--- /dev/null
+++ b/Help/guide/tutorial/Step8/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step8/TutorialConfig.h.in b/Help/guide/tutorial/Step8/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step8/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step8/tutorial.cxx b/Help/guide/tutorial/Step8/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step8/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt
index 97ec6aa..7edce35 100644
--- a/Help/guide/tutorial/Step9/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/CMakeLists.txt
@@ -1,70 +1,58 @@
-cmake_minimum_required(VERSION 3.15)
+cmake_minimum_required(VERSION 3.23)
 
-# set the project name and version
-project(Tutorial VERSION 1.0)
+# TODO9: Add a VERSION parameter to the project() command for version 1.0.0
+project(Tutorial)
 
-# specify the C++ standard
-add_library(tutorial_compiler_flags INTERFACE)
-target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+option(TUTORIAL_BUILD_UTILITIES "Build the Tutorial executable" ON)
+option(TUTORIAL_USE_STD_SQRT "Use std::sqrt" OFF)
+option(TUTORIAL_ENABLE_IPO "Check for and use IPO support" ON)
+option(BUILD_TESTING "Enable testing and build tests" ON)
 
-# add compiler warning flags just when building this project via
-# the BUILD_INTERFACE genex
-set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
-set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
-target_compile_options(tutorial_compiler_flags INTERFACE
-  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
-  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
-)
+if(TUTORIAL_ENABLE_IPO)
+  include(CheckIPOSupported)
+  check_ipo_supported(RESULT result OUTPUT output)
+  if(result)
+    message("IPO is supported, enabling IPO")
+    set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+  else()
+    message(WARNING "IPO is not supported: ${output}")
+  endif()
+endif()
 
-# configure a header file to pass some of the CMake settings
-# to the source code
-configure_file(TutorialConfig.h.in TutorialConfig.h)
+if(TUTORIAL_BUILD_UTILITIES)
+  add_subdirectory(Tutorial)
+  # TODO1: Install the Tutorial target
 
-# add the MathFunctions library
+  # TODO3: Add the Tutorial target to the TutorialTargets export
+endif()
+
+if(BUILD_TESTING)
+  enable_testing()
+  add_subdirectory(Tests)
+endif()
+
 add_subdirectory(MathFunctions)
 
-# add the executable
-add_executable(Tutorial tutorial.cxx)
+# TODO4: Include the GNUInstallDirs module
 
-target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
+# TODO2: Install the MathFunctions, OpAdd, OpMul, OpSub, SqrtTable, and
+#        MathLogger targets. Ensure you name their header file set so the
+#        headers will be installed.
 
-# add the binary tree to the search path for include files
-# so that we will find TutorialConfig.h
-target_include_directories(Tutorial PUBLIC
-                           "${PROJECT_BINARY_DIR}"
-                           )
+# TODO5: Add the targets from TODO2 to the TutorialTargets export
 
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
-  DESTINATION include
-  )
+# TODO6: Install the TutorialTargets export to:
+#          ${CMAKE_INSTALL_LIBDIR}/cmake/Tutorial
+#        And give them a namespace of "Tutorial::"
 
-# enable testing
-include(CTest)
+# TODO10: Include CMakePackageConfigHelpers
 
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
+# TODO11: Use write_basic_package_version_file to write a
+#         TutorialConfigVersion.cmake file to the CMAKE_CURRENT_BINARY_DIR.
+#         The version compatibility should be ExactVersion.
 
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
-  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
-  )
+# TODO12: Add the generated TutorialConfigVersion.cmake file to the file list
+#         of the TODO7 install() command.
 
-# define a function to simplify adding tests
-function(do_test target arg result)
-  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
-  set_tests_properties(Comp${arg}
-    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
-    )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
+# TODO7: Install the config file at cmake/TutorialConfig.cmake to the same
+#        destination as the TutorialTargets export.
diff --git a/Help/guide/tutorial/Step9/CMakePresets.json b/Help/guide/tutorial/Step9/CMakePresets.json
new file mode 100644
index 0000000..f393977
--- /dev/null
+++ b/Help/guide/tutorial/Step9/CMakePresets.json
@@ -0,0 +1,15 @@
+{
+  "version": 4,
+  "configurePresets": [
+    {
+      "name": "tutorial",
+      "displayName": "Tutorial Preset",
+      "description": "Preset to use with the tutorial",
+      "binaryDir": "${sourceDir}/build",
+      "cacheVariables": {
+        "TUTORIAL_USE_STD_SQRT": "OFF",
+        "TUTORIAL_ENABLE_IPO": "OFF"
+      }
+    }
+  ]
+}
diff --git a/Help/guide/tutorial/Step9/CTestConfig.cmake b/Help/guide/tutorial/Step9/CTestConfig.cmake
deleted file mode 100644
index b2922fe..0000000
--- a/Help/guide/tutorial/Step9/CTestConfig.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
-
-set(CTEST_SUBMIT_URL "https://my.cdash.org/submit.php?project=CMakeTutorial")
diff --git a/Help/guide/tutorial/Step9/License.txt b/Help/guide/tutorial/Step9/License.txt
deleted file mode 100644
index 85760e5..0000000
--- a/Help/guide/tutorial/Step9/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 5addc6d..8673342 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -1,44 +1,54 @@
-add_library(MathFunctions MathFunctions.cxx)
+add_library(MathFunctions)
 
-# state that anybody linking to us needs to include the current source dir
-# to find MathFunctions.h, while we don't.
-target_include_directories(MathFunctions
-                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
-                           )
+target_sources(MathFunctions
+  PRIVATE
+    MathFunctions.cxx
 
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if (USE_MYMATH)
-  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  PUBLIC
+    FILE_SET HEADERS
+    FILES
+      MathFunctions.h
+)
 
-  # generate Table.h
-  include(MakeTable.cmake)
+target_link_libraries(MathFunctions
+  PRIVATE
+    MathLogger
+    SqrtTable
 
-  # library that just does sqrt
-  add_library(SqrtLibrary STATIC
-              mysqrt.cxx
-              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-              )
+  PUBLIC
+    OpAdd
+    OpMul
+    OpSub
+)
 
-  # state that we depend on our binary dir to find Table.h
-  target_include_directories(SqrtLibrary PRIVATE
-                             ${CMAKE_CURRENT_BINARY_DIR}
-                             )
+target_compile_features(MathFunctions PRIVATE cxx_std_20)
 
-  # link SqrtLibrary to tutorial_compiler_flags
-  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
-
-  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
+if(TUTORIAL_USE_STD_SQRT)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_STD_SQRT)
 endif()
 
-# link MathFunctions to tutorial_compiler_flags
-target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+include(CheckIncludeFiles)
+check_include_files(emmintrin.h HAS_EMMINTRIN LANGUAGE CXX)
 
-# install libs
-set(installable_libs MathFunctions tutorial_compiler_flags)
-if(TARGET SqrtLibrary)
-  list(APPEND installable_libs SqrtLibrary)
+if(HAS_EMMINTRIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_SSE2)
 endif()
-install(TARGETS ${installable_libs} DESTINATION lib)
-# install include headers
-install(FILES MathFunctions.h DESTINATION include)
+
+include(CheckSourceCompiles)
+check_source_compiles(CXX
+  [=[
+    typedef double v2df __attribute__((vector_size(16)));
+    int main() {
+      __builtin_ia32_sqrtsd(v2df{});
+    }
+  ]=]
+  HAS_GNU_BUILTIN
+)
+
+if(HAS_GNU_BUILTIN)
+  target_compile_definitions(MathFunctions PRIVATE TUTORIAL_USE_GNU_BUILTIN)
+endif()
+
+add_subdirectory(MathLogger)
+add_subdirectory(MathExtensions)
+add_subdirectory(MakeTable)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cmake b/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cmake
deleted file mode 100644
index 12865a9..0000000
--- a/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
-
-# add the command to generate the source code
-add_custom_command(
-  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
-  DEPENDS MakeTable
-  )
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MakeTable/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MakeTable/CMakeLists.txt
new file mode 100644
index 0000000..6aa2a32
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MakeTable/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_executable(MakeTable)
+
+target_sources(MakeTable
+  PRIVATE
+    MakeTable.cxx
+)
+
+add_custom_command(
+  OUTPUT SqrtTable.h
+  COMMAND MakeTable SqrtTable.h
+  DEPENDS MakeTable
+  VERBATIM
+)
+
+add_custom_target(RunMakeTable DEPENDS SqrtTable.h)
+
+add_library(SqrtTable INTERFACE)
+
+target_sources(SqrtTable
+  INTERFACE
+    FILE_SET HEADERS
+    BASE_DIRS
+      ${CMAKE_CURRENT_BINARY_DIR}
+    FILES
+      ${CMAKE_CURRENT_BINARY_DIR}/SqrtTable.h
+)
+
+add_dependencies(SqrtTable RunMakeTable)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step9/MathFunctions/MakeTable/MakeTable.cxx
similarity index 100%
rename from Help/guide/tutorial/Step9/MathFunctions/MakeTable.cxx
rename to Help/guide/tutorial/Step9/MathFunctions/MakeTable/MakeTable.cxx
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/CMakeLists.txt
new file mode 100644
index 0000000..b113786
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(OpAdd)
+add_subdirectory(OpMul)
+add_subdirectory(OpSub)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
new file mode 100644
index 0000000..f35da81
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpAdd OBJECT)
+
+target_sources(OpAdd
+  PRIVATE
+    OpAdd.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpAdd.h
+)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
new file mode 100644
index 0000000..ea11496
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpAdd(double a, double b)
+{
+  return a + b;
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.h b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.h
new file mode 100644
index 0000000..9c9efc3
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpAdd/OpAdd.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpAdd(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
new file mode 100644
index 0000000..f494fc6
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpMul OBJECT)
+
+target_sources(OpMul
+  PRIVATE
+    OpMul.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpMul.h
+)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.cxx
new file mode 100644
index 0000000..c8eb016
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpMul(double a, double b)
+{
+  return a * b;
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.h b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.h
new file mode 100644
index 0000000..52b467b
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpMul/OpMul.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpMul(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
new file mode 100644
index 0000000..1a108fd
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_library(OpSub OBJECT)
+
+target_sources(OpSub
+  PRIVATE
+    OpSub.cxx
+
+  INTERFACE
+    FILE_SET HEADERS
+    FILES
+      OpSub.h
+)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.cxx
new file mode 100644
index 0000000..b7b35da
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.cxx
@@ -0,0 +1,6 @@
+namespace mathfunctions {
+double OpSub(double a, double b)
+{
+  return a - b;
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.h b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.h
new file mode 100644
index 0000000..1406733
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathExtensions/OpSub/OpSub.h
@@ -0,0 +1,5 @@
+#pragma once
+
+namespace mathfunctions {
+double OpSub(double a, double b);
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
index dc28b4b..4bf8051 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
@@ -1,19 +1,101 @@
-#include "MathFunctions.h"
-
 #include <cmath>
+#include <format>
 
-#ifdef USE_MYMATH
-#  include "mysqrt.h"
+#include <MathLogger.h>
+
+#ifdef TUTORIAL_USE_SSE2
+#  include <emmintrin.h>
 #endif
 
+namespace {
+
+mathlogger::Logger Logger;
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+typedef double v2df __attribute__((vector_size(16)));
+
+double gnu_mysqrt(double x)
+{
+  v2df root = __builtin_ia32_sqrtsd(v2df{ x, 0.0 });
+  double result = root[0];
+  Logger.Log(std::format("Computed sqrt of {} to be {} with GNU-builtins\n", x,
+                         result));
+  return result;
+}
+#elif defined(TUTORIAL_USE_SSE2)
+double sse2_mysqrt(double x)
+{
+  __m128d root = _mm_sqrt_sd(_mm_setzero_pd(), _mm_set_sd(x));
+  double result = _mm_cvtsd_f64(root);
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with SSE2\n", x, result));
+  return result;
+}
+#endif
+
+// a hack square root calculation using simple operations
+double fallback_mysqrt(double x)
+{
+  if (x <= 0) {
+    return 0;
+  }
+
+  double result = x;
+
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+
+    Logger.Log(std::format("Computing sqrt of {} to be {}\n", x, result));
+  }
+  return result;
+}
+
+#include <SqrtTable.h>
+
+double table_sqrt(double x)
+{
+  double result = sqrtTable[static_cast<int>(x)];
+  // do ten iterations
+  for (int i = 0; i < 10; ++i) {
+    if (result <= 0) {
+      result = 0.1;
+    }
+    double delta = x - (result * result);
+    result = result + 0.5 * delta / result;
+  }
+  Logger.Log(
+    std::format("Computed sqrt of {} to be {} with TableSqrt\n", x, result));
+  return result;
+}
+
+double mysqrt(double x)
+{
+  if (x >= 1 && x < 10) {
+    return table_sqrt(x);
+  }
+
+#if defined(TUTORIAL_USE_GNU_BUILTIN)
+  return gnu_mysqrt(x);
+#elif defined(TUTORIAL_USE_SSE2)
+  return sse2_mysqrt(x);
+#else
+  return fallback_mysqrt(x);
+#endif
+}
+}
+
 namespace mathfunctions {
 double sqrt(double x)
 {
-// which square root function should we use?
-#ifdef USE_MYMATH
-  return detail::mysqrt(x);
-#else
+#ifdef TUTORIAL_USE_STD_SQRT
   return std::sqrt(x);
+#else
+  return mysqrt(x);
 #endif
 }
 }
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
index d5c2f22..91cb176 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.h
@@ -1,5 +1,9 @@
 #pragma once
 
+#include <OpAdd.h>
+#include <OpMul.h>
+#include <OpSub.h>
+
 namespace mathfunctions {
 double sqrt(double x);
 }
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathLogger/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/CMakeLists.txt
new file mode 100644
index 0000000..b20151f
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(MathLogger INTERFACE)
+
+target_sources(MathLogger
+  INTERFACE
+    FILE_SET HEADERS
+)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathFormatting.h b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathFormatting.h
new file mode 100644
index 0000000..3b6d61c
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathFormatting.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+namespace mathlogger {
+
+enum LogLevel
+{
+  INFO,
+  WARN,
+  ERROR,
+};
+
+inline std::string FormatLog(LogLevel level, std::string const& message)
+{
+  switch (level) {
+    case INFO:
+      return "INFO: " + message;
+    case WARN:
+      return "WARN: " + message;
+    case ERROR:
+      return "ERROR: " + message;
+  }
+  return "UNKNOWN: " + message;
+}
+
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathLogger.h b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathLogger.h
new file mode 100644
index 0000000..ef7b31a
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathLogger.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <string>
+
+#include "MathFormatting.h"
+#include "MathOutput.h"
+
+namespace mathlogger {
+
+struct Logger
+{
+  LogLevel level = INFO;
+
+  void SetLevel(LogLevel new_level) { level = new_level; }
+  void Log(std::string const& message)
+  {
+    std::string formatted = FormatLog(level, message);
+    WriteLog(formatted);
+  }
+};
+
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathOutput.h b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathOutput.h
new file mode 100644
index 0000000..63f0aeb
--- /dev/null
+++ b/Help/guide/tutorial/Step9/MathFunctions/MathLogger/MathOutput.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <iostream>
+#include <string>
+
+namespace mathlogger {
+inline void WriteLog(std::string const& msg)
+{
+  std::cout << msg;
+}
+}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
deleted file mode 100644
index 477d715..0000000
--- a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "mysqrt.h"
-
-#include <iostream>
-
-// include the generated table
-#include "Table.h"
-
-namespace mathfunctions {
-namespace detail {
-// a hack square root calculation using simple operations
-double mysqrt(double x)
-{
-  if (x <= 0) {
-    return 0;
-  }
-
-  // use the table to help find an initial value
-  double result = x;
-  if (x >= 1 && x < 10) {
-    std::cout << "Use the table to help find an initial value " << std::endl;
-    result = sqrtTable[static_cast<int>(x)];
-  }
-
-  // do ten iterations
-  for (int i = 0; i < 10; ++i) {
-    if (result <= 0) {
-      result = 0.1;
-    }
-    double delta = x - (result * result);
-    result = result + 0.5 * delta / result;
-    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
-  }
-
-  return result;
-}
-}
-}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
deleted file mode 100644
index 593d41e..0000000
--- a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/Step9/Tests/CMakeLists.txt b/Help/guide/tutorial/Step9/Tests/CMakeLists.txt
new file mode 100644
index 0000000..c6750ae
--- /dev/null
+++ b/Help/guide/tutorial/Step9/Tests/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_executable(TestMathFunctions)
+
+target_sources(TestMathFunctions
+  PRIVATE
+    TestMathFunctions.cxx
+)
+
+target_link_libraries(TestMathFunctions
+  PRIVATE
+    MathFunctions
+)
+
+function(MathFunctionTest op)
+  add_test(
+    NAME ${op}
+    COMMAND TestMathFunctions ${op}
+  )
+endfunction()
+
+MathFunctionTest(add)
+MathFunctionTest(mul)
+MathFunctionTest(sqrt)
+MathFunctionTest(sub)
diff --git a/Help/guide/tutorial/Step9/Tests/TestMathFunctions.cxx b/Help/guide/tutorial/Step9/Tests/TestMathFunctions.cxx
new file mode 100644
index 0000000..bda0bba
--- /dev/null
+++ b/Help/guide/tutorial/Step9/Tests/TestMathFunctions.cxx
@@ -0,0 +1,24 @@
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    return -1;
+  }
+
+  std::string op(argv[1]);
+
+  if (op == "add") {
+    return mathfunctions::OpAdd(1.0, 1.0) != 2.0;
+  } else if (op == "mul") {
+    return mathfunctions::OpMul(5.0, 5.0) != 25.0;
+  } else if (op == "sqrt") {
+    return mathfunctions::sqrt(25.0) != 5.0;
+  } else if (op == "sub") {
+    return mathfunctions::OpSub(5.0, 1.0) != 4.0;
+  }
+
+  return -1;
+}
diff --git a/Help/guide/tutorial/Step9/Tutorial/CMakeLists.txt b/Help/guide/tutorial/Step9/Tutorial/CMakeLists.txt
new file mode 100644
index 0000000..3daa5ea
--- /dev/null
+++ b/Help/guide/tutorial/Step9/Tutorial/CMakeLists.txt
@@ -0,0 +1,29 @@
+add_executable(Tutorial)
+
+target_sources(Tutorial
+  PRIVATE
+    Tutorial.cxx
+)
+
+target_link_libraries(Tutorial
+  PRIVATE
+    MathFunctions
+)
+
+target_compile_features(Tutorial PRIVATE cxx_std_20)
+
+if(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") OR
+  (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
+)
+
+  target_compile_options(Tutorial PRIVATE /W3)
+
+elseif(
+  (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
+  (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+)
+
+  target_compile_options(Tutorial PRIVATE -Wall)
+
+endif()
diff --git a/Help/guide/tutorial/Step9/Tutorial/Tutorial.cxx b/Help/guide/tutorial/Step9/Tutorial/Tutorial.cxx
new file mode 100644
index 0000000..44b7831
--- /dev/null
+++ b/Help/guide/tutorial/Step9/Tutorial/Tutorial.cxx
@@ -0,0 +1,26 @@
+// A simple program that computes the square root of a number
+#include <format>
+#include <iostream>
+#include <string>
+
+#include <MathFunctions.h>
+
+int main(int argc, char* argv[])
+{
+  if (argc < 2) {
+    std::cout << std::format("Usage: {} number\n", argv[0]);
+    return 1;
+  }
+
+  // convert input to double
+  double const inputValue = std::stod(argv[1]);
+
+  // calculate square root
+  double const outputValue = mathfunctions::sqrt(inputValue);
+  std::cout << std::format("The square root of {} is {}\n", inputValue,
+                           outputValue);
+
+  double const checkValue = mathfunctions::OpMul(outputValue, outputValue);
+  std::cout << std::format("The square of {} is {}\n", outputValue,
+                           checkValue);
+}
diff --git a/Help/guide/tutorial/Step9/TutorialConfig.h.in b/Help/guide/tutorial/Step9/TutorialConfig.h.in
deleted file mode 100644
index 7e4d7fa..0000000
--- a/Help/guide/tutorial/Step9/TutorialConfig.h.in
+++ /dev/null
@@ -1,3 +0,0 @@
-// the configured options and settings for Tutorial
-#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
-#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/Step9/cmake/TutorialConfig.cmake b/Help/guide/tutorial/Step9/cmake/TutorialConfig.cmake
new file mode 100644
index 0000000..f8e61ea
--- /dev/null
+++ b/Help/guide/tutorial/Step9/cmake/TutorialConfig.cmake
@@ -0,0 +1,2 @@
+# TODO8: Include the TutorialTargets.cmake file, it will be located in the same
+#        list directory as this file when it is run.
diff --git a/Help/guide/tutorial/Step9/tutorial.cxx b/Help/guide/tutorial/Step9/tutorial.cxx
deleted file mode 100644
index 48be3c6..0000000
--- a/Help/guide/tutorial/Step9/tutorial.cxx
+++ /dev/null
@@ -1,27 +0,0 @@
-// A simple program that computes the square root of a number
-#include <cmath>
-#include <iostream>
-#include <string>
-
-#include "MathFunctions.h"
-#include "TutorialConfig.h"
-
-int main(int argc, char* argv[])
-{
-  if (argc < 2) {
-    // report version
-    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
-              << Tutorial_VERSION_MINOR << std::endl;
-    std::cout << "Usage: " << argv[0] << " number" << std::endl;
-    return 1;
-  }
-
-  // convert input to double
-  double const inputValue = std::stod(argv[1]);
-
-  double const outputValue = mathfunctions::sqrt(inputValue);
-
-  std::cout << "The square root of " << inputValue << " is " << outputValue
-            << std::endl;
-  return 0;
-}
diff --git a/Help/guide/tutorial/Testing and CTest.rst b/Help/guide/tutorial/Testing and CTest.rst
new file mode 100644
index 0000000..360b383
--- /dev/null
+++ b/Help/guide/tutorial/Testing and CTest.rst
@@ -0,0 +1,232 @@
+Step 8: Testing and CTest
+=========================
+
+Testing is, historically, not the role of the build system. At best it might
+have a specific target which maps to building and running the project's tests.
+
+In the CMake ecosystem, the opposite is true. CMake's testing ecosystem is
+known as CTest. This ecosystem is both deceivingly simple and incredibly
+powerful. In fact it is so powerful it deserves its own full tutorial to
+describe everything we could achieve with it.
+
+This is not that tutorial. In this step, we will scratch the surface of some
+of the facilities that CTest provides.
+
+Background
+^^^^^^^^^^
+
+At its core, CTest is a task launcher which runs commands and reports if they
+have returned zero or non-zero values. This is the level we will be dealing
+with CTest at.
+
+CMake provides direct integration with CTest via the :command:`enable_testing`
+and :command:`add_test` commands. These allow CMake to setup the necessary
+infrastructure in the build folder for CTest to discover, run, and report
+on various tests we might be interested in.
+
+After setting up and building tests, the easiest way to invoke CTest is to run
+it directly on the build directory with:
+
+.. code-block:: console
+
+  ctest --test-dir build
+
+Which will run all available tests. Specific tests can be run with regular
+expressions.
+
+.. code-block:: console
+
+  ctest --test-dir build -R SpecificTest
+
+CTest also has advanced mechanisms for scripting, fixtures, sanitizers,
+job servers, metric reportings, and much more. See the :manual:`ctest(1)`
+manual for more information.
+
+Exercise 1 - Adding Tests
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+CTest convention dictates the building and running of tests be based on a
+default-``ON`` variable named :variable:`BUILD_TESTING`. When using the full
+suite of CTest capabilities via the :module:`CTest` module, this
+:command:`option` is setup for us. When using a more stripped-down approach to
+testing, it's expected the project will setup the option (or at least one of a
+similar name) on its own.
+
+When :variable:`BUILD_TESTING` is true, the :command:`enable_testing` command
+should be called in the root CML.
+
+.. code-block:: cmake
+
+  enable_testing()
+
+This will generate all the necessary metadata into the build tree for CTest to
+find and run tests.
+
+Once that has been done, the :command:`add_test` command can be used to create
+a test anywhere in the project. The semantics of this command are similar to
+:command:`add_custom_command`; we can name an executable target as the "command".
+
+.. code-block:: cmake
+
+  add_test(
+    NAME MyAppWithTestFlag
+    COMMAND MyApp --test
+  )
+
+Goal
+----
+
+Add tests for the MathFunctions library to the project and run them with CTest.
+
+Helpful Resources
+-----------------
+
+* :variable:`BUILD_TESTING`
+* :command:`enable_testing`
+* :command:`function`
+* :command:`add_test`
+
+Files to Edit
+-------------
+
+* ``Tests/CMakeLists.txt``
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+A testing program has been written in the file ``Tests/TestMathFunctions.cxx``.
+This program takes a single command line argument, the math function to be
+tested, with valid values of ``add``, ``mul``, ``sqrt``, and ``sub``. The return
+code is zero if the operation is recognized and the calculated value is valid,
+otherwise it is non-zero.
+
+Complete ``TODO 1`` through ``TODO 7``.
+
+Build and Run
+-------------
+
+No special configuration is needed, configure and build as usual.
+
+.. code-block:: console
+
+  cmake --preset tutorial
+  cmake --build build
+
+Verify all the tests pass with CTest.
+
+.. note::
+
+  If using a multi-config generator, eg Visual Studio, it will be necessary to
+  specify a configuration with ``ctest -C <config> <remaining flags>``, where
+  ``<config>`` is a value like ``Debug`` or ``Release``. This is true whenever
+  using a multi-config generator, and won't be called out specifically in
+  future commands.
+
+.. code-block:: console
+
+  ctest --test-dir build
+
+You can run individual tests with the :option:`-R <ctest -R>` flag.
+
+.. code-block:: console
+
+  ctest --test-dir build -R sqrt
+
+Solution
+--------
+
+First we add a new executable for the tests.
+
+.. raw:: html
+
+  <details><summary>TODO 1-2: Click to show/hide answer</summary>
+
+.. literalinclude:: Step9/Tests/CMakeLists.txt
+  :caption: TODO 1-2: Tests/CMakeLists.txt
+  :name: Tests/CMakeLists.txt-add_executable
+  :language: cmake
+  :start-at: add_executable
+  :end-at: TestMathFunctions.cxx
+  :append: )
+
+.. raw:: html
+
+  </details>
+
+Then we link in the library we are testing.
+
+.. raw:: html
+
+  <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. literalinclude:: Step9/Tests/CMakeLists.txt
+  :caption: TODO 3: Tests/CMakeLists.txt
+  :name: Tests/CMakeLists.txt-target_link_libraries
+  :language: cmake
+  :start-at: target_link_libraries(TestMathFunctions
+  :end-at: )
+
+.. raw:: html
+
+  </details>
+
+We need to call :command:`add_test` for each of the valid operations, but this
+would get repetitive, so we write a :command:`function` to do it for us.
+
+.. raw:: html
+
+  <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step9/Tests/CMakeLists.txt
+  :caption: TODO 4: Tests/CMakeLists.txt
+  :name: Tests/CMakeLists.txt-function
+  :language: cmake
+  :start-at: function
+  :end-at: endfunction
+
+.. raw:: html
+
+  </details>
+
+Now we can use our :command:`function` to add all the tests.
+
+.. raw:: html
+
+  <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step9/Tests/CMakeLists.txt
+  :caption: TODO 5: Tests/CMakeLists.txt
+  :name: Tests/CMakeLists.txt-add_test
+  :language: cmake
+  :start-at: MathFunctionTest(add
+  :end-at: MathFunctionTest(sub
+
+.. raw:: html
+
+  </details>
+
+Finally, we can add the :variable:`BUILD_TESTING` option and conditionally
+enable building and running tests in the top-level CML.
+
+.. raw:: html
+
+  <details><summary>TODO 6-7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step9/CMakeLists.txt
+  :caption: TODO 6: CMakeLists.txt
+  :name: CMakeLists.txt-BUILD_TESTING
+  :language: cmake
+  :start-at: option(BUILD_TESTING
+  :end-at: option(BUILD_TESTING
+
+.. literalinclude:: Step9/CMakeLists.txt
+  :caption: TODO 7: CMakeLists.txt
+  :name: CMakeLists.txt-enable_testing
+  :language: cmake
+  :start-at: if(BUILD_TESTING)
+  :end-at: endif()
+
+.. raw:: html
+
+  </details>
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index 438f368..d85506f 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -21,6 +21,28 @@
 .. toctree::
   :maxdepth: 2
 
+  Before You Begin
+  Getting Started with CMake
+  CMake Language Fundamentals
+  Configuration and Cache Variables
+  In-Depth CMake Target Commands
+  In-Depth CMake Library Concepts
+  In-Depth System Introspection
+  Custom Commands and Generated Files
+  Testing and CTest
+  Installation Commands and Concepts
+  Finding Dependencies
+  Miscellaneous Features
+
+..
+  Whenever a step above is renamed or removed, leave forwarding text in
+  its original document file, and list it below to preserve old links
+  to cmake.org/cmake/help/latest/ URLs.
+
+.. toctree::
+  :maxdepth: 1
+  :hidden:
+
   A Basic Starting Point
   Adding a Library
   Adding Usage Requirements for a Library
@@ -33,12 +55,3 @@
   Selecting Static or Shared Libraries
   Adding Export Configuration
   Packaging Debug and Release
-
-..
-  Whenever a step above is renamed or removed, leave forwarding text in
-  its original document file, and list it below to preserve old links
-  to cmake.org/cmake/help/latest/ URLs.
-
-.. toctree::
-  :maxdepth: 1
-  :hidden:
diff --git a/Help/include/ENVIRONMENT_MODIFICATION_OPS.rst b/Help/include/ENVIRONMENT_MODIFICATION_OPS.rst
new file mode 100644
index 0000000..9ef4b14
--- /dev/null
+++ b/Help/include/ENVIRONMENT_MODIFICATION_OPS.rst
@@ -0,0 +1,20 @@
+- ``reset``: Reset to the unmodified value, ignoring all modifications to
+  ``MYVAR`` prior to this entry. Note that this will reset the variable to
+  the value set by :prop_test:`ENVIRONMENT`, if it was set, and otherwise
+  to its state from the rest of the CTest execution.
+- ``set``: Replaces the current value of ``MYVAR`` with ``VALUE``.
+- ``unset``: Unsets the current value of ``MYVAR``.
+- ``string_append``: Appends singular ``VALUE`` to the current value of
+  ``MYVAR``.
+- ``string_prepend``: Prepends singular ``VALUE`` to the current value of
+  ``MYVAR``.
+- ``path_list_append``: Appends singular ``VALUE`` to the current value of
+  ``MYVAR`` using the host platform's path list separator (``;`` on Windows
+  and ``:`` elsewhere).
+- ``path_list_prepend``: Prepends singular ``VALUE`` to the current value of
+  ``MYVAR`` using the host platform's path list separator (``;`` on Windows
+  and ``:`` elsewhere).
+- ``cmake_list_append``: Appends singular ``VALUE`` to the current value of
+  ``MYVAR`` using ``;`` as the separator.
+- ``cmake_list_prepend``: Prepends singular ``VALUE`` to the current value of
+  ``MYVAR`` using ``;`` as the separator.
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 4fa878e..61413f1 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -1443,13 +1443,9 @@
 An ``INTERFACE`` library target does not compile sources and does not
 produce a library artifact on disk, so it has no :prop_tgt:`LOCATION`.
 
-It may specify usage requirements such as
-:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
-:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`,
-:prop_tgt:`INTERFACE_COMPILE_OPTIONS`,
-:prop_tgt:`INTERFACE_LINK_LIBRARIES`,
-:prop_tgt:`INTERFACE_SOURCES`,
-and :prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE`.
+It may specify `usage requirements <Target Usage Requirements_>`_,
+`compatible interface properties <Compatible Interface Properties_>`_, and
+`custom transitive properties <Custom Transitive Properties_>`_.
 Only the ``INTERFACE`` modes of the :command:`target_include_directories`,
 :command:`target_compile_definitions`, :command:`target_compile_options`,
 :command:`target_sources`, and :command:`target_link_libraries` commands
@@ -1528,3 +1524,27 @@
 Here, the headers defined in the header set are installed to ``include/Eigen``.
 The install destination automatically becomes an include directory that is a
 usage requirement for consumers.
+
+Properties Allowed on Interface Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Since CMake 3.19, interface libraries allow setting or reading target
+properties with any name, just like other target kinds always have.
+
+Prior to CMake 3.19, interface libraries only allowed setting or reading
+target properties with a limited set of names:
+
+* Properties named with an ``INTERFACE_`` prefix, either builtin
+  `usage requirements <Target Usage Requirements_>`_, or custom names.
+
+* Built-in properties named with a ``COMPATIBLE_INTERFACE_`` prefix
+  (`compatible interface properties <Compatible Interface Properties_>`_).
+
+* Built-in properties :prop_tgt:`NAME`, :prop_tgt:`EXPORT_NAME`,
+  :prop_tgt:`EXPORT_PROPERTIES`, :prop_tgt:`MANUALLY_ADDED_DEPENDENCIES`,
+  :prop_tgt:`IMPORTED`, :prop_tgt:`IMPORTED_LIBNAME_<CONFIG>`, and
+  :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`.
+
+* .. versionadded:: 3.11
+    Properties named with a leading underscore (``_``)
+    or lowercase ASCII character.
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst
index f7896e5..86f135d 100644
--- a/Help/manual/cmake-developer.7.rst
+++ b/Help/manual/cmake-developer.7.rst
@@ -154,7 +154,7 @@
 ``Foo_FIND_COMPONENTS`` if it is set , and only set ``Foo_FOUND`` to
 true if for each searched-for component ``<c>`` that was not found,
 ``Foo_FIND_REQUIRED_<c>`` is not set to true.  The ``HANDLE_COMPONENTS``
-argument of ``find_package_handle_standard_args()`` can be used to
+argument of :command:`find_package_handle_standard_args` can be used to
 implement this.
 
 If ``Foo_FIND_COMPONENTS`` is not set, which modules are searched for
@@ -361,10 +361,10 @@
   Result Variables
   ^^^^^^^^^^^^^^^^
 
-  This will define the following variables:
+  This module defines the following variables:
 
   ``Foo_FOUND``
-    True if the system has the Foo library.
+    Boolean indicating whether (the requested version of) Foo was found.
   ``Foo_VERSION``
     The version of the Foo library which was found.
   ``Foo_INCLUDE_DIRS``
@@ -415,7 +415,7 @@
 .. code-block:: cmake
 
   find_package(PkgConfig)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(PC_Foo QUIET Foo)
   endif()
 
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index e493655..f1b1cb1 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -44,6 +44,7 @@
 
    /envvar/ADSP_ROOT
    /envvar/CMAKE_APPLE_SILICON_PROCESSOR
+   /envvar/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
    /envvar/CMAKE_BUILD_PARALLEL_LEVEL
    /envvar/CMAKE_BUILD_TYPE
    /envvar/CMAKE_COLOR_DIAGNOSTICS
@@ -53,6 +54,7 @@
    /envvar/CMAKE_CROSSCOMPILING_EMULATOR
    /envvar/CMAKE_EXPORT_BUILD_DATABASE
    /envvar/CMAKE_EXPORT_COMPILE_COMMANDS
+   /envvar/CMAKE_FASTBUILD_VERBOSE_GENERATOR
    /envvar/CMAKE_GENERATOR
    /envvar/CMAKE_GENERATOR_INSTANCE
    /envvar/CMAKE_GENERATOR_PLATFORM
@@ -60,6 +62,7 @@
    /envvar/CMAKE_INSTALL_MODE
    /envvar/CMAKE_INSTALL_PARALLEL_LEVEL
    /envvar/CMAKE_INSTALL_PREFIX
+   /envvar/CMAKE_INTERMEDIATE_DIR_STRATEGY
    /envvar/CMAKE_LANG_COMPILER_LAUNCHER
    /envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE
    /envvar/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES_EXCLUDE
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 058e4aa..e892ed1 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -125,6 +125,10 @@
 This can be used to avoid asking CMake to generate multiple object
 versions unnecessarily.
 
+.. versionadded:: 4.1
+  The ``query.json`` file is described in machine-readable form by
+  :download:`this JSON schema </manual/file_api/schema_stateful_query.json>`.
+
 A ``query.json`` file must contain a JSON object:
 
 .. code-block:: json
@@ -200,6 +204,10 @@
 the one with the largest name in lexicographic order is the current
 index file.
 
+.. versionadded:: 4.1
+  The reply index file is described in machine-readable form by
+  :download:`this JSON schema </manual/file_api/schema_index.json>`.
+
 The reply index file contains a JSON object:
 
 .. code-block:: json
@@ -471,6 +479,10 @@
 Version 1 does not exist to avoid confusion with that from
 :manual:`cmake-server(7)` mode.
 
+.. versionadded:: 4.1
+  The ``codemodel`` object kind reply is described in machine-readable form
+  by :download:`this JSON schema </manual/file_api/schema_codemodel.json>`.
+
 "codemodel" version 2
 ^^^^^^^^^^^^^^^^^^^^^
 
@@ -495,6 +507,7 @@
             "childIndexes": [ 1 ],
             "projectIndex": 0,
             "targetIndexes": [ 0 ],
+            "abstractTargetIndexes": [ 1 ],
             "hasInstallRule": true,
             "minimumCMakeVersion": {
               "string": "3.14"
@@ -507,6 +520,7 @@
             "parentIndex": 0,
             "projectIndex": 0,
             "targetIndexes": [ 1 ],
+            "abstractTargetIndexes": [ 0 ],
             "minimumCMakeVersion": {
               "string": "3.14"
             },
@@ -517,7 +531,8 @@
           {
             "name": "MyProject",
             "directoryIndexes": [ 0, 1 ],
-            "targetIndexes": [ 0, 1 ]
+            "targetIndexes": [ 0, 1 ],
+            "abstractTargetIndexes": [ 0, 1 ],
           }
         ],
         "targets": [
@@ -534,6 +549,20 @@
             "jsonFile": "<file>"
           }
         ]
+        "abstractTargets": [
+          {
+            "name": "MyImportedExecutable",
+            "directoryIndex": 1,
+            "projectIndex": 0,
+            "jsonFile": "<file>"
+          },
+          {
+            "name": "MyPureInterfaceLibrary",
+            "directoryIndex": 0,
+            "projectIndex": 0,
+            "jsonFile": "<file>"
+          }
+        ]
       }
     ]
   }
@@ -600,10 +629,20 @@
       indicating the build system project to which the this directory belongs.
 
     ``targetIndexes``
-      Optional member that is present when the directory itself has targets,
-      excluding those belonging to subdirectories.  The value is a JSON
-      array of entries corresponding to the targets.  Each entry is an
-      unsigned integer 0-based index into the main ``targets`` array.
+      Optional member that is present when the directory itself has
+      build system targets, excluding those belonging to subdirectories.
+      The value is a JSON array of entries corresponding to the build system
+      targets.  Each entry is an unsigned integer 0-based index into the main
+      ``targets`` array.
+
+    ``abstractTargetIndexes``
+      Optional member that is present when the directory itself has abstract
+      targets, excluding those belonging to subdirectories.
+      The value is a JSON array of entries corresponding to the abstract
+      targets.  Each entry is an unsigned integer 0-based index into the main
+      ``abstractTargets`` array.
+
+      This field was added in codemodel version 2.9.
 
     ``minimumCMakeVersion``
       Optional member present when a minimum required version of CMake is
@@ -665,17 +704,27 @@
       integer 0-based index into the main ``directories`` array.
 
     ``targetIndexes``
-      Optional member that is present when the project itself has targets,
-      excluding those belonging to sub-projects.  The value is a JSON
-      array of entries corresponding to the targets.  Each entry is an
-      unsigned integer 0-based index into the main ``targets`` array.
+      Optional member that is present when the project itself has
+      build system targets, excluding those belonging to sub-projects.
+      The value is a JSON array of entries corresponding to the build system
+      targets.  Each entry is an unsigned integer 0-based index into the main
+      ``targets`` array.
+
+    ``abstractTargetIndexes``
+      Optional member that is present when the project itself has
+      abstract targets, excluding those belonging to sub-projects.
+      The value is a JSON array of entries corresponding to the abstract
+      targets.  Each entry is an unsigned integer 0-based index into the main
+      ``abstractTargets`` array.
+
+      This field was added in codemodel version 2.9.
 
   ``targets``
     A JSON array of entries corresponding to the build system targets.
     Such targets are created by calls to :command:`add_executable`,
     :command:`add_library`, and :command:`add_custom_target`, excluding
-    imported targets and interface libraries (which do not generate any
-    build rules).  Each entry is a JSON object containing members:
+    imported targets and interface libraries that do not generate any
+    build rules.  Each entry is a JSON object containing members:
 
     ``name``
       A string specifying the target name.
@@ -697,13 +746,63 @@
       to another JSON file containing a
       `"codemodel" version 2 "target" object`_.
 
+  ``abstractTargets``
+    A JSON array of entries corresponding to targets that are not present
+    in the build system.  These are imported targets or interface libraries
+    created by calls to :command:`add_executable` or :command:`add_library`.
+    In the case of interface libraries, only those that are not part of the
+    build system are included in this array.  Interface libraries that do
+    participate in the build system will be included in the ``targets``
+    array instead.
+
+    Each entry is a JSON object containing members:
+
+    ``name``
+      A string specifying the target name.
+
+    ``id``
+      A string uniquely identifying the target.  This matches the ``id``
+      field in the file referenced by ``jsonFile``.
+
+    ``directoryIndex``
+      An unsigned integer 0-based index into the main ``directories`` array
+      indicating the build system directory in which the target is defined.
+
+    ``projectIndex``
+      An unsigned integer 0-based index into the main ``projects`` array
+      indicating the build system project in which the target is defined.
+
+    ``jsonFile``
+      A JSON string specifying a path relative to the codemodel file
+      to another JSON file containing a
+      `"codemodel" version 2 "target" object`_.
+
+    This field was added in codemodel version 2.9.
+
 "codemodel" version 2 "directory" object
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 4.1
+  The ``directory`` object reply is described in machine-readable form by
+  :download:`this JSON schema </manual/file_api/schema_directory.json>`.
+
 A codemodel "directory" object is referenced by a `"codemodel" version 2`_
 object's ``directories`` array.  Each "directory" object is a JSON object
 with members:
 
+``codemodelVersion``
+  This specifies the codemodel version this file is part of.  It will match
+  the ``version`` field of the codemodel object kind that references this file.
+  It is a JSON object with the following members:
+
+  ``major``
+    The codemodel major version.
+
+  ``minor``
+    The codemodel minor version.
+
+  This field was added in codemodel version 2.9.
+
 ``paths``
   A JSON object containing members:
 
@@ -976,10 +1075,27 @@
 "codemodel" version 2 "target" object
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+.. versionadded:: 4.1
+  The ``target`` object reply is described in machine-readable form by
+  :download:`this JSON schema </manual/file_api/schema_target.json>`.
+
 A codemodel "target" object is referenced by a `"codemodel" version 2`_
 object's ``targets`` array.  Each "target" object is a JSON object
 with members:
 
+``codemodelVersion``
+  This specifies the codemodel version this file is part of.  It will match
+  the ``version`` field of the codemodel object kind that references this file.
+  It is a JSON object with the following members:
+
+  ``major``
+    The codemodel major version.
+
+  ``minor``
+    The codemodel minor version.
+
+  This field was added in codemodel version 2.9.
+
 ``name``
   A string specifying the logical name of the target.
 
@@ -993,6 +1109,40 @@
   ``MODULE_LIBRARY``, ``OBJECT_LIBRARY``, ``INTERFACE_LIBRARY``,
   or ``UTILITY``.
 
+``imported``
+  Optional member that is present with boolean value ``true`` if the
+  target is an imported target.
+
+  This field was added in codemodel version 2.9.
+
+``local``
+  Optional member that is present with boolean value ``true`` if the
+  target is only defined with local scope rather than being a global target.
+  Currently, only imported targets will potentially have this field.
+
+  This field was added in codemodel version 2.9.
+
+``abstract``
+  Optional member that is present with boolean value ``true`` if the
+  target is an abstract target.  Abstract targets are not part of the build
+  system, they only exist to describe dependencies or to provide usage
+  requirements to targets that link to them.  Examples include imported targets
+  and interface libraries that have no generated sources.  Abstract targets
+  cannot be built, so they should not be presented to the user as a buildable
+  target.
+
+  This field was added in codemodel version 2.9.  Abstract targets were not
+  included in codemodel version 2.8 and earlier.
+
+``symbolic``
+  Optional member that is present with boolean value ``true`` if the target
+  is :prop_tgt:`SYMBOLIC`.  Symbolic targets are created by calls to
+  :command:`add_library(INTERFACE SYMBOLIC) <add_library(INTERFACE-SYMBOLIC)>`,
+  and are also abstract targets that are not part of the build system.
+
+  This field was added in codemodel version 2.9.  Symbolic targets were not
+  included in codemodel version 2.8 and earlier.
+
 ``backtrace``
   Optional member that is present when a CMake language backtrace to
   the command in the source code that created the target is available.
@@ -1100,8 +1250,8 @@
   This field was added in codemodel version 2.7.
 
 ``link``
-  Optional member that is present for executables and shared library
-  targets that link into a runtime binary.  The value is a JSON object
+  Optional member that is present for non-imported executables and shared
+  library targets that link into a runtime binary.  The value is a JSON object
   with members describing the link step:
 
   ``language``
@@ -1147,8 +1297,8 @@
       with forward slashes.
 
 ``archive``
-  Optional member that is present for static library targets.  The value
-  is a JSON object with members describing the archive step:
+  Optional member that is present for non-imported static library targets.
+  The value is a JSON object with members describing the archive step:
 
   ``commandFragments``
     Optional member that is present when fragments of the archiver command
@@ -1187,7 +1337,19 @@
 
 ``dependencies``
   Optional member that is present when the target depends on other targets.
-  The value is a JSON array of entries corresponding to the dependencies.
+  It is only present if the target is part of the build system.
+  Imported targets are not part of the build system.  Interface libraries
+  are only part of the build system if they have sources or file sets.
+
+  The value is a JSON array of entries corresponding to the build dependencies.
+  The array includes not just direct dependencies, but also transitive
+  dependencies.  All listed targets will build before this one.
+
+  The list of dependencies reflects the *build graph* dependencies, not
+  necessarily the link dependencies.  If there are cycles in the link
+  dependencies of static libraries, not all link dependencies will be
+  reflected in this list of build graph dependencies.
+
   Each entry is a JSON object with members:
 
   ``id``
@@ -1201,6 +1363,216 @@
     available.  The value is an unsigned integer 0-based index into
     the ``backtraceGraph`` member's ``nodes`` array.
 
+``linkLibraries``
+  Optional member that may be present when the target links directly to one or
+  more other targets or libraries.  It contains items that are used when
+  linking this target.  These come from the target's
+  :prop_tgt:`LINK_LIBRARIES` property (evaluated non-transitively), or the
+  :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` property of another target it
+  links to directly or transitively.
+
+  Items that are only applied as usage requirements (such as being wrapped in a
+  :genex:`$<COMPILE_ONLY:...>` expression) will not be present in this member.
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    Optional member that is present when the library to be linked is a target.
+    It uniquely identifies the target on which this one has a direct link
+    relationship.  This matches the main ``id`` member of that other target.
+
+    The target this ``id`` identifies is not necessarily part of the build
+    system.  It may be an imported target or an interface library with no
+    sources or file sets.
+
+    Exactly one of ``id`` or ``fragment`` will always be present.
+
+  ``fragment``
+    Optional member that is present when the library to be linked is not a
+    target.  It is a string containing the raw linker command line arguments
+    that capture the relationship.  These will typically be linking to
+    libraries or frameworks by name rather than as a target.
+
+    Exactly one of ``id`` or ``fragment`` will always be present.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to
+    the command invocation that created this relationship is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  ``fromDependency``
+    Optional member that is only present when the relationship is the result of
+    an :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` target property on one of
+    this target's directly or transitively linked libraries.  It is a JSON
+    object with one member:
+
+    ``id``
+      A string uniquely identifying the target whose
+      :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` property created the
+      relationship.  The value matches the main ``id`` member of that target.
+
+  This field was added in codemodel version 2.9.
+
+``interfaceLinkLibraries``
+  Optional member that may be present when the target has one or more interface
+  link libraries.  It contains items that are used when linking consumers of
+  this target.  These come from the target's
+  :prop_tgt:`INTERFACE_LINK_LIBRARIES` property.
+
+  Items that are only applied as usage requirements (such as being wrapped in a
+  :genex:`$<COMPILE_ONLY:...>` expression) will not be present in this member.
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    Optional member that is present when the interface link library is for a
+    target.  It uniquely identifies that target, with the value matching the
+    main ``id`` member of that target.
+
+    The target this ``id`` identifies is not necessarily part of the build
+    system.  It may be an imported target or an interface library with no
+    sources or file sets.
+
+    Exactly one of ``id`` or ``fragment`` will always be present.
+
+  ``fragment``
+    Optional member that is present when the interface link library is not for
+    a target.  It is a string containing the raw linker command line arguments
+    to be applied to consumers of this target's interface link libraries.
+    These will typically be linker arguments for linking to libraries or
+    frameworks by name rather than as a target.
+
+    Exactly one of ``id`` or ``fragment`` will always be present.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to the
+    command invocation that created this interface relationship is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  This field was added in codemodel version 2.9.
+
+``compileDependencies``
+  Optional member that may be present when the target links directly to one or
+  more other targets that may provide usage requirements to this one.  They
+  affect how this target's sources are compiled.  These relationships are
+  defined by the target's :prop_tgt:`LINK_LIBRARIES` property (evaluated
+  non-transitively) and the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT`
+  property of other targets it links to directly or transitively.
+
+  Relationships that only apply linking requirements (such as being wrapped
+  in a :genex:`$<LINK_ONLY:...>` expression) will not be present in this
+  member.
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    A string uniquely identifying the target on which this target directly
+    depends.  This matches the main ``id`` member of the other target.
+
+    The target this ``id`` identifies is not necessarily part of the build
+    system.  It may be an imported target or an interface library with no
+    sources or file sets.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to
+    the command invocation that created this relationship is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  ``fromDependency``
+    Optional member that is only present when the relationship is the result of
+    an :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` target property on one of
+    this target's directly or transitively linked libraries.  It is a JSON
+    object with one member:
+
+    ``id``
+      A string uniquely identifying the target whose
+      :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` property created the
+      relationship.  The value matches the main ``id`` member of that target.
+
+  This field was added in codemodel version 2.9.
+
+``interfaceCompileDependencies``
+  Optional member that may be present when the target has one or more interface
+  linking relationships to other targets.  It contains items that affect how
+  consumers' sources are compiled.  These relationships are defined by the
+  target's :prop_tgt:`INTERFACE_LINK_LIBRARIES` property.
+
+  Relationships that only apply linking requirements (such as being wrapped
+  in a :genex:`$<LINK_ONLY:...>` expression) will not be present in this
+  member.
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    A string uniquely identifying the target on which this target specifies
+    an interface relationship.  This matches the main ``id`` member of the
+    other target.
+
+    The target this ``id`` identifies is not necessarily part of the build
+    system.  It may be an imported target or an interface library with no
+    sources or file sets.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to
+    the command invocation that created this relationship is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  This field was added in codemodel version 2.9.
+
+``objectDependencies``
+  Optional member that is present when the target has one or more entries in
+  its :prop_tgt:`SOURCES` property where the entry is specified using
+  :genex:`$<TARGET_OBJECTS:...>`, and where no other generator expression is
+  used within the :genex:`$<TARGET_OBJECTS:...>` expression.
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    A string uniquely identifying the target whose objects are referred to in
+    the :genex:`$<TARGET_OBJECTS:...>` expression.  This matches the main
+    ``id`` member of that other target.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to
+    the command invocation that created this dependency is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  This field was added in codemodel version 2.9.
+
+``orderDependencies``
+  Optional member that is present when the target has one or more direct order
+  dependencies on other targets.  Such dependencies may arise from calls to
+  :command:`add_dependencies` or from internal CMake processing.
+  Unlike the ``dependencies`` array, the ``ZERO_CHECK`` target will not be
+  included in ``orderDependencies`` (this is only relevant for
+  :generator:`Xcode` and :ref:`Visual Studio <Visual Studio Generators>`
+  generators).
+
+  The value is a JSON array of entries.  Each entry is a JSON object with
+  members:
+
+  ``id``
+    A string uniquely identifying the target on which this target depends.
+    This matches the main ``id`` member of the other target.
+
+  ``backtrace``
+    Optional member that is present when a CMake language backtrace to
+    the command invocation that created this dependency is available.
+    The value is an unsigned integer 0-based index into the
+    ``backtraceGraph`` member's ``nodes`` array.
+
+  This field was added in codemodel version 2.9.
+
 ``fileSets``
   An optional member that is present when a target defines one or more
   file sets.  The value is a JSON array of entries corresponding to the
@@ -1471,6 +1843,10 @@
 
 There is only one ``configureLog`` object major version, version 1.
 
+.. versionadded:: 4.1
+  The ``configureLog`` object kind reply is described in machine-readable form
+  by :download:`this JSON schema </manual/file_api/schema_configureLog.json>`.
+
 "configureLog" version 1
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1511,6 +1887,10 @@
 Version 1 does not exist to avoid confusion with that from
 :manual:`cmake-server(7)` mode.
 
+.. versionadded:: 4.1
+  The ``cache`` object kind reply is described in machine-readable form by
+  :download:`this JSON schema </manual/file_api/schema_cache.json>`.
+
 "cache" version 2
 ^^^^^^^^^^^^^^^^^
 
@@ -1583,6 +1963,10 @@
 
 There is only one ``cmakeFiles`` object major version, version 1.
 
+.. versionadded:: 4.1
+  The ``cmakeFiles`` object kind reply is described in machine-readable form
+  by :download:`this JSON schema </manual/file_api/schema_cmakeFiles.json>`.
+
 "cmakeFiles" version 1
 ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1712,6 +2096,10 @@
 
 There is only one ``toolchains`` object major version, version 1.
 
+.. versionadded:: 4.1
+  The ``toolchains`` object kind reply is described in machine-readable form
+  by :download:`this JSON schema </manual/file_api/schema_toolchains.json>`.
+
 "toolchains" version 1
 ^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 4bc0435..d5dc281 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -677,7 +677,7 @@
   performed on either path. Returns ``1`` if the paths are equal, ``0``
   otherwise.
 
-  See :ref:`cmake_path(COMPARE) <Path COMPARE>` for more details.
+  See :ref:`cmake_path(COMPARE) <Path Comparison>` for more details.
 
 .. _GenEx Path Queries:
 
@@ -720,13 +720,15 @@
 
   .. versionadded:: 3.24
 
-  Returns ``1`` if the path is :ref:`absolute <IS_ABSOLUTE>`, ``0`` otherwise.
+  Returns ``1`` if the path is absolute according to
+  :command:`cmake_path(IS_ABSOLUTE)`, ``0`` otherwise.
 
 .. genex:: $<PATH:IS_RELATIVE,path>
 
   .. versionadded:: 3.24
 
-  This will return the opposite of ``IS_ABSOLUTE``.
+  Returns ``1`` if the path is relative according to
+  :command:`cmake_path(IS_RELATIVE)`, ``0`` otherwise.
 
 .. genex:: $<PATH:IS_PREFIX[,NORMALIZE],path,input>
 
@@ -818,7 +820,7 @@
   ``directory-separator``. Depending on the ``input``, the value of ``path``
   may be discarded.
 
-  See :ref:`cmake_path(APPEND) <APPEND>` for more details.
+  See :command:`cmake_path(APPEND)` for more details.
 
 .. genex:: $<PATH:REMOVE_FILENAME,path...>
 
@@ -828,7 +830,7 @@
   ``$<PATH:GET_FILENAME>``) removed. After removal, any trailing
   ``directory-separator`` is left alone, if present.
 
-  See :ref:`cmake_path(REMOVE_FILENAME) <REMOVE_FILENAME>` for more details.
+  See :command:`cmake_path(REMOVE_FILENAME)` for more details.
 
 .. genex:: $<PATH:REPLACE_FILENAME,path...,input>
 
@@ -838,7 +840,7 @@
   ``path`` has no filename component (i.e. ``$<PATH:HAS_FILENAME>`` returns
   ``0``), ``path`` is unchanged.
 
-  See :ref:`cmake_path(REPLACE_FILENAME) <REPLACE_FILENAME>` for more details.
+  See :command:`cmake_path(REPLACE_FILENAME)` for more details.
 
 .. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path...>
 
@@ -846,7 +848,7 @@
 
   Returns ``path`` with the :ref:`extension <EXTENSION_DEF>` removed, if any.
 
-  See :ref:`cmake_path(REMOVE_EXTENSION) <REMOVE_EXTENSION>` for more details.
+  See :command:`cmake_path(REMOVE_EXTENSION)` for more details.
 
 .. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path...,input>
 
@@ -855,7 +857,7 @@
   Returns ``path`` with the :ref:`extension <EXTENSION_DEF>` replaced by
   ``input``, if any.
 
-  See :ref:`cmake_path(REPLACE_EXTENSION) <REPLACE_EXTENSION>` for more details.
+  See :command:`cmake_path(REPLACE_EXTENSION)` for more details.
 
 .. genex:: $<PATH:NORMAL_PATH,path...>
 
@@ -871,8 +873,7 @@
   Returns ``path``, modified to make it relative to the ``base_directory``
   argument.
 
-  See :ref:`cmake_path(RELATIVE_PATH) <cmake_path-RELATIVE_PATH>` for more
-  details.
+  See :command:`cmake_path(RELATIVE_PATH)` for more details.
 
 .. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path...,base_directory>
 
@@ -885,7 +886,7 @@
   When the ``NORMALIZE`` option is specified, the path is
   :ref:`normalized <Normalization>` after the path computation.
 
-  See :ref:`cmake_path(ABSOLUTE_PATH) <ABSOLUTE_PATH>` for more details.
+  See :command:`cmake_path(ABSOLUTE_PATH)` for more details.
 
 Shell Paths
 ^^^^^^^^^^^
@@ -1420,8 +1421,8 @@
   Note that for proper evaluation of this expression requires policy :policy:`CMP0099`
   to be set to ``NEW``.
 
-Linker Language And ID
-^^^^^^^^^^^^^^^^^^^^^^
+Link Language and ID
+^^^^^^^^^^^^^^^^^^^^
 
 .. genex:: $<LINK_LANGUAGE>
 
@@ -1827,6 +1828,209 @@
   (see :genex:`$<DEVICE_LINK:list>` generator expression). This expression can
   only be used to specify link options.
 
+Linker ID and Frontend-Variant
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+See also the :variable:`CMAKE_<LANG>_COMPILER_LINKER_ID` and
+:variable:`CMAKE_<LANG>_COMPILER_LINKER_FRONTEND_VARIANT` variables, which are
+closely related to most of the expressions in this sub-section.
+
+.. genex:: $<C_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the C linker used.
+
+.. genex:: $<C_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the C linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<CXX_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the C++ linker used.
+
+.. genex:: $<CXX_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the C++ linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<CUDA_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the CUDA linker used.
+
+.. genex:: $<CUDA_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the CUDA linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<OBJC_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the Objective-C linker used.
+
+.. genex:: $<OBJC_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the Objective-C linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<OBJCXX_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the Objective-C++ linker used.
+
+.. genex:: $<OBJCXX_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the Objective-C++ linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<Fortran_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the Fortran linker used.
+
+.. genex:: $<Fortran_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the Fortran linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<HIP_COMPILER_LINKER_ID>
+
+  .. versionadded:: 4.2
+
+  CMake's linker id of the HIP linker used.
+
+.. genex:: $<HIP_COMPILER_LINKER_ID:linker_ids>
+
+  .. versionadded:: 4.2
+
+  where ``linker_ids`` is a comma-separated list.
+  ``1`` if CMake's linker id of the HIP linker matches any one
+  of the entries in ``linker_ids``, otherwise ``0``.
+
+.. genex:: $<C_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the C linker used.
+
+.. genex:: $<C_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the C linker matches any one
+  of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<CXX_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the C++ linker used.
+
+.. genex:: $<CXX_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the C++ linker matches any one
+  of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<CUDA_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the CUDA linker used.
+
+.. genex:: $<CUDA_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the CUDA linker matches any one
+  of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<OBJC_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the Objective-C linker used.
+
+.. genex:: $<OBJC_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the Objective-C linker matches
+  any one of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<OBJCXX_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the Objective-C++ linker used.
+
+.. genex:: $<OBJCXX_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the Objective-C++ linker matches
+  any one of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<Fortran_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the Fortran linker used.
+
+.. genex:: $<Fortran_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the Fortran linker matches
+  any one of the entries in ``variant_ids``, otherwise ``0``.
+
+.. genex:: $<HIP_COMPILER_LINKER_FRONTEND_VARIANT>
+
+  .. versionadded:: 4.2
+
+  CMake's linker frontend variant of the HIP linker used.
+
+.. genex:: $<HIP_COMPILER_LINKER_FRONTEND_VARIANT:variant_ids>
+
+  .. versionadded:: 4.2
+
+  where ``variant_ids`` is a comma-separated list.
+  ``1`` if CMake's linker frontend variant of the HIP linker matches
+  any one of the entries in ``variant_ids``, otherwise ``0``.
+
 
 .. _`Target-Dependent Expressions`:
 
@@ -2032,13 +2236,23 @@
   expression is evaluated on, unless the expression is being used in
   :command:`add_custom_command` or :command:`add_custom_target`.
 
-.. genex:: $<TARGET_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.15
 
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   Base name of ``tgt``, i.e. ``$<TARGET_FILE_NAME:tgt>`` without prefix and
-  suffix.
-  For example, if the ``tgt`` filename is ``libbase.so``, the base name is ``base``.
+  suffix and, optionally, postfix.
+  For example, if the ``tgt`` filename is ``libbase_postfix.so``, the base name
+  is:
+
+    * ``base_postfix`` for ``$<TARGET_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for ``$<TARGET_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
 
   See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
   :prop_tgt:`LIBRARY_OUTPUT_NAME` and :prop_tgt:`RUNTIME_OUTPUT_NAME`
@@ -2100,13 +2314,23 @@
   This expands to an empty string when there is no import file associated
   with the target.
 
-.. genex:: $<TARGET_IMPORT_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_IMPORT_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.27
 
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   Base name of the linker import file of the target ``tgt`` without prefix or
-  suffix. For example, if the target file name is ``libbase.tbd``, the base
-  name is ``base``.
+  suffix and, optionally, postfix.
+  For example, if the target file name is ``libbase_postfix.tbd``, the base
+  name is:
+
+    * ``base_postfix`` for ``$<TARGET_IMPORT_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_IMPORT_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for ``$<TARGET_IMPORT_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
 
   See also the :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`
   target properties, their configuration-specific variants
@@ -2176,13 +2400,24 @@
   :genex:`$<TARGET_LINKER_IMPORT_FILE>` generator expressions, depending on the
   characteristics of the target and the platform.
 
-.. genex:: $<TARGET_LINKER_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_LINKER_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.15
 
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   Base name of file used to link the target ``tgt``, i.e.
-  :genex:`$<TARGET_LINKER_FILE_NAME:tgt>` without prefix and suffix. For
-  example, if target file name is ``libbase.a``, the base name is ``base``.
+  :genex:`$<TARGET_LINKER_FILE_NAME:tgt>` without prefix and suffix, and,
+  optionally, postfix.
+  For example, if the target file name is ``libbase_postfix.a``, the base name
+  is:
+
+    * ``base_postfix`` for ``$<TARGET_LINKER_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_LINKER_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for ``$<TARGET_LINKER_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
 
   See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
   and :prop_tgt:`LIBRARY_OUTPUT_NAME` target properties, their
@@ -2244,13 +2479,25 @@
   ``tgt`` represents (``.a``, ``.so``, ``.dylib``). So, on DLL platforms, it
   will be an empty string.
 
-.. genex:: $<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.27
 
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   Base name of library file used to link the target ``tgt``, i.e.
-  :genex:`$<TARGET_LINKER_LIBRARY_FILE_NAME:tgt>` without prefix and suffix.
-  For example, if target file name is ``libbase.a``, the base name is ``base``.
+  :genex:`$<TARGET_LINKER_LIBRARY_FILE_NAME:tgt>` without prefix and
+  suffix,and, optionally, postfix.
+  For example, if the target file name is ``libbase_postfix.a``, the base name
+  is:
+
+    * ``base_postfix`` for ``$<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for
+      ``$<TARGET_LINKER_LIBRARY_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
 
   See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
   and :prop_tgt:`LIBRARY_OUTPUT_NAME` target properties, their
@@ -2314,13 +2561,25 @@
   (``.lib``, ``.tbd``). So, when no import file is involved in the link step,
   an empty string is returned.
 
-.. genex:: $<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.27
 
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
+
   Base name of the import file used to link the target ``tgt``, i.e.
-  :genex:`$<TARGET_LINKER_IMPORT_FILE_NAME:tgt>` without prefix and suffix.
-  For example, if target file name is ``libbase.tbd``, the base name is ``base``.
+  :genex:`$<TARGET_LINKER_IMPORT_FILE_NAME:tgt>` without prefix and suffix,
+  and, optionally, postfix.
+  For example, if the target file name is ``libbase_postfix.tbd``, the base
+  name is
+
+    * ``base_postfix`` for ``$<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for
+      ``$<TARGET_LINKER_IMPORT_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
 
   See also the :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
   target properties, their configuration-specific variants
@@ -2423,23 +2682,46 @@
   Full path to the linker generated program database file (.pdb)
   where ``tgt`` is the name of a target.
 
+  .. versionchanged:: 4.2
+    The postfix, as specified by :prop_tgt:`DEBUG_POSTFIX` or
+    :prop_tgt:`<CONFIG>_POSTFIX` target properties, is always included in the
+    ``PDB`` file name. See the policy :policy:`CMP0202`.
+
   See also the :prop_tgt:`PDB_NAME` and :prop_tgt:`PDB_OUTPUT_DIRECTORY`
   target properties and their configuration specific variants
   :prop_tgt:`PDB_NAME_<CONFIG>` and :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`.
 
-.. genex:: $<TARGET_PDB_FILE_BASE_NAME:tgt>
+.. genex:: $<TARGET_PDB_FILE_BASE_NAME:tgt[,POSTFIX:(INCLUDE|EXCLUDE)]>
 
   .. versionadded:: 3.15
 
   Base name of the linker generated program database file (.pdb)
   where ``tgt`` is the name of a target.
 
-  The base name corresponds to the target PDB file name (see
-  ``$<TARGET_PDB_FILE_NAME:tgt>``) without prefix and suffix. For example,
-  if target file name is ``base.pdb``, the base name is ``base``.
+  .. versionadded:: 4.2
+    The ``POSTFIX`` option can be used to control the inclusion or not
+    of the :prop_tgt:`<CONFIG>_POSTFIX` target property value as part of the
+    base name. The default is ``POSTFIX:INCLUDE``.
 
-  See also the :prop_tgt:`PDB_NAME` target property, and its
-  configuration-specific variant :prop_tgt:`PDB_NAME_<CONFIG>`.
+  .. versionchanged:: 4.2
+    The postfix, as specified by :prop_tgt:`DEBUG_POSTFIX` or
+    :prop_tgt:`<CONFIG>_POSTFIX` target properties, is always included in the
+    ``PDB`` base name, except if the ``POSTFIX`` option has the value
+    ``EXCLUDE``.  See the policy :policy:`CMP0202`.
+
+  The base name corresponds to the target PDB file name (see
+  ``$<TARGET_PDB_FILE_NAME:tgt>``) without prefix and suffix, and, optionally,
+  postfix.  For example, if the target file name is ``base_postfix.pdb``, the
+  base name is
+
+    * ``base_postfix`` for ``$<TARGET_PDB_FILE_BASE_NAME:tgt>`` or
+      ``$<TARGET_PDB_FILE_BASE_NAME:tgt,POSTFIX:INCLUDE>``.
+    * ``base`` for ``$<TARGET_PDB_FILE_BASE_NAME:tgt,POSTFIX:EXCLUDE>``.
+
+  See also the :prop_tgt:`OUTPUT_NAME` and :prop_tgt:`PDB_NAME` target
+  properties, their configuration-specific variants
+  :prop_tgt:`OUTPUT_NAME_<CONFIG>` and :prop_tgt:`PDB_NAME_<CONFIG>`, and the
+  :prop_tgt:`<CONFIG>_POSTFIX` and :prop_tgt:`DEBUG_POSTFIX` target properties.
 
   Note that ``tgt`` is not added as a dependency of the target this
   expression is evaluated on.
@@ -2558,6 +2840,13 @@
   This generator expression can e.g. be used to create a batch file using
   :command:`file(GENERATE)` which sets the PATH environment variable accordingly.
 
+.. genex:: $<TARGET_INTERMEDIATE_DIR:tgt>
+
+  .. versionadded:: 4.2
+
+  The full path to the directory where intermediate target files, such as
+  object and dependency files, are stored.
+
 Export And Install Expressions
 ------------------------------
 
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 9647f0d..a68a1f7 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -63,6 +63,14 @@
    /generator/Ninja
    /generator/Ninja Multi-Config
 
+FASTBuild Generator
+^^^^^^^^^^^^^^^^^^^
+
+.. toctree::
+   :maxdepth: 1
+
+   /generator/FASTBuild
+
 .. _`IDE Build Tool Generators`:
 
 IDE Build Tool Generators
@@ -92,6 +100,7 @@
    /generator/Visual Studio 15 2017
    /generator/Visual Studio 16 2019
    /generator/Visual Studio 17 2022
+   /generator/Visual Studio 18 2026
 
 Other Generators
 ^^^^^^^^^^^^^^^^
diff --git a/Help/manual/cmake-instrumentation.7.rst b/Help/manual/cmake-instrumentation.7.rst
index e20d8a6..967b5a2 100644
--- a/Help/manual/cmake-instrumentation.7.rst
+++ b/Help/manual/cmake-instrumentation.7.rst
@@ -21,8 +21,8 @@
 information and system diagnostic information during the configure, generate,
 build, test and install steps for a CMake project.
 
-This feature is only available for projects using the :ref:`Makefile Generators`
-or the :ref:`Ninja Generators`.
+This feature is only available for projects using the
+:ref:`Makefile Generators`, :ref:`Ninja Generators` or :generator:`FASTBuild`.
 
 All interactions with the CMake instrumentation API must specify both an API
 version and a Data version. At this time, there is only one version for each of
@@ -36,12 +36,12 @@
 tree with data specific to that command. These files remain until after
 `Indexing`_ occurs.
 
-CMake sets the :prop_gbl:`RULE_LAUNCH_COMPILE`, :prop_gbl:`RULE_LAUNCH_LINK` and
-:prop_gbl:`RULE_LAUNCH_CUSTOM` global properties to use the
-``ctest --instrument`` launcher in order to capture details of each compile, link
-and custom command respectively. If the project has been configured with :module:`CTestUseLaunchers`,
-``ctest --instrument`` will also include the behavior usually performed by
-``ctest --launch``.
+CMake sets the :prop_gbl:`RULE_LAUNCH_COMPILE`, :prop_gbl:`RULE_LAUNCH_LINK`
+and :prop_gbl:`RULE_LAUNCH_CUSTOM` global properties to use the
+``ctest --instrument`` launcher in order to capture details of each compile,
+link, and custom command respectively. If the project has been configured with
+:module:`CTestUseLaunchers`, ``ctest --instrument`` will also include the
+behavior usually performed by ``ctest --launch``.
 
 Indexing
 --------
@@ -98,9 +98,8 @@
 ----------------------------------------------
 
 You can enable instrumentation when using CTest in :ref:`Dashboard Client`
-mode by setting the :envvar:`CTEST_USE_INSTRUMENTATION` environment variable
-to the current UUID for the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` feature.
-Doing so automatically enables the ``dynamicSystemInformation`` query.
+mode by setting the :envvar:`CTEST_USE_INSTRUMENTATION` environment variable.
+Doing so automatically enables the ``dynamicSystemInformation`` option.
 
 The following table shows how each type of instrumented command gets mapped
 to a corresponding type of CTest XML file.
@@ -125,13 +124,21 @@
 You can instead choose to report the full command line (including arguments)
 by setting :envvar:`CTEST_USE_VERBOSE_INSTRUMENTATION` to 1.
 
+Alternatively, you can use the `v1 Query Files`_ to enable instrumentation for
+CDash using the ``cdashSubmit`` and ``cdashVerbose`` options.
+
+In order for the submitted ``Build.xml`` file to group the snippet files
+correctly, all configure and build commands should be executed with CTest in
+Dashboard Client mode.
+
 .. _`cmake-instrumentation API v1`:
 
 API v1
 ======
 
-The API version specifies both the subdirectory layout of the instrumentation data,
-and the format of the query files.
+The API version specifies the layout of the instrumentation directory, as well
+as the general format of the query files and :command:`cmake_instrumentation`
+command arguments.
 
 The Instrumentation API v1 is housed  in the ``instrumentation/v1/`` directory
 under either ``<build>/.cmake/`` for output data and project-level queries, or
@@ -146,14 +153,29 @@
 
 ``query/generated/``
   Holds query files generated by a CMake project with the
-  :command:`cmake_instrumentation` command. These files are owned by CMake and
-  are deleted and regenerated automatically during the CMake configure step.
+  :command:`cmake_instrumentation` command or the
+  :envvar:`CTEST_USE_INSTRUMENTATION` variable. These files are owned by CMake
+  and are deleted and regenerated automatically during the CMake configure step.
 
 ``data/``
   Holds instrumentation data collected on the project. CMake owns all data
   files, they should never be removed by other processes. Data collected here
   remains until after `Indexing`_ occurs and all `Callbacks`_ are executed.
 
+``data/index/``
+  A subset of the collected data, containing any
+  `v1 Index Files <v1 Index File_>`_.
+
+``data/content/``
+  A subset of the collected data, containing any
+  `v1 CMake Content Files <v1 CMake Content File_>`_.
+
+``data/trace/``
+  A subset of the collected data, containing the `Google Trace File`_ created
+  from the most recent `Indexing`_. Unlike other data files, the most recent
+  trace file remains even after `Indexing`_ occurs and all `Callbacks`_ are
+  executed, until the next time `Indexing`_ occurs.
+
 ``cdash/``
   Holds temporary files used internally to generate XML content to be submitted
   to CDash.
@@ -185,16 +207,22 @@
   should be one of the following:
 
   * ``postGenerate``
-  * ``preBuild`` (called when ``ninja``  or ``make`` is invoked; unavailable on Windows)
-  * ``postBuild`` (called when ``ninja`` or ``make`` completes; unavailable on Windows)
+  * ``preBuild`` (called when ``ninja``  or ``make`` is invoked)
+  * ``postBuild`` (called when ``ninja`` or ``make`` completes)
   * ``preCMakeBuild`` (called when ``cmake --build`` is invoked)
   * ``postCMakeBuild`` (called when ``cmake --build`` completes)
-  * ``postInstall``
-  * ``postTest``
+  * ``postCMakeInstall``
+  * ``postCTest``
 
-``queries``
-  A list of strings specifying additional optional data to collect during
-  instrumentation. Elements in this list should be one of the following:
+  ``preBuild`` and ``postBuild`` are not supported when using the
+  :generator:`MSYS Makefiles` or :generator:`FASTBuild` generators.
+  Additionally, they will not be triggered when the build tool is invoked by
+  ``cmake --build``.
+
+``options``
+  A list of strings used to enable certain optional behavior, including the
+  collection of certain additional data. Elements in this list should be one of
+  the following:
 
     ``staticSystemInformation``
       Enables collection of the static information about the host machine CMake
@@ -207,13 +235,30 @@
       generated by CMake, and includes information from immediately before and
       after the command is executed.
 
+    ``cdashSubmit``
+      Enables including instrumentation data in CDash. This does not
+      automatically enable ``dynamicSystemInformation``, but is otherwise
+      equivalent to having the :envvar:`CTEST_USE_INSTRUMENTATION` environment
+      variable enabled.
+
+    ``cdashVerbose``
+      Enables including the full untruncated commands in data submitted to
+      CDash. Equivalent to having the
+      :envvar:`CTEST_USE_VERBOSE_INSTRUMENTATION` environment variable enabled.
+
+    ``trace``
+      Enables generation of a `Google Trace File`_ during `Indexing`_ to
+      visualize data from the `v1 Snippet Files <v1 Snippet File_>`_ collected.
+
 The ``callbacks`` listed will be invoked during the specified hooks
 *at a minimum*. When there are multiple query files, the ``callbacks``,
-``hooks`` and ``queries`` between them will be merged. Therefore, if any query
+``hooks`` and ``options`` between them will be merged. Therefore, if any query
 file includes any ``hooks``, every ``callback`` across all query files will be
 executed at every ``hook`` across all query files. Additionally, if any query
-file includes any optional ``queries``, the optional query data will be present
-in all data files.
+file requests optional data using the ``options`` field, any related data will
+be present in all snippet files. User written ``callbacks`` should be able to
+handle the presence of this optional data, since it may be requested by an
+unrelated query.
 
 Example:
 
@@ -227,25 +272,30 @@
     ],
     "hooks": [
       "postCMakeBuild",
-      "postInstall"
+      "postCMakeInstall"
     ],
-    "queries": [
+    "options": [
       "staticSystemInformation",
-      "dynamicSystemInformation"
+      "dynamicSystemInformation",
+      "cdashSubmit",
+      "trace"
     ]
   }
 
 In this example, after every ``cmake --build`` or ``cmake --install``
 invocation, an index file ``index-<timestamp>.json`` will be generated in
-``<build>/.cmake/instrumentation/v1/data`` containing a list of data snippet
-files created since the previous indexing. The commands
+``<build>/.cmake/instrumentation/v1/data/index`` containing a list of data
+snippet files created since the previous indexing. The commands
 ``/usr/bin/python callback.py index-<timestamp>.json`` and
-``/usr/bin/cmake -P callback.cmake arg index-<timestamp>.json`` will be executed in
-that order. The index file will contain the ``staticSystemInformation`` data and
-each snippet file listed in the index will contain the
-``dynamicSystemInformation`` data. Once both callbacks have completed, the index
-file and all snippet files listed by it will be deleted from the project build
-tree.
+``/usr/bin/cmake -P callback.cmake arg index-<timestamp>.json`` will be executed
+in that order. The index file will contain the ``staticSystemInformation`` data
+and each snippet file listed in the index will contain the
+``dynamicSystemInformation`` data. Additionally, the index file will contain
+the path to the generated `Google Trace File`_. Once both callbacks have completed,
+the index file and data files listed by it (including snippet files, but not
+the trace file) will be deleted from the project build tree. The instrumentation
+data will be present in the XML files submitted to CDash, but with truncated
+command strings because ``cdashVerbose`` was not enabled.
 
 .. _`cmake-instrumentation Data v1`:
 
@@ -253,11 +303,16 @@
 =======
 
 Data version specifies the contents of the output files generated by the CMake
-instrumentation API as part of the `Data Collection`_ and `Indexing`_. There are
-two types of data files generated: the `v1 Snippet File`_ and `v1 Index File`_.
-When using the `API v1`_, these files live in
+instrumentation API as part of the `Data Collection`_ and `Indexing`_. A new
+version number will be created whenever previously included data is removed or
+reformatted such that scripts written to parse this data may become
+incompatible with the new format. There are four types of data files generated:
+the `v1 Snippet File`_, `v1 Index File`_, `v1 CMake Content File`_, and the
+`Google Trace File`_. When using the `API v1`_, these files live in
 ``<build>/.cmake/instrumentation/v1/data/`` under the project build tree.
 
+.. _`cmake-instrumentation v1 Snippet File`:
+
 v1 Snippet File
 ---------------
 
@@ -289,7 +344,8 @@
     The working directory in which the ``command`` was executed.
 
   ``result``
-    The exit-value of the command, an integer.
+    The exit code of the command, an integer. This will be ``null`` when
+    ``role`` is ``build``.
 
   ``role``
     The type of command executed, which will be one of the following values:
@@ -299,7 +355,8 @@
     * ``compile``: an individual compile step invoked during the build
     * ``link``: an individual link step invoked during the build
     * ``custom``: an individual custom command invoked during the build
-    * ``build``: a complete ``make`` or ``ninja`` invocation. Only generated if ``preBuild`` or ``postBuild`` hooks are enabled.
+    * ``build``: a complete ``make`` or ``ninja`` invocation
+      (not through ``cmake --build``).
     * ``cmakeBuild``: a complete ``cmake --build`` invocation
     * ``cmakeInstall``: a complete ``cmake --install`` invocation
     * ``install``: an individual ``cmake -P cmake_install.cmake`` invocation
@@ -308,15 +365,8 @@
 
   ``target``
     The CMake target associated with the command. Only included when ``role`` is
-    ``compile`` or ``link``.
-
-  ``targetType``
-    The :prop_tgt:`TYPE` of the target. Only included when ``role`` is
-    ``link``.
-
-  ``targetLabels``
-    The :prop_tgt:`LABELS` of the target. Only included when ``role`` is
-    ``link``.
+    ``compile`` or ``link``. In conjunction with ``cmakeContent``, this can
+    be used to look up the target type and labels.
 
   ``timeStart``
     Time at which the command started, expressed as the number of milliseconds
@@ -339,14 +389,15 @@
 
   ``language``
     The language of the source file being compiled. Only included when ``role`` is
-    ``compile``.
+    ``compile`` or ``link``.
 
   ``testName``
     The name of the test being executed. Only included when ``role`` is ``test``.
 
   ``config``
     The type of build, such as ``Release`` or ``Debug``. Only included when
-    ``role`` is ``compile``, ``link`` or ``test``.
+    ``role`` is one of: ``compile``, ``link``, ``custom``, ``install``,
+    ``test``.
 
   ``dynamicSystemInformation``
     Specifies the dynamic information collected about the host machine
@@ -358,13 +409,24 @@
       The Host Memory Used in KiB at ``timeStart``.
 
     ``afterHostMemoryUsed``
-      The Host Memory Used in KiB at ``timeStop``.
+      The Host Memory Used in KiB at ``timeStart + duration``.
 
     ``beforeCPULoadAverage``
-      The Average CPU Load at ``timeStart``.
+      The Average CPU Load at ``timeStart``, or ``null`` if it cannot be
+      determined.
 
     ``afterCPULoadAverage``
-      The Average CPU Load at ``timeStop``.
+      The Average CPU Load at ``timeStart + duration``, or ``null`` if it cannot
+      be determined.
+
+  ``cmakeContent``
+    The path to a `v1 CMake Content File`_ located under ``data``, which
+    contains information about the CMake configure and generate steps
+    responsible for generating the ``command`` in this snippet.
+
+  ``showOnly``
+    A boolean representing whether the ``--show-only`` option was passed to
+    ``ctest``. Only included when ``role`` is ``ctest``.
 
 Example:
 
@@ -389,15 +451,17 @@
       "beforeHostMemoryUsed" : 6635832.0
     },
     "timeStart" : 1737053448177,
-    "duration" : 31
+    "duration" : 31,
+    "cmakeContent" : "content/cmake-2025-07-11T12-46-32-0572.json"
   }
 
 v1 Index File
 -------------
 
-Index files contain a list of `v1 Snippet File`_. It serves as an entry point
-for navigating the instrumentation data. They are generated whenever `Indexing`_
-occurs and deleted after any user-specified `Callbacks`_ are executed.
+Index files contain a list of `v1 Snippet Files <v1 Snippet File_>`_. It
+serves as an entry point for navigating the instrumentation data. They are
+generated whenever `Indexing`_ occurs and deleted after any user-specified
+`Callbacks`_ are executed.
 
 ``version``
   The Data version of the index file, an integer. Currently the version is
@@ -416,9 +480,14 @@
   ``ctest --collect-instrumentation <build>``.
 
 ``snippets``
-  Contains a list of `v1 Snippet File`_. This includes all snippet files
-  generated since the previous index file was created. The file paths are
-  relative to ``dataDir``.
+  Contains a list of `v1 Snippet Files <v1 Snippet File_>`_. This includes all
+  snippet files generated since the previous index file was created. The file
+  paths are relative to ``dataDir``.
+
+``trace``:
+  Contains the path to the `Google Trace File`_. This includes data from all
+  corresponding ``snippets`` in the index file. The file path is relative to
+  ``dataDir``. Only included when enabled by the `v1 Query Files`_.
 
 ``staticSystemInformation``
   Specifies the static information collected about the host machine
@@ -462,5 +531,76 @@
       "ctest-<hash>-<timestamp>.json",
       "test-<hash>-<timestamp>.json",
       "test-<hash>-<timestamp>.json",
-    ]
+    ],
+    "trace": "trace/trace-<timestamp>.json"
   }
+
+.. _`cmake-instrumentation v1 CMake Content File`:
+
+v1 CMake Content File
+---------------------
+
+CMake content files contain information about the CMake configure and generate
+steps. Each `v1 Snippet File`_ provides the path to one of these files
+corresponding to the CMake invocation responsible for generating its command.
+
+Each CMake content file contains the following:
+
+  ``custom``
+    An object containing arbitrary JSON data specified by the user with the
+    :ref:`cmake_instrumentation CUSTOM_CONTENT` functionality of the
+    :command:`cmake_instrumentation` command.
+
+  ``targets``
+    An object containing CMake targets, indexed by name, that have corresponding
+    instrumentation data. Each target contains the following:
+
+    ``type``
+      The target type. One of ``EXECUTABLE``, ``STATIC_LIBRARY``,
+      ``SHARED_LIBRARY`` or ``OBJECT_LIBRARY``.
+
+    ``labels``
+      The :prop_tgt:`LABELS` property of the target.
+
+Google Trace File
+-----------------
+
+Trace files follow the `Google Trace Event Format`_. They include data from
+all `v1 Snippet Files <v1 Snippet File_>`_ listed in the current index file.
+These files remain in the build tree even after `Indexing`_ occurs and all
+`Callbacks`_ are executed, until the next time `Indexing`_ occurs.
+
+Trace files are stored in the ``JSON Array Format``, where each
+`v1 Snippet File`_ corresponds to a single trace event object. Each trace
+event contains the following data:
+
+``name``
+  A descriptive name generated by CMake based on the given snippet data.
+
+``cat``
+  The ``role`` from the `v1 Snippet File`_.
+
+``ph``
+  Currently, always ``"X"`` to represent ``Complete Events``.
+
+``ts``
+  The ``timeStart`` from the `v1 Snippet File`_, converted from milliseconds to
+  microseconds.
+
+``dur``
+  The ``duration`` from the `v1 Snippet File`_, converted from milliseconds to
+  microseconds.
+
+``pid``
+  Unused (always zero).
+
+``tid``
+  An integer ranging from zero to the number of concurrent jobs with which the
+  processes being indexed ran. This is a synthetic ID calculated by CMake
+  based on the ``ts`` and ``dur`` of all snippet files being indexed in
+  order to produce a more useful visualization of the process concurrency.
+
+``args``
+  Contains all data from the `v1 Snippet File`_ corresponding to this trace event.
+
+.. _`Google Trace Event Format`: https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
index d590b5a..908c46c 100644
--- a/Help/manual/cmake-language.7.rst
+++ b/Help/manual/cmake-language.7.rst
@@ -12,6 +12,8 @@
 
 CMake input files are written in the "CMake Language" in source files
 named ``CMakeLists.txt`` or ending in a ``.cmake`` file name extension.
+The term *listfile* is a general name for any such source file containing
+CMake commands that the tool processes.
 
 CMake Language source files in a project are organized into:
 
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index d9b9f2e..265a128 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -30,8 +30,8 @@
    /module/CheckFortranSourceCompiles
    /module/CheckFortranSourceRuns
    /module/CheckFunctionExists
-   /module/CheckIncludeFileCXX
    /module/CheckIncludeFile
+   /module/CheckIncludeFileCXX
    /module/CheckIncludeFiles
    /module/CheckIPOSupported
    /module/CheckLanguage
@@ -55,8 +55,6 @@
    /module/CMakeBackwardCompatibilityCXX
    /module/CMakeDependentOption
    /module/CMakeFindDependencyMacro
-   /module/CMakeFindPackageMode
-   /module/CMakeGraphVizOptions
    /module/CMakePackageConfigHelpers
    /module/CMakePrintHelpers
    /module/CMakePrintSystemInformation
@@ -69,7 +67,6 @@
    /module/CSharpUtilities
    /module/CTest
    /module/CTestCoverageCollectGCOV
-   /module/CTestScriptMode
    /module/CTestUseLaunchers
    /module/DeployQt4
    /module/ExternalData
@@ -186,7 +183,6 @@
    /module/FindOpenSSL
    /module/FindOpenThreads
    /module/Findosg
-   /module/Findosg_functions
    /module/FindosgAnimation
    /module/FindosgDB
    /module/FindosgFX
@@ -232,8 +228,8 @@
    /module/FindSDL_sound
    /module/FindSDL_ttf
    /module/FindSelfPackers
-   /module/FindSquish
    /module/FindSQLite3
+   /module/FindSquish
    /module/FindSubversion
    /module/FindSWIG
    /module/FindTCL
@@ -271,7 +267,6 @@
    /module/Documentation
    /module/GetPrerequisites
    /module/MacroAddFileDependencies
-   /module/SquishTestScript
    /module/TestBigEndian
    /module/TestCXXAcceptsFlag
    /module/Use_wxWindows
@@ -322,3 +317,17 @@
    /module/CPackProductBuild
    /module/CPackRPM
    /module/CPackWIX
+
+Miscellaneous Modules
+---------------------
+
+These internal modules are not intended to be included directly in projects:
+
+.. toctree::
+   :maxdepth: 1
+
+   /module/CMakeFindPackageMode
+   /module/CMakeGraphVizOptions
+   /module/CTestScriptMode
+   /module/Findosg_functions
+   /module/SquishTestScript
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 45e0ca0..51a3197 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -34,10 +34,10 @@
 
 .. code-block:: cmake
 
-  cmake_minimum_required(VERSION 3.10...4.0)
+  cmake_minimum_required(VERSION 3.10...4.1)
 
 This uses the ``<min>...<max>`` syntax to enable the ``NEW`` behaviors
-of policies introduced in CMake 4.0 and earlier while only requiring a
+of policies introduced in CMake 4.1 and earlier while only requiring a
 minimum version of CMake 3.10.  The project is expected to work with
 both the ``OLD`` and ``NEW`` behaviors of policies introduced between
 those versions.
@@ -92,6 +92,20 @@
 
 The following policies are supported.
 
+Policies Introduced by CMake 4.2
+--------------------------------
+
+.. toctree::
+   :maxdepth: 1
+
+   CMP0204: A character set is always defined when targeting the MSVC ABI. </policy/CMP0204>
+   CMP0203: _WINDLL is defined for shared libraries targeting the MSVC ABI. </policy/CMP0203>
+   CMP0202: PDB file names always include their target's per-config POSTFIX. </policy/CMP0202>
+   CMP0201: Python::NumPy does not depend on Python::Development.Module. </policy/CMP0201>
+   CMP0200: Location and configuration selection for imported targets is more consistent. </policy/CMP0200>
+   CMP0199: $<CONFIG> does not match mapped configurations that are not selected. </policy/CMP0199>
+   CMP0198: CMAKE_PARENT_LIST_FILE is not defined in CMakeLists.txt. </policy/CMP0198>
+
 Policies Introduced by CMake 4.1
 --------------------------------
 
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index 9400a1b..b0f8e03 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -270,8 +270,8 @@
 ``graphviz``
   An optional string representing the path to the graphviz input file,
   that will contain all the library and executable dependencies
-  in the project. See the documentation for :module:`CMakeGraphVizOptions`
-  for more details.
+  in the project.  See the documentation for :option:`cmake --graphviz` for
+  more details.
 
   This field supports `macro expansion`_. If a relative path is specified,
   it is calculated relative to the current working directory. It is allowed
@@ -1083,9 +1083,25 @@
 ``packageName``
   An optional string representing the package name.
 
+  .. note::
+
+    Due to problems with the implementation, this field does not affect the
+    name of the final package file produced.  Other aspects of the package
+    may use the value though, leading to inconsistencies.
+    A future CMake release may address this problem, but until then, it is
+    recommended that this field not be used.
+
 ``packageVersion``
   An optional string representing the package version.
 
+  .. note::
+
+    Due to problems with the implementation, this field does not affect the
+    name of the final package file produced.  Other aspects of the package
+    may use the value though, leading to inconsistencies.
+    A future CMake release may address this problem, but until then, it is
+    recommended that this field not be used.
+
 ``packageDirectory``
   An optional string representing the directory in which to place the package.
 
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index a2b88dd..5de9ccf 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -40,8 +40,8 @@
    /prop_gbl/GENERATOR_IS_MULTI_CONFIG
    /prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE
    /prop_gbl/GLOBAL_DEPENDS_NO_CYCLES
-   /prop_gbl/INSTALL_PARALLEL
    /prop_gbl/IN_TRY_COMPILE
+   /prop_gbl/INSTALL_PARALLEL
    /prop_gbl/JOB_POOLS
    /prop_gbl/PACKAGES_FOUND
    /prop_gbl/PACKAGES_NOT_FOUND
@@ -226,6 +226,8 @@
    /prop_tgt/EXPORT_NAME
    /prop_tgt/EXPORT_NO_SYSTEM
    /prop_tgt/EXPORT_PROPERTIES
+   /prop_tgt/FASTBUILD_CACHING
+   /prop_tgt/FASTBUILD_DISTRIBUTION
    /prop_tgt/FOLDER
    /prop_tgt/Fortran_BUILDING_INTRINSIC_MODULES
    /prop_tgt/Fortran_FORMAT
@@ -282,6 +284,8 @@
    /prop_tgt/IMPORT_SUFFIX
    /prop_tgt/INCLUDE_DIRECTORIES
    /prop_tgt/INSTALL_NAME_DIR
+   /prop_tgt/INSTALL_OBJECT_NAME_STRATEGY
+   /prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION
    /prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH
    /prop_tgt/INSTALL_RPATH
    /prop_tgt/INSTALL_RPATH_USE_LINK_PATH
@@ -329,7 +333,6 @@
    /prop_tgt/LIBRARY_OUTPUT_DIRECTORY_CONFIG
    /prop_tgt/LIBRARY_OUTPUT_NAME
    /prop_tgt/LIBRARY_OUTPUT_NAME_CONFIG
-   /prop_tgt/SPDX_LICENSE
    /prop_tgt/LINK_DEPENDS
    /prop_tgt/LINK_DEPENDS_NO_SHARED
    /prop_tgt/LINK_DIRECTORIES
@@ -400,9 +403,11 @@
    /prop_tgt/RUNTIME_OUTPUT_NAME
    /prop_tgt/RUNTIME_OUTPUT_NAME_CONFIG
    /prop_tgt/SKIP_BUILD_RPATH
+   /prop_tgt/SKIP_LINTING
    /prop_tgt/SOURCE_DIR
    /prop_tgt/SOURCES
    /prop_tgt/SOVERSION
+   /prop_tgt/SPDX_LICENSE
    /prop_tgt/STATIC_LIBRARY_FLAGS
    /prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG
    /prop_tgt/STATIC_LIBRARY_OPTIONS
@@ -412,6 +417,7 @@
    /prop_tgt/Swift_LANGUAGE_VERSION
    /prop_tgt/Swift_MODULE_DIRECTORY
    /prop_tgt/Swift_MODULE_NAME
+   /prop_tgt/SYMBOLIC
    /prop_tgt/SYSTEM
    /prop_tgt/TEST_LAUNCHER
    /prop_tgt/TRANSITIVE_COMPILE_PROPERTIES
@@ -421,6 +427,7 @@
    /prop_tgt/UNITY_BUILD_BATCH_SIZE
    /prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE
    /prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
+   /prop_tgt/UNITY_BUILD_FILENAME_PREFIX
    /prop_tgt/UNITY_BUILD_MODE
    /prop_tgt/UNITY_BUILD_RELOCATABLE
    /prop_tgt/UNITY_BUILD_UNIQUE_ID
@@ -498,13 +505,13 @@
    /prop_tgt/XCODE_SCHEME_EXECUTABLE
    /prop_tgt/XCODE_SCHEME_GUARD_MALLOC
    /prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION
-   /prop_tgt/XCODE_SCHEME_TEST_CONFIGURATION
    /prop_tgt/XCODE_SCHEME_LAUNCH_MODE
    /prop_tgt/XCODE_SCHEME_LLDB_INIT_FILE
    /prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
    /prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES
    /prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE
    /prop_tgt/XCODE_SCHEME_MALLOC_STACK
+   /prop_tgt/XCODE_SCHEME_TEST_CONFIGURATION
    /prop_tgt/XCODE_SCHEME_THREAD_SANITIZER
    /prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP
    /prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
@@ -573,12 +580,15 @@
    /prop_sf/GENERATED
    /prop_sf/HEADER_FILE_ONLY
    /prop_sf/INCLUDE_DIRECTORIES
+   /prop_sf/INSTALL_OBJECT_NAME
+   /prop_sf/JOB_POOL_COMPILE
    /prop_sf/KEEP_EXTENSION
    /prop_sf/LABELS
    /prop_sf/LANGUAGE
    /prop_sf/LOCATION
    /prop_sf/MACOSX_PACKAGE_LOCATION
    /prop_sf/OBJECT_DEPENDS
+   /prop_sf/OBJECT_NAME
    /prop_sf/OBJECT_OUTPUTS
    /prop_sf/SKIP_AUTOGEN
    /prop_sf/SKIP_AUTOMOC
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst
index f9729b3..fe269c2 100644
--- a/Help/manual/cmake-qt.7.rst
+++ b/Help/manual/cmake-qt.7.rst
@@ -224,10 +224,10 @@
 ===============================
 
 The ``moc`` and ``uic`` tools are executed as part of a synthesized
-:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` generated by
-CMake.  By default that :ref:`<ORIGIN>_autogen` target inherits the dependencies
+``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` generated by
+CMake.  By default, that ``<ORIGIN>_autogen`` target inherits the dependencies
 of the ``<ORIGIN>`` target (see :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`).
-Target dependencies may be added to the :ref:`<ORIGIN>_autogen` target by adding
+Target dependencies may be added to the ``<ORIGIN>_autogen`` target by adding
 them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property.
 
 .. note::
@@ -241,9 +241,10 @@
 
 If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or
 :ref:`Makefile Generators`, the ``<ORIGIN>_autogen_timestamp_deps`` target is
-also created in addition to the :ref:`<ORIGIN>_autogen` target.  This target
-does not have any sources or commands to execute, but it has dependencies that
-were previously inherited by the pre-Qt 5.15 :ref:`<ORIGIN>_autogen` target.
+also created in addition to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+target.  This target does not have any sources or commands to execute, but it
+has dependencies that were previously inherited by the pre-Qt 5.15
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 These dependencies will serve as a list of order-only dependencies for the
 custom command, without forcing the custom command to re-execute.
 
@@ -252,11 +253,11 @@
 
 When using the :ref:`Visual Studio Generators`, CMake
 generates a ``PRE_BUILD`` :command:`custom command <add_custom_command>`
-instead of the :ref:`<ORIGIN>_autogen`
+instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
 :command:`custom target <add_custom_target>` (for :prop_tgt:`AUTOMOC` and
 :prop_tgt:`AUTOUIC`).  This isn't always possible though and an
-:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` is used,
-when either
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+:command:`custom target <add_custom_target>` is used, when either
 
 - the ``<ORIGIN>`` target depends on :prop_sf:`GENERATED` files which aren't
   excluded from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index 9eee219..bb32490 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -704,3 +704,75 @@
 
 - Use :command:`find_package` only for libraries installed with
   :variable:`CMAKE_IOS_INSTALL_COMBINED` feature
+
+.. _`Cross Compiling for Emscripten`:
+
+Cross Compiling for Emscripten
+------------------------------
+
+.. versionadded:: 4.2
+
+A toolchain file may configure cross-compiling for `Emscripten`_ by
+setting the :variable:`CMAKE_SYSTEM_NAME` variable to ``Emscripten``.
+For example, a toolchain file might contain:
+
+.. code-block:: cmake
+
+  set(CMAKE_SYSTEM_NAME Emscripten)
+  set(CMAKE_C_COMPILER /path/to/emcc)
+  set(CMAKE_CXX_COMPILER /path/to/em++)
+
+.. _`Emscripten`: https://emscripten.org/
+
+Cross Compiling using Renesas compilers
+---------------------------------------
+
+For cross-compiling with Renesas compilers, specify at least:
+
+:variable:`CMAKE_SYSTEM_NAME`
+  Set to ``Generic``.  Must be specified to enable cross compiling.
+
+:variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>`
+  Set to the path to the Renesas C compiler, e.g.,
+  ``ccrx``, ``ccrl``, or ``ccrh``.
+
+:variable:`CMAKE_C_FLAGS <CMAKE_<LANG>_FLAGS>`
+  Set to the ``-isa=`` or ``-cpu=`` flag the compiler requires.
+
+See example toolchain files in the following sections.
+
+Renesas CC-RX
+^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  set(CMAKE_SYSTEM_NAME Generic)
+  set(CMAKE_C_COMPILER "ccrx.exe")
+  set(CMAKE_ASM_COMPILER "ccrx.exe") # if using ASM language
+  set(CMAKE_C_FLAGS "-isa=rxv3") # specify the version of target RX CPU
+  set(CMAKE_EXE_LINKER_FLAGS "-lnkopt=<your linker option here>")
+
+Renesas CC-RL
+^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  set(CMAKE_SYSTEM_NAME Generic)
+  set(CMAKE_C_COMPILER "ccrl.exe")
+  set(CMAKE_ASM_COMPILER "ccrl.exe") # if using ASM language
+  set(CMAKE_C_FLAGS "-cpu=S3") # specify the version of target RL CPU
+  # To avoid test executable runs out of const section's size.
+  set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+  # Specifying device file and section layout linker options through compiler driver.
+  set(CMAKE_EXE_LINKER_FLAGS "-lnkopt=-device=dr5f10y14.dvf -lnkopt=-auto_section_layout")
+
+Renesas CC-RH
+^^^^^^^^^^^^^
+
+.. code-block:: cmake
+
+  set(CMAKE_SYSTEM_NAME Generic)
+  set(CMAKE_C_COMPILER "ccrh.exe")
+  set(CMAKE_ASM_COMPILER "ccrh.exe") # if using ASM language
+  set(CMAKE_C_FLAGS "-Xcommon=rh850") # specify the version of target RH850 CPU
+  set(CMAKE_EXE_LINKER_FLAGS "-lnkopt=<your linker option here>")
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index d3ff681..2a23383 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -45,6 +45,7 @@
    /variable/CMAKE_CURRENT_LIST_FILE
    /variable/CMAKE_CURRENT_LIST_LINE
    /variable/CMAKE_CURRENT_SOURCE_DIR
+   /variable/CMAKE_CXX_STDLIB_MODULES_JSON
    /variable/CMAKE_DEBUG_TARGET_PROPERTIES
    /variable/CMAKE_DIRECTORY_LABELS
    /variable/CMAKE_DL_LIBS
@@ -55,6 +56,21 @@
    /variable/CMAKE_EXECUTABLE_SUFFIX
    /variable/CMAKE_EXECUTABLE_SUFFIX_LANG
    /variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
+   /variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE
+   /variable/CMAKE_FASTBUILD_CACHE_PATH
+   /variable/CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV
+   /variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG
+   /variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES
+   /variable/CMAKE_FASTBUILD_COMPILER_EXTRA_FILES
+   /variable/CMAKE_FASTBUILD_ENV_OVERRIDES
+   /variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE
+   /variable/CMAKE_FASTBUILD_IDE_ARGS
+   /variable/CMAKE_FASTBUILD_SOURCE_MAPPING
+   /variable/CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT
+   /variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS
+   /variable/CMAKE_FASTBUILD_USE_LIGHTCACHE
+   /variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS
+   /variable/CMAKE_FASTBUILD_VERBOSE_GENERATOR
    /variable/CMAKE_FIND_DEBUG_MODE
    /variable/CMAKE_FIND_DEBUG_MODE_NO_IMPLICIT_CONFIGURE_LOG
    /variable/CMAKE_FIND_PACKAGE_NAME
@@ -98,22 +114,23 @@
    /variable/CMAKE_OBJDUMP
    /variable/CMAKE_PARENT_LIST_FILE
    /variable/CMAKE_PATCH_VERSION
+   /variable/CMAKE_PROJECT_COMPAT_VERSION
    /variable/CMAKE_PROJECT_DESCRIPTION
    /variable/CMAKE_PROJECT_HOMEPAGE_URL
    /variable/CMAKE_PROJECT_NAME
+   /variable/CMAKE_PROJECT_SPDX_LICENSE
    /variable/CMAKE_PROJECT_VERSION
    /variable/CMAKE_PROJECT_VERSION_MAJOR
    /variable/CMAKE_PROJECT_VERSION_MINOR
    /variable/CMAKE_PROJECT_VERSION_PATCH
    /variable/CMAKE_PROJECT_VERSION_TWEAK
-   /variable/CMAKE_PROJECT_COMPAT_VERSION
    /variable/CMAKE_RANLIB
    /variable/CMAKE_ROOT
    /variable/CMAKE_RULE_MESSAGES
    /variable/CMAKE_SCRIPT_MODE_FILE
+   /variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX
    /variable/CMAKE_SHARED_LIBRARY_PREFIX
    /variable/CMAKE_SHARED_LIBRARY_SUFFIX
-   /variable/CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX
    /variable/CMAKE_SHARED_MODULE_PREFIX
    /variable/CMAKE_SHARED_MODULE_SUFFIX
    /variable/CMAKE_SIZEOF_VOID_P
@@ -154,28 +171,30 @@
    /variable/CMAKE_XCODE_BUILD_SYSTEM
    /variable/CMAKE_XCODE_PLATFORM_TOOLSET
    /variable/PROJECT-NAME_BINARY_DIR
+   /variable/PROJECT-NAME_COMPAT_VERSION
    /variable/PROJECT-NAME_DESCRIPTION
    /variable/PROJECT-NAME_HOMEPAGE_URL
    /variable/PROJECT-NAME_IS_TOP_LEVEL
    /variable/PROJECT-NAME_SOURCE_DIR
+   /variable/PROJECT-NAME_SPDX_LICENSE
    /variable/PROJECT-NAME_VERSION
    /variable/PROJECT-NAME_VERSION_MAJOR
    /variable/PROJECT-NAME_VERSION_MINOR
    /variable/PROJECT-NAME_VERSION_PATCH
    /variable/PROJECT-NAME_VERSION_TWEAK
-   /variable/PROJECT-NAME_COMPAT_VERSION
    /variable/PROJECT_BINARY_DIR
+   /variable/PROJECT_COMPAT_VERSION
    /variable/PROJECT_DESCRIPTION
    /variable/PROJECT_HOMEPAGE_URL
    /variable/PROJECT_IS_TOP_LEVEL
    /variable/PROJECT_NAME
    /variable/PROJECT_SOURCE_DIR
+   /variable/PROJECT_SPDX_LICENSE
    /variable/PROJECT_VERSION
    /variable/PROJECT_VERSION_MAJOR
    /variable/PROJECT_VERSION_MINOR
    /variable/PROJECT_VERSION_PATCH
    /variable/PROJECT_VERSION_TWEAK
-   /variable/PROJECT_COMPAT_VERSION
 
 Variables that Change Behavior
 ==============================
@@ -188,6 +207,7 @@
    /variable/CMAKE_ABSOLUTE_DESTINATION_FILES
    /variable/CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY
    /variable/CMAKE_APPBUNDLE_PATH
+   /variable/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
    /variable/CMAKE_BUILD_TYPE
    /variable/CMAKE_CLANG_VFS_OVERLAY
    /variable/CMAKE_CODEBLOCKS_COMPILER_ID
@@ -209,9 +229,9 @@
    /variable/CMAKE_EXECUTE_PROCESS_COMMAND_ERROR_IS_FATAL
    /variable/CMAKE_EXPORT_BUILD_DATABASE
    /variable/CMAKE_EXPORT_COMPILE_COMMANDS
-   /variable/CMAKE_EXPORT_SARIF
-   /variable/CMAKE_EXPORT_PACKAGE_REGISTRY
    /variable/CMAKE_EXPORT_NO_PACKAGE_REGISTRY
+   /variable/CMAKE_EXPORT_PACKAGE_REGISTRY
+   /variable/CMAKE_EXPORT_SARIF
    /variable/CMAKE_FIND_APPBUNDLE
    /variable/CMAKE_FIND_FRAMEWORK
    /variable/CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX
@@ -246,6 +266,7 @@
    /variable/CMAKE_INSTALL_MESSAGE
    /variable/CMAKE_INSTALL_PREFIX
    /variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT
+   /variable/CMAKE_INTERMEDIATE_DIR_STRATEGY
    /variable/CMAKE_KATE_FILES_MODE
    /variable/CMAKE_KATE_MAKE_ARGUMENTS
    /variable/CMAKE_LIBRARY_PATH
@@ -312,13 +333,13 @@
    /variable/CMAKE_XCODE_SCHEME_ENVIRONMENT
    /variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC
    /variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
-   /variable/CMAKE_XCODE_SCHEME_TEST_CONFIGURATION
    /variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE
    /variable/CMAKE_XCODE_SCHEME_LLDB_INIT_FILE
    /variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
    /variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
    /variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
    /variable/CMAKE_XCODE_SCHEME_MALLOC_STACK
+   /variable/CMAKE_XCODE_SCHEME_TEST_CONFIGURATION
    /variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER
    /variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
    /variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
@@ -342,8 +363,8 @@
    /variable/CMAKE_ANDROID_NDK_VERSION
    /variable/CMAKE_CL_64
    /variable/CMAKE_COMPILER_2005
-   /variable/CMAKE_HOST_APPLE
    /variable/CMAKE_HOST_AIX
+   /variable/CMAKE_HOST_APPLE
    /variable/CMAKE_HOST_BSD
    /variable/CMAKE_HOST_EXECUTABLE_SUFFIX
    /variable/CMAKE_HOST_LINUX
@@ -387,8 +408,8 @@
    :maxdepth: 1
 
    /variable/CMAKE_ADSP_ROOT
-   /variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE
    /variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS
+   /variable/CMAKE_AIX_SHARED_LIBRARY_ARCHIVE
    /variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
    /variable/CMAKE_ANDROID_API
    /variable/CMAKE_ANDROID_API_MIN
@@ -428,18 +449,18 @@
    /variable/CMAKE_AUTOMOC
    /variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES
    /variable/CMAKE_AUTOMOC_DEPEND_FILTERS
+   /variable/CMAKE_AUTOMOC_EXECUTABLE
    /variable/CMAKE_AUTOMOC_INCLUDE_DIRECTORIES
    /variable/CMAKE_AUTOMOC_MACRO_NAMES
    /variable/CMAKE_AUTOMOC_MOC_OPTIONS
    /variable/CMAKE_AUTOMOC_PATH_PREFIX
-   /variable/CMAKE_AUTOMOC_EXECUTABLE
    /variable/CMAKE_AUTORCC
-   /variable/CMAKE_AUTORCC_OPTIONS
    /variable/CMAKE_AUTORCC_EXECUTABLE
+   /variable/CMAKE_AUTORCC_OPTIONS
    /variable/CMAKE_AUTOUIC
+   /variable/CMAKE_AUTOUIC_EXECUTABLE
    /variable/CMAKE_AUTOUIC_OPTIONS
    /variable/CMAKE_AUTOUIC_SEARCH_PATHS
-   /variable/CMAKE_AUTOUIC_EXECUTABLE
    /variable/CMAKE_BUILD_RPATH
    /variable/CMAKE_BUILD_RPATH_USE_ORIGIN
    /variable/CMAKE_BUILD_WITH_INSTALL_NAME_DIR
@@ -484,6 +505,8 @@
    /variable/CMAKE_INCLUDE_CURRENT_DIR
    /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
    /variable/CMAKE_INSTALL_NAME_DIR
+   /variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY
+   /variable/CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION
    /variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
    /variable/CMAKE_INSTALL_RPATH
    /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
@@ -494,9 +517,9 @@
    /variable/CMAKE_LANG_COMPILER_LAUNCHER
    /variable/CMAKE_LANG_CPPCHECK
    /variable/CMAKE_LANG_CPPLINT
-   /variable/CMAKE_LANG_LINK_DEF_FILE_FLAG
    /variable/CMAKE_LANG_ICSTAT
    /variable/CMAKE_LANG_INCLUDE_WHAT_YOU_USE
+   /variable/CMAKE_LANG_LINK_DEF_FILE_FLAG
    /variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE
    /variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED
    /variable/CMAKE_LANG_LINK_LIBRARY_FEATURE_ATTRIBUTES
@@ -560,6 +583,7 @@
    /variable/CMAKE_SHARED_LINKER_FLAGS_INIT
    /variable/CMAKE_SKIP_BUILD_RPATH
    /variable/CMAKE_SKIP_INSTALL_RPATH
+   /variable/CMAKE_SKIP_LINTING
    /variable/CMAKE_STATIC_LINKER_FLAGS
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG
    /variable/CMAKE_STATIC_LINKER_FLAGS_CONFIG_INIT
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 46ad589..316ba25 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -252,11 +252,145 @@
 
 .. option:: --graphviz=<file>
 
- Generate graphviz of dependencies, see :module:`CMakeGraphVizOptions` for more.
+  Generate `Graphviz <https://www.graphviz.org/>`_ of dependencies
 
- Generate a graphviz input file that will contain all the library and
- executable dependencies in the project.  See the documentation for
- :module:`CMakeGraphVizOptions` for more details.
+  This option generates a graphviz input file that will contain all the
+  library and executable dependencies in the project showing the
+  dependencies between the targets in a project, as well as external libraries
+  which are linked against.
+
+  When running CMake with the ``--graphviz=foo.dot`` option, it produces:
+
+  * a ``foo.dot`` file, showing all dependencies in the project
+  * a ``foo.dot.<target>`` file for each target, showing on which other targets
+    it depends
+  * a ``foo.dot.<target>.dependers`` file for each target, showing which other
+    targets depend on it
+
+  Those .dot files can be converted to images using the *dot* command from the
+  Graphviz package:
+
+  .. code-block:: shell
+
+    dot -Tpng -o foo.png foo.dot
+
+  .. versionadded:: 3.10
+    The different dependency types ``PUBLIC``, ``INTERFACE`` and ``PRIVATE``
+    are represented as solid, dashed and dotted edges.
+
+  .. rubric:: Variables specific to the Graphviz support
+
+  The resulting graphs can be huge.  The look and content of the generated graphs
+  can be controlled using the file ``CMakeGraphVizOptions.cmake``.  This file is
+  first searched in :variable:`CMAKE_BINARY_DIR`, and then in
+  :variable:`CMAKE_SOURCE_DIR`.  If found, the variables set in it are used to
+  adjust options for the generated Graphviz files.
+
+  .. variable:: GRAPHVIZ_GRAPH_NAME
+
+    The graph name.
+
+    * Mandatory: NO
+    * Default: value of :variable:`CMAKE_PROJECT_NAME`
+
+  .. variable:: GRAPHVIZ_GRAPH_HEADER
+
+    The header written at the top of the Graphviz files.
+
+    * Mandatory: NO
+    * Default: "node [ fontsize = "12" ];"
+
+  .. variable:: GRAPHVIZ_NODE_PREFIX
+
+    The prefix for each node in the Graphviz files.
+
+    * Mandatory: NO
+    * Default: "node"
+
+  .. variable:: GRAPHVIZ_EXECUTABLES
+
+    Set to FALSE to exclude executables from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_STATIC_LIBS
+
+    Set to FALSE to exclude static libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_SHARED_LIBS
+
+    Set to FALSE to exclude shared libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_MODULE_LIBS
+
+    Set to FALSE to exclude module libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_INTERFACE_LIBS
+
+    Set to FALSE to exclude interface libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_OBJECT_LIBS
+
+    Set to FALSE to exclude object libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_UNKNOWN_LIBS
+
+    Set to FALSE to exclude unknown libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_EXTERNAL_LIBS
+
+    Set to FALSE to exclude external libraries from the generated graphs.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_CUSTOM_TARGETS
+
+    Set to TRUE to include custom targets in the generated graphs.
+
+    * Mandatory: NO
+    * Default: FALSE
+
+  .. variable:: GRAPHVIZ_IGNORE_TARGETS
+
+    A list of regular expressions for names of targets to exclude from the
+    generated graphs.
+
+    * Mandatory: NO
+    * Default: empty
+
+  .. variable:: GRAPHVIZ_GENERATE_PER_TARGET
+
+    Set to FALSE to not generate per-target graphs ``foo.dot.<target>``.
+
+    * Mandatory: NO
+    * Default: TRUE
+
+  .. variable:: GRAPHVIZ_GENERATE_DEPENDERS
+
+    Set to FALSE to not generate depender graphs ``foo.dot.<target>.dependers``.
+
+    * Mandatory: NO
+    * Default: TRUE
 
 .. option:: --system-information [file]
 
@@ -1029,6 +1163,19 @@
   ``copy_directory_if_different`` does follow symlinks.
   The command fails when the source directory does not exist.
 
+.. option:: copy_directory_if_newer <dir>... <destination>
+
+  .. versionadded:: 4.2
+
+  Copy content of ``<dir>...`` directories to ``<destination>`` directory
+  if source files are newer than destination files (based on file timestamps).
+  If ``<destination>`` directory does not exist it will be created.
+
+  ``copy_directory_if_newer`` does follow symlinks.
+  The command fails when the source directory does not exist.
+  This is faster than ``copy_directory_if_different`` as it only compares
+  file timestamps instead of file contents.
+
 .. option:: copy_if_different <file>... <destination>
 
   Copy files to ``<destination>`` (either file or directory) if
@@ -1040,6 +1187,18 @@
   .. versionadded:: 3.5
     Support for multiple input files.
 
+.. option:: copy_if_newer <file>... <destination>
+
+  .. versionadded:: 4.2
+
+  Copy files to ``<destination>`` (either file or directory) if
+  source files are newer than destination files (based on file timestamps).
+  If multiple files are specified, the ``<destination>`` must be
+  directory and it must exist.
+  ``copy_if_newer`` does follow symlinks.
+  This is faster than ``copy_if_different`` as it only compares
+  file timestamps instead of file contents.
+
 .. option:: create_symlink <old> <new>
 
   Create a symbolic link ``<new>`` naming ``<old>``.
diff --git a/Help/manual/cpack-generators.7.rst b/Help/manual/cpack-generators.7.rst
index abb291b..5c8c075 100644
--- a/Help/manual/cpack-generators.7.rst
+++ b/Help/manual/cpack-generators.7.rst
@@ -13,6 +13,7 @@
 .. toctree::
    :maxdepth: 1
 
+   /cpack_gen/appimage
    /cpack_gen/archive
    /cpack_gen/bundle
    /cpack_gen/cygwin
diff --git a/Help/manual/file_api/schema_cache.json b/Help/manual/file_api/schema_cache.json
new file mode 100644
index 0000000..78ebf8e
--- /dev/null
+++ b/Help/manual/file_api/schema_cache.json
@@ -0,0 +1,83 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake cache object kind",
+  "type": "object",
+  "required": [
+    "kind",
+    "version",
+    "entries"
+  ],
+  "properties": {
+    "kind": {
+      "type": "string",
+      "const": "cache"
+    },
+    "version": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "const": 0
+        }
+      },
+      "additionalProperties": false
+    },
+    "entries": {
+      "type": "array",
+      "description": "Array of CMake cache entries",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "value",
+          "type",
+          "properties"
+        ],
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "Name of the cache entry"
+          },
+          "value": {
+            "type": "string",
+            "description": "Value of the cache entry"
+          },
+          "type": {
+            "type": "string",
+            "description": "Type of the cache entry used by CMake GUI to choose a widget for editing"
+          },
+          "properties": {
+            "type": "array",
+            "description": "Associated properties for the cache entry",
+            "items": {
+              "type": "object",
+              "required": [
+                "name",
+                "value"
+              ],
+              "properties": {
+                "name": {
+                  "type": "string"
+                },
+                "value": {
+                  "type": "string"
+                }
+              },
+              "additionalProperties": false
+            }
+          }
+        },
+        "additionalProperties": false
+      }
+    }
+  },
+  "additionalProperties": false
+}
diff --git a/Help/manual/file_api/schema_cmakeFiles.json b/Help/manual/file_api/schema_cmakeFiles.json
new file mode 100644
index 0000000..3611825
--- /dev/null
+++ b/Help/manual/file_api/schema_cmakeFiles.json
@@ -0,0 +1,186 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake cmakeFiles object kind",
+  "type": "object",
+  "required": [
+    "kind",
+    "version",
+    "paths",
+    "inputs"
+  ],
+  "oneOf": [
+    {
+      "$ref": "#/definitions/cmakeFilesV1_0"
+    },
+    {
+      "$ref": "#/definitions/cmakeFilesV1_1"
+    }
+  ],
+  "definitions": {
+    "kind": {
+      "type": "string",
+      "const": "cmakeFiles",
+      "description": "Specifies the object kind"
+    },
+    "versionV1_0": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 1
+        },
+        "minor": {
+          "type": "integer",
+          "const": 0
+        }
+      },
+      "additionalProperties": false
+    },
+    "versionV1_1": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 1
+        },
+        "minor": {
+          "type": "integer",
+          "const": 1
+        }
+      },
+      "additionalProperties": false
+    },
+    "paths": {
+      "type": "object",
+      "required": [
+        "build",
+        "source"
+      ],
+      "properties": {
+        "build": {
+          "type": "string",
+          "description": "Absolute path to the top-level build directory"
+        },
+        "source": {
+          "type": "string",
+          "description": "Absolute path to the top-level source directory"
+        }
+      },
+      "additionalProperties": false
+    },
+    "inputs": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "type": "string",
+            "description": "Path to an input file to CMake"
+          },
+          "isGenerated": {
+            "type": "boolean",
+            "description": "Indicates if the file is under the build directory in out-of-source builds"
+          },
+          "isExternal": {
+            "type": "boolean",
+            "description": "Indicates if the file is not under source or build directories"
+          },
+          "isCMake": {
+            "type": "boolean",
+            "description": "Indicates if the file is in the CMake installation"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "globsDependentV1_1": {
+      "type": "array",
+      "description": "Optional member present only when the project calls file(GLOB) or file(GLOB_RECURSE) with the CONFIGURE_DEPENDS option",
+      "items": {
+        "type": "object",
+        "required": [
+          "expression",
+          "paths"
+        ],
+        "properties": {
+          "expression": {
+            "type": "string",
+            "description": "The globbing expression. If the result of the expression no longer matches the same list of paths, the build system is considered out of date and the build tool will re-run cmake."
+          },
+          "recurse": {
+            "type": "boolean",
+            "description": "This will be true if the glob expression was from a file(GLOB_RECURSE) call"
+          },
+          "listDirectories": {
+            "type": "boolean",
+            "description": "This will be true if the expression is from a file(GLOB) that does not specify LIST_DIRECTORIES false, or from a file(GLOB_RECURSE) with LIST_DIRECTORIES set to true"
+          },
+          "followSymlinks": {
+            "type": "boolean",
+            "description": "This will be true if the FOLLOW_SYMLINKS option was given"
+          },
+          "relative": {
+            "type": "string",
+            "description": "This will be present if the RELATIVE option was given. The value is the path given after the RELATIVE keyword."
+          },
+          "paths": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "Paths matched by the globbing expression"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "cmakeFilesV1_0": {
+      "properties": {
+        "kind": {
+          "$ref": "#/definitions/kind"
+        },
+        "version": {
+          "$ref": "#/definitions/versionV1_0"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "inputs": {
+          "$ref": "#/definitions/inputs"
+        }
+      },
+      "additionalProperties": false
+    },
+    "cmakeFilesV1_1": {
+      "properties": {
+        "kind": {
+          "$ref": "#/definitions/kind"
+        },
+        "version": {
+          "$ref": "#/definitions/versionV1_1"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "inputs": {
+          "$ref": "#/definitions/inputs"
+        },
+        "globsDependent": {
+          "$ref": "#/definitions/globsDependentV1_1"
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_codemodel.json b/Help/manual/file_api/schema_codemodel.json
new file mode 100644
index 0000000..72902cb
--- /dev/null
+++ b/Help/manual/file_api/schema_codemodel.json
@@ -0,0 +1,565 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake codemodel object kind",
+  "type": "object",
+  "required": [
+    "kind",
+    "version",
+    "paths",
+    "configurations"
+  ],
+  "oneOf": [
+    {
+      "$ref": "#/definitions/codemodelV2_0"
+    },
+    {
+      "$ref": "#/definitions/codemodelV2_3"
+    },
+    {
+      "$ref": "#/definitions/codemodelV2_9"
+    }
+  ],
+  "definitions": {
+    "kind": {
+      "type": "string",
+      "const": "codemodel",
+      "description": "Specifies the object kind"
+    },
+    "versionV2_0": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "minimum": 0,
+          "maximum": 2
+        }
+      },
+      "additionalProperties": false
+    },
+    "versionV2_3": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "minimum": 3,
+          "maximum": 8
+        }
+      },
+      "additionalProperties": false
+    },
+    "versionV2_9": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "minimum": 9
+        }
+      },
+      "additionalProperties": false
+    },
+    "paths": {
+      "type": "object",
+      "required": [
+        "source",
+        "build"
+      ],
+      "properties": {
+        "source": {
+          "type": "string",
+          "description": "Absolute path to the top-level source directory"
+        },
+        "build": {
+          "type": "string",
+          "description": "Absolute path to the top-level build directory"
+        }
+      },
+      "additionalProperties": false
+    },
+    "configurationDirectoryItemSource": {
+      "type": "string",
+      "description": "Path to the source directory. If it is inside the top level source directory, the path will be relative to that directory. For the top level source directory, this will simply be '.'. Paths outside the top level source directory will be absolute."
+    },
+    "configurationDirectoryItemBuild": {
+      "type": "string",
+      "description": "Path to the build directory. If it is inside the top level build directory, the path will be relative to that directory. For the top level build directory, this will simply be '.'. Paths outside the top level build directory will be absolute."
+    },
+    "configurationDirectoryItemParentIndex": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index of the parent directory in the directories array"
+    },
+    "configurationDirectoryItemChildIndexes": {
+      "type": "array",
+      "items": {
+        "type": "integer",
+        "minimum": 0
+      },
+      "description": "Indices of child directories"
+    },
+    "configurationDirectoryItemProjectIndex": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index into the projects array"
+    },
+    "configurationDirectoryItemBuildSystemTargetIndexes": {
+      "type": "array",
+      "items": {
+        "type": "integer",
+        "minimum": 0
+      },
+      "description": "Indices into the targets array"
+    },
+    "configurationDirectoryItemAbstractTargetIndexesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "integer",
+        "minimum": 0
+      },
+      "description": "Indices into the abstractTargets array"
+    },
+    "configurationDirectoryItemMinimumCMakeVersion": {
+      "type": "object",
+      "required": [
+        "string"
+      ],
+      "properties": {
+        "string": {
+          "type": "string",
+          "description": "Minimum required CMake version, if known"
+        }
+      },
+      "additionalProperties": false
+    },
+    "configurationDirectoryItemHasInstallRule": {
+      "type": "boolean",
+      "description": "Whether the directory has install rules"
+    },
+    "configurationDirectoryItemJsonFileV2_3": {
+      "jsonFile": {
+        "type": "string",
+        "description": "Path to directory-specific JSON file"
+      }
+    },
+    "configurationDirectoriesV2_0": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "source",
+          "build",
+          "projectIndex"
+        ],
+        "properties": {
+          "source": {
+            "$ref": "#/definitions/configurationDirectoryItemSource"
+          },
+          "build": {
+            "$ref": "#/definitions/configurationDirectoryItemBuild"
+          },
+          "parentIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemParentIndex"
+          },
+          "childIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemChildIndexes"
+          },
+          "projectIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemProjectIndex"
+          },
+          "targetIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemBuildSystemTargetIndexes"
+          },
+          "minimumCMakeVersion": {
+            "$ref": "#/definitions/configurationDirectoryItemMinimumCMakeVersion"
+          },
+          "hasInstallRule": {
+            "$ref": "#/definitions/configurationDirectoryItemHasInstallRule"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "configurationDirectoriesV2_3": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "source",
+          "build",
+          "projectIndex"
+        ],
+        "properties": {
+          "source": {
+            "$ref": "#/definitions/configurationDirectoryItemSource"
+          },
+          "build": {
+            "$ref": "#/definitions/configurationDirectoryItemBuild"
+          },
+          "parentIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemParentIndex"
+          },
+          "childIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemChildIndexes"
+          },
+          "projectIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemProjectIndex"
+          },
+          "targetIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemBuildSystemTargetIndexes"
+          },
+          "minimumCMakeVersion": {
+            "$ref": "#/definitions/configurationDirectoryItemMinimumCMakeVersion"
+          },
+          "hasInstallRule": {
+            "$ref": "#/definitions/configurationDirectoryItemHasInstallRule"
+          },
+          "jsonFile": {
+            "$ref": "#/definitions/configurationDirectoryItemJsonFileV2_3"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "configurationDirectoriesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "source",
+          "build",
+          "projectIndex"
+        ],
+        "properties": {
+          "source": {
+            "$ref": "#/definitions/configurationDirectoryItemSource"
+          },
+          "build": {
+            "$ref": "#/definitions/configurationDirectoryItemBuild"
+          },
+          "parentIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemParentIndex"
+          },
+          "childIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemChildIndexes"
+          },
+          "projectIndex": {
+            "$ref": "#/definitions/configurationDirectoryItemProjectIndex"
+          },
+          "targetIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemBuildSystemTargetIndexes"
+          },
+          "abstractTargetIndexes": {
+            "$ref": "#/definitions/configurationDirectoryItemAbstractTargetIndexesV2_9"
+          },
+          "minimumCMakeVersion": {
+            "$ref": "#/definitions/configurationDirectoryItemMinimumCMakeVersion"
+          },
+          "hasInstallRule": {
+            "$ref": "#/definitions/configurationDirectoryItemHasInstallRule"
+          },
+          "jsonFile": {
+            "$ref": "#/definitions/configurationDirectoryItemJsonFileV2_3"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "configurationName": {
+      "type": "string",
+      "description": "Configuration name (e.g., 'Debug')"
+    },
+    "configurationProjects": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directoryIndexes"
+        ],
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "Project name"
+          },
+          "parentIndex": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index of parent project"
+          },
+          "childIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices of child projects"
+          },
+          "directoryIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into directories array"
+          },
+          "targetIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into targets array"
+          }
+        }
+      }
+    },
+    "configurationProjectsV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directoryIndexes"
+        ],
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "Project name"
+          },
+          "parentIndex": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index of parent project"
+          },
+          "childIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices of child projects"
+          },
+          "directoryIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into directories array"
+          },
+          "targetIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into targets array"
+          },
+          "abstractTargetIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into abstractTargets array"
+          }
+        }
+      }
+    },
+    "configurationTargets": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directoryIndex",
+          "projectIndex",
+          "jsonFile"
+        ],
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "Target name"
+          },
+          "id": {
+            "type": "string",
+            "description": "Unique target identifier"
+          },
+          "directoryIndex": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into directories array"
+          },
+          "projectIndex": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into projects array"
+          },
+          "jsonFile": {
+            "type": "string",
+            "description": "Path to target-specific JSON file"
+          }
+        }
+      }
+    },
+    "configurationsV2_0": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directories",
+          "projects",
+          "targets"
+        ],
+        "properties": {
+          "name": {
+            "$ref": "#/definitions/configurationName"
+          },
+          "projects": {
+            "$ref": "#/definitions/configurationProjects"
+          },
+          "targets": {
+            "$ref": "#/definitions/configurationTargets"
+          },
+          "directories": {
+            "$ref": "#/definitions/configurationDirectoriesV2_0"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "configurationsV2_3": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directories",
+          "projects",
+          "targets"
+        ],
+        "properties": {
+          "name": {
+            "$ref": "#/definitions/configurationName"
+          },
+          "projects": {
+            "$ref": "#/definitions/configurationProjects"
+          },
+          "targets": {
+            "$ref": "#/definitions/configurationTargets"
+          },
+          "directories": {
+            "$ref": "#/definitions/configurationDirectoriesV2_3"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "configurationsV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "directories",
+          "projects",
+          "targets",
+          "abstractTargets"
+        ],
+        "properties": {
+          "name": {
+            "$ref": "#/definitions/configurationName"
+          },
+          "projects": {
+            "$ref": "#/definitions/configurationProjectsV2_9"
+          },
+          "targets": {
+            "$ref": "#/definitions/configurationTargets"
+          },
+          "abstractTargets": {
+            "$ref": "#/definitions/configurationTargets"
+          },
+          "directories": {
+            "$ref": "#/definitions/configurationDirectoriesV2_9"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "codemodelV2_0": {
+      "properties": {
+        "kind": {
+          "$ref": "#/definitions/kind"
+        },
+        "version": {
+          "$ref": "#/definitions/versionV2_0"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "configurations": {
+          "$ref": "#/definitions/configurationsV2_0"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_3": {
+      "properties": {
+        "kind": {
+          "$ref": "#/definitions/kind"
+        },
+        "version": {
+          "$ref": "#/definitions/versionV2_3"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "configurations": {
+          "$ref": "#/definitions/configurationsV2_3"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_9": {
+      "properties": {
+        "kind": {
+          "$ref": "#/definitions/kind"
+        },
+        "version": {
+          "$ref": "#/definitions/versionV2_9"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "configurations": {
+          "$ref": "#/definitions/configurationsV2_9"
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_configureLog.json b/Help/manual/file_api/schema_configureLog.json
new file mode 100644
index 0000000..2f380b8
--- /dev/null
+++ b/Help/manual/file_api/schema_configureLog.json
@@ -0,0 +1,55 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake configureLog object kind",
+  "type": "object",
+  "required": [
+    "kind",
+    "version",
+    "path",
+    "eventKindNames"
+  ],
+  "properties": {
+    "kind": {
+      "type": "string",
+      "const": "configureLog"
+    },
+    "version": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 1
+        },
+        "minor": {
+          "type": "integer",
+          "const": 0
+        }
+      },
+      "additionalProperties": false
+    },
+    "path": {
+      "type": "string",
+      "description": "Path to the configure log file. Clients must read the log file from this path, which may be different to the path in CMake's documentation. The log file specified by this path might not exist if no events have been logged."
+    },
+    "eventKindNames": {
+      "type": "array",
+      "description": "Names of versioned event kinds included in the configure log. Other event kinds might be present in the configure log, but clients must ignore those not listed in this array.",
+      "items": {
+        "type": "string",
+        "enum": [
+          "message-v1",
+          "try_compile-v1",
+          "try_run-v1",
+          "find-v1",
+          "find_package-v1"
+        ]
+      },
+      "uniqueItems": true
+    }
+  },
+  "additionalProperties": false
+}
diff --git a/Help/manual/file_api/schema_directory.json b/Help/manual/file_api/schema_directory.json
new file mode 100644
index 0000000..9b59229
--- /dev/null
+++ b/Help/manual/file_api/schema_directory.json
@@ -0,0 +1,636 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake codemodel directory object",
+  "type": "object",
+  "oneOf": [
+    {
+      "$comment": "The top level codemodelVersion field was only added in version 2.9, so we can't differentiate between earlier versions",
+      "anyOf": [
+        {
+          "$ref": "#/definitions/codemodelV2_0"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_4"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_5"
+        }
+      ]
+    },
+    {
+      "$ref": "#/definitions/codemodelV2_9"
+    }
+  ],
+  "definitions": {
+    "codemodelVersionV2_9": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "minimum": 9
+        }
+      },
+      "additionalProperties": false
+    },
+    "backtraceGraph": {
+      "type": "object",
+      "required": [
+        "nodes",
+        "commands",
+        "files"
+      ],
+      "properties": {
+        "nodes": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "required": [
+              "file"
+            ],
+            "properties": {
+              "file": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "0-based index into the backtrace files array"
+              },
+              "line": {
+                "type": "integer",
+                "minimum": 1,
+                "description": "This is present when the node represents a line within the file. The line number is a 1-based value."
+              },
+              "command": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "This is present when the node represents a command invocation. It is a 0-based index into the backtrace commands array."
+              },
+              "parent": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "This is present when the node is not the bottom of the call stack. It is a 0-based index of another node in the backtrace nodes array."
+              }
+            },
+            "additionalProperties": false
+          }
+        },
+        "commands": {
+          "type": "array",
+          "description": "Each list item is a string specifying a command name",
+          "items": {
+            "type": "string"
+          }
+        },
+        "files": {
+          "type": "array",
+          "description": "Each list item is a string specifying the path to a file, represented with forward slashes. If the file is inside the top level source directory, the path is specified relative to that directory. Otherwise, the path is absolute.",
+          "items": {
+            "type": "string"
+          }
+        }
+      },
+      "additionalProperties": false
+    },
+    "paths": {
+      "type": "object",
+      "required": [
+        "source",
+        "build"
+      ],
+      "properties": {
+        "source": {
+          "type": "string",
+          "description": "Path to the source directory. If it is inside the top level source directory, the path will be relative to that directory. For the top level source directory, this will simply be '.'. Paths outside the top level source directory will be absolute."
+        },
+        "build": {
+          "type": "string",
+          "description": "Path to the build directory. If it is inside the top level build directory, the path will be relative to that directory. For the top level build directory, this will simply be '.'. Paths outside the top level build directory will be absolute."
+        }
+      },
+      "additionalProperties": false
+    },
+    "installerComponent": {
+      "type": "string",
+      "description": "Specifies the component selected by the corresponding install command invocation"
+    },
+    "installerDestination": {
+      "type": "string",
+      "description": "The install destination path. May be absolute or relative to the install prefix"
+    },
+    "installerPaths": {
+      "type": "array",
+      "description": "Paths (files or directories) to be installed",
+      "items": {
+        "oneOf": [
+          {
+            "type": "string",
+            "description": "Path from which a file/directory is installed, also specifying the install path"
+          },
+          {
+            "type": "object",
+            "properties": {
+              "from": {
+                "type": "string",
+                "description": "Path from which a file/directory is installed"
+              },
+              "to": {
+                "type": "string",
+                "description": "Path to which the file/directory is installed under the destination"
+              }
+            },
+            "required": [
+              "from",
+              "to"
+            ]
+          }
+        ]
+      }
+    },
+    "installerItemTypesV2_0": {
+      "type": "string",
+      "enum": [
+        "file",
+        "directory",
+        "target",
+        "export",
+        "script",
+        "code",
+        "importedRuntimeArtifacts",
+        "runtimeDependencySet"
+      ]
+    },
+    "installerItemTypesV2_4": {
+      "type": "string",
+      "enum": [
+        "fileSet"
+      ]
+    },
+    "installerItemTypesV2_5": {
+      "type": "string",
+      "enum": [
+        "cxxModuleBmi"
+      ]
+    },
+    "installerTypeV2_0": {
+      "$ref": "#/definitions/installerItemTypesV2_0",
+      "description": "Type of installation rule"
+    },
+    "installerTypeV2_4": {
+      "anyOf": [
+        {
+          "$ref": "#/definitions/installerItemTypesV2_0"
+        },
+        {
+          "$ref": "#/definitions/installerItemTypesV2_4"
+        }
+      ],
+      "description": "Type of installation rule"
+    },
+    "installerTypeV2_5": {
+      "anyOf": [
+        {
+          "$ref": "#/definitions/installerItemTypesV2_0"
+        },
+        {
+          "$ref": "#/definitions/installerItemTypesV2_4"
+        },
+        {
+          "$ref": "#/definitions/installerItemTypesV2_5"
+        }
+      ],
+      "description": "Type of installation rule"
+    },
+    "installerIsExcludeFromAll": {
+      "type": "boolean",
+      "description": "Present when install is called with EXCLUDE_FROM_ALL option"
+    },
+    "installerIsForAllComponents": {
+      "type": "boolean",
+      "description": "Present when install(SCRIPT|CODE) is called with ALL_COMPONENTS option"
+    },
+    "installerIsOptional": {
+      "type": "boolean",
+      "description": "Present when install is called with OPTIONAL option"
+    },
+    "installerTargetId": {
+      "type": "string",
+      "description": "Uniquely identifying string for the target to be installed"
+    },
+    "installerTargetIndex": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "0-based index into the codemodel targets array"
+    },
+    "installerTargetIsImportLibrary": {
+      "type": "boolean",
+      "description": "Present for Windows DLL import library or AIX linker import file"
+    },
+    "installerTargetInstallNamelink": {
+      "type": "string",
+      "enum": [
+        "skip",
+        "only"
+      ],
+      "description": "How to handle symlinks for VERSION/SOVERSION target properties"
+    },
+    "installerExportName": {
+      "type": "string",
+      "description": "Name of the export for export type"
+    },
+    "installerExportTargets": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "String uniquely identifying the target"
+          },
+          "index": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "0-based index into the codemodel targets array"
+          }
+        },
+        "additionalProperties": false,
+        "required": [
+          "id",
+          "index"
+        ]
+      }
+    },
+    "installerRuntimeDependencySetName": {
+      "type": "string",
+      "description": "Name of the runtime dependency set"
+    },
+    "installerRuntimeDependencySetType": {
+      "type": "string",
+      "enum": [
+        "library",
+        "framework"
+      ],
+      "description": "Type of runtime dependency set"
+    },
+    "installerScriptFile": {
+      "type": "string",
+      "description": "Path to the script file on disk"
+    },
+    "installerBacktrace": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "0-based index into the backtraceGraph nodes array"
+    },
+    "installerFileSetNameV2_4": {
+      "type": "string",
+      "description": "Name of the file set"
+    },
+    "installerFileSetTypeV2_4": {
+      "type": "string",
+      "description": "Type of the file set"
+    },
+    "installerFileSetDirectoriesV2_4": {
+      "type": "array",
+      "items": {
+        "type": "string"
+      },
+      "description": "File set's base directories"
+    },
+    "installerFileSetTargetV2_4": {
+      "type": "object",
+      "required": [
+        "id",
+        "index"
+      ],
+      "properties": {
+        "id": {
+          "type": "string",
+          "description": "String uniquely identifying the target"
+        },
+        "index": {
+          "type": "integer",
+          "minimum": 0,
+          "description": "0-based index into the codemodel targets array"
+        }
+      },
+      "additionalProperties": false
+    },
+    "installerCxxModuleBmiTargetV2_5": {
+      "type": "object",
+      "properties": {
+        "id": {
+          "type": "string"
+        },
+        "index": {
+          "type": "integer",
+          "minimum": 0
+        }
+      },
+      "additionalProperties": false
+    },
+    "installersV2_0": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "component",
+          "type"
+        ],
+        "properties": {
+          "component": {
+            "$ref": "#/definitions/installerComponent"
+          },
+          "destination": {
+            "$ref": "#/definitions/installerDestination"
+          },
+          "paths": {
+            "$ref": "#/definitions/installerPaths"
+          },
+          "type": {
+            "$ref": "#/definitions/installerTypeV2_0"
+          },
+          "isExcludeFromAll": {
+            "$ref": "#/definitions/installerIsExcludeFromAll"
+          },
+          "isForAllComponents": {
+            "$ref": "#/definitions/installerIsForAllComponents"
+          },
+          "isOptional": {
+            "$ref": "#/definitions/installerIsOptional"
+          },
+          "targetId": {
+            "$ref": "#/definitions/installerTargetId"
+          },
+          "targetIndex": {
+            "$ref": "#/definitions/installerTargetIndex"
+          },
+          "targetIsImportLibrary": {
+            "$ref": "#/definitions/installerTargetIsImportLibrary"
+          },
+          "targetInstallNamelink": {
+            "$ref": "#/definitions/installerTargetInstallNamelink"
+          },
+          "exportName": {
+            "$ref": "#/definitions/installerExportName"
+          },
+          "exportTargets": {
+            "$ref": "#/definitions/installerExportTargets"
+          },
+          "runtimeDependencySetName": {
+            "$ref": "#/definitions/installerRuntimeDependencySetName"
+          },
+          "runtimeDependencySetType": {
+            "$ref": "#/definitions/installerRuntimeDependencySetType"
+          },
+          "scriptFile": {
+            "$ref": "#/definitions/installerScriptFile"
+          },
+          "backtrace": {
+            "$ref": "#/definitions/installerBacktrace"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "installersV2_4": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "component",
+          "type"
+        ],
+        "properties": {
+          "component": {
+            "$ref": "#/definitions/installerComponent"
+          },
+          "destination": {
+            "$ref": "#/definitions/installerDestination"
+          },
+          "paths": {
+            "$ref": "#/definitions/installerPaths"
+          },
+          "type": {
+            "$ref": "#/definitions/installerTypeV2_0"
+          },
+          "isExcludeFromAll": {
+            "$ref": "#/definitions/installerIsExcludeFromAll"
+          },
+          "isForAllComponents": {
+            "$ref": "#/definitions/installerIsForAllComponents"
+          },
+          "isOptional": {
+            "$ref": "#/definitions/installerIsOptional"
+          },
+          "targetId": {
+            "$ref": "#/definitions/installerTargetId"
+          },
+          "targetIndex": {
+            "$ref": "#/definitions/installerTargetIndex"
+          },
+          "targetIsImportLibrary": {
+            "$ref": "#/definitions/installerTargetIsImportLibrary"
+          },
+          "targetInstallNamelink": {
+            "$ref": "#/definitions/installerTargetInstallNamelink"
+          },
+          "exportName": {
+            "$ref": "#/definitions/installerExportName"
+          },
+          "exportTargets": {
+            "$ref": "#/definitions/installerExportTargets"
+          },
+          "runtimeDependencySetName": {
+            "$ref": "#/definitions/installerRuntimeDependencySetName"
+          },
+          "runtimeDependencySetType": {
+            "$ref": "#/definitions/installerRuntimeDependencySetType"
+          },
+          "scriptFile": {
+            "$ref": "#/definitions/installerScriptFile"
+          },
+          "backtrace": {
+            "$ref": "#/definitions/installerBacktrace"
+          },
+          "fileSetName": {
+            "$ref": "#/definitions/installerFileSetNameV2_4"
+          },
+          "fileSetType": {
+            "$ref": "#/definitions/installerFileSetTypeV2_4"
+          },
+          "fileSetDirectories": {
+            "$ref": "#/definitions/installerFileSetDirectoriesV2_4"
+          },
+          "fileSetTarget": {
+            "$ref": "#/definitions/installerFileSetTargetV2_4"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "installersV2_5": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "component",
+          "type"
+        ],
+        "properties": {
+          "component": {
+            "$ref": "#/definitions/installerComponent"
+          },
+          "destination": {
+            "$ref": "#/definitions/installerDestination"
+          },
+          "paths": {
+            "$ref": "#/definitions/installerPaths"
+          },
+          "type": {
+            "$ref": "#/definitions/installerTypeV2_5"
+          },
+          "isExcludeFromAll": {
+            "$ref": "#/definitions/installerIsExcludeFromAll"
+          },
+          "isForAllComponents": {
+            "$ref": "#/definitions/installerIsForAllComponents"
+          },
+          "isOptional": {
+            "$ref": "#/definitions/installerIsOptional"
+          },
+          "targetId": {
+            "$ref": "#/definitions/installerTargetId"
+          },
+          "targetIndex": {
+            "$ref": "#/definitions/installerTargetIndex"
+          },
+          "targetIsImportLibrary": {
+            "$ref": "#/definitions/installerTargetIsImportLibrary"
+          },
+          "targetInstallNamelink": {
+            "$ref": "#/definitions/installerTargetInstallNamelink"
+          },
+          "exportName": {
+            "$ref": "#/definitions/installerExportName"
+          },
+          "exportTargets": {
+            "$ref": "#/definitions/installerExportTargets"
+          },
+          "runtimeDependencySetName": {
+            "$ref": "#/definitions/installerRuntimeDependencySetName"
+          },
+          "runtimeDependencySetType": {
+            "$ref": "#/definitions/installerRuntimeDependencySetType"
+          },
+          "scriptFile": {
+            "$ref": "#/definitions/installerScriptFile"
+          },
+          "backtrace": {
+            "$ref": "#/definitions/installerBacktrace"
+          },
+          "fileSetName": {
+            "$ref": "#/definitions/installerFileSetNameV2_4"
+          },
+          "fileSetType": {
+            "$ref": "#/definitions/installerFileSetTypeV2_4"
+          },
+          "fileSetDirectories": {
+            "$ref": "#/definitions/installerFileSetDirectoriesV2_4"
+          },
+          "fileSetTarget": {
+            "$ref": "#/definitions/installerFileSetTargetV2_4"
+          },
+          "cxxModuleBmiTarget": {
+            "$ref": "#/definitions/installerCxxModuleBmiTargetV2_5"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "codemodelV2_0": {
+      "required": [
+        "backtraceGraph",
+        "paths",
+        "installers"
+      ],
+      "properties": {
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "installers": {
+          "$ref": "#/definitions/installersV2_0"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_4": {
+      "required": [
+        "backtraceGraph",
+        "paths",
+        "installers"
+      ],
+      "properties": {
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "installers": {
+          "$ref": "#/definitions/installersV2_4"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_5": {
+      "required": [
+        "backtraceGraph",
+        "paths",
+        "installers"
+      ],
+      "properties": {
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "installers": {
+          "$ref": "#/definitions/installersV2_5"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_9": {
+      "required": [
+        "codemodelVersion",
+        "backtraceGraph",
+        "paths",
+        "installers"
+      ],
+      "properties": {
+        "codemodelVersion": {
+          "$ref": "#/definitions/codemodelVersionV2_9"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "installers": {
+          "$ref": "#/definitions/installersV2_5"
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_index.json b/Help/manual/file_api/schema_index.json
new file mode 100644
index 0000000..a49ba1a
--- /dev/null
+++ b/Help/manual/file_api/schema_index.json
@@ -0,0 +1,248 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "type": "object",
+  "required": [
+    "cmake",
+    "objects",
+    "reply"
+  ],
+  "properties": {
+    "cmake": {
+      "type": "object",
+      "description": "High level details about CMake itself and the CMake generator used",
+      "required": [
+        "version",
+        "paths",
+        "generator"
+      ],
+      "properties": {
+        "version": {
+          "description": "Full version details of the CMake used to produce the replies",
+          "type": "object",
+          "required": [
+            "major",
+            "minor",
+            "patch",
+            "string",
+            "isDirty"
+          ],
+          "properties": {
+            "major": {
+              "type": "integer",
+              "minimum": 3
+            },
+            "minor": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "patch": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "suffix": {
+              "type": "string",
+              "description": "A version suffix may be present when CMake is built from sources, or for release candidates. Official releases do not normally have a suffix."
+            },
+            "string": {
+              "type": "string",
+              "description": "The full version string in the format <major>.<minor>.<patch>[-<suffix>]"
+            },
+            "isDirty": {
+              "type": "boolean",
+              "description": "When this is true, it indicates CMake was built from a version-controlled source tree with local modifications"
+            }
+          },
+          "additionalProperties": false
+        },
+        "paths": {
+          "description": "Absolute paths to tools and locations within the CMake installation",
+          "type": "object",
+          "required": [
+            "cmake",
+            "ctest",
+            "cpack",
+            "root"
+          ],
+          "properties": {
+            "cmake": {
+              "description": "Absolute path to the cmake executable",
+              "type": "string"
+            },
+            "ctest": {
+              "description": "Absolute path to the ctest executable",
+              "type": "string"
+            },
+            "cpack": {
+              "description": "Absolute path to the cpack executable",
+              "type": "string"
+            },
+            "root": {
+              "description": "Absolute path to the directory containing CMake resources like the Modules directory",
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        },
+        "generator": {
+          "description": "Details for the CMake generator used",
+          "type": "object",
+          "required": [
+            "multiConfig",
+            "name"
+          ],
+          "properties": {
+            "multiConfig": {
+              "description": "True for multi-configuration generators, false for single-configuration generators",
+              "type": "boolean"
+            },
+            "name": {
+              "type": "string"
+            },
+            "platform": {
+              "description": "This string will only be set if the generator supports the CMAKE_GENERATOR_PLATFORM variable, which specifies the generator platform name",
+              "type": "string"
+            }
+          },
+          "additionalProperties": false
+        }
+      }
+    },
+    "objects": {
+      "type": "array",
+      "items": {
+        "$ref": "#/definitions/kindJsonFile"
+      }
+    },
+    "reply": {
+      "type": "object",
+      "patternProperties": {
+        "^[^-]+-v\\d+$": {
+          "description": "A member of this form appears for each of the shared stateless query files that CMake recognized as a request for the specified object kind and major version",
+          "oneOf": [
+            {
+              "$ref": "#/definitions/kindJsonFile"
+            },
+            {
+              "description": "A member of this form appears if the query's object kind is not recognized or is malformed",
+              "$ref": "#/definitions/replyError"
+            }
+          ]
+        },
+        "^client-[^/]+$": {
+          "description": "A member of this form appears for each client-owned directory holding client stateless query files. The value is a JSON object mirroring the content of the query/client-<client>/ directory.",
+          "patternProperties": {
+            "^[^-]+-v\\d+$": {
+              "description": "A member of this form appears for each of the client stateless query files that CMake recognized as a request for the specified object kind and major version",
+              "oneOf": [
+                {
+                  "$ref": "#/definitions/kindJsonFile"
+                },
+                {
+                  "description": "A member of this form appears if the client query's object kind is not recognized or is malformed",
+                  "$ref": "#/definitions/replyError"
+                }
+              ]
+            },
+            "^query\\.json$": {
+              "description": "This member appears for clients using client stateful query files",
+              "oneOf": [
+                {
+                  "type": "object",
+                  "properties": {
+                    "client": {
+                      "type": "object"
+                    },
+                    "requests": {},
+                    "responses": {
+                      "oneOf": [
+                        {
+                          "$ref": "#/definitions/replyError"
+                        },
+                        {
+                          "type": "array",
+                          "items": {
+                            "oneOf": [
+                              {
+                                "$ref": "#/definitions/kindJsonFile"
+                              },
+                              {
+                                "$ref": "#/definitions/replyError"
+                              }
+                            ]
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  "additionalProperties": false
+                },
+                {
+                  "description": "A member of this form appears if the query.json file failed to read or parse as a JSON object",
+                  "$ref": "#/definitions/replyError"
+                }
+              ]
+            }
+          },
+          "additionalProperties": {
+            "description": "A member of this form appears for each of the client stateless query files that CMake did not recognize.",
+            "$ref": "#/definitions/replyError"
+          }
+        }
+      },
+      "additionalProperties": {
+        "description": "A member of this form appears for each of the shared stateless query files that CMake did not recognize.",
+        "$ref": "#/definitions/replyError"
+      }
+    }
+  },
+  "definitions": {
+    "kindJsonFile": {
+      "type": "object",
+      "required": [
+        "kind",
+        "version",
+        "jsonFile"
+      ],
+      "properties": {
+        "kind": {
+          "type": "string"
+        },
+        "version": {
+          "type": "object",
+          "required": [
+            "major",
+            "minor"
+          ],
+          "properties": {
+            "major": {
+              "type": "integer",
+              "minimum": 1
+            },
+            "minor": {
+              "type": "integer",
+              "minimum": 0
+            }
+          },
+          "additionalProperties": false
+        },
+        "jsonFile": {
+          "type": "string",
+          "description": "Specifies a path relative to the reply index file to another JSON file containing the object"
+        }
+      },
+      "additionalProperties": false
+    },
+    "replyError": {
+      "type": "object",
+      "required": [
+        "error"
+      ],
+      "properties": {
+        "error": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_stateful_query.json b/Help/manual/file_api/schema_stateful_query.json
new file mode 100644
index 0000000..fc3c251
--- /dev/null
+++ b/Help/manual/file_api/schema_stateful_query.json
@@ -0,0 +1,84 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for CMake file API query.json files",
+  "type": "object",
+  "required": [
+    "requests"
+  ],
+  "properties": {
+    "requests": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "kind",
+          "version"
+        ],
+        "properties": {
+          "kind": {
+            "type": "string",
+            "description": "Specifies one of the Object Kinds to be included in the reply"
+          },
+          "version": {
+            "description": "Version(s) of the object kind that the client understands",
+            "oneOf": [
+              {
+                "$ref": "#/definitions/versionMajorOnly"
+              },
+              {
+                "$ref": "#/definitions/versionObject"
+              },
+              {
+                "type": "array",
+                "items": {
+                  "oneOf": [
+                    {
+                      "$ref": "#/definitions/versionMajorOnly"
+                    },
+                    {
+                      "$ref": "#/definitions/versionObject"
+                    }
+                  ]
+                }
+              }
+            ]
+          },
+          "client": {
+            "description": "Optional member reserved for use by the client. This value is preserved in the reply."
+          }
+        }
+      }
+    },
+    "client": {
+      "description": "Optional member reserved for use by the client. This value is preserved in the reply."
+    }
+  },
+  "$comment": "Other top level properties are reserved for future use. If present, they are ignored for forward compatibility.",
+  "additionalProperties": true,
+  "definitions": {
+    "versionMajorOnly": {
+      "type": "integer",
+      "description": "A non-negative major version number",
+      "minimum": 0
+    },
+    "versionObject": {
+      "type": "object",
+      "required": [
+        "major"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "description": "The major version number",
+          "minimum": 0
+        },
+        "minor": {
+          "type": "integer",
+          "description": "The minor version number",
+          "minimum": 0
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_target.json b/Help/manual/file_api/schema_target.json
new file mode 100644
index 0000000..909c49f
--- /dev/null
+++ b/Help/manual/file_api/schema_target.json
@@ -0,0 +1,1579 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake codemodel target object",
+  "type": "object",
+  "oneOf": [
+    {
+      "$comment": "The top level codemodelVersion field was only added in version 2.9, so we can't differentiate between earlier versions",
+      "anyOf": [
+        {
+          "$ref": "#/definitions/codemodelV2_0"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_1"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_2"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_5"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_6"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_7"
+        },
+        {
+          "$ref": "#/definitions/codemodelV2_8"
+        }
+      ]
+    },
+    {
+      "$ref": "#/definitions/codemodelV2_9"
+    }
+  ],
+  "definitions": {
+    "codemodelVersionV2_9": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 2
+        },
+        "minor": {
+          "type": "integer",
+          "minimum": 9
+        }
+      },
+      "additionalProperties": false
+    },
+    "name": {
+      "type": "string",
+      "description": "Logical name of the target"
+    },
+    "id": {
+      "type": "string",
+      "description": "Unique identifier for the target. The format is unspecified and should not be interpreted by clients."
+    },
+    "typeV2_0": {
+      "type": "string",
+      "enum": [
+        "EXECUTABLE",
+        "STATIC_LIBRARY",
+        "SHARED_LIBRARY",
+        "MODULE_LIBRARY",
+        "OBJECT_LIBRARY",
+        "INTERFACE_LIBRARY",
+        "UTILITY"
+      ]
+    },
+    "typeV2_9": {
+      "type": "string",
+      "enum": [
+        "EXECUTABLE",
+        "STATIC_LIBRARY",
+        "SHARED_LIBRARY",
+        "MODULE_LIBRARY",
+        "OBJECT_LIBRARY",
+        "INTERFACE_LIBRARY",
+        "UNKNOWN_LIBRARY",
+        "UTILITY"
+      ]
+    },
+    "importedV2_9": {
+      "type": "boolean",
+      "description": "True if the target is imported"
+    },
+    "localV2_9": {
+      "type": "boolean",
+      "description": "True if the target is defined in a local scope rather than being a global target"
+    },
+    "symbolicV2_9": {
+      "type": "boolean",
+      "description": "True if an interface target has the SYMBOLIC property set"
+    },
+    "abstractV2_9": {
+      "type": "boolean",
+      "description": "True if the target is not part of the build system"
+    },
+    "backtrace": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index into backtraceGraph nodes array"
+    },
+    "folder": {
+      "type": "object",
+      "description": "This will only be present if the FOLDER target property is set",
+      "required": [
+        "name"
+      ],
+      "properties": {
+        "name": {
+          "type": "string",
+          "description": "Name of the folder to place the target under in IDEs and other GUI tools"
+        }
+      },
+      "additionalProperties": false
+    },
+    "paths": {
+      "type": "object",
+      "required": [
+        "source",
+        "build"
+      ],
+      "properties": {
+        "source": {
+          "type": "string",
+          "description": "Path to the source directory. If it is inside the top level source directory, the path will be relative to that directory. For the top level source directory, this will simply be '.'. Paths outside the top level source directory will be absolute."
+        },
+        "build": {
+          "type": "string",
+          "description": "Path to the build directory. If it is inside the top level build directory, the path will be relative to that directory. For the top level build directory, this will simply be '.'. Paths outside the top level build directory will be absolute."
+        }
+      },
+      "additionalProperties": false
+    },
+    "nameOnDisk": {
+      "type": "string",
+      "description": "File name of the primary artifact on disk, only present for executable and library targets that are linked or archived into a single primary artifact"
+    },
+    "artifacts": {
+      "type": "array",
+      "description": "Only present for executable and library targets that produce artifacts on disk meant for consumption by dependents",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "type": "string",
+            "description": "Path to artifact file on disk. If the file is inside the top-level build directory, the path is specified relative to that directory. Otherwise, the path is absolute."
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "isGeneratorProvided": {
+      "type": "boolean",
+      "description": "Only present and will have the value true if the target is provided by CMake's build system generator rather than by a command in the project's source code"
+    },
+    "install": {
+      "type": "object",
+      "description": "Only present if the target has an install() rule",
+      "required": [
+        "prefix",
+        "destinations"
+      ],
+      "properties": {
+        "prefix": {
+          "type": "object",
+          "required": [
+            "path"
+          ],
+          "properties": {
+            "path": {
+              "type": "string",
+              "description": "The value of CMAKE_INSTALL_PREFIX"
+            }
+          },
+          "additionalProperties": false
+        },
+        "destinations": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "required": [
+              "path"
+            ],
+            "properties": {
+              "path": {
+                "type": "string",
+                "description": "Install destination path. It may be absolute or relative to the install prefix."
+              },
+              "backtrace": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "Index into the backtraceGraph nodes array, if a backtrace is available"
+              }
+            },
+            "additionalProperties": false
+          }
+        }
+      },
+      "additionalProperties": false
+    },
+    "launchersV2_7": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "command",
+          "type"
+        ],
+        "properties": {
+          "command": {
+            "type": "string",
+            "description": "Path to the launcher on disk. If the file is inside the top-level source directory, the path is specified relative to that directory."
+          },
+          "arguments": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "Arguments preceding the executable"
+          },
+          "type": {
+            "type": "string",
+            "enum": [
+              "emulator",
+              "test"
+            ],
+            "description": "Type of launcher"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "link": {
+      "type": "object",
+      "description": "This is only present for executables and shared library targets that link into a runtime binary",
+      "required": [
+        "language"
+      ],
+      "properties": {
+        "language": {
+          "type": "string",
+          "description": "Language of the toolchain used to invoke the linker"
+        },
+        "commandFragments": {
+          "type": "array",
+          "description": "Ordered fragments of the link command line, if available",
+          "items": {
+            "type": "object",
+            "required": [
+              "fragment",
+              "role"
+            ],
+            "properties": {
+              "fragment": {
+                "type": "string",
+                "description": "Fragment of link command line"
+              },
+              "role": {
+                "type": "string",
+                "enum": [
+                  "flags",
+                  "libraries",
+                  "libraryPath",
+                  "frameworkPath"
+                ],
+                "description": "Role of the fragment content"
+              },
+              "backtrace": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "Index into backtraceGraph nodes array for the command that added the link fragment, if available"
+              }
+            },
+            "additionalProperties": false
+          }
+        },
+        "lto": {
+          "type": "boolean",
+          "description": "True if link-time optimization is enabled"
+        },
+        "sysroot": {
+          "type": "object",
+          "description": "Only present when the CMAKE_SYSROOT_LINK or CMAKE_SYSROOT variable is defined",
+          "required": [
+            "path"
+          ],
+          "properties": {
+            "path": {
+              "type": "string",
+              "description": "Absolute path to the sysroot"
+            }
+          },
+          "additionalProperties": false
+        }
+      },
+      "additionalProperties": false
+    },
+    "archive": {
+      "type": "object",
+      "description": "Only present for static library targets",
+      "properties": {
+        "commandFragments": {
+          "type": "array",
+          "description": "Ordered fragments of the archiver command line, if available",
+          "items": {
+            "type": "object",
+            "required": [
+              "fragment",
+              "role"
+            ],
+            "properties": {
+              "fragment": {
+                "type": "string",
+                "description": "Fragment of the archiver command line"
+              },
+              "role": {
+                "type": "string",
+                "enum": [
+                  "flags"
+                ],
+                "description": "Role of the fragment content"
+              }
+            },
+            "additionalProperties": false
+          }
+        },
+        "lto": {
+          "type": "boolean",
+          "description": "True if link-time optimization is enabled"
+        }
+      },
+      "additionalProperties": false
+    },
+    "debuggerV2_8": {
+      "type": "object",
+      "properties": {
+        "workingDirectory": {
+          "type": "string",
+          "description": "Working directory for a debugger"
+        }
+      },
+      "additionalProperties": false
+    },
+    "dependencies": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "id"
+        ],
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of another target on which this one depends"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "linkLibrariesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of the target for the dependency"
+          },
+          "fragment": {
+            "type": "string",
+            "description": "Raw linker command line arguments that capture the dependency"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          },
+          "fromDependency": {
+            "type": "object",
+            "properties": {
+              "id": {
+                "type": "string",
+                "description": "Unique identifier of another target whose INTERFACE_LINK_LIBRARIES_DIRECT property created this dependency"
+              }
+            }
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "interfaceLinkLibrariesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of the target for the dependency"
+          },
+          "fragment": {
+            "type": "string",
+            "description": "Raw linker command line arguments that capture the dependency"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileDependenciesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "id"
+        ],
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of the target for the dependency"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          },
+          "fromDependency": {
+            "type": "object",
+            "properties": {
+              "id": {
+                "type": "string",
+                "description": "Unique identifier of another target whose INTERFACE_LINK_LIBRARIES_DIRECT property created this dependency"
+              }
+            }
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "interfaceCompileDependenciesV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "id"
+        ],
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of the target for the dependency"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "onlyTargetDependenciesArrayV2_9": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "string",
+            "description": "Unique identifier of the target for the dependency"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into backtraceGraph nodes array of the command that created the dependency, if available"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "fileSetsV2_5": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "type",
+          "visibility",
+          "baseDirectories"
+        ],
+        "properties": {
+          "name": {
+            "type": "string"
+          },
+          "type": {
+            "type": "string",
+            "enum": [
+              "HEADERS",
+              "CXX_MODULES"
+            ]
+          },
+          "visibility": {
+            "type": "string",
+            "enum": [
+              "PUBLIC",
+              "PRIVATE",
+              "INTERFACE"
+            ]
+          },
+          "baseDirectories": {
+            "type": "array",
+            "minItems": 1,
+            "items": {
+              "type": "string"
+            },
+            "description": "Base directories containing the file set's files. If a directory is inside the top level source directory, its path is specified relative to that directory. Otherwise, its path is absolute."
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "sourcesPath": {
+      "type": "string",
+      "description": "Path to the source file. If the file is inside the top level source directory, the path is specified relative to that directory. Otherwise, the path is absolute."
+    },
+    "sourcesCompileGroupIndex": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index into the compileGroups array. Only present if the file is compiled."
+    },
+    "sourcesSourceGroupIndex": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index into the sourceGroups array. Only present if the file is part of a source group."
+    },
+    "sourcesIsGenerated": {
+      "type": "boolean",
+      "description": "True if the file has its GENERATED property set to true"
+    },
+    "sourcesFileSetIndexV2_5": {
+      "type": "integer",
+      "minimum": 0,
+      "description": "Index into the fileSets array. Only present if the file is part of a file set."
+    },
+    "sourcesV2_0": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "$ref": "#/definitions/sourcesPath"
+          },
+          "compileGroupIndex": {
+            "$ref": "#/definitions/sourcesCompileGroupIndex"
+          },
+          "sourceGroupIndex": {
+            "$ref": "#/definitions/sourcesSourceGroupIndex"
+          },
+          "isGenerated": {
+            "$ref": "#/definitions/sourcesIsGenerated"
+          },
+          "backtrace": {
+            "$ref": "#/definitions/backtrace"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "sourcesV2_5": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "$ref": "#/definitions/sourcesPath"
+          },
+          "compileGroupIndex": {
+            "$ref": "#/definitions/sourcesCompileGroupIndex"
+          },
+          "sourceGroupIndex": {
+            "$ref": "#/definitions/sourcesSourceGroupIndex"
+          },
+          "isGenerated": {
+            "$ref": "#/definitions/sourcesIsGenerated"
+          },
+          "backtrace": {
+            "$ref": "#/definitions/backtrace"
+          },
+          "fileSetIndex": {
+            "$ref": "#/definitions/sourcesFileSetIndexV2_5"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "sourceGroups": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "name",
+          "sourceIndexes"
+        ],
+        "properties": {
+          "name": {
+            "type": "string",
+            "description": "Name of source group"
+          },
+          "sourceIndexes": {
+            "type": "array",
+            "items": {
+              "type": "integer",
+              "minimum": 0
+            },
+            "description": "Indices into sources array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsSourceIndexes": {
+      "type": "array",
+      "items": {
+        "type": "integer",
+        "minimum": 0
+      },
+      "description": "Indices into the sources array for sources belonging to the group"
+    },
+    "compileGroupsLanguage": {
+      "type": "string",
+      "description": "Language used to compile sources in the group"
+    },
+    "compileGroupsLanguageStandardV2_2": {
+      "type": "object",
+      "required": [
+        "backtraces",
+        "standard"
+      ],
+      "properties": {
+        "backtraces": {
+          "type": "array",
+          "items": {
+            "type": "integer",
+            "minimum": 0
+          },
+          "description": "Indices into the backtraceGraph nodes array"
+        },
+        "standard": {
+          "type": "string",
+          "description": "Language standard"
+        }
+      },
+      "additionalProperties": false
+    },
+    "compileGroupsCompileCommandFragments": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "fragment"
+        ],
+        "properties": {
+          "fragment": {
+            "type": "string",
+            "description": "Fragment of the compile command line"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into the backtraceGraph nodes array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsIncludes": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "type": "string",
+            "description": "Include directory path"
+          },
+          "isSystem": {
+            "type": "boolean",
+            "description": "True if the path is a system include directory"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into the backtraceGraph nodes array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsFrameworksV2_6": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "path"
+        ],
+        "properties": {
+          "path": {
+            "type": "string",
+            "description": "Framework directory path"
+          },
+          "isSystem": {
+            "type": "boolean",
+            "description": "True if the path is to a system framework directory"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into the backtraceGraph nodes array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsPrecompileHeadersV2_1": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "header"
+        ],
+        "properties": {
+          "header": {
+            "type": "string",
+            "description": "Path to the precompile header file"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into the backtraceGraph nodes array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsDefines": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "define"
+        ],
+        "properties": {
+          "define": {
+            "type": "string",
+            "description": "Preprocessor definition in name or name=value format"
+          },
+          "backtrace": {
+            "type": "integer",
+            "minimum": 0,
+            "description": "Index into the backtraceGraph nodes array"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsSysroot": {
+      "type": "object",
+      "required": [
+        "path"
+      ],
+      "properties": {
+        "path": {
+          "type": "string",
+          "description": "Absolute path to the sysroot"
+        }
+      },
+      "additionalProperties": false
+    },
+    "compileGroupsV2_0": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "sourceIndexes",
+          "language"
+        ],
+        "properties": {
+          "sourceIndexes": {
+            "$ref": "#/definitions/compileGroupsSourceIndexes"
+          },
+          "language": {
+            "$ref": "#/definitions/compileGroupsLanguage"
+          },
+          "compileCommandFragments": {
+            "$ref": "#/definitions/compileGroupsCompileCommandFragments"
+          },
+          "includes": {
+            "$ref": "#/definitions/compileGroupsIncludes"
+          },
+          "defines": {
+            "$ref": "#/definitions/compileGroupsDefines"
+          },
+          "sysroot": {
+            "$ref": "#/definitions/compileGroupsSysroot"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsV2_1": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "sourceIndexes",
+          "language"
+        ],
+        "properties": {
+          "sourceIndexes": {
+            "$ref": "#/definitions/compileGroupsSourceIndexes"
+          },
+          "language": {
+            "$ref": "#/definitions/compileGroupsLanguage"
+          },
+          "compileCommandFragments": {
+            "$ref": "#/definitions/compileGroupsCompileCommandFragments"
+          },
+          "includes": {
+            "$ref": "#/definitions/compileGroupsIncludes"
+          },
+          "precompileHeaders": {
+            "$ref": "#/definitions/compileGroupsPrecompileHeadersV2_1"
+          },
+          "defines": {
+            "$ref": "#/definitions/compileGroupsDefines"
+          },
+          "sysroot": {
+            "$ref": "#/definitions/compileGroupsSysroot"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsV2_2": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "sourceIndexes",
+          "language"
+        ],
+        "properties": {
+          "sourceIndexes": {
+            "$ref": "#/definitions/compileGroupsSourceIndexes"
+          },
+          "language": {
+            "$ref": "#/definitions/compileGroupsLanguage"
+          },
+          "languageStandard": {
+            "$ref": "#/definitions/compileGroupsLanguageStandardV2_2"
+          },
+          "compileCommandFragments": {
+            "$ref": "#/definitions/compileGroupsCompileCommandFragments"
+          },
+          "includes": {
+            "$ref": "#/definitions/compileGroupsIncludes"
+          },
+          "precompileHeaders": {
+            "$ref": "#/definitions/compileGroupsPrecompileHeadersV2_1"
+          },
+          "defines": {
+            "$ref": "#/definitions/compileGroupsDefines"
+          },
+          "sysroot": {
+            "$ref": "#/definitions/compileGroupsSysroot"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "compileGroupsV2_6": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "sourceIndexes",
+          "language"
+        ],
+        "properties": {
+          "sourceIndexes": {
+            "$ref": "#/definitions/compileGroupsSourceIndexes"
+          },
+          "language": {
+            "$ref": "#/definitions/compileGroupsLanguage"
+          },
+          "languageStandard": {
+            "$ref": "#/definitions/compileGroupsLanguageStandardV2_2"
+          },
+          "compileCommandFragments": {
+            "$ref": "#/definitions/compileGroupsCompileCommandFragments"
+          },
+          "includes": {
+            "$ref": "#/definitions/compileGroupsIncludes"
+          },
+          "frameworks": {
+            "$ref": "#/definitions/compileGroupsFrameworksV2_6"
+          },
+          "precompileHeaders": {
+            "$ref": "#/definitions/compileGroupsPrecompileHeadersV2_1"
+          },
+          "defines": {
+            "$ref": "#/definitions/compileGroupsDefines"
+          },
+          "sysroot": {
+            "$ref": "#/definitions/compileGroupsSysroot"
+          }
+        },
+        "additionalProperties": false
+      }
+    },
+    "backtraceGraph": {
+      "type": "object",
+      "required": [
+        "nodes",
+        "commands",
+        "files"
+      ],
+      "properties": {
+        "nodes": {
+          "type": "array",
+          "items": {
+            "type": "object",
+            "required": [
+              "file"
+            ],
+            "properties": {
+              "file": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "0-based index into the backtrace files array"
+              },
+              "line": {
+                "type": "integer",
+                "minimum": 1,
+                "description": "This is present when the node represents a line within the file. The line number is a 1-based value."
+              },
+              "command": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "This is present when the node represents a command invocation. It is a 0-based index into the backtrace commands array."
+              },
+              "parent": {
+                "type": "integer",
+                "minimum": 0,
+                "description": "This is present when the node is not the bottom of the call stack. It is a 0-based index of another node in the backtrace nodes array."
+              }
+            },
+            "additionalProperties": false
+          }
+        },
+        "commands": {
+          "type": "array",
+          "description": "Each list item is a string specifying a command name",
+          "items": {
+            "type": "string"
+          }
+        },
+        "files": {
+          "type": "array",
+          "description": "Each list item is a string specifying the path to a file, represented with forward slashes. If the file is inside the top level source directory, the path is specified relative to that directory. Otherwise, the path is absolute.",
+          "items": {
+            "type": "string"
+          }
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_0": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_0"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_0"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_1": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_0"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_1"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_2": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_0"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_2"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_5": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "fileSets": {
+          "$ref": "#/definitions/fileSetsV2_5"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_5"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_2"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_6": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "fileSets": {
+          "$ref": "#/definitions/fileSetsV2_5"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_5"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_6"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_7": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "launchers": {
+          "$ref": "#/definitions/launchersV2_7"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "fileSets": {
+          "$ref": "#/definitions/fileSetsV2_5"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_5"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_6"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_8": {
+      "required": [
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_0"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "launchers": {
+          "$ref": "#/definitions/launchersV2_7"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "debugger": {
+          "$ref": "#/definitions/debuggerV2_8"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "fileSets": {
+          "$ref": "#/definitions/fileSetsV2_5"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_5"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_6"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    },
+    "codemodelV2_9": {
+      "required": [
+        "codemodelVersion",
+        "name",
+        "id",
+        "type",
+        "paths",
+        "sources",
+        "backtraceGraph"
+      ],
+      "properties": {
+        "codemodelVersion": {
+          "$ref": "#/definitions/codemodelVersionV2_9"
+        },
+        "name": {
+          "$ref": "#/definitions/name"
+        },
+        "id": {
+          "$ref": "#/definitions/id"
+        },
+        "type": {
+          "$ref": "#/definitions/typeV2_9"
+        },
+        "imported": {
+          "$ref": "#/definitions/importedV2_9"
+        },
+        "local": {
+          "$ref": "#/definitions/localV2_9"
+        },
+        "abstract": {
+          "$ref": "#/definitions/abstractV2_9"
+        },
+        "backtrace": {
+          "$ref": "#/definitions/backtrace"
+        },
+        "folder": {
+          "$ref": "#/definitions/folder"
+        },
+        "paths": {
+          "$ref": "#/definitions/paths"
+        },
+        "nameOnDisk": {
+          "$ref": "#/definitions/nameOnDisk"
+        },
+        "artifacts": {
+          "$ref": "#/definitions/artifacts"
+        },
+        "isGeneratorProvided": {
+          "$ref": "#/definitions/isGeneratorProvided"
+        },
+        "install": {
+          "$ref": "#/definitions/install"
+        },
+        "launchers": {
+          "$ref": "#/definitions/launchersV2_7"
+        },
+        "link": {
+          "$ref": "#/definitions/link"
+        },
+        "archive": {
+          "$ref": "#/definitions/archive"
+        },
+        "debugger": {
+          "$ref": "#/definitions/debuggerV2_8"
+        },
+        "dependencies": {
+          "$ref": "#/definitions/dependencies"
+        },
+        "linkLibraries": {
+          "$ref": "#/definitions/linkLibrariesV2_9"
+        },
+        "interfaceLinkLibraries": {
+          "$ref": "#/definitions/interfaceLinkLibrariesV2_9"
+        },
+        "compileDependencies": {
+          "$ref": "#/definitions/compileDependenciesV2_9"
+        },
+        "interfaceCompileDependencies": {
+          "$ref": "#/definitions/interfaceCompileDependenciesV2_9"
+        },
+        "objectDependencies": {
+          "$ref": "#/definitions/onlyTargetDependenciesArrayV2_9"
+        },
+        "orderDependencies": {
+          "$ref": "#/definitions/onlyTargetDependenciesArrayV2_9"
+        },
+        "fileSets": {
+          "$ref": "#/definitions/fileSetsV2_5"
+        },
+        "sources": {
+          "$ref": "#/definitions/sourcesV2_5"
+        },
+        "symbolic": {
+          "$ref": "#/definitions/symbolicV2_9"
+        },
+        "sourceGroups": {
+          "$ref": "#/definitions/sourceGroups"
+        },
+        "compileGroups": {
+          "$ref": "#/definitions/compileGroupsV2_6"
+        },
+        "backtraceGraph": {
+          "$ref": "#/definitions/backtraceGraph"
+        }
+      },
+      "additionalProperties": false
+    }
+  }
+}
diff --git a/Help/manual/file_api/schema_toolchains.json b/Help/manual/file_api/schema_toolchains.json
new file mode 100644
index 0000000..8ac4f29
--- /dev/null
+++ b/Help/manual/file_api/schema_toolchains.json
@@ -0,0 +1,117 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "description": "Schema for the CMake toolchains object kind",
+  "type": "object",
+  "required": [
+    "kind",
+    "version",
+    "toolchains"
+  ],
+  "properties": {
+    "kind": {
+      "type": "string",
+      "const": "toolchains",
+      "description": "Specifies the object kind"
+    },
+    "version": {
+      "type": "object",
+      "required": [
+        "major",
+        "minor"
+      ],
+      "properties": {
+        "major": {
+          "type": "integer",
+          "const": 1
+        },
+        "minor": {
+          "type": "integer",
+          "const": 0
+        }
+      },
+      "additionalProperties": false
+    },
+    "toolchains": {
+      "type": "array",
+      "description": "Array of toolchain configurations per language",
+      "items": {
+        "type": "object",
+        "required": [
+          "language",
+          "compiler"
+        ],
+        "properties": {
+          "language": {
+            "type": "string",
+            "description": "Toolchain language identifier (e.g. C, CXX)"
+          },
+          "compiler": {
+            "type": "object",
+            "properties": {
+              "path": {
+                "type": "string",
+                "description": "Path to the compiler executable. This is present when the CMAKE_<LANG>_COMPILER variable is defined."
+              },
+              "id": {
+                "type": "string",
+                "description": "Compiler identifier (e.g. GNU, MSVC). This is present when the CMAKE_<LANG>_COMPILER_ID variable is defined."
+              },
+              "version": {
+                "type": "string",
+                "description": "Version of the compiler. This is present when the CMAKE_<LANG>_COMPILER_VERSION variable is defined."
+              },
+              "target": {
+                "type": "string",
+                "description": "Cross-compiling target of the compiler. This is present when the CMAKE_<LANG>_COMPILER_TARGET variable is defined."
+              },
+              "implicit": {
+                "type": "object",
+                "properties": {
+                  "includeDirectories": {
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    },
+                    "description": "List of implicit include directories for the compiler. This is present when the CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES variable is defined."
+                  },
+                  "linkDirectories": {
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    },
+                    "description": "List of implicit link directories for the compiler front end. This is present when the CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES variable is defined."
+                  },
+                  "linkFrameworkDirectories": {
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    },
+                    "description": "List of implicit link framework directories for the compiler front end. This is present when the CMAKE_<LANG>_IMPLICIT_FRAMEWORK_DIRECTORIES variable is defined."
+                  },
+                  "linkLibraries": {
+                    "type": "array",
+                    "items": {
+                      "type": "string"
+                    },
+                    "description": "List of implicit link libraries for the compiler front end. This is present when the CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES variable is defined."
+                  }
+                },
+                "additionalProperties": false
+              }
+            },
+            "additionalProperties": false
+          },
+          "sourceFileExtensions": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            },
+            "description": "List of source file extensions (without leading dot) supported by this toolchain"
+          }
+        },
+        "additionalProperties": false
+      }
+    }
+  },
+  "additionalProperties": false
+}
diff --git a/Help/policy/CMP0183.rst b/Help/policy/CMP0183.rst
index 6804c3b..f2d6601 100644
--- a/Help/policy/CMP0183.rst
+++ b/Help/policy/CMP0183.rst
@@ -5,7 +5,7 @@
 
 :command:`add_feature_info` supports full :ref:`Condition Syntax`.
 
-The ``<enabled>`` parameter accepts a :ref:`semicolon-separated list <CMake
+The ``<condition>`` parameter accepts a :ref:`semicolon-separated list <CMake
 Language Lists>` of conditions.  CMake 3.31 and lower evaluate each
 ``condition`` as ``if(${condition})``, which does not properly handle
 conditions with nested paren groups.  CMake 4.0 and above instead prefer
diff --git a/Help/policy/CMP0198.rst b/Help/policy/CMP0198.rst
new file mode 100644
index 0000000..4e32e1c
--- /dev/null
+++ b/Help/policy/CMP0198.rst
@@ -0,0 +1,23 @@
+CMP0198
+-------
+
+.. versionadded:: 4.2
+
+:variable:`CMAKE_PARENT_LIST_FILE` is not defined in ``CMakeLists.txt``.
+
+CMake 4.1 and below defined ``CMAKE_PARENT_LIST_FILE`` when processing
+a ``CMakeLists.txt`` even though there is no parent file.  CMake 4.2
+and above prefer to not define ``CMAKE_PARENT_LIST_FILE``.  This policy
+provides compatibility for projects that accidentally relied on the
+old behavior.
+
+The ``OLD`` behavior for this policy is to set
+:variable:`CMAKE_PARENT_LIST_FILE` to :variable:`CMAKE_CURRENT_LIST_FILE`
+when processing a ``CMakeLists.txt``.  The ``NEW`` behavior for this policy
+is to not set :variable:`CMAKE_PARENT_LIST_FILE`.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0199.rst b/Help/policy/CMP0199.rst
new file mode 100644
index 0000000..b102845
--- /dev/null
+++ b/Help/policy/CMP0199.rst
@@ -0,0 +1,97 @@
+CMP0199
+-------
+
+.. versionadded:: 4.2
+
+:genex:`$<CONFIG:cfgs>` does not match mapped configurations that are not
+selected.
+
+Historically, when a :genex:`$<CONFIG:cfgs>` generator expression appeared in
+the properties of an imported target, it would match (that is, evaluate to
+``1``) if any of the ``cfgs`` matched *any* of the following:
+
+1. The selected configuration of the imported target being consumed.
+
+2. The configuration of the consuming target.
+
+3. *Any* of the configurations in the :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`
+   of the imported target being consumed
+   (where ``<CONFIG>`` is the configuration of the consuming target),
+   *whether or not such configurations are valid for the imported target*.
+
+This can result in expressions which are intended to be mutually exclusive
+being concurrently evaluated.  This can be especially problematic if the value
+of a compile definition is intended to be determined by the configuration, as
+this lack of exclusivity could result in redefinition.
+
+CMake 4.2 and above prefer to consider *only* the configuration of the
+consuming target and (when applicable) the selected configuration of the
+imported target; that is, (2) and (1) in the above list.  Unfortunately,
+because users rely on both of these, this policy is not able to fully prevent
+multiple unique ``$<CONFIG:cfg>`` expressions from matching concurrently.
+
+This policy provides compatibility with projects that rely on the historical
+behavior.  The ``OLD`` behavior for this policy is to retain the historic
+behavior as described above.  The ``NEW`` behavior is to consider only the
+configurations of the consuming and consumed targets.
+
+.. note::
+
+  This policy only applies to generator expressions being evaluated as part of
+  the usage requirements of imported targets which are not imported from |CPS|
+  packages.
+
+  For non-imported targets, both the historic and ongoing behavior is to
+  consider only the configuration of the consuming target.  (The selected
+  configuration of a non-imported target is always the active build
+  configuration, which is necessarily the same as the consuming target's
+  configuration.)
+
+  For targets imported from |CPS| packages, **only** the configuration of the
+  consumed imported target is considered, regardless of the policy setting.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
+
+Examples
+^^^^^^^^
+
+Consider the following imported libraries:
+
+.. code-block:: cmake
+
+  add_library(test1 INTERFACE IMPORTED)
+  set_target_properties(test1 PROPERTIES
+    IMPORTED_CONFIGURATIONS "DEBUG"
+    INTERFACE_COMPILE_DEFINITIONS
+      "$<$<CONFIG:debug>:DEBUG>;$<$<CONFIG:release>:RELEASE>"
+  )
+
+  add_library(test2 INTERFACE IMPORTED)
+  set_target_properties(test2 PROPERTIES
+    IMPORTED_CONFIGURATIONS "TEST"
+    INTERFACE_COMPILE_DEFINITIONS
+      "$<$<CONFIG:debug>:DEBUG>;$<$<CONFIG:example>:EXAMPLE>;$<$<CONFIG:test>:TEST>"
+    MAP_IMPORTED_CONFIG_RELEASE "DEBUG;EXAMPLE;TEST"
+  )
+
+Assume that the consuming project is built in the ``Release`` configuration.
+A consumer of ``test1`` will see both ``DEBUG`` and ``RELEASE`` defined,
+regardless of the policy setting; ``$<CONFIG:debug>`` evaluates to ``1``
+because the selected configuration of ``test1`` is ``DEBUG``, and
+``$<CONFIG:release>`` evaluates to ``1`` because the consumer's configuration
+is ``Release`` (keeping in mind that configuration matching is
+case-insensitive).
+
+Under the ``OLD`` policy, a consumer of ``test2`` would see all of ``DEBUG``,
+``EXAMPLE`` and ``TEST`` defined; ``$<CONFIG:debug>``, ``$<CONFIG:example>``
+and ``$<CONFIG:test>`` all evaluate to ``1`` because all of these
+configurations appear in ``MAP_IMPORTED_CONFIG_RELEASE``.
+
+Under the ``NEW`` policy, a consumer of ``test2`` will see only ``TEST``
+defined.
+
+.. |CPS| replace:: Common Package Specification
diff --git a/Help/policy/CMP0200.rst b/Help/policy/CMP0200.rst
new file mode 100644
index 0000000..cf2dbde
--- /dev/null
+++ b/Help/policy/CMP0200.rst
@@ -0,0 +1,117 @@
+CMP0200
+-------
+
+.. versionadded:: 4.2
+
+Location and configuration selection for imported targets is more consistent.
+
+The way CMake historically selected the configuration to use for imported
+targets prioritized selection based on location properties for a candidate
+configuration and only considered :prop_tgt:`IMPORTED_CONFIGURATIONS` as a
+fallback.  This could result in incorrect configuration selection especially
+for ``INTERFACE`` libraries.
+
+CMake 4.2 and above consider :prop_tgt:`IMPORTED_CONFIGURATIONS` to be a
+definitive list of available configurations, regardless of whether a
+configuration specific location is provided for the library.  Additionally,
+CMake will respect non-configuration-specific locations when a configuration
+specific location is not specified.
+
+This policy provides compatibility with projects that rely on the historical
+behavior.  The policy setting applies to targets and is recorded at the point
+an imported target is created.  Accordingly, imported packages may override the
+policy set by the consumer for targets they create.  In particular, targets
+imported from |CPS| packages always use the ``NEW`` behavior.
+
+The ``OLD`` behavior for this policy is to retain the historic behavior.
+The ``NEW`` behavior prioritizes selection based on the advertised list of
+available configurations.  Both behaviors are described in detail below.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: warns
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
+
+Mapped configuration selection
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` (where ``<CONFIG>`` is the
+configuration of the consuming target) is set on an imported target, CMake
+would historically select from that list the first configuration which provides
+a configuration-specific location.  If no such configuration exists, CMake
+would selects the consuming target's configuration, if the imported target is
+an ``INTERFACE`` library.  Otherwise, CMake considers the target as not having
+a suitable configuration.
+
+For ``INTERFACE`` libraries which do not provide a location, this results in
+CMake always selecting the consuming target's configuration and effectively
+ignoring :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>`.  This behavior is not
+consistent with configuration selection for imported targets which provide a
+location.
+
+Under the ``NEW`` behavior, CMake selects the first configuration from the
+mapping which appears in :prop_tgt:`IMPORTED_CONFIGURATIONS`.  If
+:prop_tgt:`IMPORTED_CONFIGURATIONS` is not set, CMake selects the first
+configuration from the mapping which is "usable".  For non-``INTERFACE``
+libraries, "usable" means that a location (either configuration-specific or
+configuration-agnostic) is available.  ``INTERFACE`` libraries are always
+considered "usable".
+
+If no match is found, CMake considers the target as not having a suitable
+configuration.
+
+Non-mapped configuration selection
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is *not* set, CMake would
+historically select the first configuration which provides a location out of
+the following:
+
+- The consuming target's configuration, or
+
+- The empty configuration, or
+
+- The list of configurations in :prop_tgt:`IMPORTED_CONFIGURATIONS`.
+
+As an implementation artifact, this results in CMake selecting the *last*
+configuration in :prop_tgt:`IMPORTED_CONFIGURATIONS` for ``INTERFACE``
+libraries which do not provide a location.  Again, this behavior is not
+consistent with configuration selection for imported targets which provide a
+location.
+
+Under the ``NEW`` behavior, if :prop_tgt:`IMPORTED_CONFIGURATIONS` is set,
+CMake will select the consuming target's configuration if present therein,
+otherwise CMake will select the first imported configuration.  If
+:prop_tgt:`IMPORTED_CONFIGURATIONS` is *not* set, CMake will select the
+consuming target's configuration if it is "usable" (as defined in the previous
+section); otherwise, CMake considers the target as not having a suitable
+configuration.
+
+Examples
+^^^^^^^^
+
+Consider the following imported library:
+
+.. code-block:: cmake
+
+  add_library(test INTERFACE IMPORTED)
+  set_target_properties(test PROPERTIES
+    IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
+    INTERFACE_COMPILE_DEFINITIONS "$<$<CONFIG:debug>:DEBUG>"
+  )
+
+Under the ``OLD`` policy, CMake will select the ``DEBUG`` configuration of
+``test`` (and thus define the symbol ``DEBUG``) for any target linking to
+``test``, because CMake does not consider any configuration "valid", and, as
+an implementation artifact, the last configuration considered is accepted.
+
+Under the ``NEW`` policy, the ``RELEASE`` configuration will be selected
+if the consuming project is built in any configuration other than ``Debug``
+(keeping in mind that configuration matching is case-insensitive).  This is
+because ``DEBUG`` will be preferred if the consumer's configuration is also
+``DEBUG``, but ``RELEASE`` will be preferred otherwise because it appears
+first in :prop_tgt:`IMPORTED_CONFIGURATIONS`, and its appearance therein makes
+it a "valid" configuration for an ``INTERFACE`` library.
+
+.. |CPS| replace:: Common Package Specification
diff --git a/Help/policy/CMP0201.rst b/Help/policy/CMP0201.rst
new file mode 100644
index 0000000..d2c5f21
--- /dev/null
+++ b/Help/policy/CMP0201.rst
@@ -0,0 +1,30 @@
+CMP0201
+-------
+
+.. versionadded:: 4.2
+
+``Python::NumPy`` does not depend on ``Python::Development.Module``.
+
+:module:`FindPython3`, :module:`FindPython2`, and :module:`FindPython` provide
+``Python{3,2,}::NumPy`` and ``Python{3,2,}::Development.Module`` targets when
+the corresponding components are requested.
+
+In CMake 4.1 and below, requesting the ``NumPy`` component implies the
+``Development.Module`` component, and the provided ``Python{3,2,}::NumPy``
+targets depend on the provided ``Python{3,2,}::Development.Module`` targets.
+This dependency is not necessary.
+In CMake 4.2 and above, requesting the ``NumPy`` component does not imply the
+``Development.Module`` component, and the provided ``Python{3,2,}::NumPy``
+targets do not depend on the provided ``Python{3,2,}::Development.Module``
+targets.
+This policy provides compatibility with projects that expect the legacy
+behavior.
+
+The ``OLD`` behavior for this policy makes ``NumPy`` depend on
+``Development.Module``.  The ``NEW`` behavior for this policy does not.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0202.rst b/Help/policy/CMP0202.rst
new file mode 100644
index 0000000..98c8b01
--- /dev/null
+++ b/Help/policy/CMP0202.rst
@@ -0,0 +1,30 @@
+CMP0202
+-------
+
+.. versionadded:: 4.2
+
+PDB file names always include their target's per-config POSTFIX.
+
+Program database files (``.pdb``) are always named with their target's
+:prop_tgt:`DEBUG_POSTFIX` or :prop_tgt:`<CONFIG>_POSTFIX` target property
+value.
+
+If the :prop_tgt:`PDB_NAME` target property is defined, CMake 4.1 and below
+exclude the target's per-config postfix from the program data base file name.
+Otherwise, the per-config postfix is included.  This is inconsistent.
+CMake 4.2 and above prefer to always name the program database file with the
+per-config postfix regardless how the name is computed, i.e., using
+:prop_tgt:`OUTPUT_NAME`, or :prop_tgt:`PDB_NAME`, or neither.  This policy
+provides compatibility with projects that have not been updated to account
+for the new behavior.
+
+The ``OLD`` behavior for this policy does not use the per-config postfix in
+``.pdb`` file names if the :prop_tgt:`PDB_NAME` target property is defined.
+The ``NEW`` behavior always uses the per-config postfix in ``.pdb`` file
+names.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0203.rst b/Help/policy/CMP0203.rst
new file mode 100644
index 0000000..c6927eb
--- /dev/null
+++ b/Help/policy/CMP0203.rst
@@ -0,0 +1,28 @@
+CMP0203
+-------
+
+.. versionadded:: 4.2
+
+``_WINDLL`` is defined for shared libraries targeting the MSVC ABI.
+
+In CMake 4.1 and below, :ref:`Visual Studio Generators` compile sources in
+shared libraries with ``_WINDLL`` defined due to behavior of Visual Studio
+itself.  The preprocessor definition is not modeled by CMake and is therefore
+not added by other generators, such as :generator:`Ninja`.
+
+CMake 4.2 and above, when targeting the MSVC ABI, prefer to compile sources
+in shared libraries with ``_WINDLL`` defined by all generators.
+This policy provides compatibility with projects that have not been updated
+to be aware of the definition.  Its setting is recorded by each target as
+it is created, and affects compilation of sources in that target.
+
+The ``OLD`` behavior for this policy does not model the ``_WINDLL``
+preprocessor definition in CMake itself.  The ``NEW`` behavior for this
+policy adds the ``_WINDLL`` preprocessor definition to sources in shared
+libraries when targeting the MSVC ABI.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/policy/CMP0204.rst b/Help/policy/CMP0204.rst
new file mode 100644
index 0000000..d22263a
--- /dev/null
+++ b/Help/policy/CMP0204.rst
@@ -0,0 +1,29 @@
+CMP0204
+-------
+
+.. versionadded:: 4.2
+
+A character set is always defined when targeting the MSVC ABI.
+
+In CMake 4.1 and below, :ref:`Visual Studio Generators` compile sources in with
+``_MBCS``, ``_UNICODE`` or ``_SBCS`` defined due to behavior of Visual Studio
+itself.  The preprocessor definition is not modeled by CMake and is therefore
+not added by other generators, such as :generator:`Ninja`.
+
+CMake 4.2 and above, when targeting the MSVC ABI, prefer to compile sources
+with ``_MBCS`` defined by all generators unless another charset preprocessor
+definition is found (``_UNICODE`` or ``_SBCS``).
+This policy provides compatibility with projects that have not been updated
+to be aware of the definition.  Its setting is recorded by each target as
+it is created, and affects compilation of sources in that target.
+
+The ``OLD`` behavior for this policy does not model the ``_MBCS``
+preprocessor definition in CMake itself.  The ``NEW`` behavior for this
+policy adds the ``_MBCS`` preprocessor definition to sources
+as a default encoding when targeting the MSVC ABI.
+
+.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 4.2
+.. |WARNS_OR_DOES_NOT_WARN| replace:: does *not* warn
+.. include:: include/STANDARD_ADVICE.rst
+
+.. include:: include/DEPRECATED.rst
diff --git a/Help/prop_gbl/INSTALL_PARALLEL.rst b/Help/prop_gbl/INSTALL_PARALLEL.rst
index 936b1ef..5c5c78a 100644
--- a/Help/prop_gbl/INSTALL_PARALLEL.rst
+++ b/Help/prop_gbl/INSTALL_PARALLEL.rst
@@ -23,5 +23,5 @@
 Calls to :command:`install(CODE)` or :command:`install(SCRIPT)` might depend
 on actions performed by an earlier :command:`install` command in a different
 directory such as files installed or variable settings. If the project has
-such order-dependent installation logic, parallel installation should be
+such order-dependent installation logic, parallel installation should
 not be enabled, in order to prevent possible race conditions.
diff --git a/Help/prop_gbl/JOB_POOLS.rst b/Help/prop_gbl/JOB_POOLS.rst
index 5dfe6de..7d39d8b 100644
--- a/Help/prop_gbl/JOB_POOLS.rst
+++ b/Help/prop_gbl/JOB_POOLS.rst
@@ -14,15 +14,21 @@
 
   set_property(GLOBAL PROPERTY JOB_POOLS two_jobs=2 ten_jobs=10)
 
-Defined pools could be used globally by setting
-:variable:`CMAKE_JOB_POOL_COMPILE` and :variable:`CMAKE_JOB_POOL_LINK`
-or per target by setting the target properties
-:prop_tgt:`JOB_POOL_COMPILE` and :prop_tgt:`JOB_POOL_LINK`.
-:command:`Custom commands <add_custom_command>` and
-:command:`custom targets <add_custom_target>` can specify pools using the
-option ``JOB_POOL``.
-Using a pool that is not defined by ``JOB_POOLS`` causes
-an error by ninja at build time.
+Defined pools can be used at different levels:
+
+* Globally, by setting :variable:`CMAKE_JOB_POOL_COMPILE` and
+  :variable:`CMAKE_JOB_POOL_LINK`.
+* Per target, by setting the target properties :prop_tgt:`JOB_POOL_COMPILE`
+  and :prop_tgt:`JOB_POOL_LINK`.
+* :command:`Custom commands <add_custom_command>` and
+  :command:`custom targets <add_custom_target>` can specify pools using the
+  option ``JOB_POOL``.
+* Per-source, by setting the source file property :prop_sf:`JOB_POOL_COMPILE`,
+  in case some specific source files require to override their global or
+  target assigned pool.
+
+Using a pool that is not defined by ``JOB_POOLS`` causes an error by ninja
+at build time.
 
 If not set, this property uses the value of the :variable:`CMAKE_JOB_POOLS`
 variable.
diff --git a/Help/prop_sf/INSTALL_OBJECT_NAME.rst b/Help/prop_sf/INSTALL_OBJECT_NAME.rst
new file mode 100644
index 0000000..34d1b6a
--- /dev/null
+++ b/Help/prop_sf/INSTALL_OBJECT_NAME.rst
@@ -0,0 +1,26 @@
+INSTALL_OBJECT_NAME
+-------------------
+
+.. versionadded:: 4.2
+
+Set the installed object name (without the object extension) of the source
+file. An empty string value disables custom object naming. The value must be a
+relative path, and may not include special directory components (e.g.,
+``..``).
+
+Note that the object name might not be used as-is in some
+:prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` strategies.  It may be changed as
+the strategy requires to fulfill its goals.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+.. note::
+   No collision resistance within a target is performed by CMake. When using
+   this property, collisions must be avoided in the project code. CMake has a
+   number of source files it generates that also create object files that may
+   collide with a given custom name. These include:
+
+   * Generated PCH source files (``cmake_pch``)
+   * Generated Unity compilation files (``unity_...``)
+   * Qt autogen sources (``moc_compilations.cpp``)
diff --git a/Help/prop_sf/JOB_POOL_COMPILE.rst b/Help/prop_sf/JOB_POOL_COMPILE.rst
new file mode 100644
index 0000000..79409da
--- /dev/null
+++ b/Help/prop_sf/JOB_POOL_COMPILE.rst
@@ -0,0 +1,21 @@
+JOB_POOL_COMPILE
+----------------
+
+.. versionadded:: 4.2
+
+Ninja only: Pool used for compiling.
+
+The number of parallel compile processes could be limited by defining
+pools with the global :prop_gbl:`JOB_POOLS`
+property and then specifying here the pool name.
+
+This allows to override the :prop_tgt:`JOB_POOL_COMPILE`
+value for specific source files within a same target.
+
+For instance:
+
+.. code-block:: cmake
+
+  set_property(SOURCE main.cc PROPERTY JOB_POOL_COMPILE two_jobs)
+
+This property is undefined by default.
diff --git a/Help/prop_sf/OBJECT_NAME.rst b/Help/prop_sf/OBJECT_NAME.rst
new file mode 100644
index 0000000..173e5ba
--- /dev/null
+++ b/Help/prop_sf/OBJECT_NAME.rst
@@ -0,0 +1,34 @@
+OBJECT_NAME
+-----------
+
+.. versionadded:: 4.2
+
+Set the object name (without the object extension) of the source file. An
+empty string value disables custom object naming. The value must be a relative
+path, and may not include special directory components (e.g., ``..``).
+
+Note that the object name might not be used as-is in
+:variable:`CMAKE_INTERMEDIATE_DIR_STRATEGY` and
+:prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` strategies.  It may be changed as
+the strategy requires to fulfill its goals.
+
+When installing objects, the :prop_sf:`INSTALL_OBJECT_NAME` property takes
+precedence.
+
+This property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`, but does not
+allow for context-sensitive (i.e., configuration-dependent) expressions.
+
+.. note::
+   No collision resistance within a target is performed by CMake. When using
+   this property, collisions must be avoided in the project code. CMake has a
+   number of source files it generates that also create object files that may
+   collide with a given custom name. These include:
+
+   * Generated PCH source files (``cmake_pch``)
+   * Generated Unity compilation files (``unity_...``)
+   * Qt autogen sources (``moc_compilations.cpp``)
+
+.. note::
+   The :generator:`FASTBuild` and :generator:`Xcode` generators do not support
+   this property and will ignore it.
diff --git a/Help/prop_sf/SKIP_LINTING.rst b/Help/prop_sf/SKIP_LINTING.rst
index fe0f2d4..f995cb4 100644
--- a/Help/prop_sf/SKIP_LINTING.rst
+++ b/Help/prop_sf/SKIP_LINTING.rst
@@ -41,3 +41,8 @@
 source files from the linting process. This allows you to focus the
 linting tools on the relevant parts of your project, enhancing the efficiency
 and effectiveness of the linting workflow.
+
+See Also
+^^^^^^^^
+
+* :prop_tgt:`SKIP_LINTING` target property
diff --git a/Help/prop_test/ENVIRONMENT_MODIFICATION.rst b/Help/prop_test/ENVIRONMENT_MODIFICATION.rst
index c6c1a82..cb9cfcd 100644
--- a/Help/prop_test/ENVIRONMENT_MODIFICATION.rst
+++ b/Help/prop_test/ENVIRONMENT_MODIFICATION.rst
@@ -13,26 +13,7 @@
 to be modified.  Entries are considered in the order specified in the
 property's value.  The ``OP`` may be one of:
 
-- ``reset``: Reset to the unmodified value, ignoring all modifications to
-  ``MYVAR`` prior to this entry. Note that this will reset the variable to
-  the value set by :prop_test:`ENVIRONMENT`, if it was set, and otherwise
-  to its state from the rest of the CTest execution.
-- ``set``: Replaces the current value of ``MYVAR`` with ``VALUE``.
-- ``unset``: Unsets the current value of ``MYVAR``.
-- ``string_append``: Appends singular ``VALUE`` to the current value of
-  ``MYVAR``.
-- ``string_prepend``: Prepends singular ``VALUE`` to the current value of
-  ``MYVAR``.
-- ``path_list_append``: Appends singular ``VALUE`` to the current value of
-  ``MYVAR`` using the host platform's path list separator (``;`` on Windows
-  and ``:`` elsewhere).
-- ``path_list_prepend``: Prepends singular ``VALUE`` to the current value of
-  ``MYVAR`` using the host platform's path list separator (``;`` on Windows
-  and ``:`` elsewhere).
-- ``cmake_list_append``: Appends singular ``VALUE`` to the current value of
-  ``MYVAR`` using ``;`` as the separator.
-- ``cmake_list_prepend``: Prepends singular ``VALUE`` to the current value of
-  ``MYVAR`` using ``;`` as the separator.
+ .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
 
 Unrecognized ``OP`` values will result in the test failing before it is
 executed. This is so that future operations may be added without changing
diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
index 33db8a7..4bf83eb 100644
--- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
@@ -4,29 +4,29 @@
 .. versionadded:: 3.14
 
 Switch for forwarding origin target dependencies to the corresponding
-:ref:`<ORIGIN>_autogen` target.
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 
   .. note::
 
     If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
     or :ref:`Makefile Generators`, origin target dependencies are forwarded to
-    the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of
-    :ref:`<ORIGIN>_autogen`
-
+    the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
+    target instead of :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`.
 
 Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
-``ON`` have a corresponding :ref:`<ORIGIN>_autogen` target which generates
-``moc`` and ``uic`` files.  As this :ref:`<ORIGIN>_autogen` target is created at
+``ON`` have a corresponding :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target
+which generates ``moc`` and ``uic`` files.
+As this :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target is created at
 generate-time, it is not possible to define dependencies of it using
 e.g.  :command:`add_dependencies`.  Instead the ``AUTOGEN_ORIGIN_DEPENDS``
 target property decides whether the origin target dependencies should be
-forwarded to the :ref:`<ORIGIN>_autogen` target or not.
+forwarded to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target or not.
 
 By default ``AUTOGEN_ORIGIN_DEPENDS`` is initialized from
 :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default.
 
-In total the dependencies of the :ref:`<ORIGIN>_autogen` target are composed
-from
+In total the dependencies of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+target are composed from
 
 - forwarded origin target dependencies
   (enabled by default via ``AUTOGEN_ORIGIN_DEPENDS``)
@@ -38,11 +38,12 @@
 .. note::
 
     Disabling ``AUTOGEN_ORIGIN_DEPENDS`` is useful to avoid building of
-    origin target dependencies when building the :ref:`<ORIGIN>_autogen` target
-    only. This is especially interesting when a
+    origin target dependencies when building the
+    :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target only.
+    This is especially interesting when a
     :variable:`global autogen target <CMAKE_GLOBAL_AUTOGEN_TARGET>` is enabled.
 
-    When the :ref:`<ORIGIN>_autogen` target doesn't require all the origin target's
-    dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is disabled, it might be
-    necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` to add missing
-    dependencies.
+    When the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target doesn't require
+    all the origin target's dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is
+    disabled, it might be necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS`
+    to add missing dependencies.
diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
index 9d34355..c1c86e8 100644
--- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst
+++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
@@ -6,9 +6,9 @@
 Number of parallel ``moc`` or ``uic`` processes to start when using
 :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
 
-The custom :ref:`<ORIGIN>_autogen` target starts a number of threads of which
-each one parses a source file and on demand starts a ``moc`` or ``uic``
-process. ``AUTOGEN_PARALLEL`` controls how many parallel threads
+The custom :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target starts a number
+of threads.  Each thread parses a source file and on demand starts a ``moc``
+or ``uic`` process. ``AUTOGEN_PARALLEL`` controls how many parallel threads
 (and therefore ``moc`` or ``uic`` processes) are started.
 
 - An empty (or unset) value or the string ``AUTO`` sets the number of
diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
index 13e2ef7..892dc5e 100644
--- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
+++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
@@ -1,28 +1,29 @@
 AUTOGEN_TARGET_DEPENDS
 ----------------------
 
-Additional target dependencies of the corresponding :ref:`<ORIGIN>_autogen`
-target.
+Additional target dependencies of the corresponding
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 
   .. note::
 
     If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
     or :ref:`Makefile Generators`, additional target dependencies are added to
-    the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the
-    :ref:`<ORIGIN>_autogen` target.
+    the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
+    target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 
 
 Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
-``ON`` have a corresponding :ref:`<ORIGIN>_autogen`  target which generates
-``moc`` and ``uic`` files.  As this :ref:`<ORIGIN>_autogen`  target is created
+``ON`` have a corresponding :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`  target
+which generates ``moc`` and ``uic`` files.
+As this :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target is created
 at generate-time, it is not possible to define dependencies of it using e.g.
 :command:`add_dependencies`.  Instead the ``AUTOGEN_TARGET_DEPENDS`` target
 property can be set to a :ref:`;-list <CMake Language Lists>` of additional
-dependencies for the :ref:`<ORIGIN>_autogen`  target. Dependencies can be target
-names or file names.
+dependencies for the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`  target.
+Dependencies can be target names or file names.
 
-In total the dependencies of the :ref:`<ORIGIN>_autogen`  target are composed
-from
+In total, the dependencies of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+target are composed from
 
 - forwarded origin target dependencies
   (enabled by default via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`)
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index 0bd4d13..25c5632 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -251,8 +251,8 @@
 
 :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`:
 A global ``autogen`` target, that depends on all ``AUTOMOC`` or
-:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project,
-will be generated when this variable is ``ON``.
+:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+targets in the project, will be generated when this variable is ``ON``.
 
 :prop_tgt:`AUTOGEN_PARALLEL`:
 This target property controls the number of ``moc`` or ``uic`` processes to
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
index fec98f6..50da7c0 100644
--- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -22,7 +22,7 @@
 
 If any of the extracted files is :prop_sf:`GENERATED` or if it is not in the
 target's sources, then it might be necessary to add it to the
-:ref:`<ORIGIN>_autogen` target  dependencies.
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target dependencies.
 See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference.
 
 By default ``AUTOMOC_DEPEND_FILTERS`` is initialized from
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index 6f1c85c..8901de3 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -76,8 +76,8 @@
 
 :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`:
 A global ``autogen`` target, that depends on all :prop_tgt:`AUTOMOC` or
-``AUTOUIC`` generated :ref:`<ORIGIN>_autogen` targets in the project,
-will be generated when this variable is ``ON``.
+``AUTOUIC`` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+targets in the project, will be generated when this variable is ``ON``.
 
 :prop_tgt:`AUTOGEN_PARALLEL`:
 This target property controls the number of ``moc`` or ``uic`` processes to
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME.rst b/Help/prop_tgt/COMPILE_PDB_NAME.rst
index 1b4657e..166cfc1 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME.rst
@@ -9,6 +9,9 @@
 This property specifies the base name for the debug symbols file.
 If not set, the default is unspecified.
 
+If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
+is ignored and the reusage target's value of this property is used instead.
+
 .. versionadded:: 4.1
 
   Contents of ``COMPILE_PDB_NAME`` may use
diff --git a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
index f21bdc9..162011d 100644
--- a/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_NAME_CONFIG.rst
@@ -13,5 +13,8 @@
   Contents of ``COMPILE_PDB_NAME_<CONFIG>`` may use
   :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
+If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
+is ignored and the reusage target's value of this property is used instead.
+
 .. |PDB_XXX| replace:: :prop_tgt:`PDB_NAME_<CONFIG>`
 .. include:: include/COMPILE_PDB_NOTE.rst
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
index 5bfb50b..9fa7ff2 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY.rst
@@ -21,5 +21,8 @@
 :variable:`CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY` variable if it is
 set when a target is created.
 
+If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
+is ignored and the reusage target's value of this property is used instead.
+
 .. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY`
 .. include:: include/COMPILE_PDB_NOTE.rst
diff --git a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
index c2d4a94..fc9121c 100644
--- a/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
+++ b/Help/prop_tgt/COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG.rst
@@ -20,5 +20,8 @@
   Contents of ``COMPILE_PDB_OUTPUT_DIRECTORY_<CONFIG>`` may use
   :manual:`generator expressions <cmake-generator-expressions(7)>`.
 
+If the :prop_tgt:`PRECOMPILE_HEADERS_REUSE_FROM` target is set, this property
+is ignored and the reusage target's value of this property is used instead.
+
 .. |PDB_XXX| replace:: :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`
 .. include:: include/COMPILE_PDB_NOTE.rst
diff --git a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
index d09ff19..8a5c562 100644
--- a/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
+++ b/Help/prop_tgt/CROSSCOMPILING_EMULATOR.rst
@@ -20,3 +20,6 @@
 This property is initialized by the value of the
 :variable:`CMAKE_CROSSCOMPILING_EMULATOR` variable if it is set when a target
 is created.
+
+This property is not supported when using the old form of :command:`add_test`
+(i.e. without the ``NAME`` and ``COMMAND`` keywords).
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index 9b381e4..177f12e 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -40,9 +40,6 @@
 ``26``
   .. versionadded:: 3.25
 
-  C++26. CMake 3.25 and later *recognize* ``26`` as a valid value,
-  no version has support for any compiler.
-
 If the value requested does not result in a compile flag being added for
 the compiler in use, a previous standard flag will be added instead.  This
 means that using:
diff --git a/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst b/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst
index b7405d6..f74f6d3 100644
--- a/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst
+++ b/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst
@@ -6,9 +6,10 @@
   Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES``.
 
 Control the package name associated with a dependency target when exporting a
-:command:`find_dependency` call in :command:`install(EXPORT)` or
+:command:`find_dependency` call in :command:`install(PACKAGE_INFO)`,
+:command:`export(PACKAGE_INFO)`, :command:`install(EXPORT)` or
 :command:`export(EXPORT)`. This can be used to assign a package name to a
-package that is built by CMake and exported, or to override the package in the
-:command:`find_package` call that created the target.
+package that is built by CMake and exported, or a package that was provided by
+:module:`FetchContent`.
 
 This property is initialized by :variable:`CMAKE_EXPORT_FIND_PACKAGE_NAME`.
diff --git a/Help/prop_tgt/FASTBUILD_CACHING.rst b/Help/prop_tgt/FASTBUILD_CACHING.rst
new file mode 100644
index 0000000..6ef1dc0
--- /dev/null
+++ b/Help/prop_tgt/FASTBUILD_CACHING.rst
@@ -0,0 +1,19 @@
+FASTBUILD_CACHING
+-----------------
+
+.. versionadded:: 4.2
+
+A target property that controls whether caching is enabled for the given
+target in the generated ``fbuild.bff``.
+
+If set to ``OFF``, the :generator:`FASTBuild` generator disables caching
+features for this target. This is useful for targets that are known to be
+unreliably cached or not worth caching.
+
+Example:
+
+.. code-block:: cmake
+
+  set_property(TARGET my_target PROPERTY FASTBUILD_CACHING OFF)
+
+Defaults to ``ON``.
diff --git a/Help/prop_tgt/FASTBUILD_DISTRIBUTION.rst b/Help/prop_tgt/FASTBUILD_DISTRIBUTION.rst
new file mode 100644
index 0000000..58d6df6
--- /dev/null
+++ b/Help/prop_tgt/FASTBUILD_DISTRIBUTION.rst
@@ -0,0 +1,19 @@
+FASTBUILD_DISTRIBUTION
+----------------------
+
+.. versionadded:: 4.2
+
+A target property that controls whether distribution is enabled for the given
+target in the generated ``fbuild.bff``.
+
+If set to ``OFF``, the :generator:`FASTBuild` generator disables distributed
+compilation for this target. This can be helpful for targets that are fast to
+build locally or are incompatible with distributed execution.
+
+Example:
+
+.. code-block:: cmake
+
+  set_property(TARGET my_target PROPERTY FASTBUILD_DISTRIBUTION OFF)
+
+Defaults to ``ON``.
diff --git a/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst b/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst
new file mode 100644
index 0000000..45cf7d8
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst
@@ -0,0 +1,24 @@
+INSTALL_OBJECT_NAME_STRATEGY
+----------------------------
+
+.. versionadded:: 4.2
+
+``INSTALL_OBJECT_NAME_STRATEGY`` is a string target property variable
+specifying the strategy to use when naming installed object files. The
+supported values are:
+
+- ``FULL``: Object files are named after the associated source file or
+  its :prop_sf:`OBJECT_NAME` property.
+- ``SHORT``: Object files are named based on the hash of the source file name
+  to reduce path lengths.
+
+When unset or the named strategy is not supported, the ``FULL`` strategy is
+used.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_INSTALL_OBJECT_NAME_STRATEGY` if it is set when a target is
+created.
+
+.. note::
+  Not all generators support all strategies and paths may differ between
+  generators.
diff --git a/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst b/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst
new file mode 100644
index 0000000..9f55496
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst
@@ -0,0 +1,20 @@
+INSTALL_OBJECT_ONLY_USE_DESTINATION
+-----------------------------------
+
+.. versionadded:: 4.2
+
+Controls whether the ``install(DESTINATION)`` for object libraries is used
+as-is or supplemented with conflict-avoiding subdirectories.
+
+When installing object files, CMake automatically adds
+``objects[-<CONFIG>]/<TARGET_NAME>`` components to the destination to avoid
+conflicts. Use this property to suppress these components. Note that when
+using a single install prefix for multiple configurations (whether via
+multi-config generators or separate build trees), the destination must use
+``$<CONFIG>`` to avoid conflicts. Alternatively, the
+:prop_sf:`INSTALL_OBJECT_NAME` may be used to avoid configuration-based
+conflicts.
+
+This property is initialized by the value of
+:variable:`CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION` when the target is
+created.
diff --git a/Help/prop_tgt/OPTIMIZE_DEPENDENCIES.rst b/Help/prop_tgt/OPTIMIZE_DEPENDENCIES.rst
index fcacb00..51c7254 100644
--- a/Help/prop_tgt/OPTIMIZE_DEPENDENCIES.rst
+++ b/Help/prop_tgt/OPTIMIZE_DEPENDENCIES.rst
@@ -21,8 +21,8 @@
 * The dependency has any ``PRE_BUILD``, ``PRE_LINK``, or ``POST_BUILD`` custom
   commands associated with it.
 * The dependency contains any source files that were generated by a custom
-  command. However, if :policy:`CMP0154` is `NEW` for the dependency and it
-  uses :ref:`File Sets`, only source files that are not in a ``PUBLIC``,
+  command. However, if :policy:`CMP0154` is ``NEW`` for the dependency and it
+  uses :ref:`File Sets`, only source files that are scoped as ``PUBLIC``,
   ``INTERFACE``, or of type ``CXX_MODULES`` are considered.
 * The dependency contains any languages which produce side effects that are
   relevant to the library. Currently, all languages except C, C++, Objective-C,
diff --git a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
index 2ba1e6f..85e4cf6 100644
--- a/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
+++ b/Help/prop_tgt/POSITION_INDEPENDENT_CODE.rst
@@ -1,10 +1,11 @@
 POSITION_INDEPENDENT_CODE
 -------------------------
 
-Whether to create a position-independent target
+A target property that specifies whether to create a target that has
+position-independent code enabled.
 
-The ``POSITION_INDEPENDENT_CODE`` property determines whether position
-independent executables or libraries will be created.  This
+The ``POSITION_INDEPENDENT_CODE`` target property determines whether
+position-independent executables or libraries will be created.  This
 property is ``True`` by default for ``SHARED`` and ``MODULE`` library
 targets.  For other targets, this property is initialized by the value
 of the :variable:`CMAKE_POSITION_INDEPENDENT_CODE` variable if it is set
@@ -14,3 +15,57 @@
 
   For executable targets, the link step is controlled by the :policy:`CMP0083`
   policy and the :module:`CheckPIESupported` module.
+
+Position-independent code (PIC) refers to machine code that executes
+properly regardless of its absolute memory address.  This is particularly
+important for shared libraries, which are often loaded at different memory
+addresses by different programs.  Generating position-independent code
+ensures that these libraries can be safely and efficiently shared among
+multiple processes without causing address conflicts.  On some platforms
+(notably UNIX-like systems), generating PIC is also a requirement for
+creating shared libraries.
+
+Use of position-independent code is recommended or required in the following
+cases:
+
+* When building shared or module libraries (e.g., with
+  ``add_library(... SHARED)``, or ``add_library(... MODULE)``), where PIC
+  allows dynamic relocation at runtime.
+
+* When building executables as position-independent executables (PIE), which
+  can enhance security by enabling Address Space Layout Randomization (ASLR).
+
+* On platforms or toolchains that require PIC for certain types of linking
+  or sandboxed environments.
+
+Enabling PIC can result in slightly larger or slower code on some
+architectures, but this is often outweighed by the benefits of flexibility
+and security.
+
+Examples
+^^^^^^^^
+
+Enabling PIC for a static library target:
+
+.. code-block:: cmake
+
+  add_library(foo STATIC foo.c)
+  set_target_properties(foo PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
+
+Enabling PIC for an executable target:
+
+.. code-block:: cmake
+
+  add_executable(app app.c)
+
+  set_target_properties(app PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
+
+  # Additionally, pass PIE-related link-time options to executable(s).
+  include(CheckPIESupported)
+  check_pie_supported()
+
+See Also
+^^^^^^^^
+
+* The :module:`CheckPIESupported` module to pass PIE-related options to the
+  linker for executables.
diff --git a/Help/prop_tgt/SKIP_LINTING.rst b/Help/prop_tgt/SKIP_LINTING.rst
new file mode 100644
index 0000000..031f653
--- /dev/null
+++ b/Help/prop_tgt/SKIP_LINTING.rst
@@ -0,0 +1,25 @@
+SKIP_LINTING
+------------
+
+.. versionadded:: 4.2
+
+Exclude all sources of a target from running configured linting tools.
+
+When this boolean property is enabled on a target, C/C++ linting tools enabled
+for that target (e.g. :prop_tgt:`<LANG>_CPPLINT`, :prop_tgt:`<LANG>_CLANG_TIDY`,
+:prop_tgt:`<LANG>_CPPCHECK`, :prop_tgt:`<LANG>_ICSTAT` and
+:prop_tgt:`<LANG>_INCLUDE_WHAT_YOU_USE`) will not be invoked for source files
+compiled by the target.  If the :prop_sf:`SKIP_LINTING` source-file property
+is set on a specific source, it takes precedence over this target-wide property.
+
+This is a convenience alternative to setting the :prop_sf:`SKIP_LINTING`
+source file property individually on each source.  If either the target's
+:prop_tgt:`SKIP_LINTING` or a source’s :prop_sf:`SKIP_LINTING` is enabled,
+that source will be excluded from linting.
+
+The property has no effect on targets that do not have sources.
+
+See Also
+^^^^^^^^
+
+* :prop_sf:`SKIP_LINTING` source file property
diff --git a/Help/prop_tgt/SPDX_LICENSE.rst b/Help/prop_tgt/SPDX_LICENSE.rst
index 056c860..a030e6c 100644
--- a/Help/prop_tgt/SPDX_LICENSE.rst
+++ b/Help/prop_tgt/SPDX_LICENSE.rst
@@ -3,9 +3,9 @@
 
 .. versionadded:: 4.1
 
-Specify the license of a target using a |SPDX|_ (SPDX) `License Expression`_.
-See the SPDX `License List`_ for a list of commonly used licenses and their
-identifiers.
+Specify the license(s) of a target using a |SPDX|_ (SPDX)
+`License Expression`_. See the SPDX `License List`_ for a list of commonly used
+licenses and their identifiers.
 
 .. _SPDX: https://spdx.dev/
 .. |SPDX| replace:: System Package Data Exchange
diff --git a/Help/prop_tgt/SYMBOLIC.rst b/Help/prop_tgt/SYMBOLIC.rst
new file mode 100644
index 0000000..36ebe6b
--- /dev/null
+++ b/Help/prop_tgt/SYMBOLIC.rst
@@ -0,0 +1,11 @@
+SYMBOLIC
+--------
+
+.. versionadded:: 4.2
+
+Read-only indication of whether a target is ``SYMBOLIC``.
+
+Symbolic targets are created by calls to
+:command:`add_library(INTERFACE SYMBOLIC) <add_library(INTERFACE-SYMBOLIC)>`.
+They are useful for packages to represent additional **components** or
+**feature selectors** that consumers can request via ``find_package()``.
diff --git a/Help/prop_tgt/TEST_LAUNCHER.rst b/Help/prop_tgt/TEST_LAUNCHER.rst
index 7eec319..a2103bc 100644
--- a/Help/prop_tgt/TEST_LAUNCHER.rst
+++ b/Help/prop_tgt/TEST_LAUNCHER.rst
@@ -21,3 +21,6 @@
 This property is initialized by the value of the
 :variable:`CMAKE_TEST_LAUNCHER` variable if it is set when a target
 is created.
+
+This property is not supported when using the old form of :command:`add_test`
+(i.e. without the ``NAME`` and ``COMMAND`` keywords).
diff --git a/Help/prop_tgt/UNITY_BUILD_FILENAME_PREFIX.rst b/Help/prop_tgt/UNITY_BUILD_FILENAME_PREFIX.rst
new file mode 100644
index 0000000..d6c1e6a
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_FILENAME_PREFIX.rst
@@ -0,0 +1,25 @@
+UNITY_BUILD_FILENAME_PREFIX
+---------------------------
+
+.. versionadded:: 4.2
+
+By default, the unity file generated when :prop_tgt:`UNITY_BUILD` is enabled
+is of the form ``unity_<index>_<suffix>``, where ``<suffix>`` is language-specific.
+
+If several targets are using unity builds, the build output may give no
+indication which target a unity file belongs to. This property allows
+customizing the prefix of the generated unity file name. If unset,
+the default prefix ``unity_`` is used.
+
+Example usage:
+
+.. code-block:: cmake
+
+  add_library(example_library
+              source1.cxx
+              source2.cxx
+              source3.cxx)
+
+  set_target_properties(example_library PROPERTIES
+                        UNITY_BUILD True
+                        UNITY_BUILD_FILENAME_PREFIX "example_")
diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst
index 6b3a187..e4a386a 100644
--- a/Help/release/3.14.rst
+++ b/Help/release/3.14.rst
@@ -302,7 +302,7 @@
 * A new :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` variable and
   :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property may be set to enable or
   disable forwarding of the origin target dependencies to the corresponding
-  :ref:`<ORIGIN>_autogen` target.
+  :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 
 CTest
 -----
@@ -346,6 +346,9 @@
   ``xmlrpc``.  CDash is the only maintained testing dashboard for CTest,
   and it only supports submissions over ``http`` and ``https``.
 
+* The :module:`MacroAddFileDependencies` module is deprecated.
+  Port projects to use :command:`set_property` directly.
+
 Other Changes
 =============
 
diff --git a/Help/release/3.16.rst b/Help/release/3.16.rst
index 28273a7..f9f9b33 100644
--- a/Help/release/3.16.rst
+++ b/Help/release/3.16.rst
@@ -165,7 +165,7 @@
   a new ``REASON_FAILURE_MESSAGE`` option to specify a message
   giving the reason for the failure.
 
-* The :module:`FindPkgConfig` module :command:`pkg_search_module` macro
+* The :module:`FindPkgConfig` module :command:`pkg_search_module` command
   now defines a ``<prefix>_MODULE_NAME`` result variable containing the
   first matching module name.
 
diff --git a/Help/release/3.22.rst b/Help/release/3.22.rst
index efc8115..fa57fc4 100644
--- a/Help/release/3.22.rst
+++ b/Help/release/3.22.rst
@@ -75,7 +75,7 @@
 
 * The :module:`FindMatlab` module now provides imported targets.
 
-* The :module:`FindPkgConfig` module gained a :variable:`PKG_CONFIG_ARGN`
+* The :module:`FindPkgConfig` module gained a ``PKG_CONFIG_ARGN``
   variable to specify arguments to ``pkg-config`` calls.
 
 * The :module:`GoogleTest` module :command:`gtest_discover_tests`
diff --git a/Help/release/3.3.rst b/Help/release/3.3.rst
index efb6a7c..3b1da25 100644
--- a/Help/release/3.3.rst
+++ b/Help/release/3.3.rst
@@ -135,7 +135,7 @@
   documentation, and unit tests.
 
 * The :module:`FindPackageHandleStandardArgs` module
-  ``find_package_handle_standard_args`` function now
+  :command:`find_package_handle_standard_args` command now
   always populates both the ``<PackageName>_FOUND``
   and ``<UPPERCASE_NAME>_FOUND`` variables (the latter
   for backwards compatibility).  The ``FOUND_VAR``
diff --git a/Help/release/4.2.rst b/Help/release/4.2.rst
new file mode 100644
index 0000000..a47112e
--- /dev/null
+++ b/Help/release/4.2.rst
@@ -0,0 +1,247 @@
+CMake 4.2 Release Notes
+***********************
+
+.. only:: html
+
+  .. contents::
+
+Changes made since CMake 4.1 include the following.
+
+New Features
+============
+
+File-Based API
+--------------
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 ``version`` field has
+  been updated to 2.9.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" and
+  "directory" objects gained a new ``codemodelVersion`` field.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 now includes imported
+  targets and all interface library targets in its replies.  Previously,
+  imported targets were omitted, and only those interface targets that
+  participated in the build system were included.  The following changes
+  support these new additions:
+
+  * The "target" object gained ``imported``, ``local``, and ``abstract`` fields.
+  * The "target" object's ``type`` field can now also hold the value
+    ``UNKNOWN_LIBRARY``.
+  * The "codemodel" object's ``configurations`` entries gained a new
+    ``abstractTargets`` array.
+  * Entries in the ``directories`` and ``projects`` arrays of the "codemodel"
+    object's ``configurations`` entries gained a new ``abstractTargetIndexes``
+    array.
+
+* The :manual:`cmake-file-api(7)` "codemodel" version 2 "target" object gained
+  new ``linkLibraries``, ``interfaceLinkLibraries``, ``compileDependencies``,
+  ``interfaceCompileDependencies``, ``objectDependencies``, and
+  ``orderDependencies`` fields.
+
+Generators
+----------
+
+* The :generator:`Visual Studio 18 2026` generator was added.
+
+* The :generator:`FASTBuild` generator was added.
+
+Platforms
+---------
+
+* CMake now supports :ref:`Cross Compiling for Emscripten` with simple
+  toolchain files.
+
+Command-Line
+------------
+
+* The :manual:`cmake(1)` command-line tool now supports
+  ``cmake -E copy_if_newer`` and ``cmake -E copy_directory_if_newer``
+  subcommands to copy files based on timestamp comparison instead of
+  content comparison. These commands copy files only if the source is
+  newer than the destination, providing better performance for build
+  systems compared to ``copy_if_different`` which compares file contents.
+
+Commands
+--------
+
+* The :command:`cmake_language(TRACE)` command was added to enable or
+  disable tracing during script execution.
+
+* The :command:`set(CACHE{<variable>}) <set(CACHE)>` and
+  :command:`unset(CACHE{<variable>}) <unset(CACHE)>` commands were added to
+  explicitly set and unset cache entries.
+
+* The :command:`string(REGEX QUOTE)` command was added to
+  generate a regular expression exactly matching a string.
+
+Variables
+---------
+
+* The :variable:`CMAKE_CXX_STDLIB_MODULES_JSON` variable was added to set
+  the path to the ``import std`` metadata file for the standard library
+  rather than using the compiler to discover its location.
+
+* The :variable:`CMAKE_INTERMEDIATE_DIR_STRATEGY` variable and corresponding
+  :envvar:`CMAKE_INTERMEDIATE_DIR_STRATEGY` environment variable were added
+  to change the strategy used to name intermediate directories used for
+  object files and other associated target metadata.
+
+* The :variable:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY` variable and
+  corresponding :envvar:`CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY` environment
+  variable were added to change the strategy used to name intermediate
+  directories used for :manual:`Qt Autogen <cmake-qt(7)>` files.
+
+* The :variable:`CMAKE_SKIP_LINTING` variable and corresponding
+  :prop_tgt:`SKIP_LINTING` target property were added to tell the
+  :ref:`Command-Line Build Tool Generators` to skip linting all
+  sources in a target.
+
+Properties
+----------
+
+* The :prop_sf:`INSTALL_OBJECT_NAME` source file property was added to
+  control names of installed object files for specific compiled sources.
+
+* The :prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` target property was added
+  to control the naming strategy for installed object files.
+
+* The :prop_tgt:`INSTALL_OBJECT_ONLY_USE_DESTINATION` target property was
+  added to more precisely control the installation path for object files.
+
+* The :prop_sf:`JOB_POOL_COMPILE` source file property was added
+  to assign individual source compilations to :prop_gbl:`JOB_POOLS`.
+
+* The :prop_sf:`OBJECT_NAME` source file property was added to control
+  object names of compiled source files.
+
+* The :prop_tgt:`UNITY_BUILD_FILENAME_PREFIX` target property was added
+  to control names of source files generated by :prop_tgt:`UNITY_BUILD`.
+
+Modules
+-------
+
+* Nearly all find modules now provide a ``<PackageName>_VERSION`` result
+  variable matching the casing of its module name.  Existing variants such as
+  ``<PackageName>_VERSION_STRING`` and uppercased ``<PACKAGENAME>_VERSION``
+  are deprecated.  See documentation of each find module for details.
+
+* The :module:`CheckTypeSize` module's :command:`check_type_size` command
+  gained a new ``RESULT_VARIABLE`` keyword to customize the result variable
+  name instead of the default ``HAVE_<size-var>``.
+
+* The :module:`ExternalProject` module's :command:`ExternalProject_Add`
+  and :command:`ExternalProject_Add_Step` commands now provide options to set
+  environment variables on the configure, build, install, and test steps.
+
+* The :module:`FindPython3`, :module:`FindPython2`, and :module:`FindPython`
+  modules no longer make ``NumPy`` depend on ``Development.Module``.
+  See policy :policy:`CMP0201`.
+
+* The :module:`GoogleTest` module's :command:`gtest_discover_tests()`
+  command now sets the ``DEF_SOURCE_LINE`` test property for each
+  discovered test if gtest supports the ``--gtest_output=json`` option.
+  This test property is used by some IDEs to locate the source for each test.
+
+* The :module:`UseSWIG` module's :command:`swig_add_library` command gained a
+  ``DEBUG_POSTFIX`` option to control the :prop_tgt:`DEBUG_POSTFIX` target
+  property.
+
+Generator Expressions
+---------------------
+
+* The :genex:`<LANG>_COMPILER_LINKER_ID <C_COMPILER_LINKER_ID>` and
+  :genex:`<LANG>_COMPILER_LINKER_FRONTEND_VARIANT <C_COMPILER_LINKER_FRONTEND_VARIANT>`
+  families of generator expressions were added to access the value of the
+  associated :variable:`CMAKE_<LANG>_COMPILER_LINKER_ID` and
+  :variable:`CMAKE_<LANG>_COMPILER_LINKER_FRONTEND_VARIANT` variables.
+
+* The :genex:`TARGET_FILE_BASE_NAME`, :genex:`TARGET_IMPORT_FILE_BASE_NAME`,
+  :genex:`TARGET_LINKER_FILE_BASE_NAME`,
+  :genex:`TARGET_LINKER_LIBRARY_FILE_BASE_NAME`,
+  :genex:`TARGET_LINKER_IMPORT_FILE_BASE_NAME`, and
+  :genex:`TARGET_PDB_FILE_BASE_NAME`
+  generator expressions gained a ``POSTFIX`` option to control the inclusion
+  of the :prop_tgt:`<CONFIG>_POSTFIX` target property as part of the base
+  names of the corresponding files.
+
+* The :genex:`TARGET_INTERMEDIATE_DIR` generator expression was
+  added to refer to a target's intermediate files directory in
+  the build tree.
+
+CPack
+-----
+
+* The :cpack_gen:`CPack AppImage Generator` was added.
+
+* The :variable:`CPACK_PACKAGE_CHECKSUM` variable now supports multiple values.
+
+* The :cpack_gen:`CPack NSIS Generator` gained a
+  :variable:`CPACK_NSIS_CRC_CHECK` variable for setting the ``CRCCheck``
+  attribute.
+
+* The :cpack_gen:`CPack WIX Generator` gained a
+  :variable:`CPACK_WIX_CAB_PER_COMPONENT` variable to enable one ``.cab``
+  per component.
+
+Deprecated and Removed Features
+===============================
+
+* All find modules now provide a ``<PackageName>_FOUND`` result variable
+  matching the casing of its module name.  Existing variants, such as the
+  uppercased ``<PACKAGENAME>_FOUND``, are deprecated where appropriate.
+  See documentation of each find module for details.
+
+* The :module:`FindwxWidgets` module's result variable
+  ``wxWidgets_USE_FILE`` is now deprecated in favor of including the
+  :module:`UsewxWidgets` module directly.
+
+* The :generator:`Visual Studio 14 2015` generator is now deprecated
+  and will be removed in a future version of CMake.
+
+Other Changes
+=============
+
+* The :genex:`$<CONFIG:cfgs>` generator expression, when appearing on an
+  imported target, has been fixed to not match configurations that are not
+  applicable.  See policy :policy:`CMP0199`.
+
+* Selection of configuration and location of imported targets is now more
+  consistent.  See policy :policy:`CMP0200`.
+
+* The :variable:`CMAKE_PARENT_LIST_FILE` variable is no longer defined when
+  processing a ``CMakeLists.txt`` file.  See policy :policy:`CMP0198`.
+
+* For builds targeting the MSVC ABI, all generators now add the ``_MBCS``
+  preprocessor definition when compiling sources unless ``_UNICODE`` or
+  ``_SBCS`` is found.  See policy :policy:`CMP0204`.
+
+* For builds targeting the MSVC ABI, all generators now add the ``_WINDLL``
+  preprocessor definition when compiling sources in shared libraries.
+  See policy :policy:`CMP0203`.
+
+* The :ref:`Visual Studio Generators` now suppress Visual Studio's default
+  flags ``-fp:precise``, ``-Gd``, and ``-GS`` if they are not specified by
+  the project or user.  This makes builds more consistent with other
+  generators, and with what projects and users actually specify.
+
+Updates
+=======
+
+Changes made since CMake 4.2.0 include the following.
+
+4.2.1
+-----
+
+* This version made no changes to documented features or interfaces.
+  Some implementation updates were made to support ecosystem changes
+  and/or fix regressions.
+
+4.2.2
+-----
+
+* Policy :policy:`CMP0199`'s NEW behavior has been partially reverted.
+  In 4.2.0 and 4.2.1, ``$<CONFIG:cfgs>`` only matched the configuration
+  of the consumed target.  This broke existing use cases that rely on
+  matching the configuration of the consuming target, and so has been
+  partially reverted to match either as CMake 4.1 and below did.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 400e1f2..54190ee 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -13,6 +13,7 @@
 .. toctree::
    :maxdepth: 1
 
+   4.2 <4.2>
    4.1 <4.1>
    4.0 <4.0>
    3.31 <3.31>
diff --git a/Help/variable/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst b/Help/variable/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst
new file mode 100644
index 0000000..3cede1f
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY.rst
@@ -0,0 +1,33 @@
+CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY
+---------------------------------------
+
+.. versionadded:: 4.2
+
+``CMAKE_AUTOGEN_INTERMEDIATE_DIR_STRATEGY`` is a string cache variable
+specifying the strategy to use for autogen target intermediate directories and
+their contents. The supported values are:
+
+- ``FULL``: Intermediate directories are named based on a
+  ``<TARGET_NAME>_autogen.dir`` and ``<TARGET_NAME>_autogen`` pattern (with
+  some slight deviations and sanitizations applied in various places). Object
+  file names are based on the filename of the source file being compiled.
+- ``SHORT``: Intermediate directories are named from the hash of the target
+  name and the build directory location and an ``/autogen`` subdirectory.
+  This may help with projects that generate long paths in the build directory
+  to support building in directories other than those near a root path.
+
+When unset or the named strategy is not supported, the ``FULL`` strategy is
+used.
+
+.. note::
+  This only works as a cache variable, not a locally-scoped variable.
+
+This is supported by the following generators:
+
+- :ref:`Ninja Generators`
+- :ref:`Makefile Generators`
+- :ref:`Visual Studio Generators`
+
+.. note::
+  Not all generators support all strategies and paths may differ between
+  generators.
diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
index 52aa891..139268b 100644
--- a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
+++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
@@ -4,14 +4,14 @@
 .. versionadded:: 3.14
 
 Switch for forwarding origin target dependencies to the corresponding
-:ref:`<ORIGIN>_autogen` targets.
+:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets.
 
   .. note::
 
     If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
     or :ref:`Makefile Generators`, additional target dependencies are added to
-    the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the
-    :ref:`<ORIGIN>_autogen` target.
+    the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
+    target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
 
 This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`
 property on all the targets.  See that target property for additional
diff --git a/Help/variable/CMAKE_BINARY_DIR.rst b/Help/variable/CMAKE_BINARY_DIR.rst
index 96c6319..b046037 100644
--- a/Help/variable/CMAKE_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_BINARY_DIR.rst
@@ -11,3 +11,5 @@
 ``CMAKE_BINARY_DIR``, :variable:`CMAKE_SOURCE_DIR`,
 :variable:`CMAKE_CURRENT_BINARY_DIR` and
 :variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
+
+Modifying ``CMAKE_BINARY_DIR`` has undefined behavior.
diff --git a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
index 1d7a111..1eabaef 100644
--- a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
@@ -13,3 +13,5 @@
 :variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
 ``CMAKE_CURRENT_BINARY_DIR`` and
 :variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
+
+Modifying ``CMAKE_CURRENT_BINARY_DIR`` has undefined behavior.
diff --git a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
index 4205efb..7a08892 100644
--- a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
@@ -10,3 +10,5 @@
 :variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
 :variable:`CMAKE_CURRENT_BINARY_DIR` and
 ``CMAKE_CURRENT_SOURCE_DIR`` to the current working directory.
+
+Modifying ``CMAKE_CURRENT_SOURCE_DIR`` has undefined behavior.
diff --git a/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst b/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst
new file mode 100644
index 0000000..134e8d6
--- /dev/null
+++ b/Help/variable/CMAKE_CXX_STDLIB_MODULES_JSON.rst
@@ -0,0 +1,11 @@
+CMAKE_CXX_STDLIB_MODULES_JSON
+-----------------------------
+
+.. versionadded:: 4.2
+
+This variable may be used to set the path to a metadata file for CMake to
+understand how the ``import std`` target for the active CXX compiler should be
+constructed.
+
+This should only be used when the compiler does not know how to discover the
+relevant module metadata file without such assistance.
diff --git a/Help/variable/CMAKE_DL_LIBS.rst b/Help/variable/CMAKE_DL_LIBS.rst
index 50d313d..11fc742 100644
--- a/Help/variable/CMAKE_DL_LIBS.rst
+++ b/Help/variable/CMAKE_DL_LIBS.rst
@@ -1,7 +1,49 @@
 CMAKE_DL_LIBS
 -------------
 
-Name of library containing ``dlopen`` and ``dlclose``.
+This variable contains a name of the dynamic loading library, or a list of
+system libraries needed to use the ``dlopen()`` and ``dlclose()`` functions.
 
-The name of the library that has ``dlopen`` and ``dlclose`` in it, usually
-``-ldl`` on most UNIX machines.
+Few examples of the values this variable is set to:
+
+``dl``
+  On most Unix-like systems.
+
+``-lld``
+  On AIX, prior to CMake 4.2.
+
+``dld``
+  On HP-UX.
+
+""
+  Empty string value or not set on systems that have ``dl*()`` functions
+  either in the default library that is implicitly linked (e.g., BSD-like
+  systems, Haiku, macOS, SunOS, etc.), or on systems that don't provide these
+  functions (e.g., Windows).
+
+Examples
+^^^^^^^^
+
+Example: Linking Dynamic Loading Library
+""""""""""""""""""""""""""""""""""""""""
+
+Using this variable in a project that uses dynamic loading functionality:
+
+.. code-block:: cmake
+
+  target_link_libraries(example PRIVATE ${CMAKE_DL_LIBS})
+
+Example: Checking Symbols
+"""""""""""""""""""""""""
+
+Checking for symbols with the dynamic loading library linked during the check:
+
+.. code-block:: cmake
+
+  include(CheckSymbolExists)
+  include(CMakePushCheckState)
+
+  cmake_push_check_state(RESET)
+    set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
+    check_symbol_exists(dlopen "dlfcn.h" HAVE_DLOPEN)
+  cmake_pop_check_state()
diff --git a/Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst b/Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst
new file mode 100644
index 0000000..c937537
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_ALLOW_RESPONSE_FILE
+-----------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``AllowResponseFile`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_CACHE_PATH.rst b/Help/variable/CMAKE_FASTBUILD_CACHE_PATH.rst
new file mode 100644
index 0000000..0bb0d94
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_CACHE_PATH.rst
@@ -0,0 +1,12 @@
+CMAKE_FASTBUILD_CACHE_PATH
+--------------------------
+
+.. versionadded:: 4.2
+
+Specifies the directory for the FASTBuild artifact cache in the generated file.
+
+If not set, FASTBuild will use the ``FASTBUILD_CACHE_PATH`` environment
+variable at build time.
+
+See the `FASTBuild caching documentation <https://www.fastbuild.org/docs/features/caching.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV.rst b/Help/variable/CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV.rst
new file mode 100644
index 0000000..c415984
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV.rst
@@ -0,0 +1,15 @@
+CMAKE_FASTBUILD_CAPTURE_SYSTEM_ENV
+----------------------------------
+
+.. versionadded:: 4.2
+
+Controls capturing of the system environment into ``fbuild.bff``.
+Setting it to ``OFF`` makes the invocation of all tools (compilers and other external processes) hermetic.
+
+.. note::
+
+   Setting this variable to ``OFF`` can break MSVC toolchains that rely on
+   environment variables such as ``INCLUDE`` or ``LIB`` unless these are
+   manually configured elsewhere.
+
+Defaults to ``ON``.
diff --git a/Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst b/Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst
new file mode 100644
index 0000000..0552d90
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_CLANG_GCC_UPDATE_XLANG_ARG
+------------------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``ClangGCCUpdateXLanguageArg`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst b/Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst
new file mode 100644
index 0000000..4be7b2e
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_CLANG_REWRITE_INCLUDES
+--------------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``ClangRewriteIncludes`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_COMPILER_EXTRA_FILES.rst b/Help/variable/CMAKE_FASTBUILD_COMPILER_EXTRA_FILES.rst
new file mode 100644
index 0000000..86c6172
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_COMPILER_EXTRA_FILES.rst
@@ -0,0 +1,10 @@
+CMAKE_FASTBUILD_COMPILER_EXTRA_FILES
+-------------------------------------
+
+.. versionadded:: 4.2
+
+Specifies a semicolon-separated list of additional files (usually DLLs) to
+include in the FASTBuild ``Compiler()`` node.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_ENV_OVERRIDES.rst b/Help/variable/CMAKE_FASTBUILD_ENV_OVERRIDES.rst
new file mode 100644
index 0000000..d469409
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_ENV_OVERRIDES.rst
@@ -0,0 +1,32 @@
+CMAKE_FASTBUILD_ENV_OVERRIDES
+-----------------------------
+
+.. versionadded:: 4.2
+
+Allows overriding environment variables in the captured environment written to
+``fbuild.bff``.
+
+Specify a CMake-style list of key=value pairs. These values will override the
+corresponding variables in the environment block that FASTBuild uses during
+execution of tools (e.g., compilers, linkers, resource compilers, etc.).
+
+This is especially useful for ensuring consistent behavior when tools depend
+on environment variables (e.g., overriding ``PATH`` to control tool resolution
+for ``rc.exe`` or ``mt.exe``).
+
+Example:
+
+.. code-block:: cmake
+
+   set(CMAKE_FASTBUILD_ENV_OVERRIDES
+       "PATH=C:/MyTools/bin"
+       "TMP=C:/temp"
+       "MY_CUSTOM_VAR=some_value"
+   )
+
+.. note::
+
+   This only affects the environment seen by FASTBuild-generated rules.
+   It does **not** modify the environment in which CMake itself runs.
+
+Defaults to empty (no overrides).
diff --git a/Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst b/Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst
new file mode 100644
index 0000000..04bae8e
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_FORCE_RESPONSE_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_FORCE_RESPONSE_FILE
+-----------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``ForceResponseFile`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_IDE_ARGS.rst b/Help/variable/CMAKE_FASTBUILD_IDE_ARGS.rst
new file mode 100644
index 0000000..a594bb3
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_IDE_ARGS.rst
@@ -0,0 +1,17 @@
+CMAKE_FASTBUILD_IDE_ARGS
+------------------------
+
+.. versionadded:: 4.2
+
+Specifies the command-line arguments used when invoking ``fbuild`` from IDE
+projects.
+
+If not set, the following arguments are used::
+
+  -ide -cache -summary -dist
+
+Example:
+
+.. code-block:: cmake
+
+   set(CMAKE_FASTBUILD_IDE_ARGS "-ide -cache -summary -dist -clean")
diff --git a/Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst b/Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst
new file mode 100644
index 0000000..69cd9f2
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_SOURCE_MAPPING.rst
@@ -0,0 +1,15 @@
+CMAKE_FASTBUILD_SOURCE_MAPPING
+------------------------------
+
+.. versionadded:: 4.2
+
+Sets FASTBuild's ``SourceMapping_Experimental`` option.
+
+Example:
+
+.. code-block:: cmake
+
+   set(CMAKE_FASTBUILD_SOURCE_MAPPING "/another/root")
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT.rst b/Help/variable/CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT.rst
new file mode 100644
index 0000000..07da28d
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT.rst
@@ -0,0 +1,17 @@
+CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT
+------------------------------------------
+
+.. versionadded:: 4.2
+
+By default, custom commands declaring only ``BYPRODUCTS`` will always
+run unconditionally.
+You can use this variable to make FASTBuild rerun the command only when its
+inputs have changed or the byproduct file is missing.
+
+.. note::
+
+   When this variable is ``OFF`` (the default), ``BYPRODUCTS`` are treated
+   similarly to how Ninja handles them — as opaque side effects — and the
+   generator emits ``ExecAlways`` nodes to ensure they always run.
+
+Defaults to ``OFF``.
diff --git a/Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst b/Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst
new file mode 100644
index 0000000..cf2bc19
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_USE_DETERMINISTIC_PATHS
+---------------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``UseDeterministicPaths_Experimental`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_USE_LIGHTCACHE.rst b/Help/variable/CMAKE_FASTBUILD_USE_LIGHTCACHE.rst
new file mode 100644
index 0000000..e3498d9
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_USE_LIGHTCACHE.rst
@@ -0,0 +1,10 @@
+CMAKE_FASTBUILD_USE_LIGHTCACHE
+-------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild’s *light caching* mode, which accelerates cache lookups by
+parsing source files directly (instead of invoking the compiler preprocessor).
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst b/Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst
new file mode 100644
index 0000000..6fd5571
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_USE_RELATIVE_PATHS.rst
@@ -0,0 +1,9 @@
+CMAKE_FASTBUILD_USE_RELATIVE_PATHS
+----------------------------------
+
+.. versionadded:: 4.2
+
+Enables FASTBuild's ``UseRelativePaths_Experimental`` option.
+
+See the `FASTBuild Compiler() documentation <https://www.fastbuild.org/docs/functions/compiler.html>`_
+for more information.
diff --git a/Help/variable/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst b/Help/variable/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst
new file mode 100644
index 0000000..522ed05
--- /dev/null
+++ b/Help/variable/CMAKE_FASTBUILD_VERBOSE_GENERATOR.rst
@@ -0,0 +1,11 @@
+CMAKE_FASTBUILD_VERBOSE_GENERATOR
+----------------------------------
+
+.. versionadded:: 4.2
+
+Enables verbose logging during FASTBuild file generation.
+
+Initialized by the :envvar:`CMAKE_FASTBUILD_VERBOSE_GENERATOR`
+environment variable.
+
+Defaults to ``OFF``.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
index 92758fd..033748a 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION.rst
@@ -3,16 +3,21 @@
 
 .. versionadded:: 3.7
 
+.. versionchanged:: 4.2
+
+  The default sort direction has changed from ``DEC`` to ``ASC``.
+
+
 The sorting direction used by :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER`.
 It can assume one of the following values:
 
 ``ASC``
-  Default.  Ordering is done in ascending mode.
+  Ordering is done in ascending mode.
   The lowest folder found will be tested first.
 
 ``DEC``
-  Ordering is done in descending mode.
+  Default. Ordering is done in descending mode.
   The highest folder found will be tested first.
 
-If :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` is not set or is set to ``NONE``
-this variable has no effect.
+If :variable:`CMAKE_FIND_PACKAGE_SORT_ORDER` is set to ``NONE`` this variable
+has no effect.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
index f1016d9..524b2ef 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_SORT_ORDER.rst
@@ -3,39 +3,40 @@
 
 .. versionadded:: 3.7
 
+.. versionchanged:: 4.2
+
+  The default sort order has changed from ``NONE`` to ``NATURAL``.
+
+
 The default order for sorting directories which match a search path containing
 a glob expression found using :command:`find_package`.  It can assume one of
 the following values:
 
 ``NONE``
-  Default.  No attempt is done to sort directories.
+  No attempt is done to sort directories.
   The first valid package found will be selected.
 
 ``NAME``
   Sort directories lexicographically before searching.
 
 ``NATURAL``
-  Sort directories using natural order (see ``strverscmp(3)`` manual),
+  Default. Sort directories using natural order (see ``strverscmp(3)`` manual),
   i.e. such that contiguous digits are compared as whole numbers.
 
-Natural sorting can be employed to return the highest version when multiple
-versions of the same library are available to be found by
-:command:`find_package`.  For example suppose that the following libraries
-have package configuration files on disk, in a directory of the same name,
-with all such directories residing in the same parent directory:
+Natural sorting is employed by default to return the highest version when
+multiple versions of the same library are available to be found by
+:command:`find_package`.  For example suppose that the following libraries have
+package configuration files on disk, in a directory of the same name, with all
+such directories residing in the same parent directory:
 
-* libX-1.1.0
-* libX-1.2.9
-* libX-1.2.10
+* ``libX-1.1.0``
+* ``libX-1.2.9``
+* ``libX-1.2.10``
 
-By setting ``NATURAL`` order we can select the one with the highest
-version number ``libX-1.2.10``.
-
-.. code-block:: cmake
-
-  set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
-  find_package(libX CONFIG)
+The default order of ``NATURAL`` will select the one with the highest version
+number, i.e. ``libX-1.2.10``.
 
 The sort direction can be controlled using the
-:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable
-(by default descending, e.g. lib-B will be tested before lib-A).
+:variable:`CMAKE_FIND_PACKAGE_SORT_DIRECTION` variable (by default descending,
+i.e. ``libX-1.2`` will be tested before ``libX-1.0`` and  ``lib-B`` will be
+tested before ``lib-A``).
diff --git a/Help/variable/CMAKE_FIND_REQUIRED.rst b/Help/variable/CMAKE_FIND_REQUIRED.rst
index 0518edb..cb3f4b1 100644
--- a/Help/variable/CMAKE_FIND_REQUIRED.rst
+++ b/Help/variable/CMAKE_FIND_REQUIRED.rst
@@ -22,6 +22,6 @@
 Multiple calls to :command:`find_package` are sometimes used to obtain a
 different search order to the default.
 
-See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` for making
-a :command:`find_package` call ``REQUIRED``, and for additional information on
-how enabling these variables can break commonly used patterns.
+See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable for
+making a :command:`find_package` call ``REQUIRED``, and for additional
+information on how enabling these variables can break commonly used patterns.
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
index 2bf5f05..6e2ecc3 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
@@ -7,9 +7,10 @@
 
 When ``CMAKE_GLOBAL_AUTOGEN_TARGET`` is enabled, a custom target
 ``autogen`` is generated.  This target depends on all :prop_tgt:`AUTOMOC` and
-:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project.
-By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and
-:prop_tgt:`AUTOUIC` files in the project will be generated.
+:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
+targets in the project.  By building the global ``autogen`` target, all
+:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` files in the project will be
+generated.
 
 The name of the global ``autogen`` target can be changed by setting
 :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME`.
@@ -21,7 +22,8 @@
 
 .. note::
 
-    :ref:`<ORIGIN>_autogen` targets by default inherit their origin target's
-    dependencies. This might result in unintended dependency target builds when
-    only :ref:`<ORIGIN>_autogen` targets are built.  A solution is to disable
-    :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on the respective origin targets.
+    :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets by default inherit their
+    origin target's dependencies. This might result in unintended dependency
+    target builds when only :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets
+    are built.  A solution is to disable :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on
+    the respective origin targets.
diff --git a/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst b/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst
new file mode 100644
index 0000000..4c71d73
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst
@@ -0,0 +1,10 @@
+CMAKE_INSTALL_OBJECT_NAME_STRATEGY
+----------------------------------
+
+.. versionadded:: 4.2
+
+Strategy to use for naming installed object files.
+
+``CMAKE_INSTALL_OBJECT_NAME_STRATEGY`` is used to initialize the
+:prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` property on all targets.  See that
+target property for more information.
diff --git a/Help/variable/CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION.rst b/Help/variable/CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION.rst
new file mode 100644
index 0000000..cb5fa56
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION.rst
@@ -0,0 +1,11 @@
+CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION
+-----------------------------------------
+
+.. versionadded:: 4.2
+
+Controls whether the ``install(DESTINATION)`` for object libraries is used
+as-is or supplemented with conflict-avoiding subdirectories.
+
+``CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION`` is used to initialize the
+:prop_tgt:`INSTALL_OBJECT_ONLY_USE_DESTINATION` property on all targets.  See
+that target property for more information.
diff --git a/Help/variable/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst b/Help/variable/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst
new file mode 100644
index 0000000..1d26ffd
--- /dev/null
+++ b/Help/variable/CMAKE_INTERMEDIATE_DIR_STRATEGY.rst
@@ -0,0 +1,35 @@
+CMAKE_INTERMEDIATE_DIR_STRATEGY
+-------------------------------
+
+.. versionadded:: 4.2
+
+``CMAKE_INTERMEDIATE_DIR_STRATEGY`` is a string cache variable specifying the
+strategy to use for target intermediate directories and their contents. The
+supported values are:
+
+- ``FULL``: Intermediate directories are named based on a
+  ``<TARGET_NAME>.dir`` pattern (with some slight deviations and sanitizations
+  applied in various places). Object file names are based on the filename of
+  the source file being compiled or, if set, its :prop_sf:`OBJECT_NAME`
+  property.
+- ``SHORT``: Intermediate directories are named from the hash of the target
+  name and the build directory location. Object file names are based on hashes
+  of the source file name to reduce path lengths. This may help with projects
+  that generate long paths in the build directory to support building in
+  directories other than those near a root path.
+
+When unset or the named strategy is not supported, the ``FULL`` strategy is
+used.
+
+.. note::
+  This only works as a cache variable, not a locally-scoped variable.
+
+This is supported by the following generators:
+
+- :ref:`Ninja Generators`
+- :ref:`Makefile Generators`
+- :ref:`Visual Studio Generators`
+
+.. note::
+  Not all generators support all strategies and paths may differ between
+  generators.
diff --git a/Help/variable/CMAKE_LANG_BYTE_ORDER.rst b/Help/variable/CMAKE_LANG_BYTE_ORDER.rst
index 78f0ae6..da60af6 100644
--- a/Help/variable/CMAKE_LANG_BYTE_ORDER.rst
+++ b/Help/variable/CMAKE_LANG_BYTE_ORDER.rst
@@ -18,3 +18,78 @@
 If :variable:`CMAKE_OSX_ARCHITECTURES` specifies multiple architectures, the
 value of ``CMAKE_<LANG>_BYTE_ORDER`` is non-empty only if all architectures
 share the same byte order.
+
+Examples
+^^^^^^^^
+
+Example: Checking Endianness
+""""""""""""""""""""""""""""
+
+Checking endianness (byte order) of the target architecture in a CMake
+project, where ``C`` language is one of the enabled languages, and storing
+the result in a variable ``WORDS_BIGENDIAN``:
+
+.. code-block:: cmake
+
+  if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+    set(WORDS_BIGENDIAN TRUE)
+  elseif(CMAKE_C_BYTE_ORDER STREQUAL "LITTLE_ENDIAN")
+    set(WORDS_BIGENDIAN FALSE)
+  else()
+    set(WORDS_BIGENDIAN FALSE)
+    message(WARNING "Endianness could not be determined.")
+  endif()
+
+Or, if the project doesn't have ``C`` language enabled, it can be replaced
+with some other enabled language.  For example, if ``CXX`` is enabled:
+
+.. code-block:: cmake
+
+  if(CMAKE_CXX_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+    set(WORDS_BIGENDIAN TRUE)
+  elseif(CMAKE_CXX_BYTE_ORDER STREQUAL "LITTLE_ENDIAN")
+    set(WORDS_BIGENDIAN FALSE)
+  else()
+    set(WORDS_BIGENDIAN FALSE)
+    message(WARNING "Endianness could not be determined.")
+  endif()
+
+Note, that in most cases this can be simplified by only checking for a
+big-endian target:
+
+.. code-block:: cmake
+
+  if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+    set(WORDS_BIGENDIAN TRUE)
+  else()
+    set(WORDS_BIGENDIAN FALSE)
+  endif()
+
+Example: Per-language Endianness Check
+""""""""""""""""""""""""""""""""""""""
+
+Most of the time, architectures used today are consistent in endianness
+across compilers.  But here's when per-language endianness check can matter:
+
+* Cross-compilation to different architectures (e.g., big-endian embedded
+  system).
+
+* Heterogeneous toolchains where one target architecture is for C language
+  and another target is for different language.
+
+* Static libraries or binaries reused across platforms (e.g., distributing
+  precompiled CUDA kernels).
+
+.. code-block:: cmake
+
+  if(CMAKE_C_BYTE_ORDER)
+    message(STATUS "C byte order: ${CMAKE_C_BYTE_ORDER}")
+  endif()
+
+  if(CMAKE_CXX_BYTE_ORDER)
+    message(STATUS "C++ byte order: ${CMAKE_CXX_BYTE_ORDER}")
+  endif()
+
+  if(CMAKE_CUDA_BYTE_ORDER)
+    message(STATUS "CUDA byte order: ${CMAKE_CUDA_BYTE_ORDER}")
+  endif()
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
index 1efbf1c..c6853e3 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ARCHITECTURE_ID.rst
@@ -123,6 +123,15 @@
 ``sparcv9``
   SPARC 64-bit
 
+``sw_64``
+  Sunway
+
+``wasm32``
+  WebAssembly (Emscripten) 32-bit
+
+``wasm64``
+  WebAssembly (Emscripten) 64-bit
+
 ``x86_64``
   Intel 64-bit
 
diff --git a/Help/variable/CMAKE_LANG_LINK_MODE.rst b/Help/variable/CMAKE_LANG_LINK_MODE.rst
index 6025671..f8286e4 100644
--- a/Help/variable/CMAKE_LANG_LINK_MODE.rst
+++ b/Help/variable/CMAKE_LANG_LINK_MODE.rst
@@ -12,3 +12,8 @@
   The linker is used directly for the link step.
 
 This variable is read-only. Setting it is undefined behavior.
+
+See Also
+^^^^^^^^
+
+* The :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable.
diff --git a/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
index 7b252aa..a3d6c97 100644
--- a/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
+++ b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
@@ -1,10 +1,17 @@
 CMAKE_<LANG>_USING_LINKER_MODE
 ------------------------------
 
+.. deprecated:: 4.0
+
+  This variable is no longer used.  The type of information stored in the
+  :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable is determined by
+  the :variable:`CMAKE_<LANG>_LINK_MODE` variable.
+
 .. versionadded:: 3.29
 
-This controls how the value of the :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>`
-variable should be interpreted. The supported linker mode values are:
+This variable controls how the value of the
+:variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable should be interpreted.
+The supported linker mode values are:
 
 ``FLAG``
   :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` holds a
@@ -22,11 +29,5 @@
 
   * value ``TOOL`` is expected and required when the linker is used directly
     for the link step.
-  * value ``FLAGS`` is expected or the variable not set when the compiler is
+  * value ``FLAG`` is expected or the variable not set when the compiler is
     used as driver for the link step.
-
-.. deprecated:: 4.0
-
-This variable is no longer used. The type of information stored in the
-:variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable is determined by the
-:variable:`CMAKE_<LANG>_LINK_MODE` variable.
diff --git a/Help/variable/CMAKE_OSX_ARCHITECTURES.rst b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst
index f660df9..3e9e427 100644
--- a/Help/variable/CMAKE_OSX_ARCHITECTURES.rst
+++ b/Help/variable/CMAKE_OSX_ARCHITECTURES.rst
@@ -7,4 +7,8 @@
 property on each target as it is created.  See that target property
 for additional information.
 
+If ``CMAKE_OSX_ARCHITECTURES`` is not set, the compiler's default target
+architecture is used.  For compilers provided by Xcode, this is the host
+machine's architecture.
+
 .. include:: include/CMAKE_OSX_VARIABLE.rst
diff --git a/Help/variable/CMAKE_PARENT_LIST_FILE.rst b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
index 7e71efa..c0c6469 100644
--- a/Help/variable/CMAKE_PARENT_LIST_FILE.rst
+++ b/Help/variable/CMAKE_PARENT_LIST_FILE.rst
@@ -8,7 +8,8 @@
 including it.
 
 While processing a ``CMakeLists.txt`` file, even in subdirectories,
-this variable has the same value as :variable:`CMAKE_CURRENT_LIST_FILE`.
+this variable is not defined.  See policy :policy:`CMP0198`.
+
 While processing a :option:`cmake -P` script, this variable is not defined
 in the outermost script.
 
diff --git a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
index f83246a..19f5e57 100644
--- a/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
+++ b/Help/variable/CMAKE_POSITION_INDEPENDENT_CODE.rst
@@ -1,9 +1,19 @@
 CMAKE_POSITION_INDEPENDENT_CODE
 -------------------------------
 
-Default value for :prop_tgt:`POSITION_INDEPENDENT_CODE` of targets.
+Default value for the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property.
 
 This variable is used to initialize the
 :prop_tgt:`POSITION_INDEPENDENT_CODE` property on targets that
 are not ``SHARED`` or ``MODULE`` library targets.
 If set, its value is also used by the :command:`try_compile` command.
+
+The ``SHARED`` and ``MODULE`` library targets have by default position
+independent code enabled regardless of this variable.  To disable PIC on
+these library types, only manually setting the target property disables it.
+
+See Also
+^^^^^^^^
+
+* The :module:`CheckPIESupported` module to pass PIE-related options to the
+  linker for executables.
diff --git a/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
new file mode 100644
index 0000000..0cbde7c
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
@@ -0,0 +1,41 @@
+CMAKE_PROJECT_SPDX_LICENSE
+--------------------------
+
+.. versionadded:: 4.2
+
+.. note::
+
+  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+
+The license(s) of the top level project.
+
+This variable holds the license expression of the project as specified in the
+top level CMakeLists.txt file by a :command:`project` command.  In the event
+that the top level CMakeLists.txt contains multiple :command:`project` calls,
+the most recently called one from that top level CMakeLists.txt will determine
+the value that ``CMAKE_PROJECT_SPDX_LICENSE`` contains.  For example, consider
+the following top level CMakeLists.txt:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 4.2)
+  project(First SPDX_LICENSE "BSD-3-Clause")
+  project(Second SPDX_LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
+  add_subdirectory(sub)
+  project(Third SPDX_LICENSE "BSD-3-Clause AND CC0-1.0")
+
+And ``sub/CMakeLists.txt`` with the following contents:
+
+.. code-block:: cmake
+
+  project(SubProj SPDX_LICENSE Apache-2.0)
+  message("CMAKE_PROJECT_SPDX_LICENSE = ${CMAKE_PROJECT_SPDX_LICENSE}")
+
+The most recently seen :command:`project` command from the top level
+CMakeLists.txt would be ``project(Second ...)``, so this will print::
+
+  CMAKE_PROJECT_SPDX_LICENSE = BSD-3-Clause AND CC-BY-SA-4.0
+
+To obtain the version from the most recent call to :command:`project` in
+the current directory scope or above, see the :variable:`PROJECT_SPDX_LICENSE`
+variable.
diff --git a/Help/variable/CMAKE_SKIP_LINTING.rst b/Help/variable/CMAKE_SKIP_LINTING.rst
new file mode 100644
index 0000000..72fe635
--- /dev/null
+++ b/Help/variable/CMAKE_SKIP_LINTING.rst
@@ -0,0 +1,9 @@
+CMAKE_SKIP_LINTING
+------------------
+
+.. versionadded:: 4.2
+
+Default value for the :prop_tgt:`SKIP_LINTING` target property.
+
+This is used to initialize the :prop_tgt:`SKIP_LINTING` target property
+for all targets created *afterward*.
diff --git a/Help/variable/CMAKE_SOURCE_DIR.rst b/Help/variable/CMAKE_SOURCE_DIR.rst
index f1d1bee..be28f4d 100644
--- a/Help/variable/CMAKE_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_SOURCE_DIR.rst
@@ -11,3 +11,5 @@
 :variable:`CMAKE_BINARY_DIR`, ``CMAKE_SOURCE_DIR``,
 :variable:`CMAKE_CURRENT_BINARY_DIR` and
 :variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
+
+Modifying ``CMAKE_SOURCE_DIR`` has undefined behavior.
diff --git a/Help/variable/CMAKE_SYSTEM_NAME.rst b/Help/variable/CMAKE_SYSTEM_NAME.rst
index 41c1b78..de688b5 100644
--- a/Help/variable/CMAKE_SYSTEM_NAME.rst
+++ b/Help/variable/CMAKE_SYSTEM_NAME.rst
@@ -104,3 +104,15 @@
 * Cygwin's ``cmake`` package (``/usr/bin/cmake``) uses system name ``CYGWIN``.
   A non-cygwin CMake on Windows (e.g. ``$PROGRAMFILES/CMake/bin/cmake``)
   uses system name ``Windows`` even when it runs under a Cygwin environment.
+
+Removed Platforms
+^^^^^^^^^^^^^^^^^
+
+The following platforms were once supported by CMake and got removed either due
+to platform's EOL, or other incompatibilities:
+
+========================= ===================================== ================
+Value                     Name                                  Removed in CMake
+========================= ===================================== ================
+``kFreeBSD``              FreeBSD kernel with a GNU userland    4.1
+========================= ===================================== ================
diff --git a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst
index c7e4148..afad4b2 100644
--- a/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst
+++ b/Help/variable/CMAKE_VS_PLATFORM_TOOLSET_FORTRAN.rst
@@ -9,4 +9,11 @@
 that have the required Visual Studio Integration feature installed.  The
 compiler may be specified by a field in :variable:`CMAKE_GENERATOR_TOOLSET` of
 the form ``fortran=...``. CMake provides the selected Fortran compiler in this
-variable. The value may be empty if the field was not specified.
+variable.
+
+If the field was not specified, the default depends on the generator:
+
+* On :generator:`Visual Studio 18 2026` and above, the default is ``ifx``.
+
+* On older :ref:`Visual Studio Generators`, the default is empty, which the
+  Intel Visual Studio Integration interprets as equivalent to ``ifort``.
diff --git a/Help/variable/MSVC_TOOLSET_VERSION.rst b/Help/variable/MSVC_TOOLSET_VERSION.rst
index 84a6f33..cfd24ab 100644
--- a/Help/variable/MSVC_TOOLSET_VERSION.rst
+++ b/Help/variable/MSVC_TOOLSET_VERSION.rst
@@ -24,6 +24,7 @@
   141   VS 2017 (15.0)
   142   VS 2019 (16.0)
   143   VS 2022 (17.0)
+  145   VS 2026 (18.0)
   ===== ==============
 
 Compiler versions newer than those known to CMake will be reported
diff --git a/Help/variable/MSVC_VERSION.rst b/Help/variable/MSVC_VERSION.rst
index 4d87a03..e3140a9 100644
--- a/Help/variable/MSVC_VERSION.rst
+++ b/Help/variable/MSVC_VERSION.rst
@@ -26,6 +26,7 @@
   1910-1919 VS 15.0 (v141 toolset)
   1920-1929 VS 16.0 (v142 toolset)
   1930-1949 VS 17.0 (v143 toolset)
+  1950-1959 VS 18.0 (v145 toolset)
   ========= ==============
 
 See also the  :variable:`CMAKE_<LANG>_COMPILER_VERSION` and
diff --git a/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
new file mode 100644
index 0000000..06c395d
--- /dev/null
+++ b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
@@ -0,0 +1,11 @@
+<PROJECT-NAME>_SPDX_LICENSE
+---------------------------
+
+.. versionadded:: 4.2
+
+.. note::
+
+  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+
+Value given to the ``SPDX_LICENSE`` option of the most recent call to the
+:command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_SPDX_LICENSE.rst b/Help/variable/PROJECT_SPDX_LICENSE.rst
new file mode 100644
index 0000000..4f62e94
--- /dev/null
+++ b/Help/variable/PROJECT_SPDX_LICENSE.rst
@@ -0,0 +1,12 @@
+PROJECT_SPDX_LICENSE
+--------------------
+
+.. versionadded:: 4.2
+
+.. note::
+
+  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+
+Value given to the ``SPDX_LICENSE`` option of the most recent call to the
+:command:`project` command, if any. To obtain the compatibility version of the
+top level project, see the :variable:`CMAKE_PROJECT_SPDX_LICENSE` variable.
diff --git a/Modules/AddFileDependencies.cmake b/Modules/AddFileDependencies.cmake
index 13828f2..25a78a8 100644
--- a/Modules/AddFileDependencies.cmake
+++ b/Modules/AddFileDependencies.cmake
@@ -6,28 +6,38 @@
 -------------------
 
 .. deprecated:: 3.20
+  Do not use this module in new code.
 
-Add dependencies to a source file.
+  Instead use the :command:`set_property` command to append to the
+  :prop_sf:`OBJECT_DEPENDS` source file property directly:
+
+  .. code-block:: cmake
+
+    set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
+
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
-  add_file_dependencies(<source> <files>...)
+  include(AddFileDependencies)
 
-Adds the given ``<files>`` to the dependencies of file ``<source>``.
+Commands
+^^^^^^^^
 
-Do not use this command in new code.  It is just a wrapper around:
+This module provides the following command:
 
-.. code-block:: cmake
+.. command:: add_file_dependencies
 
-  set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
+  Adds dependencies to a source file:
 
-Instead use the :command:`set_property` command to append to the
-:prop_sf:`OBJECT_DEPENDS` source file property directly.
+  .. code-block:: cmake
 
+    add_file_dependencies(<source> <files>...)
+
+  This command adds the given ``<files>`` to the dependencies of file
+  ``<source>``.
 #]=======================================================================]
 
 function(add_file_dependencies _file)
-
   set_property(SOURCE "${_file}" APPEND PROPERTY OBJECT_DEPENDS "${ARGN}")
-
 endfunction()
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake
index 4df5bb9..40821e0 100644
--- a/Modules/BundleUtilities.cmake
+++ b/Modules/BundleUtilities.cmake
@@ -9,7 +9,7 @@
 bundle-style applications with CMake, such as macOS ``.app`` bundles or
 similar directory-based application bundles on other operating systems.
 
-Load this module in CMake installation with:
+Load this module in a CMake installation with:
 
 .. code-block:: cmake
 
@@ -733,7 +733,9 @@
     string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}")
     if(load_cmds_ov)
       foreach(rpath ${load_cmds_ov})
-        gp_append_unique(${rpaths_var} "${rpath}")
+        if(NOT rpath IN_LIST ${rpaths_var})
+          list(APPEND ${rpaths_var} "${rpath}")
+        endif()
       endforeach()
     endif()
   endif()
@@ -744,7 +746,9 @@
     foreach(rpath ${rpath_var} ${runpath_var})
       # Substitute $ORIGIN with the exepath and add to the found rpaths
       string(REPLACE "$ORIGIN" "${item_dir}" rpath "${rpath}")
-      gp_append_unique(${rpaths_var} "${rpath}")
+      if(NOT rpath IN_LIST ${rpaths_var})
+        list(APPEND ${rpaths_var} "${rpath}")
+      endif()
     endforeach()
   endif()
 
@@ -787,7 +791,9 @@
   get_item_key("${item}" key)
 
   list(LENGTH ${keys_var} length_before)
-  gp_append_unique(${keys_var} "${key}")
+  if(NOT key IN_LIST ${keys_var})
+    list(APPEND ${keys_var} "${key}")
+  endif()
   list(LENGTH ${keys_var} length_after)
 
   if(NOT length_before EQUAL length_after)
diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake
index 9b386b0..7eec1f2 100644
--- a/Modules/CMakeAddFortranSubdirectory.cmake
+++ b/Modules/CMakeAddFortranSubdirectory.cmake
@@ -8,7 +8,7 @@
 This module provides a command to add a Fortran project located in a
 subdirectory.
 
-Load it in a CMake project with:
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
diff --git a/Modules/CMakeCSharpCompilerId.cs.in b/Modules/CMakeCSharpCompilerId.cs.in
index b43ec04..7a9011b 100644
--- a/Modules/CMakeCSharpCompilerId.cs.in
+++ b/Modules/CMakeCSharpCompilerId.cs.in
@@ -19,6 +19,8 @@
         + "Visual Studio"
 #elif PlatformToolsetv143
         + "Visual Studio"
+#elif PlatformToolsetv145
+        + "Visual Studio"
 #else
         + "unknown"
 #endif
@@ -53,6 +55,8 @@
         + "2019"
 #elif PlatformToolsetv143
         + "2022"
+#elif PlatformToolsetv145
+        + "2026"
 #else
         + "9999"
 #endif
diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
index ef9f138..92fdc69 100644
--- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
+++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
@@ -8,34 +8,34 @@
 
 macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR)
   set(${_VAR}
-    FAIL_REGEX "[Uu]nrecogni[sz]ed .*option"               # GNU, NAG, Fujitsu
-    FAIL_REGEX "switch .* is no longer supported"          # GNU
-    FAIL_REGEX "unknown .*option"                          # Clang
-    FAIL_REGEX "optimization flag .* not supported"        # Clang
-    FAIL_REGEX "unknown argument ignored"                  # Clang (cl)
-    FAIL_REGEX "ignoring unknown option"                   # MSVC, Intel
-    FAIL_REGEX "warning D9002"                             # MSVC, any lang
-    FAIL_REGEX "option.*not supported"                     # Intel
-    FAIL_REGEX "invalid argument .*option"                 # Intel
-    FAIL_REGEX "ignoring option .*argument required"       # Intel
-    FAIL_REGEX "ignoring option .*argument is of wrong type" # Intel
+    FAIL_REGEX "[Uu]nrecogni[sz]ed [^\n]*option"                             # GNU, NAG, Fujitsu
+    FAIL_REGEX "switch [^\n]* is no longer supported"                        # GNU
+    FAIL_REGEX "unknown [^\n]*option"                                        # Clang
+    FAIL_REGEX "optimization flag [^\n]* not supported"                      # Clang
+    FAIL_REGEX "unknown argument ignored"                                    # Clang (cl)
+    FAIL_REGEX "ignoring unknown option"                                     # MSVC, Intel
+    FAIL_REGEX "warning D9002"                                               # MSVC, any lang
+    FAIL_REGEX "option[^\n]*not supported"                                   # Intel
+    FAIL_REGEX "invalid argument [^\n]*option"                               # Intel
+    FAIL_REGEX "ignoring option [^\n]*argument required"                     # Intel
+    FAIL_REGEX "ignoring option [^\n]*argument is of wrong type"             # Intel
     # noqa: spellcheck off
-    FAIL_REGEX "[Uu]nknown option"                         # HP
+    FAIL_REGEX "[Uu]nknown option"                                           # HP
     # noqa: spellcheck on
-    FAIL_REGEX "[Ww]arning: [Oo]ption"                     # SunPro
-    FAIL_REGEX "command option .* is not recognized"       # XL
-    FAIL_REGEX "command option .* contains an incorrect subargument" # XL
-    FAIL_REGEX "Option .* is not recognized.  Option will be ignored." # XL
-    FAIL_REGEX "not supported in this configuration. ignored"       # AIX
-    FAIL_REGEX "File with unknown suffix passed to linker" # PGI
+    FAIL_REGEX "[Ww]arning: [Oo]ption"                                       # SunPro
+    FAIL_REGEX "command option [^\n]* is not recognized"                     # XL
+    FAIL_REGEX "command option [^\n]* contains an incorrect subargument"     # XL
+    FAIL_REGEX "Option [^\n]* is not recognized.  Option will be ignored."   # XL
+    FAIL_REGEX "not supported in this configuration. ignored"                # AIX
+    FAIL_REGEX "File with unknown suffix passed to linker"                   # PGI
     # noqa: spellcheck off
-    FAIL_REGEX "[Uu]nknown switch"                         # PGI
+    FAIL_REGEX "[Uu]nknown switch"                                           # PGI
     # noqa: spellcheck on
-    FAIL_REGEX "WARNING: unknown flag:"                    # Open64
-    FAIL_REGEX "Incorrect command line option:"            # Borland
-    FAIL_REGEX "Warning: illegal option"                   # SunStudio 12
-    FAIL_REGEX "[Ww]arning: Invalid suboption"             # Fujitsu
-    FAIL_REGEX "An invalid option .* appears on the command line" # Cray
-    FAIL_REGEX "WARNING: invalid compiler option"          # TI armcl
+    FAIL_REGEX "WARNING: unknown flag:"                                      # Open64
+    FAIL_REGEX "Incorrect command line option:"                              # Borland
+    FAIL_REGEX "Warning: illegal option"                                     # SunStudio 12
+    FAIL_REGEX "[Ww]arning: Invalid suboption"                               # Fujitsu
+    FAIL_REGEX "An invalid option [^\n]* appears on the command line"        # Cray
+    FAIL_REGEX "WARNING: invalid compiler option"                            # TI armcl
   )
 endmacro ()
diff --git a/Modules/CMakeCompilerABI.h b/Modules/CMakeCompilerABI.h
index dc71f9f..bd90ea2 100644
--- a/Modules/CMakeCompilerABI.h
+++ b/Modules/CMakeCompilerABI.h
@@ -114,6 +114,8 @@
 #  define ARCHITECTURE_ID "riscv64"
 #elif defined(__riscv) && __riscv_xlen == 32
 #  define ARCHITECTURE_ID "riscv32"
+#elif defined(__sw_64)
+#  define ARCHITECTURE_ID "sw_64"
 #elif defined(__s390x__)
 #  define ARCHITECTURE_ID "s390x"
 #elif defined(__s390__)
@@ -142,6 +144,10 @@
 #  else
 #    define ARCHITECTURE_ID "ppc"
 #  endif
+#elif defined(__wasm64) || defined(__wasm64__)
+#  define ARCHITECTURE_ID "wasm64"
+#elif defined(__wasm32) || defined(__wasm32__)
+#  define ARCHITECTURE_ID "wasm32"
 #endif
 
 /* Construct the string literal in pieces to prevent the source from
diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake
index 3db05da..0d840fc 100644
--- a/Modules/CMakeDependentOption.cmake
+++ b/Modules/CMakeDependentOption.cmake
@@ -10,7 +10,7 @@
 maintain a clean configuration interface by only displaying options that are
 relevant to the current settings.
 
-Load this module in a CMake project with:
+Load this module in CMake with:
 
 .. code-block:: cmake
 
@@ -82,6 +82,9 @@
     The value assigned to a local variable named ``<variable>``, when
     ``<condition>`` evaluates to boolean false.
 
+  In CMake project mode, boolean cache variables are created as explained
+  above.  In CMake script mode, boolean variables are set instead.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index edb3cc8..44456d6 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -4,9 +4,10 @@
 include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
 
-if(NOT ((CMAKE_GENERATOR MATCHES "Make") OR
-        (CMAKE_GENERATOR MATCHES "Ninja") OR
-        (CMAKE_GENERATOR MATCHES "Visual Studio (1|[9][0-9])")))
+if( NOT ( ("${CMAKE_GENERATOR}" MATCHES "Make") OR
+          ("${CMAKE_GENERATOR}" MATCHES "Ninja") OR
+          ("${CMAKE_GENERATOR}" MATCHES "FASTBuild") OR
+          ("${CMAKE_GENERATOR}" MATCHES "Visual Studio (1|[9][0-9])") ) )
   message(FATAL_ERROR "CUDA language not currently supported by \"${CMAKE_GENERATOR}\" generator")
 endif()
 
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index 16c5554..097916e 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -137,9 +137,13 @@
     execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -print-sysroot
       OUTPUT_STRIP_TRAILING_WHITESPACE
       OUTPUT_VARIABLE _cmake_sysroot_run_out
-      ERROR_VARIABLE _cmake_sysroot_run_err)
+      ERROR_VARIABLE _cmake_sysroot_run_err
+      RESULT_VARIABLE _cmake_sysroot_run_res
+    )
 
-    if(_cmake_sysroot_run_out AND NOT _cmake_sysroot_run_err
+    if(_cmake_sysroot_run_res EQUAL 0
+        AND _cmake_sysroot_run_out
+        AND NOT _cmake_sysroot_run_err
         AND NOT _cmake_sysroot_run_out STREQUAL "/"
         AND IS_DIRECTORY "${_cmake_sysroot_run_out}/usr")
       file(TO_CMAKE_PATH "${_cmake_sysroot_run_out}/usr" _cmake_sysroot_run_out_usr)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 2b7d797..d431f04 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -242,7 +242,7 @@
     set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
   endif()
 
-  if((CMAKE_GENERATOR MATCHES "^Ninja"
+  if((CMAKE_GENERATOR MATCHES "^Ninja|FASTBuild"
         OR ((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
           AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"))
       AND MSVC_${lang}_ARCHITECTURE_ID)
@@ -604,7 +604,7 @@
       set(id_api_level "<AndroidAPILevel>android-${CMAKE_SYSTEM_VERSION}</AndroidAPILevel>")
       if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
         set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
-      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
+      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[5678]")
         set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
       else()
         set(id_system_version "")
diff --git a/Modules/CMakeFastbuildFindMake.cmake b/Modules/CMakeFastbuildFindMake.cmake
new file mode 100644
index 0000000..d37fac6
--- /dev/null
+++ b/Modules/CMakeFastbuildFindMake.cmake
@@ -0,0 +1,7 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+find_program(CMAKE_MAKE_PROGRAM
+  NAMES fbuild
+  DOC "Program used to build from FASTBuild .bff files.")
+mark_as_advanced(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index 1948c63..91543a6 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -219,6 +219,11 @@
     list(PREPEND _CMAKE_LINKER_NAMES "armlink")
   endif()
 
+  if(EMSCRIPTEN)
+    list(PREPEND _CMAKE_AR_NAMES "emar")
+    list(PREPEND _CMAKE_RANLIB_NAMES "emranlib")
+  endif()
+
   list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE TAPI)
 endif()
 
@@ -259,8 +264,7 @@
 
 
 if(CMAKE_PLATFORM_HAS_INSTALLNAME)
-  find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
-
+  find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool llvm-install-name-tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
   if(NOT CMAKE_INSTALL_NAME_TOOL)
     message(FATAL_ERROR "Could not find install_name_tool, please check your installation.")
   endif()
diff --git a/Modules/CMakeFindDependencyMacro.cmake b/Modules/CMakeFindDependencyMacro.cmake
index 99624d2..fba1f63 100644
--- a/Modules/CMakeFindDependencyMacro.cmake
+++ b/Modules/CMakeFindDependencyMacro.cmake
@@ -5,6 +5,26 @@
 CMakeFindDependencyMacro
 ------------------------
 
+This module provides a command implemented as a macro that finds dependency
+for a package.
+
+Load this module in a CMake package configuration file with:
+
+.. code-block:: cmake
+  :caption: ``FooConfig.cmake`` or ``foo-config.cmake``:
+
+  include(CMakeFindDependencyMacro)
+
+.. note::
+
+  This module is designed to be used in a :ref:`Package Configuration File
+  <Config File Packages>` (``<PackageName>Config.cmake``).
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
+
 .. command:: find_dependency
 
   The ``find_dependency()`` macro wraps a :command:`find_package` call for
@@ -56,44 +76,59 @@
 
 #]=======================================================================]
 
-macro(find_dependency dep)
+macro(__find_dependency_common cmake_fd_call_hash dep)
+  set(cmake_fd_quiet_arg)
+  if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
+    set(cmake_fd_quiet_arg QUIET)
+  endif()
+  set(cmake_fd_required_arg)
+  if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
+    set(cmake_fd_required_arg REQUIRED)
+  endif()
+
+  get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY
+    _CMAKE_${dep}_TRANSITIVE_DEPENDENCY
+    )
+
+  find_package(${dep} ${ARGN}
+    ${cmake_fd_quiet_arg}
+    ${cmake_fd_required_arg}
+    )
+  set("_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND" "${${dep}_FOUND}")
+
+  if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive)
+    set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE)
+  endif()
+
+  unset(cmake_fd_alreadyTransitive)
+  unset(cmake_fd_quiet_arg)
+  unset(cmake_fd_required_arg)
+endmacro()
+
+macro(__find_dependency_no_return dep)
   string(SHA256 cmake_fd_call_hash "${dep};${ARGN};${${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED}")
   if(_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND)
-    unset(cmake_fd_call_hash)
+    set(${dep}_FOUND ${_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND})
   else()
-    list(APPEND _CMAKE_${dep}_HASH_STACK ${cmake_fd_call_hash})
-    set(cmake_fd_quiet_arg)
-    if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
-      set(cmake_fd_quiet_arg QUIET)
-    endif()
-    set(cmake_fd_required_arg)
-    if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED)
-      set(cmake_fd_required_arg REQUIRED)
-    endif()
-
-    get_property(cmake_fd_alreadyTransitive GLOBAL PROPERTY
-      _CMAKE_${dep}_TRANSITIVE_DEPENDENCY
-      )
-
-    find_package(${dep} ${ARGN}
-      ${cmake_fd_quiet_arg}
-      ${cmake_fd_required_arg}
-      )
-    list(POP_BACK _CMAKE_${dep}_HASH_STACK cmake_fd_call_hash)
-    set("_CMAKE_${dep}_${cmake_fd_call_hash}_FOUND" "${${dep}_FOUND}")
-
-    if(NOT DEFINED cmake_fd_alreadyTransitive OR cmake_fd_alreadyTransitive)
-      set_property(GLOBAL PROPERTY _CMAKE_${dep}_TRANSITIVE_DEPENDENCY TRUE)
-    endif()
-
-    unset(cmake_fd_alreadyTransitive)
-    unset(cmake_fd_call_hash)
-    unset(cmake_fd_quiet_arg)
-    unset(cmake_fd_required_arg)
+    __find_dependency_common(${cmake_fd_call_hash} ${ARGV})
     if (NOT ${dep}_FOUND)
       set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.")
       set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False)
+    endif()
+  endif()
+  unset(cmake_fd_call_hash)
+endmacro()
+
+macro(find_dependency dep)
+  string(SHA256 cmake_fd_call_hash "${dep};${ARGN};${${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED}")
+  if(NOT _CMAKE_${dep}_${cmake_fd_call_hash}_FOUND)
+    __find_dependency_common(${cmake_fd_call_hash} ${ARGV})
+    if (NOT ${dep}_FOUND)
+      set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency ${dep} could not be found.")
+      set(${CMAKE_FIND_PACKAGE_NAME}_FOUND False)
+      unset(cmake_fd_call_hash)
       return()
     endif()
   endif()
+  unset(cmake_fd_call_hash)
 endmacro()
diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake
index e85c3f9..9b85c68 100644
--- a/Modules/CMakeForceCompiler.cmake
+++ b/Modules/CMakeForceCompiler.cmake
@@ -9,66 +9,98 @@
 
   Do not use.
 
-The macros provided by this module were once intended for use by
-cross-compiling toolchain files when CMake was not able to automatically
-detect the compiler identification.  Since the introduction of this module,
-CMake's compiler identification capabilities have improved and can now be
-taught to recognize any compiler.  Furthermore, the suite of information
-CMake detects from a compiler is now too extensive to be provided by
-toolchain files using these macros.
+  The commands provided by this module were once intended for use by
+  cross-compiling toolchain files when CMake was not able to automatically
+  detect the compiler identification.  Since the introduction of this module,
+  CMake's compiler identification capabilities have improved and can now be
+  taught to recognize any compiler.  Furthermore, the suite of information
+  CMake detects from a compiler is now too extensive to be provided by
+  toolchain files using these macros.
 
-One common use case for this module was to skip CMake's checks for a
-working compiler when using a cross-compiler that cannot link binaries
-without special flags or custom linker scripts.  This case is now supported
-by setting the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable in the
-toolchain file instead.
+  One common use case for this module was to skip CMake's checks for a
+  working compiler when using a cross-compiler that cannot link binaries
+  without special flags or custom linker scripts.  This case is now supported
+  by setting the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable in the
+  toolchain file instead.
 
--------------------------------------------------------------------------
-
-Macro ``CMAKE_FORCE_C_COMPILER`` has the following signature:
+Load this module in a CMake toolchain file:
 
 .. code-block:: cmake
 
-   CMAKE_FORCE_C_COMPILER(<compiler> <compiler-id>)
+  include(CMakeForceCompiler)
 
-It sets :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` to
-the given compiler and the cmake internal variable
-:variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given
-compiler-id.  It also bypasses the check for working compiler and basic
-compiler information tests.
+Commands
+^^^^^^^^
 
-Macro ``CMAKE_FORCE_CXX_COMPILER`` has the following signature:
+This module provides the following commands:
+
+.. command:: cmake_force_c_compiler
+
+  Sets the :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` variable to
+  the given compiler and the :variable:`CMAKE_C_COMPILER_ID
+  <CMAKE_<LANG>_COMPILER_ID>` variable to the given compiler-id:
+
+  .. code-block:: cmake
+
+    cmake_force_c_compiler(<compiler> <compiler-id>)
+
+  This command also bypasses the check for working compiler and basic
+  compiler information tests.
+
+.. command:: cmake_force_cxx_compiler
+
+  Sets the :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variable
+  to the given compiler and the :variable:`CMAKE_CXX_COMPILER_ID
+  <CMAKE_<LANG>_COMPILER_ID>` variable to the given compiler-id:
+
+  .. code-block:: cmake
+
+    cmake_force_cxx_compiler(<compiler> <compiler-id>)
+
+  This command also bypasses the check for working compiler and basic
+  compiler information tests.
+
+.. command:: cmake_force_fortran_compiler
+
+  Sets the :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>`
+  variable to the given compiler and the
+  :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` variable
+  to the given compiler-id:
+
+  .. code-block:: cmake
+
+    cmake_force_fortran_compiler(<compiler> <compiler-id>)
+
+  This command also bypasses the check for working compiler and basic
+  compiler information tests.
+
+Examples
+^^^^^^^^
+
+A simple toolchain file using this module could look like this:
 
 .. code-block:: cmake
+  :caption: ``cmake/toolchains/example-toolchain.cmake``
 
-   CMAKE_FORCE_CXX_COMPILER(<compiler> <compiler-id>)
+  include(CMakeForceCompiler)
+  set(CMAKE_SYSTEM_NAME Generic)
+  cmake_force_c_compiler(chc12 MetrowerksHicross)
+  cmake_force_cxx_compiler(chc12 MetrowerksHicross)
 
-It sets :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` to
-the given compiler and the cmake internal variable
-:variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given
-compiler-id.  It also bypasses the check for working compiler and basic
-compiler information tests.
-
-Macro ``CMAKE_FORCE_Fortran_COMPILER`` has the following signature:
+In new CMake code, compiler is detected automatically when setting required
+variables instead:
 
 .. code-block:: cmake
+  :caption: ``cmake/toolchains/example-toolchain.cmake``
 
-   CMAKE_FORCE_Fortran_COMPILER(<compiler> <compiler-id>)
+  set(CMAKE_SYSTEM_NAME Generic)
+  set(CMAKE_C_COMPILER chc12)
+  set(CMAKE_CXX_COMPILER chc12)
 
-It sets :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>` to
-the given compiler and the cmake internal variable
-:variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given
-compiler-id.  It also bypasses the check for working compiler and basic
-compiler information tests.
+See Also
+^^^^^^^^
 
-So a simple toolchain file could look like this:
-
-.. code-block:: cmake
-
-   include (CMakeForceCompiler)
-   set(CMAKE_SYSTEM_NAME Generic)
-   CMAKE_FORCE_C_COMPILER   (chc12 MetrowerksHicross)
-   CMAKE_FORCE_CXX_COMPILER (chc12 MetrowerksHicross)
+* :manual:`cmake-toolchains(7)`
 #]=======================================================================]
 
 macro(CMAKE_FORCE_C_COMPILER compiler id)
diff --git a/Modules/CMakeFortranCompilerABI.F b/Modules/CMakeFortranCompilerABI.F
index 81676cb..ed82730 100644
--- a/Modules/CMakeFortranCompilerABI.F
+++ b/Modules/CMakeFortranCompilerABI.F
@@ -113,6 +113,8 @@
         PRINT *, 'INFO:arch[riscv64]'
 #elif defined(__riscv) && __riscv_xlen == 32
         PRINT *, 'INFO:arch[riscv32]'
+#elif defined(__sw_64) || defined(__sw_64__)
+        PRINT *, 'INFO:arch[sw_64]'
 #elif defined(__s390x__)
         PRINT *, 'INFO:arch[s390x]'
 #elif defined(__s390__)
@@ -141,6 +143,10 @@
 #  else
         PRINT *, 'INFO:arch[ppc]'
 #  endif
+#elif defined(__wasm64) || defined(__wasm64__)
+        PRINT *, 'INFO:arch[wasm64]'
+#elif defined(__wasm32) || defined(__wasm32__)
+        PRINT *, 'INFO:arch[wasm32]'
 #endif
 
         PRINT *, 'ABI Detection'
diff --git a/Modules/CMakeFortranCompilerABI.F90 b/Modules/CMakeFortranCompilerABI.F90
index 2a9259b..1dfd560 100644
--- a/Modules/CMakeFortranCompilerABI.F90
+++ b/Modules/CMakeFortranCompilerABI.F90
@@ -105,6 +105,8 @@
 PRINT *, 'INFO:arch[loongarch32]'
 #elif defined(__m68k__)
 PRINT *, 'INFO:arch[m68k]'
+#elif defined(__sw_64)
+PRINT *, 'INFO:arch[sw_64]'
 #elif defined(__mips64) || defined(__mips64__)
 #  if defined(_MIPSEL)
 PRINT *, 'INFO:arch[mips64el]'
@@ -149,6 +151,10 @@
 #  else
 PRINT *, 'INFO:arch[ppc]'
 #  endif
+#elif defined(__wasm64) || defined(__wasm64__)
+PRINT *, 'INFO:arch[wasm64]'
+#elif defined(__wasm32) || defined(__wasm32__)
+PRINT *, 'INFO:arch[wasm32]'
 #endif
 
 PRINT *, 'ABI Detection'
diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake
index 1d7dc0f..ee1c55a 100644
--- a/Modules/CMakeGraphVizOptions.cmake
+++ b/Modules/CMakeGraphVizOptions.cmake
@@ -5,146 +5,9 @@
 CMakeGraphVizOptions
 --------------------
 
-The builtin Graphviz support of CMake.
+.. note::
 
-Generating Graphviz files
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-CMake can generate `Graphviz <https://www.graphviz.org/>`_ files showing the
-dependencies between the targets in a project, as well as external libraries
-which are linked against.
-
-When running CMake with the ``--graphviz=foo.dot`` option, it produces:
-
-* a ``foo.dot`` file, showing all dependencies in the project
-* a ``foo.dot.<target>`` file for each target, showing on which other targets
-  it depends
-* a ``foo.dot.<target>.dependers`` file for each target, showing which other
-  targets depend on it
-
-Those .dot files can be converted to images using the *dot* command from the
-Graphviz package:
-
-.. code-block:: shell
-
-  dot -Tpng -o foo.png foo.dot
-
-.. versionadded:: 3.10
-  The different dependency types ``PUBLIC``, ``INTERFACE`` and ``PRIVATE``
-  are represented as solid, dashed and dotted edges.
-
-Variables specific to the Graphviz support
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The resulting graphs can be huge.  The look and content of the generated graphs
-can be controlled using the file ``CMakeGraphVizOptions.cmake``.  This file is
-first searched in :variable:`CMAKE_BINARY_DIR`, and then in
-:variable:`CMAKE_SOURCE_DIR`.  If found, the variables set in it are used to
-adjust options for the generated Graphviz files.
-
-.. variable:: GRAPHVIZ_GRAPH_NAME
-
- The graph name.
-
- * Mandatory: NO
- * Default: value of :variable:`CMAKE_PROJECT_NAME`
-
-.. variable:: GRAPHVIZ_GRAPH_HEADER
-
- The header written at the top of the Graphviz files.
-
- * Mandatory: NO
- * Default: "node [ fontsize = "12" ];"
-
-.. variable:: GRAPHVIZ_NODE_PREFIX
-
- The prefix for each node in the Graphviz files.
-
- * Mandatory: NO
- * Default: "node"
-
-.. variable:: GRAPHVIZ_EXECUTABLES
-
- Set to FALSE to exclude executables from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_STATIC_LIBS
-
- Set to FALSE to exclude static libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_SHARED_LIBS
-
- Set to FALSE to exclude shared libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_MODULE_LIBS
-
- Set to FALSE to exclude module libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_INTERFACE_LIBS
-
- Set to FALSE to exclude interface libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_OBJECT_LIBS
-
- Set to FALSE to exclude object libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_UNKNOWN_LIBS
-
- Set to FALSE to exclude unknown libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_EXTERNAL_LIBS
-
- Set to FALSE to exclude external libraries from the generated graphs.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_CUSTOM_TARGETS
-
- Set to TRUE to include custom targets in the generated graphs.
-
- * Mandatory: NO
- * Default: FALSE
-
-.. variable:: GRAPHVIZ_IGNORE_TARGETS
-
- A list of regular expressions for names of targets to exclude from the
- generated graphs.
-
- * Mandatory: NO
- * Default: empty
-
-.. variable:: GRAPHVIZ_GENERATE_PER_TARGET
-
- Set to FALSE to not generate per-target graphs ``foo.dot.<target>``.
-
- * Mandatory: NO
- * Default: TRUE
-
-.. variable:: GRAPHVIZ_GENERATE_DEPENDERS
-
- Set to FALSE to not generate depender graphs ``foo.dot.<target>.dependers``.
-
- * Mandatory: NO
- * Default: TRUE
+  This module is not intended to be included in CMake projects directly.
+  It once contained the information for using Graphviz in CMake.  For
+  Graphviz usage in CMake refer to the :option:`cmake --graphviz`.
 #]=======================================================================]
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index ba03080..c253296 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -5,9 +5,16 @@
 CMakePackageConfigHelpers
 -------------------------
 
-Helper functions for creating config files that can be included by other
+This module provides helper commands for creating :ref:`config files
+<Libraries providing Config-file packages>` that can be included by other
 projects to find and use a package.
 
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CMakePackageConfigHelpers)
+
 Generating a Package Configuration File
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 77e999c..1b16a68 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -71,6 +71,9 @@
   if(is_cray)
     string(APPEND linker "|cce_omp_offload_linker")
   endif()
+  if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+    string(APPEND linker "|wasm-ld")
+  endif()
   if(CMAKE_LINKER)
     get_filename_component(default_linker ${CMAKE_LINKER} NAME)
     if (NOT default_linker MATCHES "(${linker})")
@@ -86,7 +89,10 @@
   # whole line and just the command (argv[0]).
   set(linker_regex "^( *|.*[/\\])(${linker}|${startfile}|([^/\\]+-)?ld|collect2)[^/\\]*( |$)")
   set(linker_exclude_regex "collect2 version |^[A-Za-z0-9_]+=|/ldfe ")
-  set(linker_tool_regex "^[ \t]*(->|\")?[ \t]*(([^\"]*[/\\])?(${linker}))(\"|,| |$)")
+
+  # Skip FASTBuild's output mangling, like:
+  # "2> -Build: 0 ms    .../link.exe"/"13>-Build: 0 ms    .../link.exe"
+  set(linker_tool_regex "^[ \t]*(->|\"|[0-9]+>[ \t-]*Build:[ \t0-9]+ ms[ \t]*)?[ \t]*(([^\"]*[/\\])?(${linker}))(\"|,| |$)")
   set(linker_tool_exclude_regex "cuda-fake-ld|-fuse-ld=|^ExecuteExternalTool ")
   if(is_lfortran_less_0_40)
     # lfortran < 0.40 has no way to pass -v to clang/gcc driver.
diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake
index 4a539bc..da04af8 100644
--- a/Modules/CMakePrintSystemInformation.cmake
+++ b/Modules/CMakePrintSystemInformation.cmake
@@ -7,16 +7,27 @@
 
 This module can be used for diagnostics to print system information.
 
-Examples
-^^^^^^^^
-
-Including this module in a project:
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
   include(CMakePrintSystemInformation)
 
-prints various internal CMake variables.  For example::
+Examples
+^^^^^^^^
+
+For example, including this module in a project:
+
+.. code-block:: cmake
+  :caption: ``CMakeLists.txt``
+
+  project(Example)
+
+  # ...
+
+  include(CMakePrintSystemInformation)
+
+prints various CMake variables::
 
   CMAKE_SYSTEM is Linux-6.11.0-17-generic Linux 6.11.0-17-generic x86_64
   CMAKE_SYSTEM file is Platform/Linux
diff --git a/Modules/CMakePushCheckState.cmake b/Modules/CMakePushCheckState.cmake
index cbf49de..30505cd 100644
--- a/Modules/CMakePushCheckState.cmake
+++ b/Modules/CMakePushCheckState.cmake
@@ -11,7 +11,7 @@
 how various CMake check commands (e.g., :command:`check_symbol_exists`, etc.)
 are performed.
 
-Load this module in CMake project with:
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
diff --git a/Modules/CMakeVerifyManifest.cmake b/Modules/CMakeVerifyManifest.cmake
index d98a49e..5333869 100644
--- a/Modules/CMakeVerifyManifest.cmake
+++ b/Modules/CMakeVerifyManifest.cmake
@@ -5,31 +5,53 @@
 CMakeVerifyManifest
 -------------------
 
-Use this script to verify that embedded manifests and side-by-side
-manifests for a project match.
+This module is intended to be used in command-line mode using the
+:ref:`cmake -P <Script Processing Mode>` to verify that embedded manifests
+and side-by-side manifests for a project match.
 
-This script first recursively globs ``*.manifest`` files from
-the current directory and creates a list of allowed version.
-Additional versions can be passed by setting ``allow_versions``
-from the invocation command.
-Next, the script globs ``*.exe`` and ``*.dll`` files.  Each
+Load this module in a CMake script with:
+
+.. code-block:: cmake
+
+  include(CMakeVerifyManifest)
+
+This module first recursively globs ``*.manifest`` files from
+the current source directory and creates a list of allowed versions.
+
+Next, the script globs all ``*.exe`` and ``*.dll`` files.  Each
 ``.exe`` and ``.dll`` file is scanned for embedded manifests and
 the versions of CRT are checked to be in the list of allowed
-version.
+versions.
 
-Example
-^^^^^^^
+Input Variables
+^^^^^^^^^^^^^^^
 
-To run this script, navigate to a directory and run the script
-with ``cmake -P``.
+This module accepts the following variables:
 
-::
+``allow_versions``
+  Additional versions can be passed by setting the ``allow_versions``
+  variable from the invocation command.  This enables using additional
+  embedded manifest versions in a project, even if that version was not
+  found in a ``.manifest`` file.
 
-  cmake -Dallow_versions=8.0.50608.0 -PCMakeVerifyManifest.cmake
+Examples
+^^^^^^^^
 
-This call allows an embedded manifest of 8.0.50608.0 to be used
-in a project, even if that version was not found in a
-``.manifest`` file.
+To use this module in the project, create a local command-line script (for
+example, in the project's subdirectory ``cmake/scripts``) and include the
+module:
+
+.. code-block:: cmake
+  :caption: ``cmake/scripts/verify-manifest.cmake``
+
+  include(CMakeVerifyManifest)
+
+Then run the local script in command-line and, for example, specify
+additional embedded manifest of ``8.0.50608.0`` to be used in a project:
+
+.. code-block:: shell
+
+  cmake -Dallow_versions=8.0.50608.0 -Pcmake/scripts/verify-manifest.cmake
 #]=======================================================================]
 
 # crt_version:
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 803332b..0be4846 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -5,7 +5,13 @@
 CPack
 -----
 
-Configure generators for binary installers and source packages.
+This module configures generators for binary installers and source packages.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CPack)
 
 Introduction
 ^^^^^^^^^^^^
@@ -198,8 +204,8 @@
 
   .. versionadded:: 3.7
 
-  An algorithm that will be used to generate an additional file with the
-  checksum of the package.  The output file name will be:
+  One or multiple algorithms that will be used to generate additional files with
+  the checksum of the package.  The output file names will be:
 
   .. code-block:: cmake
 
@@ -208,6 +214,9 @@
   Supported algorithms are those listed by the
   :ref:`string(\<HASH\>) <Supported Hash Algorithms>` command.
 
+  .. versionchanged:: 4.2
+    The variable accepts a list of algorithms.
+
 .. variable:: CPACK_PROJECT_CONFIG_FILE
 
   CPack-time project CPack configuration file.  This file is included at cpack
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index 3197fc3..96d6bde 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -5,7 +5,14 @@
 CPackComponent
 --------------
 
-Configure components for binary installers and source packages.
+This module provides commands to configure components for binary installers
+and source packages.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CPackComponent)
 
 .. only:: html
 
@@ -14,7 +21,7 @@
 Introduction
 ^^^^^^^^^^^^
 
-This module is automatically included by :module:`CPack`.
+This module is also automatically included by :module:`CPack`.
 
 Certain binary installers (especially the graphical installers) generated
 by CPack allow users to select individual application *components* to install.
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index 2a2f478..8826064 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -11,6 +11,12 @@
 `Qt Installer Framework <https://doc.qt.io/qtinstallerframework/index.html>`_
 (QtIFW).
 
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CPackIFW)
+
 The module also defines several commands to control the behavior of the
 :cpack_gen:`CPack IFW Generator`.
 
@@ -639,7 +645,7 @@
 endmacro()
 
 # Resolve full path to license file
-macro(_cpack_ifw_resolve_lisenses _variable)
+macro(_cpack_ifw_resolve_licenses _variable)
   if(${_variable})
     set(_ifw_license_file FALSE)
     set(_ifw_licenses_fix)
@@ -683,7 +689,7 @@
   cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
 
   _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
-  _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
+  _cpack_ifw_resolve_licenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
   _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_USER_INTERFACES)
   _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_TRANSLATIONS)
 
@@ -724,7 +730,7 @@
   cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
 
   _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)
-  _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
+  _cpack_ifw_resolve_licenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
   _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_USER_INTERFACES)
   _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_TRANSLATIONS)
 
diff --git a/Modules/CPackIFWConfigureFile.cmake b/Modules/CPackIFWConfigureFile.cmake
index 6759c9c..f92fc10 100644
--- a/Modules/CPackIFWConfigureFile.cmake
+++ b/Modules/CPackIFWConfigureFile.cmake
@@ -7,9 +7,14 @@
 
 .. versionadded:: 3.8
 
-The module defines :command:`configure_file` similar command to
+This module defines :command:`configure_file` similar command to
 configure file templates prepared in QtIFW/SDK/Creator style.
 
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CPackIFWConfigureFile)
 
 Commands
 ^^^^^^^^
@@ -31,10 +36,6 @@
 
 #]=======================================================================]
 
-# NOTE: This file used to himself packaging via CPack IFW generator and
-# should be compatible with minimal CMake version defined in
-# ../CMakeLists.txt file.
-
 if(NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED)
 set(CPackIFWConfigureFile_CMake_INCLUDED 1)
 
diff --git a/Modules/CTestScriptMode.cmake b/Modules/CTestScriptMode.cmake
index d5dbddb..b8f98b4 100644
--- a/Modules/CTestScriptMode.cmake
+++ b/Modules/CTestScriptMode.cmake
@@ -5,9 +5,11 @@
 CTestScriptMode
 ---------------
 
+.. note::
 
-
-This file is read by ctest in script mode (-S)
+  This module is not intended to be included or invoked directly by project
+  code.  It is internally used by CTest running in script mode (-S) to
+  determine current system.  For usage details refer to the :option:`ctest -S`.
 #]=======================================================================]
 
 # Determine the current system, so this information can be used
diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake
index 5a7232f..2840875 100644
--- a/Modules/CTestTargets.cmake
+++ b/Modules/CTestTargets.cmake
@@ -86,7 +86,7 @@
   endforeach()
 
   # For Makefile generators add more granular targets.
-  if("${CMAKE_GENERATOR}" MATCHES "(Ninja|Make)")
+  if("${CMAKE_GENERATOR}" MATCHES "(Ninja|Make|FASTBuild)")
     # Make targets for Experimental builds
     foreach(mode Nightly Experimental Continuous)
       foreach(testtype
diff --git a/Modules/CTestUseLaunchers.cmake b/Modules/CTestUseLaunchers.cmake
index dc015f8..0ffaa11 100644
--- a/Modules/CTestUseLaunchers.cmake
+++ b/Modules/CTestUseLaunchers.cmake
@@ -13,6 +13,12 @@
 * :prop_gbl:`RULE_LAUNCH_CUSTOM`
 * :prop_gbl:`RULE_LAUNCH_LINK`
 
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CTestUseLaunchers)
+
 The ``CTestUseLaunchers`` module is automatically included by the
 :module:`CTest` module when ``include(CTest)`` is called.  However, it is
 provided as a separate module so that projects can use the
@@ -54,13 +60,13 @@
     CACHE INTERNAL "CTEST_USE_LAUNCHERS initial value from ENV")
 endif()
 
-if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
+if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja|FASTBuild")
   set(CTEST_USE_LAUNCHERS 0)
 endif()
 
 if(CTEST_USE_LAUNCHERS)
   set(__launch_common_options
-    "--target-name <TARGET_NAME> --current-build-dir <CMAKE_CURRENT_BINARY_DIR>")
+    "--target-name <TARGET_NAME> --current-build-dir <CMAKE_CURRENT_BINARY_DIR> --build-dir <CMAKE_BINARY_DIR> --object-dir <TARGET_SUPPORT_DIR>")
 
   set(__launch_compile_options
     "${__launch_common_options} --output <OBJECT> --source <SOURCE> --language <LANGUAGE>")
@@ -71,7 +77,7 @@
   set(__launch_custom_options
     "${__launch_common_options} --output <OUTPUT>")
 
-  if("${CMAKE_GENERATOR}" MATCHES "Ninja")
+  if("${CMAKE_GENERATOR}" MATCHES "Ninja|FASTBuild")
     string(APPEND __launch_compile_options " --filter-prefix <CMAKE_CL_SHOWINCLUDES_PREFIX>")
   endif()
 
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index dab4f68..3bd4652 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -20,17 +20,26 @@
 
 .. command:: check_include_file
 
-  Checks once whether a header file can be included in C code:
+  Checks once whether a header file exists and can be included in C code:
 
   .. code-block:: cmake
 
     check_include_file(<include> <variable> [<flags>])
 
-  This command checks once whether the given ``<include>`` header file
-  exists and can be included in a C source file.  The result of the check
-  is stored in an internal cache variable named ``<variable>``.  The
-  optional third argument may be used to add additional compilation flags
-  to the check (or use the ``CMAKE_REQUIRED_FLAGS`` variable below).
+  .. rubric:: The arguments are:
+
+  ``<include>``
+    A header file to be checked.
+
+  ``<variable>``
+    The name of the variable to store the result of the check.  This
+    variable will be created as an internal cache variable.
+
+  ``<flags>``
+    (Optional) A :ref:`semicolon-separated list <CMake Language Lists>` of
+    additional compilation flags to be added to the check.  Alternatively,
+    flags can be also specified with the ``CMAKE_REQUIRED_FLAGS`` variable
+    below.
 
   .. rubric:: Variables Affecting the Check
 
@@ -76,7 +85,7 @@
 In the following example, this module is used in combination with the
 :module:`CMakePushCheckState` module to temporarily modify the required
 compile definitions (via ``CMAKE_REQUIRED_DEFINITIONS``) and verify whether
-the C header ``ucontext.h`` is available.  The result is stored
+the C header ``<ucontext.h>`` is available.  The result is stored
 in the internal cache variable ``HAVE_UCONTEXT_H``.
 
 For example, on macOS, the ``ucontext`` API is deprecated, and headers may
@@ -95,7 +104,7 @@
       set(CMAKE_REQUIRED_DEFINITIONS -D_XOPEN_SOURCE)
     endif()
 
-    check_include_files(ucontext.h HAVE_UCONTEXT_H)
+    check_include_file(ucontext.h HAVE_UCONTEXT_H)
   cmake_pop_check_state()
 
 See Also
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index 54b7f55..e0eae7b 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -20,17 +20,26 @@
 
 .. command:: check_include_file_cxx
 
-  Checks once whether a header file can be included in C++ code:
+  Checks once whether a header file exists and can be included in C++ code:
 
   .. code-block:: cmake
 
     check_include_file_cxx(<include> <variable> [<flags>])
 
-  This command checks once whether the given ``<include>`` header file
-  exists and can be included in a ``CXX`` source file.  The result of the
-  check is stored in an internal cache variable named ``<variable>``.  The
-  optional third argument may be used to add additional compilation flags
-  to the check (or use the ``CMAKE_REQUIRED_FLAGS`` variable below).
+  .. rubric:: The arguments are:
+
+  ``<include>``
+    A header file to be checked.
+
+  ``<variable>``
+    The name of the variable to store the result of the check.  This
+    variable will be created as an internal cache variable.
+
+  ``<flags>``
+    (Optional) A :ref:`semicolon-separated list <CMake Language Lists>` of
+    additional compilation flags to be added to the check.  Alternatively,
+    flags can be also specified with the ``CMAKE_REQUIRED_FLAGS`` variable
+    below.
 
   .. rubric:: Variables Affecting the Check
 
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index 7debbe6..9870340 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -20,24 +20,30 @@
 
 .. command:: check_include_files
 
-  Checks once whether one or more header files can be included together in
-  source code:
+  Checks once whether one or more header files exist and can be included
+  together in C or C++ code:
 
   .. code-block:: cmake
 
     check_include_files(<includes> <variable> [LANGUAGE <language>])
 
-  This command checks once whether the given ``<includes>`` list of header
-  files exist and can be included together in a C or C++ source file.  The
-  result of the check is stored in an internal cache variable named
-  ``<variable>``.  Specify the ``<includes>`` argument as a
-  :ref:`semicolon-separated list <CMake Language Lists>` of header file
-  names.
+  .. rubric:: The arguments are:
 
-  If ``LANGUAGE`` is set, the specified compiler will be used to perform the
-  check.  Acceptable values are ``C`` and ``CXX``.  If not set, the C
-  compiler will be used if enabled.  If the C compiler is not enabled, the
-  C++ compiler will be used if enabled.
+  ``<includes>``
+    A :ref:`semicolon-separated list <CMake Language Lists>` of header
+    files to be checked.
+
+  ``<variable>``
+    The name of the variable to store the result of the check.  This
+    variable will be created as an internal cache variable.
+
+  ``LANGUAGE <language>``
+    .. versionadded:: 3.11
+
+    If set, the specified ``<language>`` compiler will be used to perform
+    the check.  Acceptable values are ``C`` and ``CXX``.  If this option is
+    not given, the C compiler will be used if enabled.  If the C compiler
+    is not enabled, the C++ compiler will be used if enabled.
 
   .. rubric:: Variables Affecting the Check
 
diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake
index 592612c..b4d47f9 100644
--- a/Modules/CheckPIESupported.cmake
+++ b/Modules/CheckPIESupported.cmake
@@ -7,23 +7,36 @@
 
 .. versionadded:: 3.14
 
-This module provides the ``check_pie_supported()`` function to check whether the
-linker supports Position Independent Code (PIE) or No Position Independent Code
-(NO_PIE) for executables.
+This module provides a command to check whether the linker supports Position
+Independent Code (PIE) or No Position Independent Code (NO_PIE) for
+executables.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(CheckPIESupported)
 
 When setting the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property,
 PIC-related compile and link options are added when building library objects,
 and PIE-related compile options are added when building objects of executable
 targets, regardless of this module.  Use this module to ensure that the
-``POSITION_INDEPENDENT_CODE`` target property for executables is also honored at
-link time.
+``POSITION_INDEPENDENT_CODE`` target property for executables is also honored
+at link time.
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
 
 .. command:: check_pie_supported
 
+  Checks for PIE/NO_PIE support and prepares all executables to have link
+  time PIE options enabled:
+
   .. code-block:: cmake
 
-    check_pie_supported([OUTPUT_VARIABLE <output>]
-                        [LANGUAGES <lang>...])
+    check_pie_supported([OUTPUT_VARIABLE <output>] [LANGUAGES <langs>...])
 
   Options are:
 
@@ -32,7 +45,7 @@
     bypassed because it uses cached results from a previous call, the output
     will be empty even if errors were present in the previous call.
 
-  ``LANGUAGES <lang>...``
+  ``LANGUAGES <langs>...``
     Check the linkers used for each of the specified languages.
     If this option is not provided, the command checks all enabled languages.
 
@@ -50,13 +63,13 @@
 Variables
 ^^^^^^^^^
 
-For each language checked, the ``check_pie_supported()`` function defines two
+For each language checked, the ``check_pie_supported()`` command defines two
 boolean cache variables:
 
- ``CMAKE_<lang>_LINK_PIE_SUPPORTED``
-   Set to true if ``PIE`` is supported by the linker and false otherwise.
- ``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED``
-   Set to true if ``NO_PIE`` is supported by the linker and false otherwise.
+``CMAKE_<lang>_LINK_PIE_SUPPORTED``
+  Set to true if ``PIE`` is supported by the linker and false otherwise.
+``CMAKE_<lang>_LINK_NO_PIE_SUPPORTED``
+  Set to true if ``NO_PIE`` is supported by the linker and false otherwise.
 
 Examples
 ^^^^^^^^
@@ -82,11 +95,17 @@
 
   add_executable(foo ...)
 
+  message(CHECK_START "Checking for C linker PIE support")
+
   include(CheckPIESupported)
   check_pie_supported(OUTPUT_VARIABLE output LANGUAGES C)
   set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
-  if(NOT CMAKE_C_LINK_PIE_SUPPORTED)
-    message(WARNING "PIE is not supported at link time:\n${output}"
+
+  if(CMAKE_C_LINK_PIE_SUPPORTED)
+    message(CHECK_PASS "yes")
+  else()
+    message(CHECK_FAIL "no")
+    message(VERBOSE "PIE is not supported at link time:\n${output}"
                     "PIE link options will not be passed to linker.")
   endif()
 
@@ -98,7 +117,6 @@
 
   add_executable(foo ...)
   set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE TRUE)
-
 #]=======================================================================]
 
 
diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake
index b1acaab..d77e81c 100644
--- a/Modules/CheckPrototypeDefinition.cmake
+++ b/Modules/CheckPrototypeDefinition.cmake
@@ -93,10 +93,6 @@
   )
 #]=======================================================================]
 
-#
-
-get_filename_component(__check_proto_def_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
-
 include_guard(GLOBAL)
 
 function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
@@ -143,7 +139,7 @@
     set(CHECK_PROTOTYPE_DEFINITION_PROTO ${_PROTOTYPE})
     set(CHECK_PROTOTYPE_DEFINITION_RETURN ${_RETURN})
 
-    file(READ ${__check_proto_def_dir}/CheckPrototypeDefinition.c.in _SOURCE)
+    file(READ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CheckPrototypeDefinition.c.in _SOURCE)
     string(CONFIGURE "${_SOURCE}" _SOURCE @ONLY)
 
     try_compile(${_VARIABLE}
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 9643d87..1f5a622 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -25,23 +25,42 @@
 
   .. code-block:: cmake
 
-    check_type_size(<type> <variable> [BUILTIN_TYPES_ONLY] [LANGUAGE <language>])
+    check_type_size(
+      <type>
+      <size-var>
+      [RESULT_VARIABLE <result-var>]
+      [BUILTIN_TYPES_ONLY]
+      [LANGUAGE <language>]
+    )
 
   The arguments are:
 
   ``<type>``
     The type or expression being checked.
 
-  ``<variable>``
-    The name of the variable and a prefix used for storing the check results.
+  ``<size-var>``
+    The name of the internal cache variable for storing the size of the type
+    or expression ``<type>``.  This name is also used as a prefix as
+    explained below.
+
+  ``RESULT_VARIABLE <result-var>``
+    .. versionadded:: 4.2
+
+    The name of the internal cache variable that holds a boolean value
+    indicating whether the type or expression ``<type>`` exists.  If *not*
+    given, the command will by default define an internal cache variable
+    named ``HAVE_<size-var>`` instead.
 
   ``BUILTIN_TYPES_ONLY``
     If given, only compiler-builtin types will be supported in the check.
     If *not* given, the command checks for common headers ``<sys/types.h>``,
     ``<stdint.h>``, and ``<stddef.h>``, and saves results in
     ``HAVE_SYS_TYPES_H``, ``HAVE_STDINT_H``, and ``HAVE_STDDEF_H`` internal
-    cache variables.  The type size check automatically includes the available
-    headers, thus supporting checks of types defined in the headers.
+    cache variables.  For C++ ``std::`` types, ``<cstdint>`` and
+    ``<cstddef>`` are also checked with ``HAVE_CSTDINT`` and
+    ``HAVE_CSTDDEF`` defined respectively.  The command automatically
+    includes the available headers in the type size check, thus supporting
+    checks of types defined in the headers.
 
   ``LANGUAGE <language>``
     Uses the ``<language>`` compiler to perform the check.
@@ -52,40 +71,50 @@
 
   Results are reported in the following variables:
 
-  ``HAVE_<variable>``
-    Internal cache variable that holds a boolean true or false value
-    indicating whether the type or expression ``<type>`` exists.
-
-  ``<variable>``
+  ``<size-var>``
     Internal cache variable that holds one of the following values:
 
     ``<size>``
-      If the type or expression exists, it will have a non-zero size
-      ``<size>`` in bytes.
+      If the type or expression ``<type>`` exists, it will have a non-zero
+      size ``<size>`` in bytes.
 
     ``0``
-      When type has architecture-dependent size;  This may occur when
-      :variable:`CMAKE_OSX_ARCHITECTURES` has multiple architectures.
-      In this case ``<variable>_CODE`` contains preprocessor tests
-      mapping from each architecture macro to the corresponding type size.
-      The list of architecture macros is stored in ``<variable>_KEYS``,
-      and the value for each key is stored in ``<variable>-<key>``.
+      When the type has an architecture-dependent size;  This may occur when
+      :variable:`CMAKE_OSX_ARCHITECTURES` has multiple architectures.  In
+      this case also the ``<size-var>_KEYS`` variable is defined and the
+      ``<size-var>_CODE`` variable contains preprocessor tests mapping as
+      explained below.
 
     "" (empty string)
-      When type or expression does not exist.
+      When the type or expression ``<type>`` does not exist.
 
-  ``<variable>_CODE``
+  ``HAVE_<size-var>``
+    Internal cache variable that holds a boolean value indicating whether
+    the type or expression ``<type>`` exists.  This variable is defined
+    when the ``RESULT_VARIABLE`` argument is not used.
+
+  ``<result-var>``
+    .. versionadded:: 4.2
+
+    Internal cache variable defined when the ``RESULT_VARIABLE`` argument
+    is used. It holds a boolean value indicating whether the type or
+    expression ``<type>`` exists (same value as ``HAVE_<size-var>``). In
+    this case, the ``HAVE_<size-var>`` variable is not defined.
+
+  ``<size-var>_CODE``
     CMake variable that holds preprocessor code to define the macro
-    ``<variable>`` to the size of the type, or to leave the macro undefined
+    ``<size-var>`` to the size of the type, or to leave the macro undefined
     if the type does not exist.
 
-  Despite the name of this command, it may also be used to determine the size
-  of more complex expressions.  For example, to check the size of a struct
-  member:
+    When the type has an architecture-dependent size (``<size-var>`` value
+    is ``0``) this variable contains preprocessor tests mapping from each
+    architecture macro to the corresponding type size.
 
-  .. code-block:: cmake
-
-    check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
+  ``<size-var>_KEYS``
+    CMake variable that is defined only when the type has an
+    architecture-dependent size (``<size-var>`` value is ``0``) and contains
+    a list of architecture macros. The value for each key is stored in
+    ``<size-var>-<key>`` variables.
 
   .. rubric:: Variables Affecting the Check
 
@@ -121,6 +150,7 @@
 
   # Check for size of long.
   check_type_size(long SIZEOF_LONG)
+
   message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
   message("SIZEOF_LONG: ${SIZEOF_LONG}")
   message("SIZEOF_LONG_CODE: ${SIZEOF_LONG_CODE}")
@@ -133,21 +163,21 @@
 
 On Apple platforms, when :variable:`CMAKE_OSX_ARCHITECTURES` has multiple
 architectures, types may have architecture-dependent sizes.
-For example, with the code
+For example, with the code:
 
 .. code-block:: cmake
 
   include(CheckTypeSize)
 
   check_type_size(long SIZEOF_LONG)
+
   message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
   message("SIZEOF_LONG: ${SIZEOF_LONG}")
-  foreach(key IN LISTS SIZE_OF_LONG_KEYS)
+  foreach(key IN LISTS SIZEOF_LONG_KEYS)
     message("key: ${key}")
-    message("value: ${SIZE_OF_LONG-${key}}")
+    message("value: ${SIZEOF_LONG-${key}}")
   endforeach()
-  message("SIZEOF_LONG_CODE:
-  ${SIZEOF_LONG_CODE}")
+  message("SIZEOF_LONG_CODE:\n${SIZEOF_LONG_CODE}")
 
 the result may be::
 
@@ -159,27 +189,108 @@
   value: 8
   SIZEOF_LONG_CODE:
   #if defined(__i386)
-  # define SIZE_OF_LONG 4
+  # define SIZEOF_LONG 4
   #elif defined(__x86_64)
-  # define SIZE_OF_LONG 8
+  # define SIZEOF_LONG 8
   #else
-  # error SIZE_OF_LONG unknown
+  # error SIZEOF_LONG unknown
   #endif
+
+Example: Configuration Header
+"""""""""""""""""""""""""""""
+
+The next example demonstrates how the result variables can be used in a
+configuration header:
+
+.. code-block:: cmake
+
+  include(CheckTypeSize)
+  check_type_size(long SIZEOF_LONG)
+
+  configure_file(config.h.in config.h @ONLY)
+
+.. code-block:: c
+  :caption: ``config.h.in``
+  :force:
+
+  /* Define whether the type 'long' exists. */
+  #cmakedefine HAVE_SIZEOF_LONG
+
+  /* The size of 'long', as computed by sizeof. */
+  @SIZEOF_LONG_CODE@
+
+Example: Checking Complex Expressions
+"""""""""""""""""""""""""""""""""""""
+
+Despite the name of this module, it may also be used to determine the size
+of more complex expressions.  For example, to check the size of a struct
+member:
+
+.. code-block:: cmake
+
+  include(CheckTypeSize)
+  check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
+
+Example: Isolated Check
+"""""""""""""""""""""""
+
+In the following example, the check is performed with temporarily modified
+additional headers using the ``CMAKE_EXTRA_INCLUDE_FILES`` variable and
+:module:`CMakePushCheckState` module.  The result of the check is stored in
+``HAVE_SIZEOF_UNION_SEMUN``, and size is stored in ``SIZEOF_UNION_SEMUN``
+internal cache variables.
+
+.. code-block:: cmake
+
+  include(CheckTypeSize)
+  include(CMakePushCheckState)
+
+  cmake_push_check_state(RESET)
+    set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ipc.h sys/sem.h)
+    check_type_size("union semun" SIZEOF_UNION_SEMUN)
+  cmake_pop_check_state()
+
+Example: Customizing Result Variable
+""""""""""""""""""""""""""""""""""""
+
+Since CMake 4.2, the ``HAVE_<size-var>`` variable name can be customized
+using the ``RESULT_VARIABLE`` argument. In the following example, this
+module is used to check whether the ``struct flock`` exists, and the result
+is stored in the ``MyProj_HAVE_STRUCT_FLOCK`` internal cache variable:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 4.2)
+
+  # ...
+
+  include(CheckTypeSize)
+  include(CMakePushCheckState)
+
+  cmake_push_check_state(RESET)
+    set(CMAKE_EXTRA_INCLUDE_FILES "fcntl.h")
+
+    check_type_size(
+      "struct flock"
+      MyProj_SIZEOF_STRUCT_FLOCK
+      RESULT_VARIABLE MyProj_HAVE_STRUCT_FLOCK
+    )
+  cmake_pop_check_state()
 #]=======================================================================]
 
 include(CheckIncludeFile)
 include(CheckIncludeFileCXX)
 
-get_filename_component(__check_type_size_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
-
 include_guard(GLOBAL)
 
 block(SCOPE_FOR POLICIES)
+cmake_policy(SET CMP0140 NEW)
 cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
+cmake_policy(SET CMP0174 NEW)
 
 #-----------------------------------------------------------------------------
 # Helper function.  DO NOT CALL DIRECTLY.
-function(__check_type_size_impl type var map builtin language)
+function(__check_type_size_impl type var result_var map builtin language)
   if(NOT CMAKE_REQUIRED_QUIET)
     message(CHECK_START "Check size of ${type}")
   endif()
@@ -196,7 +307,7 @@
 
   # Include header files.
   set(headers)
-  if(builtin)
+  if(NOT builtin)
     if(language STREQUAL "CXX" AND type MATCHES "^std::")
       if(HAVE_SYS_TYPES_H)
         string(APPEND headers "#include <sys/types.h>\n")
@@ -232,9 +343,9 @@
 
   # Perform the check.
   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
-  file(READ ${__check_type_size_dir}/CheckTypeSize.c.in src_content)
+  file(READ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CheckTypeSize.c.in src_content)
   string(CONFIGURE "${src_content}" src_content @ONLY)
-  try_compile(HAVE_${var} SOURCE_FROM_VAR "${src}" src_content
+  try_compile(${result_var} SOURCE_FROM_VAR "${src}" src_content
     COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
     LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}
     LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}
@@ -246,7 +357,7 @@
     )
   unset(_CTS_LINK_DIRECTORIES)
 
-  if(HAVE_${var})
+  if(${result_var})
     # The check compiled.  Load information from the binary.
     file(STRINGS ${bin} strings LIMIT_COUNT 10 REGEX "INFO:size")
 
@@ -280,7 +391,7 @@
 
     # Update the architecture-to-size map.
     if(mismatch AND keys)
-      configure_file(${__check_type_size_dir}/CheckTypeSizeMap.cmake.in ${map} @ONLY)
+      configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CheckTypeSizeMap.cmake.in ${map} @ONLY)
       set(${var} 0)
     else()
       file(REMOVE ${map})
@@ -305,45 +416,53 @@
 endfunction()
 
 #-----------------------------------------------------------------------------
-macro(CHECK_TYPE_SIZE TYPE VARIABLE)
-  # parse arguments
-  unset(doing)
-  foreach(arg ${ARGN})
-    if("x${arg}" STREQUAL "xBUILTIN_TYPES_ONLY")
-      set(_CHECK_TYPE_SIZE_${arg} 1)
-      unset(doing)
-    elseif("x${arg}" STREQUAL "xLANGUAGE") # change to MATCHES for more keys
-      set(doing "${arg}")
-      set(_CHECK_TYPE_SIZE_${doing} "")
-    elseif("x${doing}" STREQUAL "xLANGUAGE")
-      set(_CHECK_TYPE_SIZE_${doing} "${arg}")
-      unset(doing)
-    else()
-      message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
-    endif()
-  endforeach()
-  if("x${doing}" MATCHES "^x(LANGUAGE)$")
-    message(FATAL_ERROR "Missing argument:\n  ${doing} arguments requires a value\n")
+function(CHECK_TYPE_SIZE TYPE VARIABLE)
+  cmake_parse_arguments(
+    PARSE_ARGV
+    2
+    _CHECK_TYPE_SIZE
+    "BUILTIN_TYPES_ONLY" # Options
+    "RESULT_VARIABLE;LANGUAGE" # One-value arguments
+    "" # Multi-value arguments
+  )
+
+  if(_CHECK_TYPE_SIZE_UNPARSED_ARGUMENTS)
+    message(
+      FATAL_ERROR
+      "Unknown arguments:\n  ${_CHECK_TYPE_SIZE_UNPARSED_ARGUMENTS}\n"
+    )
   endif()
-  if(DEFINED _CHECK_TYPE_SIZE_LANGUAGE)
-    if(NOT "x${_CHECK_TYPE_SIZE_LANGUAGE}" MATCHES "^x(C|CXX)$")
-      message(FATAL_ERROR "Unknown language:\n  ${_CHECK_TYPE_SIZE_LANGUAGE}.\nSupported languages: C, CXX.\n")
-    endif()
-    set(_language ${_CHECK_TYPE_SIZE_LANGUAGE})
-  else()
-    set(_language C)
+
+  if(NOT DEFINED _CHECK_TYPE_SIZE_RESULT_VARIABLE)
+    set(_CHECK_TYPE_SIZE_RESULT_VARIABLE HAVE_${VARIABLE})
+  elseif(_CHECK_TYPE_SIZE_RESULT_VARIABLE STREQUAL "")
+    message(
+      FATAL_ERROR
+      "Missing argument:\n  RESULT_VARIABLE argument requires a value\n"
+    )
+  endif()
+
+  if(NOT DEFINED _CHECK_TYPE_SIZE_LANGUAGE)
+    set(_CHECK_TYPE_SIZE_LANGUAGE C)
+  elseif(_CHECK_TYPE_SIZE_LANGUAGE STREQUAL "")
+    message(
+      FATAL_ERROR
+      "Missing argument:\n  LANGUAGE argument requires a value\n"
+    )
+  elseif(NOT _CHECK_TYPE_SIZE_LANGUAGE MATCHES "^(C|CXX)$")
+    message(
+      FATAL_ERROR
+      "Unknown language:\n  ${_CHECK_TYPE_SIZE_LANGUAGE}.\n"
+      "Supported languages: C, CXX.\n")
   endif()
 
   # Optionally check for standard headers.
-  if(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
-    set(_builtin 0)
-  else()
-    set(_builtin 1)
-    if(_language STREQUAL "C")
+  if(NOT _CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
+    if(_CHECK_TYPE_SIZE_LANGUAGE STREQUAL "C")
       check_include_file(sys/types.h HAVE_SYS_TYPES_H)
       check_include_file(stdint.h HAVE_STDINT_H)
       check_include_file(stddef.h HAVE_STDDEF_H)
-    elseif(_language STREQUAL "CXX")
+    elseif(_CHECK_TYPE_SIZE_LANGUAGE STREQUAL "CXX")
       check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
       if("${TYPE}" MATCHES "^std::")
         check_include_file_cxx(cstdint HAVE_CSTDINT)
@@ -354,18 +473,23 @@
       endif()
     endif()
   endif()
-  unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
-  unset(_CHECK_TYPE_SIZE_LANGUAGE)
 
   # Compute or load the size or size map.
   set(${VARIABLE}_KEYS)
   set(_map_file ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${VARIABLE}.cmake)
-  if(NOT DEFINED HAVE_${VARIABLE})
-    __check_type_size_impl(${TYPE} ${VARIABLE} ${_map_file} ${_builtin} ${_language})
+  if(NOT DEFINED ${_CHECK_TYPE_SIZE_RESULT_VARIABLE})
+    __check_type_size_impl(
+      ${TYPE}
+      ${VARIABLE}
+      ${_CHECK_TYPE_SIZE_RESULT_VARIABLE}
+      ${_map_file}
+      ${_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY}
+      ${_CHECK_TYPE_SIZE_LANGUAGE}
+    )
   endif()
   include(${_map_file} OPTIONAL)
-  set(_map_file)
-  set(_builtin)
+
+  set(_propagated_vars "")
 
   # Create preprocessor code.
   if(${VARIABLE}_KEYS)
@@ -374,15 +498,17 @@
     foreach(key ${${VARIABLE}_KEYS})
       string(APPEND ${VARIABLE}_CODE "#${_if} defined(${key})\n# define ${VARIABLE} ${${VARIABLE}-${key}}\n")
       set(_if elif)
+      list(APPEND _propagated_vars ${VARIABLE}-${key})
     endforeach()
     string(APPEND ${VARIABLE}_CODE "#else\n# error ${VARIABLE} unknown\n#endif")
-    set(_if)
   elseif(${VARIABLE})
     set(${VARIABLE}_CODE "#define ${VARIABLE} ${${VARIABLE}}")
   else()
     set(${VARIABLE}_CODE "/* #undef ${VARIABLE} */")
   endif()
-endmacro()
+
+  return(PROPAGATE ${VARIABLE}_CODE ${VARIABLE}_KEYS ${_propagated_vars})
+endfunction()
 
 #-----------------------------------------------------------------------------
 endblock()
diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
index 5330eb1..9061e00 100644
--- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
@@ -10,21 +10,25 @@
     return ()
   endif ()
 
-  execute_process(
-    COMMAND
-      "${CMAKE_CXX_COMPILER}"
-      ${CMAKE_CXX_COMPILER_ID_ARG1}
-      "-print-file-name=${_clang_modules_json_impl}.modules.json"
-    OUTPUT_VARIABLE _clang_libcxx_modules_json_file
-    ERROR_VARIABLE _clang_libcxx_modules_json_file_err
-    RESULT_VARIABLE _clang_libcxx_modules_json_file_res
-    OUTPUT_STRIP_TRAILING_WHITESPACE
-    ERROR_STRIP_TRAILING_WHITESPACE)
-  if (_clang_libcxx_modules_json_file_res)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `${_clang_modules_json_impl}.modules.json` resource\")\n"
-      PARENT_SCOPE)
-    return ()
+  if (CMAKE_CXX_STDLIB_MODULES_JSON)
+    set(_clang_libcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
+  else ()
+    execute_process(
+      COMMAND
+        "${CMAKE_CXX_COMPILER}"
+        ${CMAKE_CXX_COMPILER_ID_ARG1}
+        "-print-file-name=${_clang_modules_json_impl}.modules.json"
+      OUTPUT_VARIABLE _clang_libcxx_modules_json_file
+      ERROR_VARIABLE _clang_libcxx_modules_json_file_err
+      RESULT_VARIABLE _clang_libcxx_modules_json_file_res
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_STRIP_TRAILING_WHITESPACE)
+    if (_clang_libcxx_modules_json_file_res)
+      set("${variable}"
+        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `${_clang_modules_json_impl}.modules.json` resource\")\n"
+        PARENT_SCOPE)
+      return ()
+    endif ()
   endif ()
 
   # Without this file, we do not have modules installed.
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index d01d704..6b150ea 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -113,8 +113,14 @@
     if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0.0 AND NOT __is_apple_clang)
       set(CMAKE_${lang}_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH -fpch-instantiate-templates)
     endif()
-    set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
-    set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
+    if (CMAKE_GENERATOR MATCHES "FASTBuild")
+      # We can't use "-Xclang -emit-pch" since Fastbuild gets spammed with binary content of the .pch file while trying to scan dependencies.
+      set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include-pch <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
+    else()
+      set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
+      set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER> -x ${__pch_header_${lang}})
+    endif()
 
     # '-fcolor-diagnostics' introduced since Clang 2.6
     if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2.6)
diff --git a/Modules/Compiler/GHS-C.cmake b/Modules/Compiler/GHS-C.cmake
index a825b0b..9b0d0e8 100644
--- a/Modules/Compiler/GHS-C.cmake
+++ b/Modules/Compiler/GHS-C.cmake
@@ -5,6 +5,6 @@
 
 string(APPEND CMAKE_C_FLAGS_INIT " ")
 string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -Odebug -g")
-string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -Ospace")
-string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -O")
-string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -O -g")
+string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -DNDEBUG -Ospace")
+string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG -O")
+string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG -O -g")
diff --git a/Modules/Compiler/GHS-CXX.cmake b/Modules/Compiler/GHS-CXX.cmake
index 07b5044..773fe1c 100644
--- a/Modules/Compiler/GHS-CXX.cmake
+++ b/Modules/Compiler/GHS-CXX.cmake
@@ -5,6 +5,6 @@
 
 string(APPEND CMAKE_CXX_FLAGS_INIT " ")
 string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -Odebug -g")
-string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -Ospace")
-string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -O")
-string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -O -g")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -DNDEBUG -Ospace")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -DNDEBUG -O")
+string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -DNDEBUG -O -g")
diff --git a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
index 965e25a..834e999 100644
--- a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
@@ -6,21 +6,25 @@
     return ()
   endif ()
 
-  execute_process(
-    COMMAND
-      "${CMAKE_CXX_COMPILER}"
-      ${CMAKE_CXX_COMPILER_ID_ARG1}
-      -print-file-name=libstdc++.modules.json
-    OUTPUT_VARIABLE _gnu_libstdcxx_modules_json_file
-    ERROR_VARIABLE _gnu_libstdcxx_modules_json_file_err
-    RESULT_VARIABLE _gnu_libstdcxx_modules_json_file_res
-    OUTPUT_STRIP_TRAILING_WHITESPACE
-    ERROR_STRIP_TRAILING_WHITESPACE)
-  if (_gnu_libstdcxx_modules_json_file_res)
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libstdc++.modules.json` resource\")\n"
-      PARENT_SCOPE)
-    return ()
+  if (CMAKE_CXX_STDLIB_MODULES_JSON)
+    set(_gnu_libstdcxx_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
+  else ()
+    execute_process(
+      COMMAND
+        "${CMAKE_CXX_COMPILER}"
+        ${CMAKE_CXX_COMPILER_ID_ARG1}
+        -print-file-name=libstdc++.modules.json
+      OUTPUT_VARIABLE _gnu_libstdcxx_modules_json_file
+      ERROR_VARIABLE _gnu_libstdcxx_modules_json_file_err
+      RESULT_VARIABLE _gnu_libstdcxx_modules_json_file_res
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+      ERROR_STRIP_TRAILING_WHITESPACE)
+    if (_gnu_libstdcxx_modules_json_file_res)
+      set("${variable}"
+        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `libstdc++.modules.json` resource\")\n"
+        PARENT_SCOPE)
+      return ()
+    endif ()
   endif ()
 
   # Without this file, we do not have modules installed.
diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake
index 7de6039..85ceae8 100644
--- a/Modules/Compiler/MSVC-C.cmake
+++ b/Modules/Compiler/MSVC-C.cmake
@@ -33,6 +33,16 @@
     endmacro()
   endif()
 
+  if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.39)
+    # VS 17.10 did not have a "stdclatest" value for LanguageStandard_C.
+    if(NOT CMAKE_GENERATOR MATCHES "Visual Studio"
+        OR CMAKE_VS_VERSION_BUILD_NUMBER VERSION_GREATER_EQUAL 17.11)
+      set(CMAKE_C23_STANDARD_COMPILE_OPTION "-std:clatest")
+      set(CMAKE_C23_EXTENSION_COMPILE_OPTION "-std:clatest")
+      set(CMAKE_C_STANDARD_LATEST 23)
+    endif()
+  endif()
+
   __compiler_check_default_language_standard(C 19.27 99)
 else()
   # MSVC has no specific options to set C language standards, but set them as
diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
index 08199f7..ff01263 100644
--- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
@@ -1,21 +1,25 @@
 function (_cmake_cxx_import_std std variable)
-  find_file(_msvc_modules_json_file
-    NAME modules.json
-    HINTS
-      "$ENV{VCToolsInstallDir}/modules"
-    PATHS
-      "$ENV{INCLUDE}"
-      "${CMAKE_CXX_COMPILER}/../../.."
-      "${CMAKE_CXX_COMPILER}/../.."    # msvc-wine layout
-    PATH_SUFFIXES
-      ../modules
-    NO_CACHE)
-  # Without this file, we do not have modules installed.
-  if (NOT EXISTS "${_msvc_modules_json_file}")
-    set("${variable}"
-      "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `modules.json` resource\")\n"
-      PARENT_SCOPE)
-    return ()
+  if (CMAKE_CXX_STDLIB_MODULES_JSON)
+    set(_msvc_modules_json_file "${CMAKE_CXX_STDLIB_MODULES_JSON}")
+  else ()
+    find_file(_msvc_modules_json_file
+      NAME modules.json
+      HINTS
+        "$ENV{VCToolsInstallDir}/modules"
+      PATHS
+        "$ENV{INCLUDE}"
+        "${CMAKE_CXX_COMPILER}/../../.."
+        "${CMAKE_CXX_COMPILER}/../.."    # msvc-wine layout
+      PATH_SUFFIXES
+        ../modules
+      NO_CACHE)
+    # Without this file, we do not have modules installed.
+    if (NOT EXISTS "${_msvc_modules_json_file}")
+      set("${variable}"
+        "set(CMAKE_CXX${std}_COMPILER_IMPORT_STD_NOT_FOUND_MESSAGE \"Could not find `modules.json` resource\")\n"
+        PARENT_SCOPE)
+      return ()
+    endif ()
   endif ()
 
   file(READ "${_msvc_modules_json_file}" _msvc_modules_json)
diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake
index d16b2d4..aede0bc 100644
--- a/Modules/Compiler/QCC.cmake
+++ b/Modules/Compiler/QCC.cmake
@@ -13,7 +13,7 @@
   set(CMAKE_PREFIX_LIBRARY_ARCHITECTURE "ON")
 
   set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "-Wc,-isysroot,")
-  set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
+  set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
   set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEP_FILE> -Wp,-MT,<DEP_TARGET> -Wp,-MF,<DEP_FILE>")
 
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
diff --git a/Modules/Compiler/TIClang-C.cmake b/Modules/Compiler/TIClang-C.cmake
index b6ce3dc..ed637be 100644
--- a/Modules/Compiler/TIClang-C.cmake
+++ b/Modules/Compiler/TIClang-C.cmake
@@ -22,12 +22,23 @@
 set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-std=gnu11")
 set(CMAKE_C11_STANDARD__HAS_FULL_SUPPORT ON)
 
-set(CMAKE_C_STANDARD_LATEST 11)
+if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 1.3)
+  set(CMAKE_C17_STANDARD_COMPILE_OPTION "-std=c17")
+  set(CMAKE_C17_EXTENSION_COMPILE_OPTION "-std=gnu17")
+  set(CMAKE_C17_STANDARD__HAS_FULL_SUPPORT ON)
+  set(CMAKE_C_STANDARD_LATEST 17)
+else()
+  set(CMAKE_C_STANDARD_LATEST 11)
+endif()
+
 
 # Including the "${CMAKE_ROOT}/Modules/Compiler/Clang-C.cmake" script above may set several other compile option
 # variables which do not necessarily apply here. So, we unset those variables accordingly.
-unset(CMAKE_C17_STANDARD_COMPILE_OPTION)
-unset(CMAKE_C17_EXTENSION_COMPILE_OPTION)
+
+if(CMAKE_C_COMPILER_VERSION VERSION_LESS 1.3)
+  unset(CMAKE_C17_STANDARD_COMPILE_OPTION)
+  unset(CMAKE_C17_EXTENSION_COMPILE_OPTION)
+endif()
 
 unset(CMAKE_C23_STANDARD_COMPILE_OPTION)
 unset(CMAKE_C23_EXTENSION_COMPILE_OPTION)
diff --git a/Modules/ExternalData.cmake b/Modules/ExternalData.cmake
index 5d28929..02d8bd9 100644
--- a/Modules/ExternalData.cmake
+++ b/Modules/ExternalData.cmake
@@ -9,7 +9,14 @@
 
    .. contents::
 
-Manage data files stored outside source tree
+This module provides commands to manage data files stored outside source
+tree.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(ExternalData)
 
 Introduction
 ^^^^^^^^^^^^
@@ -485,7 +492,7 @@
 
   # Store configuration for use by build-time script.
   set(config ${CMAKE_CURRENT_BINARY_DIR}/${target}_config.cmake)
-  configure_file(${_ExternalData_SELF_DIR}/ExternalData_config.cmake.in ${config} @ONLY)
+  configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalData_config.cmake.in ${config} @ONLY)
 
   set(files "")
 
@@ -517,7 +524,7 @@
                                    -DExternalData_ACTION=local
                                    -DExternalData_SHOW_PROGRESS=${_ExternalData_add_target_SHOW_PROGRESS}
                                    -DExternalData_CONFIG=${config}
-                                   -P ${_ExternalData_SELF}
+                                   -P ${CMAKE_CURRENT_FUNCTION_LIST_FILE}
           MAIN_DEPENDENCY "${name}"
           )
       endif()
@@ -554,7 +561,7 @@
                                    -DExternalData_ACTION=fetch
                                    -DExternalData_SHOW_PROGRESS=${_ExternalData_add_target_SHOW_PROGRESS}
                                    -DExternalData_CONFIG=${config}
-                                   -P ${_ExternalData_SELF}
+                                   -P ${CMAKE_CURRENT_FUNCTION_LIST_FILE}
           # Update whenever the object hash changes.
           MAIN_DEPENDENCY "${name}${first_ext}"
           )
@@ -608,8 +615,6 @@
 
 set(_ExternalData_REGEX_ALGO "MD5|SHA1|SHA224|SHA256|SHA384|SHA512|SHA3_224|SHA3_256|SHA3_384|SHA3_512")
 set(_ExternalData_REGEX_EXT "md5|sha1|sha224|sha256|sha384|sha512|sha3-224|sha3-256|sha3-384|sha3-512")
-set(_ExternalData_SELF "${CMAKE_CURRENT_LIST_FILE}")
-get_filename_component(_ExternalData_SELF_DIR "${_ExternalData_SELF}" PATH)
 
 function(_ExternalData_compute_hash var_hash algo file)
   if("${algo}" MATCHES "^${_ExternalData_REGEX_ALGO}$")
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 61e2ea5..fefcd27 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -11,6 +11,15 @@
 
    .. contents::
 
+This module provides commands to download and build external projects as
+part of CMake build phase.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(ExternalProject)
+
 External Project Definition
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -654,6 +663,48 @@
   examples of build systems whose build step is smart enough to know if the
   configure step needs to be rerun.
 
+``CONFIGURE_ENVIRONMENT_MODIFICATION <modification>...``
+  .. versionadded:: 4.2
+
+  Specify environment variables that should be modified for the configure step.
+
+  Set a :ref:`semicolon-separated list <CMake Language Lists>` of environment
+  variables and values of the form ``MYVAR=OP:VALUE``, where ``MYVAR`` is the
+  case-sensitive name of an environment variable to be modified.  Entries are
+  considered in the order specified in the property's value. The ``OP`` may be
+  one of:
+
+  .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
+
+  .. code-block:: cmake
+
+    ExternalProject_Add(example
+      ... # Download options, etc...
+      CONFIGURE_ENVIRONMENT_MODIFICATION
+        SDKROOT=set:macosx
+        PKG_CONFIG_PATH=set:$ENV{PKG_CONFIG_PATH}
+    )
+
+  This snippet defines two environment variables when configuring the example
+  project. The ``SDKROOT`` environment variable is set to ``macosx``, while
+  the value of ``PKG_CONFIG_PATH`` is forwarded to the external project.
+
+  Environment modifications work with ``LIST_SEPARATOR`` to replace the
+  separator with a ``;`` in the environment variable.
+
+  .. code-block:: cmake
+
+    ExternalProject_Add(example
+      ... # Download options, etc...
+      LIST_SEPARATOR ,
+      CONFIGURE_ENVIRONMENT_MODIFICATION
+        LIST_VAR=set:a,b,c
+    )
+
+  This snippet
+  and the environment variable ``LIST_VAR`` is passed to the configure command
+  invocation with the value ``a;b;c``.
+
 Build Step Options
 """"""""""""""""""
 
@@ -719,6 +770,19 @@
   ``JOB_SERVER_AWARE`` option for details.  This option is relevant
   only when an explicit ``BUILD_COMMAND`` is specified.
 
+``BUILD_ENVIRONMENT_MODIFICATION <modification>...``
+  .. versionadded:: 4.2
+
+  Specify environment variables that should be modified for the build step.
+
+  Set a :ref:`semicolon-separated list <CMake Language Lists>` of environment
+  variables and values of the form ``MYVAR=OP:VALUE``, where ``MYVAR`` is the
+  case-sensitive name of an environment variable to be modified.  Entries are
+  considered in the order specified in the property's value. The ``OP`` may be
+  one of:
+
+  .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
+
 Install Step Options
 """"""""""""""""""""
 
@@ -777,6 +841,19 @@
   :envvar:`CMAKE_INSTALL_MODE` environment variable changes from one run
   to another.
 
+``INSTALL_ENVIRONMENT_MODIFICATION <modification>...``
+  .. versionadded:: 4.2
+
+  Specify environment variables that should be modified for the install step.
+
+  Set a :ref:`semicolon-separated list <CMake Language Lists>` of environment
+  variables and values of the form ``MYVAR=OP:VALUE``, where ``MYVAR`` is the
+  case-sensitive name of an environment variable to be modified.  Entries are
+  considered in the order specified in the property's value. The ``OP`` may be
+  one of:
+
+  .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
+
 Test Step Options
 """""""""""""""""
 
@@ -815,6 +892,19 @@
   This may cause a step target to be created automatically for either
   the ``install`` or ``build`` step.  See policy :policy:`CMP0114`.
 
+``TEST_ENVIRONMENT_MODIFICATION <modification>...``
+  .. versionadded:: 4.2
+
+  Specify environment variables that should be modified for the test step.
+
+  Set a :ref:`semicolon-separated list <CMake Language Lists>` of environment
+  variables and values of the form ``MYVAR=OP:VALUE``, where ``MYVAR`` is the
+  case-sensitive name of an environment variable to be modified.  Entries are
+  considered in the order specified in the property's value. The ``OP`` may be
+  one of:
+
+  .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
+
 Output Logging Options
 """"""""""""""""""""""
 
@@ -940,7 +1030,8 @@
 """""""""""""""""""""
 
 ``LIST_SEPARATOR <sep>``
-  For any of the various ``..._COMMAND`` options, and ``CMAKE_ARGS``,
+  For any of the various ``..._COMMAND`` options, ``CMAKE_ARGS``, and
+  `..._ENVIRONMENT_MODIFICATION`` operations,
   ``ExternalProject`` will replace ``<sep>`` with ``;`` in the specified
   command lines. This can be used to ensure a command has a literal ``;`` in it
   where direct usage would otherwise be interpreted as argument separators to
@@ -1043,6 +1134,20 @@
   ``DEPENDS <file>...``
     Files on which this custom step depends.
 
+  ``ENVIRONMENT_MODIFICATION <modification>...``
+    .. versionadded:: 4.2
+
+    Specify environment variables that should be modified while running the
+    commands in the external project step.
+
+    Set a :ref:`semicolon-separated list <CMake Language Lists>` of environment
+    variables and values of the form ``MYVAR=OP:VALUE``, where ``MYVAR`` is the
+    case-sensitive name of an environment variable to be modified.  Entries are
+    considered in the order specified in the property's value. The ``OP`` may be
+    one of:
+
+    .. include:: ../include/ENVIRONMENT_MODIFICATION_OPS.rst
+
   ``INDEPENDENT <bool>``
     .. versionadded:: 3.19
 
@@ -2057,6 +2162,7 @@
     DEPENDEES
     DEPENDERS
     DEPENDS
+    ENVIRONMENT_MODIFICATION
     INDEPENDENT
     BYPRODUCTS
     ALWAYS
@@ -2167,13 +2273,50 @@
     PROPERTY _EP_${step}_WORKING_DIRECTORY
   )
 
-  # Replace list separators.
+  # Replace list separators and inject environment modifications.
   get_property(sep
     TARGET ${name}
     PROPERTY _EP_LIST_SEPARATOR
   )
-  if(sep AND command)
-    string(REPLACE "${sep}" "\\;" command "${command}")
+  get_property(environment
+    TARGET ${name}
+    PROPERTY _EP_${step}_ENVIRONMENT_MODIFICATION
+  )
+  if(environment)
+    set(env_args "")
+    foreach(env_mod IN LISTS environment)
+      if(env_mod MATCHES [[^([^=:]+)=([a-z_]+):(.*)$]])
+        set(_value "${CMAKE_MATCH_3}")
+        # Replace the separator only in the value in case it is `:`.
+        if(sep)
+          string(REPLACE "${sep}" [[\;]] _value "${_value}")
+        endif()
+        list(APPEND env_args --modify "${CMAKE_MATCH_1}=${CMAKE_MATCH_2}:${_value}")
+      else()
+        message(SEND_ERROR "Malformed environment modification specifier:"
+        " '${env_mod}'\n"
+        "Expected MYVAR=OP:VALUE")
+      endif()
+    endforeach()
+    set(env_command "${CMAKE_COMMAND};-E;env;${env_args};--")
+  else()
+    set(env_command "")
+  endif()
+  if(command)
+    if(env_command)
+      # Strip empty commands so we do not add env for them.
+      string(REGEX REPLACE [[^COMMAND;+(COMMAND;+)*]] "" command "${command}")
+      string(REGEX REPLACE [[;COMMAND;+(COMMAND;+)*]] ";COMMAND;" command "${command}")
+      # Replace the separator with an extra escape to survive list(TRANSFORM).
+      if(sep)
+        string(REPLACE "${sep}" [[\\;]] command "${command}")
+      endif()
+      # Prepend every command with our environment modification launcher.
+      list(TRANSFORM command APPEND ";${env_command}" REGEX "^COMMAND$")
+      set(command "${env_command};${command}")
+    elseif(sep)
+      string(REPLACE "${sep}" [[\;]] command "${command}")
+    endif()
   endif()
 
   # Replace location tags.
@@ -2660,6 +2803,14 @@
     set(dependees patch)
   endif()
 
+  get_property(environment
+    TARGET ${name}
+    PROPERTY _EP_CONFIGURE_ENVIRONMENT_MODIFICATION
+  )
+  if(environment)
+    set(environment "ENVIRONMENT_MODIFICATION" ${environment})
+  endif()
+
   get_property(log
     TARGET ${name}
     PROPERTY _EP_LOG_CONFIGURE
@@ -2691,6 +2842,7 @@
       WORKING_DIRECTORY \${binary_dir}
       DEPENDEES \${dependees}
       DEPENDS \${file_deps}
+      ${environment}
       ${log}
       ${uses_terminal}
     )"
@@ -2770,6 +2922,13 @@
     set(maybe_JOB_SERVER_AWARE "")
   endif()
 
+  get_property(environment
+    TARGET ${name}
+    PROPERTY _EP_BUILD_ENVIRONMENT_MODIFICATION
+  )
+  if(environment)
+    set(environment ENVIRONMENT_MODIFICATION ${environment})
+  endif()
 
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
@@ -2785,6 +2944,7 @@
       DEPENDS \${file_deps}
       ALWAYS \${always}
       ${maybe_JOB_SERVER_AWARE}
+      ${environment}
       ${log}
       ${uses_terminal}
     )"
@@ -2857,6 +3017,14 @@
     set(maybe_JOB_SERVER_AWARE "")
   endif()
 
+  get_property(environment
+    TARGET ${name}
+    PROPERTY _EP_INSTALL_ENVIRONMENT_MODIFICATION
+  )
+  if(environment)
+    set(environment ENVIRONMENT_MODIFICATION ${environment})
+  endif()
+
   set(__cmdQuoted)
   foreach(__item IN LISTS cmd)
     string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -2870,6 +3038,7 @@
       DEPENDEES build
       ALWAYS \${always}
       ${maybe_JOB_SERVER_AWARE}
+      ${environment}
       ${log}
       ${uses_terminal}
     )"
@@ -2936,6 +3105,14 @@
       set(uses_terminal "")
     endif()
 
+    get_property(environment
+      TARGET ${name}
+      PROPERTY _EP_TEST_ENVIRONMENT_MODIFICATION
+    )
+    if(environment)
+      set(environment ENVIRONMENT_MODIFICATION ${environment})
+    endif()
+
     set(__cmdQuoted)
     foreach(__item IN LISTS cmd)
       string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -2948,6 +3125,7 @@
         ${dependees_args}
         ${dependers_args}
         ${exclude_args}
+        ${environment}
         ${log}
         ${uses_terminal}
       )"
@@ -3043,11 +3221,11 @@
   # rebuilds.  It is important that 'done' is not the output of any
   # custom command so that CMake does not propagate build rules to
   # other external project targets, which may cause problems during
-  # parallel builds.  However, the Ninja generator needs to see the entire
+  # parallel builds.  However, the Ninja and Fastbuild generators need to see the entire
   # dependency graph, and can cope with custom commands belonging to
-  # multiple targets, so we add the 'done' mark as an output for Ninja only.
+  # multiple targets, so we add the 'done' mark as an output for Ninja and Fastbuild only.
   set(complete_outputs ${complete_stamp_file})
-  if(${CMAKE_GENERATOR} MATCHES "Ninja")
+  if(${CMAKE_GENERATOR} MATCHES "Ninja|FASTBuild")
     set(complete_outputs ${complete_outputs} ${done_stamp_file})
   endif()
 
diff --git a/Modules/ExternalProject/shared_internal_commands.cmake b/Modules/ExternalProject/shared_internal_commands.cmake
index cb7b772..b7077ef 100644
--- a/Modules/ExternalProject/shared_internal_commands.cmake
+++ b/Modules/ExternalProject/shared_internal_commands.cmake
@@ -1,4 +1,4 @@
-cmake_policy(VERSION 3.25)
+cmake_policy(VERSION 4.1)
 
 # Determine the remote URL of the project containing the working_directory.
 # This will leave output_variable unset if the URL can't be determined.
@@ -55,9 +55,9 @@
     endif()
   endif()
 
-  if(GIT_VERSION VERSION_LESS 1.7.5)
+  if(Git_VERSION VERSION_LESS 1.7.5)
     set(_git_remote_url_cmd_args config remote.${git_remote_name}.url)
-  elseif(GIT_VERSION VERSION_LESS 2.7)
+  elseif(Git_VERSION VERSION_LESS 2.7)
     set(_git_remote_url_cmd_args ls-remote --get-url ${git_remote_name})
   else()
     set(_git_remote_url_cmd_args remote get-url ${git_remote_name})
@@ -399,7 +399,7 @@
   tls_verify
 )
 
-  if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
+  if(NOT Git_VERSION VERSION_LESS 1.8.5)
     # Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
     set(git_checkout_explicit-- "--")
   else()
@@ -412,14 +412,14 @@
     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 VERSION_LESS 2.20 OR
+    2.21 VERSION_LESS_EQUAL Git_VERSION)
     set(git_clone_options "--no-checkout")
   else()
     set(git_clone_options)
   endif()
   if(git_shallow)
-    if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.10)
+    if(NOT Git_VERSION VERSION_LESS 1.7.10)
       list(APPEND git_clone_options "--depth 1 --no-single-branch")
     else()
       list(APPEND git_clone_options "--depth 1")
@@ -511,10 +511,10 @@
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
   set(git_stash_save_options --quiet)
-  if(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.7)
+  if(Git_VERSION VERSION_GREATER_EQUAL 1.7.7)
     # This avoids stashing files covered by .gitignore
     list(APPEND git_stash_save_options --include-untracked)
-  elseif(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.6)
+  elseif(Git_VERSION VERSION_GREATER_EQUAL 1.7.6)
     # Untracked files, but also ignored files, so potentially slower
     list(APPEND git_stash_save_options --all)
   endif()
@@ -740,10 +740,10 @@
   set(${git_submodules_recurse} "${recurseFlag}" PARENT_SCOPE)
 
   # The git submodule update '--recursive' flag requires git >= v1.6.5
-  if(recurseFlag AND GIT_VERSION_STRING VERSION_LESS 1.6.5)
+  if(recurseFlag AND Git_VERSION VERSION_LESS 1.6.5)
     message(FATAL_ERROR
       "git version 1.6.5 or later required for --recursive flag with "
-      "'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'"
+      "'git submodule ...': Git_VERSION='${Git_VERSION}'"
     )
   endif()
 endfunction()
@@ -921,7 +921,7 @@
   elseif(git_repository)
     set(method git)
     # FetchContent gives us these directly, so don't try to recompute them
-    if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING)
+    if(NOT GIT_EXECUTABLE OR NOT Git_VERSION)
       unset(CMAKE_MODULE_PATH) # Use CMake builtin find module
       find_package(Git QUIET)
       if(NOT GIT_EXECUTABLE)
@@ -957,7 +957,7 @@
 
     # If git supports it, make checkouts quiet when checking out a git hash.
     # This avoids the very noisy detached head message.
-    if(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.7)
+    if(Git_VERSION VERSION_GREATER_EQUAL 1.7.7)
       list(PREPEND git_config advice.detachedHead=false)
     endif()
 
@@ -1496,7 +1496,7 @@
 
   elseif(git_repository)
     # FetchContent gives us these directly, so don't try to recompute them
-    if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING)
+    if(NOT GIT_EXECUTABLE OR NOT Git_VERSION)
       unset(CMAKE_MODULE_PATH) # Use CMake builtin find module
       find_package(Git QUIET)
       if(NOT GIT_EXECUTABLE)
@@ -1596,7 +1596,7 @@
       set(hg_tag "tip")
     endif()
 
-    if("${HG_VERSION_STRING}" STREQUAL "2.1")
+    if("${Hg_VERSION}" STREQUAL "2.1")
       set(notesAnchor
         "#A2.1.1:_revert_pull_return_code_change.2C_compile_issue_on_OS_X"
       )
@@ -1896,6 +1896,7 @@
     # Configure step options
     #
     CONFIGURE_COMMAND
+    CONFIGURE_ENVIRONMENT_MODIFICATION
     CMAKE_COMMAND
     CMAKE_GENERATOR
     CMAKE_GENERATOR_PLATFORM
@@ -1910,6 +1911,7 @@
     # Build step options
     #
     BUILD_COMMAND
+    BUILD_ENVIRONMENT_MODIFICATION
     BUILD_IN_SOURCE
     BUILD_ALWAYS
     BUILD_BYPRODUCTS
@@ -1918,12 +1920,14 @@
     # Install step options
     #
     INSTALL_COMMAND
+    INSTALL_ENVIRONMENT_MODIFICATION
     INSTALL_BYPRODUCTS
     INSTALL_JOB_SERVER_AWARE
     #
     # Test step options
     #
     TEST_COMMAND
+    TEST_ENVIRONMENT_MODIFICATION
     TEST_BEFORE_INSTALL
     TEST_AFTER_INSTALL
     TEST_EXCLUDE_FROM_MAIN
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake
index c4b27da..6b83903 100644
--- a/Modules/FeatureSummary.cmake
+++ b/Modules/FeatureSummary.cmake
@@ -7,32 +7,45 @@
 FeatureSummary
 --------------
 
-Functions for generating a summary of enabled/disabled features.
+.. only:: html
 
-These functions can be used to generate a summary of enabled and disabled
-packages and/or features for a build tree such as::
+   .. contents::
 
-    -- The following features have been enabled:
+This module provides commands for generating a summary of enabled/disabled
+features.
 
-     * Example, usage example
+Load this module in CMake with:
 
-    -- The following OPTIONAL packages have been found:
+.. code-block:: cmake
 
-     * LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org>
-       Enables HTML-import in MyWordProcessor
-       Enables odt-export in MyWordProcessor
-     * PNG, image library, <http://www.libpng.org/pub/png/>
-       Enables saving screenshots
+  include(FeatureSummary)
 
-    -- The following OPTIONAL packages have not been found:
+Commands provided by this module can be used to generate a summary of enabled
+and disabled packages and/or features for a build tree such as::
 
-     * Lua, the Lua scripting language, <https://www.lua.org>
-       Enables macros in MyWordProcessor
-     * OpenGL, Open Graphics Library
+  -- The following features have been enabled:
+
+   * Example, usage example
+
+  -- The following OPTIONAL packages have been found:
+
+   * LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org>
+     Enables HTML-import in MyWordProcessor
+     Enables odt-export in MyWordProcessor
+   * PNG, image library, <http://www.libpng.org/pub/png/>
+     Enables saving screenshots
+
+  -- The following OPTIONAL packages have not been found:
+
+   * Lua, the Lua scripting language, <https://www.lua.org>
+     Enables macros in MyWordProcessor
+   * OpenGL, Open Graphics Library
 
 Global Properties
 ^^^^^^^^^^^^^^^^^
 
+The following global properties are used by this module:
+
 .. variable:: FeatureSummary_PKG_TYPES
 
   .. versionadded:: 3.8
@@ -69,8 +82,9 @@
 
   This global property defines the default package type.
 
-  When the :command:`feature_summary()` command is called, and the user has not
-  explicitly set a type of some package, its type will be set to this value.
+  When the :command:`feature_summary()` command is called, and the user has
+  not explicitly set a type of some package, its type will be set to the
+  value of this property.
 
   This value must be one of the types defined in the
   :variable:`FeatureSummary_PKG_TYPES` global property.
@@ -88,6 +102,519 @@
       The following <FeatureSummary_<TYPE>_DESCRIPTION> have been found:
 
   If not set, default string ``<TYPE> packages`` is used.
+
+Commands
+^^^^^^^^
+
+This module provides the following commands:
+
+* :command:`feature_summary`
+* :command:`set_package_properties`
+* :command:`add_feature_info`
+
+Printing Feature Summary
+""""""""""""""""""""""""
+
+.. command:: feature_summary
+
+  Prints information about enabled or disabled packages and features of a
+  project:
+
+  .. code-block:: cmake
+
+    feature_summary(
+      WHAT (ALL
+        | PACKAGES_FOUND | PACKAGES_NOT_FOUND
+        | <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND
+        | ENABLED_FEATURES | DISABLED_FEATURES)
+      [FILENAME <file>]
+      [APPEND]
+      [VAR <variable-name>]
+      [INCLUDE_QUIET_PACKAGES]
+      [FATAL_ON_MISSING_REQUIRED_PACKAGES]
+      [DESCRIPTION <description> | DEFAULT_DESCRIPTION]
+      [QUIET_ON_EMPTY]
+    )
+
+  This command can be used to print information about enabled or disabled
+  packages and features of a project.  By default, only the names of the
+  features/packages will be printed and their required version when one was
+  specified.  Use :command:`set_package_properties()` to add more useful
+  information, e.g., a homepage URL for the respective package or their
+  purpose in the project.
+
+  .. rubric:: The arguments are:
+
+  ``WHAT``
+    This is the only mandatory option.  It specifies what information will be
+    printed:
+
+    ``ALL``
+      Print everything.
+    ``ENABLED_FEATURES``
+      The list of all features which are enabled.
+    ``DISABLED_FEATURES``
+      The list of all features which are disabled.
+    ``PACKAGES_FOUND``
+      The list of all packages which have been found.
+    ``PACKAGES_NOT_FOUND``
+      The list of all packages which have not been found.
+
+    For each package type ``<TYPE>`` defined by the
+    :variable:`FeatureSummary_PKG_TYPES` global property, the following
+    information can also be used:
+
+    ``<TYPE>_PACKAGES_FOUND``
+      The list of only packages of type ``<TYPE>`` which have been found.
+    ``<TYPE>_PACKAGES_NOT_FOUND``
+      The list of only packages of type ``<TYPE>`` which have not been found.
+
+    .. versionchanged:: 3.1
+      The ``WHAT`` option is now a multi-value keyword, so that these values can
+      be combined, with the exception of the ``ALL`` value, in order to
+      customize the output.  For example:
+
+    .. code-block:: cmake
+
+      feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
+
+  ``FILENAME <file>``
+    If this option is given, the information is printed into this file instead
+    of the terminal.  Relative ``<file>`` path is interpreted as being relative
+    to the current source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).
+
+  ``APPEND``
+    If this option is given, the output is appended to the ``<file>`` provided
+    by the ``FILENAME`` option, otherwise the file is overwritten if it already
+    exists.
+
+  ``VAR <variable-name>``
+    If this option is given, the information is stored into the specified
+    variable ``<variable-name>`` instead of the terminal.
+
+  ``INCLUDE_QUIET_PACKAGES``
+    If this option is given, packages which have been searched with
+    :command:`find_package(... QUIET)` will also be listed.  By default they are
+    skipped.
+
+  ``FATAL_ON_MISSING_REQUIRED_PACKAGES``
+    If this option is given, CMake will abort with fatal error if a package
+    which is marked as one of the package types listed in the
+    :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global property has not been
+    found.
+
+  ``DESCRIPTION <description>``
+    A description or headline which will be printed above the actual content.
+    Without this option, if only one package type was requested, no title is
+    printed, unless a custom string is explicitly set using this option or
+    ``DEFAULT_DESCRIPTION`` option is used that outputs a default title for the
+    requested type.
+
+  ``DEFAULT_DESCRIPTION``
+    .. versionadded:: 3.9
+
+    The default description or headline to be printed above the content as
+    opposed to the customizable ``DESCRIPTION <description>``.
+
+  ``QUIET_ON_EMPTY``
+    .. versionadded:: 3.8
+
+    If this option is given, when only one package type was requested, and no
+    packages belonging to that category were found, then no output (including
+    the ``DESCRIPTION``) is printed nor added to the ``FILENAME``, or the
+    ``VAR`` variable.
+
+Package Properties
+""""""""""""""""""
+
+.. command:: set_package_properties
+
+  Sets package properties:
+
+  .. code-block:: cmake
+
+    set_package_properties(
+      <PackageName>
+      PROPERTIES
+        [URL <url>]
+        [DESCRIPTION <description>]
+        [TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)]
+        [PURPOSE <purpose>]
+    )
+
+  Use this command to configure and provide information about the package
+  named ``<PackageName>``, which can then be displayed using the
+  :command:`feature_summary()` command.  This command can be called either
+  directly within the corresponding :ref:`Find module <Find Modules>` or in
+  the project that uses the module after invoking the :command:`find_package()`
+  call.  The features for which information can be set are determined
+  automatically after the :command:`find_package()` command.
+
+  .. rubric:: The arguments are:
+
+  ``<PackageName>``
+    The name of the package.  For example, as specified in the
+    :command:`find_package(<PackageName>)` argument.
+
+  ``PROPERTIES``
+    Specifies the properties to set:
+
+    ``URL <url>``
+      This should be the homepage of the package, or something similar.
+      Ideally this is set already directly in the
+      :ref:`Find module <Find Modules>`.
+
+    ``DESCRIPTION <description>``
+      A short description what that package is, at most one sentence.
+      Ideally this is set already directly in the
+      :ref:`Find module <Find Modules>`.
+
+    ``TYPE <type>``
+      What type of dependency has the using project on that package.
+
+      Default ``<type>`` is ``OPTIONAL``.  In this case it is a package
+      which can be used by the project when available at buildtime, but the
+      project also works without it.
+
+      ``RECOMMENDED`` package type is similar to ``OPTIONAL``, i.e.  the
+      project will build if the package is not present, but the
+      functionality of the resulting binaries will be severely limited.  If
+      a ``REQUIRED`` package is not available at buildtime, the project may
+      not even build. This can be combined with the
+      :command:`feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES)` command
+      option.
+
+      Last, a ``RUNTIME`` package is a package which is actually not used
+      at all during the build, but which is required for actually running
+      the resulting binaries.  So if such a package is missing, the project
+      can still be built, but it may not work later on.
+
+      If ``set_package_properties()`` is called multiple times for the same
+      package with different TYPEs, the ``TYPE`` is only changed to higher
+      TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs
+      are ignored.  The ``TYPE`` property is project-specific, so it cannot
+      be set by the :ref:`Find module <Find Modules>`, but must be set in
+      the project.
+
+      The accepted types can be changed by setting the
+      :variable:`FeatureSummary_PKG_TYPES` global property.
+
+    ``PURPOSE <purpose>``
+      This describes which features this package enables in the project,
+      i.e.  it tells the user what functionality they get in the resulting
+      binaries.  If ``set_package_properties()`` is called multiple times
+      for a package, all ``PURPOSE`` properties are appended to a list of
+      purposes of the package in the project.  As the ``TYPE`` property,
+      also the ``PURPOSE`` property is project-specific, so it cannot be
+      set by the :ref:`Find module <Find Modules>`, but must be set in the
+      project.
+
+Adding Feature Info
+"""""""""""""""""""
+
+.. command:: add_feature_info
+
+  Adds feature information:
+
+  .. code-block:: cmake
+
+    add_feature_info(<name> <condition> <description>)
+
+  Use this command to add information about a feature identified with a given
+  ``<name>``.
+
+  .. rubric:: The arguments are:
+
+  ``<name>``
+    Identification name for a feature being added.
+
+  ``<condition>``
+    Specifies the conditions that determine whether this feature is enabled
+    or disabled.
+
+    The ``<condition>`` argument can be:
+
+    * A single condition (such as a variable name).
+
+    * .. versionadded:: 3.8
+        A :ref:`semicolon-separated list <CMake Language Lists>` of multiple
+        conditions.
+
+    * .. versionadded:: 4.0
+        A full :ref:`Condition Syntax` as used in an ``if(<condition>)``
+        clause.  See policy :policy:`CMP0183`.  This enables using entire
+        condition syntax (such as grouping conditions with parens and
+        similar).
+
+  ``<description>``
+    A text describing the feature.  This information can be displayed using
+    :command:`feature_summary()` for ``ENABLED_FEATURES`` and
+    ``DISABLED_FEATURES`` respectively.
+
+Deprecated Commands
+"""""""""""""""""""
+
+The following legacy and deprecated commands are provided for backward
+compatibility with previous CMake versions:
+
+.. command:: set_package_info
+
+  .. deprecated:: 3.8
+    Use the :command:`set_package_properties`, and :command:`add_feature_info`
+    commands instead.
+
+  Sets up information about the specified package, which can then be displayed
+  via :command:`feature_summary()`:
+
+  .. code-block:: cmake
+
+    set_package_info(<PackageName> <description> [<url> [<purpose>]])
+
+  ``<PackageName>``
+    Name of the package.
+
+  ``<description>``
+    A short description of the package.
+
+  ``<url>``
+    Homepage of the package.
+
+  ``<purpose>``
+    The purpose of the package.
+
+  This command can be used either directly in the
+  :ref:`Find module <Find Modules>` or in the project which uses the
+  ``FeatureSummary`` module after the :command:`find_package()` call.  The
+  features for which information can be set are added automatically by the
+  ``find_package()`` command.
+
+.. command:: set_feature_info
+
+  .. deprecated:: 3.8
+
+  Sets feature info for a package:
+
+  .. code-block:: cmake
+
+    set_feature_info(<name> <description> [<url>])
+
+  Does the same as:
+
+  .. code-block:: cmake
+
+    set_package_info(<name> <description> [<url>])
+
+.. command:: print_enabled_features
+
+  .. deprecated:: 3.8
+
+  Prints enabled features:
+
+  .. code-block:: cmake
+
+    print_enabled_features()
+
+  Does the same as:
+
+  .. code-block:: cmake
+
+    feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
+
+.. command:: print_disabled_features
+
+  .. deprecated:: 3.8
+
+  Prints disabled features:
+
+  .. code-block:: cmake
+
+    print_disabled_features()
+
+  Does the same as:
+
+  .. code-block:: cmake
+
+    feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
+
+Examples
+^^^^^^^^
+
+Example: Appending Feature Summary to a File
+""""""""""""""""""""""""""""""""""""""""""""
+
+In the following example, the feature summary output will be appended to
+a specified file instead of printing:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+  feature_summary(WHAT ALL FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
+
+Example: Storing Feature Summary in a Variable
+""""""""""""""""""""""""""""""""""""""""""""""
+
+In the following example, the feature summary of enabled features is stored
+in a specified variable ``enabledFeaturesText``, including the ``QUIET``
+packages:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  feature_summary(
+    WHAT ENABLED_FEATURES
+    INCLUDE_QUIET_PACKAGES
+    DESCRIPTION "Enabled Features:"
+    VAR enabledFeaturesText
+  )
+
+  message(STATUS "${enabledFeaturesText}")
+
+Example: Adding a Custom Package Type
+"""""""""""""""""""""""""""""""""""""
+
+In the following example a custom package type is added and printed only
+the categories that are not empty:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD)
+
+  find_package(FOO)
+  set_package_properties(FOO PROPERTIES TYPE BUILD)
+
+  feature_summary(
+    WHAT BUILD_PACKAGES_FOUND
+    DESCRIPTION "Build tools found:"
+    QUIET_ON_EMPTY
+  )
+
+  feature_summary(
+    WHAT BUILD_PACKAGES_NOT_FOUND
+    DESCRIPTION "Build tools not found:"
+    QUIET_ON_EMPTY
+  )
+
+Example: Setting Package Info
+"""""""""""""""""""""""""""""
+
+Example for setting the info for a package:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  find_package(LibXml2)
+  set_package_properties(
+    LibXml2
+    PROPERTIES
+      DESCRIPTION "XML library"
+      URL "http://xmlsoft.org"
+  )
+  # or
+  set_package_properties(
+    LibXml2
+    PROPERTIES
+      TYPE RECOMMENDED
+      PURPOSE "Enables HTML-import in MyWordProcessor"
+  )
+  # or
+  set_package_properties(
+    LibXml2
+    PROPERTIES
+      TYPE OPTIONAL
+      PURPOSE "Enables odt-export in MyWordProcessor"
+  )
+
+  find_package(DBUS)
+  set_package_properties(
+    DBUS
+    PROPERTIES
+      TYPE RUNTIME
+      PURPOSE "Necessary to disable the screensaver during a presentation"
+  )
+
+Example: Printing Feature Summary
+"""""""""""""""""""""""""""""""""
+
+In the following example, this module is used to output feature summary at
+the end of the configuration.  If any required package is not found,
+processing stops with an error message at the end of the configuration
+phase.
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.15)
+  project(Example)
+
+  add_library(example example.c)
+
+  include(FeatureSummary)
+
+  find_package(CURL)
+  set_package_properties(CURL PROPERTIES TYPE REQUIRED)
+  target_link_libraries(example PRIVATE CURL::libcurl)
+
+  find_package(LibXml2 QUIET)
+  set_package_properties(LibXml2 PROPERTIES TYPE RECOMMENDED)
+  if(LibXml2_FOUND)
+    target_link_libraries(example PRIVATE LibXml2::LibXml2)
+  endif()
+
+  feature_summary(
+    WHAT ALL
+    INCLUDE_QUIET_PACKAGES
+    DESCRIPTION "Feature summary:"
+    FATAL_ON_MISSING_REQUIRED_PACKAGES
+  )
+
+Examples: Setting Feature Info
+""""""""""""""""""""""""""""""
+
+Example for setting the info for a feature:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  option(WITH_FOO "Help for foo" ON)
+
+  add_feature_info(Foo WITH_FOO "this feature provides very cool stuff")
+
+Example for setting feature info based on a list of conditions:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  option(WITH_FOO "Help for foo" ON)
+  option(WITH_BAR "Help for bar" OFF)
+
+  add_feature_info(
+    FooBar
+    "WITH_FOO;NOT WITH_BAR"
+    "this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF"
+  )
+
+In the next example feature info are set depending on a full condition
+syntax.  Unlike semicolon-separated list of conditions, this enables using
+entire condition syntax as being the ``if`` clause argument:
+
+.. code-block:: cmake
+
+  include(FeatureSummary)
+
+  option(WITH_FOO "Help for foo" ON)
+  option(WITH_BAR "Help for bar" ON)
+  option(WITH_BAZ "Help for baz" OFF)
+
+  add_feature_info(
+    FooBarBaz
+    "WITH_FOO AND (WITH_BAR OR WITH_BAZ)"
+    "this feature is enabled when the entire condition is true"
+  )
 #]=======================================================================]
 
 get_property(_fsPkgTypeIsSet GLOBAL PROPERTY FeatureSummary_PKG_TYPES SET)
@@ -105,15 +632,7 @@
   set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE OPTIONAL)
 endif()
 
-#[=======================================================================[.rst:
-
-Functions
-^^^^^^^^^
-
-#]=======================================================================]
-
 function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet)
-
   get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES)
   get_property(_fsDefaultPkgType GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE)
 
@@ -208,155 +727,6 @@
   set(${_var} "${_currentFeatureText}" PARENT_SCOPE)
 endfunction()
 
-
-#[=======================================================================[.rst:
-.. command:: feature_summary
-
-  .. code-block:: cmake
-
-    feature_summary([FILENAME <file>]
-                    [APPEND]
-                    [VAR <variable_name>]
-                    [INCLUDE_QUIET_PACKAGES]
-                    [FATAL_ON_MISSING_REQUIRED_PACKAGES]
-                    [DESCRIPTION <description> | DEFAULT_DESCRIPTION]
-                    [QUIET_ON_EMPTY]
-                    WHAT (ALL
-                         | PACKAGES_FOUND | PACKAGES_NOT_FOUND
-                         | <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND
-                         | ENABLED_FEATURES | DISABLED_FEATURES)
-                   )
-
-  This function can be used to print information about
-  enabled or disabled packages and features of a project.  By default,
-  only the names of the features/packages will be printed and their
-  required version when one was specified.  Use
-  :command:`set_package_properties()` to add more useful information, like e.g.
-  a homepage URL for the respective package or their purpose in the project.
-
-  The options are:
-
-  ``WHAT``
-    This is the only mandatory option.  It specifies what information will be
-    printed:
-
-    ``ALL``
-      Print everything.
-    ``ENABLED_FEATURES``
-      The list of all features which are enabled.
-    ``DISABLED_FEATURES``
-      The list of all features which are disabled.
-    ``PACKAGES_FOUND``
-      The list of all packages which have been found.
-    ``PACKAGES_NOT_FOUND``
-      The list of all packages which have not been found.
-
-    For each package type ``<TYPE>`` defined by the
-    :variable:`FeatureSummary_PKG_TYPES` global property, the following
-    information can also be used:
-
-    ``<TYPE>_PACKAGES_FOUND``
-      The list of only packages of type ``<TYPE>`` which have been found.
-    ``<TYPE>_PACKAGES_NOT_FOUND``
-      The list of only packages of type ``<TYPE>`` which have not been found.
-
-    .. versionchanged:: 3.1
-      The ``WHAT`` option is now a multi-value keyword, so that these values can
-      be combined, with the exception of the ``ALL`` value, in order to
-      customize the output.  For example:
-
-    .. code-block:: cmake
-
-      feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES)
-
-  ``FILENAME <file>``
-    If this option is given, the information is printed into this file instead
-    of the terminal.  Relative ``<file>`` path is interpreted as being relative
-    to the current source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`).
-
-  ``APPEND``
-    If this option is given, the output is appended to the ``<file>`` provided
-    by the ``FILENAME`` option, otherwise the file is overwritten if it already
-    exists.
-
-  ``VAR <variable_name>``
-    If this option is given, the information is stored into the specified
-    variable ``<variable_name>`` instead of the terminal.
-
-  ``DESCRIPTION <description>``
-    A description or headline which will be printed above the actual content.
-    Without this option, if only one package type was requested, no title is
-    printed, unless a custom string is explicitly set using this option or
-    ``DEFAULT_DESCRIPTION`` option is used that outputs a default title for the
-    requested type.
-
-  ``DEFAULT_DESCRIPTION``
-    .. versionadded:: 3.9
-
-    The default description or headline to be printed above the content as
-    opposed to the customizable ``DESCRIPTION <description>``.
-
-  ``INCLUDE_QUIET_PACKAGES``
-    If this option is given, packages which have been searched with
-    :command:`find_package(... QUIET)` will also be listed.  By default they are
-    skipped.
-
-  ``FATAL_ON_MISSING_REQUIRED_PACKAGES``
-    If this option is given, CMake will abort with fatal error if a package
-    which is marked as one of the package types listed in the
-    :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global property has not been
-    found.
-
-  The :variable:`FeatureSummary_DEFAULT_PKG_TYPE` global property can be
-  modified to change the default package type assigned when not explicitly
-  assigned by the user.
-
-  ``QUIET_ON_EMPTY``
-    .. versionadded:: 3.8
-
-    If this option is given, when only one package type was requested, and no
-    packages belonging to that category were found, then no output (including
-    the ``DESCRIPTION``) is printed nor added to the ``FILENAME``, or the
-    ``VAR`` variable.
-
-  Example 1, append everything to a file:
-
-  .. code-block:: cmake
-
-   include(FeatureSummary)
-   feature_summary(WHAT ALL
-                   FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND)
-
-  Example 2, print the enabled features into the variable
-  ``enabledFeaturesText``, including the ``QUIET`` packages:
-
-  .. code-block:: cmake
-
-    include(FeatureSummary)
-    feature_summary(WHAT ENABLED_FEATURES
-                   INCLUDE_QUIET_PACKAGES
-                   DESCRIPTION "Enabled Features:"
-                   VAR enabledFeaturesText)
-    message(STATUS "${enabledFeaturesText}")
-
-  Example 3, add custom package type and print only the categories that are not
-  empty:
-
-  .. code-block:: cmake
-
-    include(FeatureSummary)
-    set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD)
-    find_package(FOO)
-    set_package_properties(FOO PROPERTIES TYPE BUILD)
-    feature_summary(WHAT BUILD_PACKAGES_FOUND
-                    DESCRIPTION "Build tools found:"
-                    QUIET_ON_EMPTY)
-    feature_summary(WHAT BUILD_PACKAGES_NOT_FOUND
-                    DESCRIPTION "Build tools not found:"
-                    QUIET_ON_EMPTY)
-
-#]=======================================================================]
-
 function(FEATURE_SUMMARY)
 # cmake_parse_arguments(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
   set(options APPEND
@@ -498,93 +868,8 @@
   if(requiredPackagesNotFound  AND  _FS_FATAL_ON_MISSING_REQUIRED_PACKAGES)
     message(FATAL_ERROR "feature_summary() Error: REQUIRED package(s) are missing, aborting CMake run.")
   endif()
-
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: set_package_properties
-
-  .. code-block:: cmake
-
-    set_package_properties(<name> PROPERTIES
-                           [URL <url>]
-                           [DESCRIPTION <description>]
-                           [TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)]
-                           [PURPOSE <purpose>]
-                          )
-
-  Use this function to configure and provide information about the package named
-  ``<name>``, which can then be displayed using the
-  :command:`feature_summary()` command.  This can be performed either directly
-  within the corresponding :ref:`Find module <Find Modules>` or in the project
-  that uses the module after invoking the :command:`find_package()` call.  The
-  features for which information can be set are determined automatically after
-  the :command:`find_package()` command.
-
-  ``URL <url>``
-    This should be the homepage of the package, or something similar.
-    Ideally this is set already directly in the
-    :ref:`Find module <Find Modules>`.
-
-  ``DESCRIPTION <description>``
-    A short description what that package is, at most one sentence.
-    Ideally this is set already directly in the
-    :ref:`Find module <Find Modules>`.
-
-  ``TYPE <type>``
-    What type of dependency has the using project on that package.
-    Default is ``OPTIONAL``.  In this case it is a package which can be used
-    by the project when available at buildtime, but it also work without.
-    ``RECOMMENDED`` is similar to ``OPTIONAL``, i.e.  the project will build if
-    the package is not present, but the functionality of the resulting
-    binaries will be severely limited.  If a ``REQUIRED`` package is not
-    available at buildtime, the project may not even build.  This can be
-    combined with the
-    :command:`feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES)` command
-    option.  Last, a ``RUNTIME`` package is a package which is actually not used
-    at all during the build, but which is required for actually running the
-    resulting binaries.  So if such a package is
-    missing, the project can still be built, but it may not work later on.
-    If ``set_package_properties()`` is called multiple times for the same
-    package with different TYPEs, the ``TYPE`` is only changed to higher
-    TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs are
-    ignored.  The ``TYPE`` property is project-specific, so it cannot be set
-    by the :ref:`Find module <Find Modules>`, but must be set in the project.
-    The accepted types can be changed by setting the
-    :variable:`FeatureSummary_PKG_TYPES` global property.
-
-  ``PURPOSE <purpose>``
-    This describes which features this package enables in the
-    project, i.e.  it tells the user what functionality they get in the
-    resulting binaries.  If ``set_package_properties()`` is called multiple
-    times for a package, all ``PURPOSE`` properties are appended to a list of
-    purposes of the package in the project.  As the ``TYPE`` property, also
-    the ``PURPOSE`` property is project-specific, so it cannot be set by the
-    :ref:`Find module <Find Modules>`, but must be set in the project.
-
-  Example for setting the info for a package:
-
-  .. code-block:: cmake
-
-    include(FeatureSummary)
-    find_package(LibXml2)
-    set_package_properties(LibXml2 PROPERTIES
-                           DESCRIPTION "XML library"
-                           URL "http://xmlsoft.org")
-    # or
-    set_package_properties(LibXml2 PROPERTIES
-                           TYPE RECOMMENDED
-                           PURPOSE "Enables HTML-import in MyWordProcessor")
-    # or
-    set_package_properties(LibXml2 PROPERTIES
-                           TYPE OPTIONAL
-                           PURPOSE "Enables odt-export in MyWordProcessor")
-
-    find_package(DBUS)
-    set_package_properties(DBUS PROPERTIES
-      TYPE RUNTIME
-      PURPOSE "Necessary to disable the screensaver during a presentation")
-#]=======================================================================]
 function(SET_PACKAGE_PROPERTIES _name _props)
   if(NOT "${_props}" STREQUAL "PROPERTIES")
     message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.")
@@ -609,7 +894,6 @@
     set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" )
   endif()
 
-
   if(_SPP_URL)
     get_property(_info  GLOBAL PROPERTY _CMAKE_${_name}_URL)
     if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}")
@@ -619,7 +903,6 @@
     set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" )
   endif()
 
-
   # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project
   if(_SPP_PURPOSE)
     set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" )
@@ -648,68 +931,8 @@
       set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" )
     endif()
   endif()
-
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: add_feature_info
-
-  .. code-block:: cmake
-
-    add_feature_info(<name> <enabled> <description>)
-
-  Use this function to add information about a feature identified with a given
-  ``<name>``.  The ``<enabled>`` contains whether this feature is enabled or
-  not.  It can be a variable or a list of conditions.
-  ``<description>`` is a text describing the feature.  The information can
-  be displayed using :command:`feature_summary()` for ``ENABLED_FEATURES`` and
-  ``DISABLED_FEATURES`` respectively.
-
-  .. versionchanged:: 3.8
-    ``<enabled>`` can be a list of conditions.
-
-  .. versionchanged:: 4.0
-    Full :ref:`Condition Syntax` is now supported for ``<enabled>``.
-    See policy :policy:`CMP0183`.
-
-  Example for setting the info for a feature:
-
-  .. code-block:: cmake
-
-    include(FeatureSummary)
-
-    option(WITH_FOO "Help for foo" ON)
-    add_feature_info(Foo WITH_FOO "this feature provides very cool stuff")
-
-  Example for setting feature info based on a list of conditions:
-
-  .. code-block:: cmake
-
-    option(WITH_FOO "Help for foo" ON)
-    option(WITH_BAR "Help for bar" OFF)
-    add_feature_info(
-      FooBar
-      "WITH_FOO;NOT WITH_BAR"
-      "this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF"
-    )
-
-  Example for setting feature info depending on a full condition syntax:
-
-  Unlike semicolon-separated list of conditions, this enables using entire
-  condition syntax as being the ``if`` clause argument, such as grouping
-  conditions with parens and similar.
-
-  .. code-block:: cmake
-
-    option(WITH_FOO "Help for foo" ON)
-    option(WITH_BAR "Help for bar" ON)
-    option(WITH_BAZ "Help for baz" OFF)
-    add_feature_info(
-      FooBarBaz
-      "WITH_FOO AND (WITH_BAR OR WITH_BAZ)"
-      "this feature is enabled when the entire condition is true"
-    )
-#]=======================================================================]
 function(ADD_FEATURE_INFO _name _depends _desc)
   cmake_policy(GET CMP0183 _CDO_CMP0183
     PARENT_SCOPE # undocumented, do not use outside of CMake
@@ -749,34 +972,8 @@
   unset(_CDO_CMP0183)
 endfunction()
 
-
 # The stuff below is only kept for compatibility
 
-#[=======================================================================[.rst:
-Deprecated Functions
-^^^^^^^^^^^^^^^^^^^^
-
-The following legacy and deprecated functions are provided for backward
-compatibility with previous CMake versions:
-
-.. command:: set_package_info
-
-  .. deprecated:: 3.8
-
-  .. code-block:: cmake
-
-    set_package_info(<name> <description> [ <url> [<purpose>] ])
-
-  Set up information about the package ``<name>``, which can then be displayed
-  via :command:`feature_summary()`.  This can be done either directly in the
-  :ref:`Find module <Find Modules>` or in the project which uses the
-  ``FeatureSummary`` module after the :command:`find_package()` call.  The
-  features for which information can be set are added automatically by the
-  ``find_package()`` command.
-
-  This function is deprecated.  Use the :command:`set_package_properties()`, and
-  :command:`add_feature_info()` functions instead.
-#]=======================================================================]
 function(SET_PACKAGE_INFO _name _desc)
   message(DEPRECATION "SET_PACKAGE_INFO is deprecated. Use SET_PACKAGE_PROPERTIES instead.")
   unset(_url)
@@ -796,62 +993,17 @@
   endif()
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: set_feature_info
-
-  .. deprecated:: 3.8
-
-  .. code-block:: cmake
-
-    set_feature_info(<name> <description> [<url>])
-
-  Does the same as:
-
-  .. code-block:: cmake
-
-    set_package_info(<name> <description> [<url>])
-#]=======================================================================]
 function(SET_FEATURE_INFO)
   message(DEPRECATION "SET_FEATURE_INFO is deprecated. Use ADD_FEATURE_INFO instead.")
   set_package_info(${ARGN})
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: print_enabled_features
-
-  .. deprecated:: 3.8
-
-  .. code-block:: cmake
-
-    print_enabled_features()
-
-  Does the same as:
-
-  .. code-block:: cmake
-
-    feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:")
-#]=======================================================================]
 function(PRINT_ENABLED_FEATURES)
   message(DEPRECATION "PRINT_ENABLED_FEATURES is deprecated. Use
     feature_summary(WHAT ENABLED_FEATURES DESCRIPTION \"Enabled features:\")")
   feature_summary(WHAT ENABLED_FEATURES  DESCRIPTION "Enabled features:")
 endfunction()
 
-#[=======================================================================[.rst:
-.. command:: print_disabled_features
-
-  .. deprecated:: 3.8
-
-  .. code-block:: cmake
-
-    print_disabled_features()
-
-  Does the same as:
-
-  .. code-block:: cmake
-
-    feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:")
-#]=======================================================================]
 function(PRINT_DISABLED_FEATURES)
   message(DEPRECATION "PRINT_DISABLED_FEATURES is deprecated. Use
     feature_summary(WHAT DISABLED_FEATURES DESCRIPTION \"Disabled features:\")")
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 2088549..4c1068e 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -11,6 +11,15 @@
 
   .. contents::
 
+This module provides commands to populate content at configure time or as
+part of the calling script.
+
+Load this module in CMake with:
+
+.. code-block:: cmake
+
+  include(FetchContent)
+
 .. note:: The :guide:`Using Dependencies Guide` provides a high-level
   introduction to this general topic. It provides a broader overview of
   where the ``FetchContent`` module fits into the bigger picture,
@@ -111,9 +120,10 @@
   The ``<contentOptions>`` can be any of the download, update, or patch options
   that the :command:`ExternalProject_Add` command understands.  The configure,
   build, install, and test steps are explicitly disabled, so options related
-  to those steps will be ignored.  The ``SOURCE_SUBDIR`` option is an
-  exception, see :command:`FetchContent_MakeAvailable` for details on how that
-  affects behavior.
+  to those steps are prohibited and will be discarded if given.
+  The ``SOURCE_SUBDIR`` option is an exception, see
+  :command:`FetchContent_MakeAvailable` for details on how that affects
+  behavior.
 
   .. versionchanged:: 3.30
     When policy :policy:`CMP0168` is set to ``NEW``, some output-related and
@@ -1128,7 +1138,7 @@
 # FetchContent_MakeAvailable() implementation details are excluded for
 # backward compatibility reasons (see just after the endblock()).
 block(SCOPE_FOR POLICIES)
-cmake_policy(VERSION 3.29)
+cmake_policy(VERSION 4.1)
 
 include(${CMAKE_CURRENT_LIST_DIR}/ExternalProject/shared_internal_commands.cmake)
 
@@ -1876,9 +1886,9 @@
 # Pass through things we've already detected in the main project to avoid
 # paying the cost of redetecting them again in ExternalProject_Add()
 set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==])
-set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==])
+set(Git_VERSION [==[${Git_VERSION}]==])
 set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
-  [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==]
+  [==[${GIT_EXECUTABLE};${Git_VERSION}]==]
 )
 ")
   endif()
diff --git a/Modules/FindALSA.cmake b/Modules/FindALSA.cmake
index 1198abe..7a5edce 100644
--- a/Modules/FindALSA.cmake
+++ b/Modules/FindALSA.cmake
@@ -5,7 +5,11 @@
 FindALSA
 --------
 
-Finds the Advanced Linux Sound Architecture (ALSA) library (``asound``).
+Finds the Advanced Linux Sound Architecture (ALSA) library (``asound``):
+
+.. code-block:: cmake
+
+  find_package(ALSA [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -24,7 +28,13 @@
 This module defines the following variables:
 
 ``ALSA_FOUND``
-  Boolean indicating whether the ALSA library is found.
+  Boolean indicating whether the (requested version of) ALSA library was
+  found.
+
+``ALSA_VERSION``
+  .. versionadded:: 4.2
+
+  The version of ALSA found.
 
 ``ALSA_LIBRARIES``
   List of libraries needed for linking to use ALSA library.
@@ -43,6 +53,17 @@
 ``ALSA_LIBRARY``
   The absolute path of the asound library.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``ALSA_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``ALSA_VERSION``.
+
+  The version of ALSA found.
+
 Examples
 ^^^^^^^^
 
@@ -68,14 +89,15 @@
 if(ALSA_INCLUDE_DIR AND EXISTS "${ALSA_INCLUDE_DIR}/alsa/version.h")
   file(STRINGS "${ALSA_INCLUDE_DIR}/alsa/version.h" alsa_version_str REGEX "^#define[\t ]+SND_LIB_VERSION_STR[\t ]+\".*\"")
 
-  string(REGEX REPLACE "^.*SND_LIB_VERSION_STR[\t ]+\"([^\"]*)\".*$" "\\1" ALSA_VERSION_STRING "${alsa_version_str}")
+  string(REGEX REPLACE "^.*SND_LIB_VERSION_STR[\t ]+\"([^\"]*)\".*$" "\\1" ALSA_VERSION "${alsa_version_str}")
+  set(ALSA_VERSION_STRING "${ALSA_VERSION}")
   unset(alsa_version_str)
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(ALSA
                                   REQUIRED_VARS ALSA_LIBRARY ALSA_INCLUDE_DIR
-                                  VERSION_VAR ALSA_VERSION_STRING)
+                                  VERSION_VAR ALSA_VERSION)
 
 if(ALSA_FOUND)
   set( ALSA_LIBRARIES ${ALSA_LIBRARY} )
diff --git a/Modules/FindASPELL.cmake b/Modules/FindASPELL.cmake
index 2c5cb93..5d612cd 100644
--- a/Modules/FindASPELL.cmake
+++ b/Modules/FindASPELL.cmake
@@ -5,12 +5,23 @@
 FindASPELL
 ----------
 
-Finds the GNU Aspell spell checker library.
+Finds the GNU Aspell spell checker library:
+
+.. code-block:: cmake
+
+  find_package(ASPELL [<version>] [COMPONENTS <components>] [...])
 
 Components
 ^^^^^^^^^^
 
-This module supports the following components:
+This module supports optional components which can be specified using the
+:command:`find_package` command:
+
+.. code-block:: cmake
+
+  find_package(ASPELL [COMPONENTS <components>...])
+
+Supported components include:
 
 ``ASPELL``
   .. versionadded:: 4.1
@@ -22,13 +33,7 @@
 
   Finds the Aspell command-line interactive spell checker executable.
 
-Components can be specified using the standard CMake syntax:
-
-.. code-block:: cmake
-
-  find_package(ASPELL [COMPONENTS <components>...])
-
-If no ``COMPONENTS`` are specified, the module searches for both the ``ASPELL``
+If no components are specified, the module searches for both the ``ASPELL``
 and ``Executable`` components by default.
 
 Imported Targets
@@ -55,7 +60,8 @@
 This module defines the following variables:
 
 ``ASPELL_FOUND``
-  Boolean indicating whether the requested Aspell components have been found.
+  Boolean indicating whether (the requested version of) Aspell and all
+  requested components were found.
 
 ``ASPELL_VERSION``
   .. versionadded:: 4.1
diff --git a/Modules/FindAVIFile.cmake b/Modules/FindAVIFile.cmake
index d3387ea..b6cfe7e 100644
--- a/Modules/FindAVIFile.cmake
+++ b/Modules/FindAVIFile.cmake
@@ -5,7 +5,11 @@
 FindAVIFile
 -----------
 
-Finds `AVIFile <https://avifile.sourceforge.net/>`_ library and include paths.
+Finds `AVIFile <https://avifile.sourceforge.net/>`_ library and include paths:
+
+.. code-block:: cmake
+
+  find_package(AVIFile [...])
 
 AVIFile is a set of libraries for i386 machines to use various AVI codecs.
 Support is limited beyond Linux.  Windows provides native AVI support, and so
@@ -17,29 +21,58 @@
 This module defines the following variables:
 
 ``AVIFile_FOUND``
-  True if AVIFile is found.  For backward compatibility, the ``AVIFILE_FOUND``
-  variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether AVIFile was found.
+
 ``AVIFILE_LIBRARIES``
   The libraries to link against.
+
 ``AVIFILE_DEFINITIONS``
   Definitions to use when compiling.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be also set:
+The following cache variables may also be set:
 
 ``AVIFILE_INCLUDE_DIR``
   Directory containing ``avifile.h`` and other AVIFile headers.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``AVIFILE_FOUND``
+  .. deprecated:: 4.2
+    Use ``AVIFile_FOUND``, which has the same value.
+
+  Boolean indicating whether AVIFile was found.
+
 Examples
 ^^^^^^^^
 
-Finding AVIFile:
+Finding AVIFile and conditionally creating an interface :ref:`Imported Target
+<Imported Targets>` that encapsulates its usage requirements for linking to a
+project target:
 
 .. code-block:: cmake
 
   find_package(AVIFile)
+
+  if(AVIFile_FOUND AND NOT TARGET AVIFile::AVIFile)
+    add_library(AVIFile::AVIFile INTERFACE IMPORTED)
+    set_target_properties(
+      AVIFile::AVIFile
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${AVIFILE_INCLUDE_DIR}"
+        INTERFACE_LINK_LIBRARIES "${AVIFILE_LIBRARIES}"
+        INTERFACE_COMPILE_DEFINITIONS "${AVIFILE_DEFINITIONS}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE AVIFile::AVIFile)
 #]=======================================================================]
 
 if (UNIX)
@@ -50,7 +83,10 @@
 endif ()
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(AVIFile DEFAULT_MSG AVIFILE_INCLUDE_DIR AVIFILE_AVIPLAY_LIBRARY)
+find_package_handle_standard_args(
+  AVIFile
+  REQUIRED_VARS AVIFILE_AVIPLAY_LIBRARY AVIFILE_INCLUDE_DIR
+)
 
 if (AVIFile_FOUND)
     set(AVIFILE_LIBRARIES ${AVIFILE_AVIPLAY_LIBRARY})
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
index f185f10..901ea22 100644
--- a/Modules/FindArmadillo.cmake
+++ b/Modules/FindArmadillo.cmake
@@ -5,8 +5,13 @@
 FindArmadillo
 -------------
 
-Finds the Armadillo C++ library.  Armadillo is a library for linear algebra and
-scientific computing.
+Finds the Armadillo C++ library:
+
+.. code-block:: cmake
+
+  find_package(Armadillo [<version>] [...])
+
+Armadillo is a library for linear algebra and scientific computing.
 
 .. versionadded:: 3.18
   Support for linking wrapped libraries directly (see the
@@ -16,30 +21,76 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``Armadillo_FOUND``
-  Set to true if the library is found.  For backward compatibility, the
-  ``ARMADILLO_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) Armadillo library
+  was found.
+
+``Armadillo_VERSION``
+  .. versionadded:: 4.2
+
+  The version of Armadillo found (e.g., ``14.90.0``).
+
+``Armadillo_VERSION_NAME``
+  .. versionadded:: 4.2
+
+  The version name of Armadillo found (e.g., ``Antipodean Antileech``).
+
 ``ARMADILLO_INCLUDE_DIRS``
   List of required include directories.
+
 ``ARMADILLO_LIBRARIES``
   List of libraries to be linked.
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``ARMADILLO_FOUND``
+  .. deprecated:: 4.2
+    Use ``Armadillo_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Armadillo library
+  was found.
+
 ``ARMADILLO_VERSION_STRING``
-  Version as a string (ex: ``1.0.4``).
+  .. deprecated:: 4.2
+    Superseded by the ``Armadillo_VERSION``.
+
+  The version of Armadillo found.
+
 ``ARMADILLO_VERSION_MAJOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Armadillo_VERSION``.
+
   Major version number.
+
 ``ARMADILLO_VERSION_MINOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Armadillo_VERSION``.
+
   Minor version number.
+
 ``ARMADILLO_VERSION_PATCH``
+  .. deprecated:: 4.2
+    Superseded by the ``Armadillo_VERSION``.
+
   Patch version number.
+
 ``ARMADILLO_VERSION_NAME``
-  Name of the version (ex: ``Antipodean Antileech``).
+  .. deprecated:: 4.2
+    Superseded by the ``Armadillo_VERSION_NAME``.
+
+  The version name of Armadillo found (e.g., ``Antipodean Antileech``).
 
 Examples
 ^^^^^^^^
 
-Using Armadillo:
+Finding Armadillo and creating an imported target:
 
 .. code-block:: cmake
 
@@ -79,10 +130,9 @@
   set(ARMADILLO_VERSION_MAJOR 0)
   set(ARMADILLO_VERSION_MINOR 0)
   set(ARMADILLO_VERSION_PATCH 0)
-  set(ARMADILLO_VERSION_NAME "EARLY RELEASE")
+  set(Armadillo_VERSION_NAME "EARLY RELEASE")
 
   if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
-
     # Read and parse armdillo version header file for version number
     file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _ARMA_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
     string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_ARMA_HEADER_CONTENTS}")
@@ -90,11 +140,13 @@
     string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_ARMA_HEADER_CONTENTS}")
 
     # WARNING: The number of spaces before the version name is not one.
-    string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_ARMA_HEADER_CONTENTS}")
+    string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" Armadillo_VERSION_NAME "${_ARMA_HEADER_CONTENTS}")
 
+    set(ARMADILLO_VERSION_NAME "${Armadillo_VERSION_NAME}")
   endif()
 
-  set(ARMADILLO_VERSION_STRING "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
+  set(Armadillo_VERSION "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
+  set(ARMADILLO_VERSION_STRING "${Armadillo_VERSION}")
 endif ()
 
 if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp")
@@ -150,7 +202,7 @@
 
 find_package_handle_standard_args(Armadillo
   REQUIRED_VARS ARMADILLO_INCLUDE_DIR ${_ARMA_REQUIRED_VARS}
-  VERSION_VAR ARMADILLO_VERSION_STRING)
+  VERSION_VAR Armadillo_VERSION)
 
 if (Armadillo_FOUND)
   set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR})
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index ef76f6a..38ea407 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -10,7 +10,7 @@
 
 .. code-block:: cmake
 
-  find_package(BISON [<version>] ...)
+  find_package(BISON [<version>] [...])
 
 Bison is a parser generator that replaced earlier Yacc (Yet Another
 Compiler-Compiler).  On Unix-like systems, most common implementation is
@@ -23,7 +23,7 @@
 This module defines the following variables:
 
 ``BISON_FOUND``
-  Boolean indicating whether (the requested version of) Bison is found.
+  Boolean indicating whether (the requested version of) Bison was found.
 
 ``BISON_VERSION``
   The version of Bison found.
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 2b8a75a..9f986a7 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -5,34 +5,67 @@
 FindBLAS
 --------
 
-Find Basic Linear Algebra Subprograms (BLAS) library
+Finds the installed Basic Linear Algebra Subprograms (BLAS) Fortran library,
+which implements the `BLAS linear-algebra interface`_:
 
-This module finds an installed Fortran library that implements the
-`BLAS linear-algebra interface`_.
+.. code-block:: cmake
+
+  find_package(BLAS [...])
 
 At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled.
 
 .. _`BLAS linear-algebra interface`: https://netlib.org/blas/
 
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following :ref:`Imported Targets`:
+
+``BLAS::BLAS``
+  .. versionadded:: 3.18
+
+  Target encapsulating the libraries and usage requirements to use BLAS,
+  available only if BLAS is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``BLAS_FOUND``
+  Boolean indicating whether the library implementing the BLAS interface
+  was found.
+``BLAS_LINKER_FLAGS``
+  Uncached list of required linker flags (excluding ``-l`` and ``-L``).
+``BLAS_LIBRARIES``
+  Uncached list of libraries (using full path name) to link against
+  to use BLAS (may be empty if compiler implicitly links BLAS).
+``BLAS95_LIBRARIES``
+  Uncached list of libraries (using full path name) to link against
+  to use BLAS95 interface.
+``BLAS95_FOUND``
+  Boolean indicating whether the library implementing the BLAS95 interface
+  was found.
+
 Input Variables
 ^^^^^^^^^^^^^^^
 
 The following variables may be set to influence this module's behavior:
 
 ``BLA_STATIC``
-  if ``ON`` use static linkage
+  If ``ON``, the static linkage will be used.
 
 ``BLA_VENDOR``
   Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only
   from the specified vendor.  If not set, all vendors are considered.
 
 ``BLA_F95``
-  if ``ON`` tries to find the BLAS95 interfaces
+  If ``ON``, the module tries to find the BLAS95 interfaces.
 
 ``BLA_PREFER_PKGCONFIG``
   .. versionadded:: 3.11
 
-  if set ``pkg-config`` will be used to search for a BLAS library first
+  If set, ``pkg-config`` will be used to search for a BLAS library first
   and if one is found that is preferred
 
 ``BLA_PKGCONFIG_BLAS``
@@ -69,41 +102,13 @@
 
   This is currently only supported by NVIDIA NVPL.
 
-Imported Targets
-^^^^^^^^^^^^^^^^
-
-This module defines the following :prop_tgt:`IMPORTED` targets:
-
-``BLAS::BLAS``
-  .. versionadded:: 3.18
-
-  The libraries to use for BLAS, if found.
-
-Result Variables
-^^^^^^^^^^^^^^^^
-
-This module defines the following variables:
-
-``BLAS_FOUND``
-  library implementing the BLAS interface is found
-``BLAS_LINKER_FLAGS``
-  uncached list of required linker flags (excluding ``-l`` and ``-L``).
-``BLAS_LIBRARIES``
-  uncached list of libraries (using full path name) to link against
-  to use BLAS (may be empty if compiler implicitly links BLAS)
-``BLAS95_LIBRARIES``
-  uncached list of libraries (using full path name) to link against
-  to use BLAS95 interface
-``BLAS95_FOUND``
-  library implementing the BLAS95 interface is found
-
 .. _`BLAS/LAPACK Vendors`:
 
 BLAS/LAPACK Vendors
 ^^^^^^^^^^^^^^^^^^^
 
 ``Generic``
-  Generic reference implementation
+  Generic reference implementation.
 
 ``ACML``, ``ACML_MP``, ``ACML_GPU``
   AMD Core Math Library
@@ -111,31 +116,31 @@
 ``AOCL``, ``AOCL_mt``
   .. versionadded:: 3.27
 
-  AMD Optimizing CPU Libraries
+  AMD Optimizing CPU Libraries.
 
 ``Apple``, ``NAS``
-  Apple BLAS (Accelerate), and Apple NAS (vecLib)
+  Apple BLAS (Accelerate), and Apple NAS (vecLib).
 
 ``Arm``, ``Arm_mp``, ``Arm_ilp64``, ``Arm_ilp64_mp``
   .. versionadded:: 3.18
 
-  Arm Performance Libraries
+  Arm Performance Libraries.
 
 ``ATLAS``
-  Automatically Tuned Linear Algebra Software
+  Automatically Tuned Linear Algebra Software.
 
 ``CXML``, ``DXML``
-  Compaq/Digital Extended Math Library
+  Compaq/Digital Extended Math Library.
 
 ``EML``, ``EML_mt``
   .. versionadded:: 3.20
 
-  Elbrus Math Library
+  Elbrus Math Library.
 
 ``FLAME``
   .. versionadded:: 3.11
 
-  BLIS Framework
+  BLIS Framework.
 
 ``FlexiBLAS``
   .. versionadded:: 3.19
@@ -143,71 +148,71 @@
 ``Fujitsu_SSL2``, ``Fujitsu_SSL2BLAMP``, ``Fujitsu_SSL2SVE``, ``Fujitsu_SSL2BLAMPSVE``
   .. versionadded:: 3.20
 
-  Fujitsu SSL2 serial and parallel blas/lapack with SVE instructions
+  Fujitsu SSL2 serial and parallel blas/lapack with SVE instructions.
 
 ``Goto``
-  GotoBLAS
+  GotoBLAS.
 
 ``IBMESSL``, ``IBMESSL_SMP``
 
-  IBM Engineering and Scientific Subroutine Library
+  IBM Engineering and Scientific Subroutine Library.
 
 ``Intel``
-  Intel MKL 32 bit and 64 bit obsolete versions
+  Intel MKL 32 bit and 64 bit obsolete versions.
 
 ``Intel10_32``
-  Intel MKL v10 32 bit, threaded code
+  Intel MKL v10 32 bit, threaded code.
 
 ``Intel10_64lp``
-  Intel MKL v10+ 64 bit, threaded code, lp64 model
+  Intel MKL v10+ 64 bit, threaded code, lp64 model.
 
 ``Intel10_64lp_seq``
-  Intel MKL v10+ 64 bit, sequential code, lp64 model
+  Intel MKL v10+ 64 bit, sequential code, lp64 model.
 
 ``Intel10_64ilp``
   .. versionadded:: 3.13
 
-  Intel MKL v10+ 64 bit, threaded code, ilp64 model
+  Intel MKL v10+ 64 bit, threaded code, ilp64 model.
 
 ``Intel10_64ilp_seq``
   .. versionadded:: 3.13
 
-  Intel MKL v10+ 64 bit, sequential code, ilp64 model
+  Intel MKL v10+ 64 bit, sequential code, ilp64 model.
 
 ``Intel10_64_dyn``
   .. versionadded:: 3.17
 
-  Intel MKL v10+ 64 bit, single dynamic library
+  Intel MKL v10+ 64 bit, single dynamic library.
 
 ``libblastrampoline``
   .. versionadded:: 3.30
 
-  A BLAS/LAPACK demuxing library using PLT trampolines
+  A BLAS/LAPACK demuxing library using PLT trampolines.
 
 ``NVPL``
   .. versionadded:: 4.1
 
-  NVIDIA Performance Libraries
+  NVIDIA Performance Libraries.
 
 ``NVHPC``
   .. versionadded:: 3.21
 
-  NVIDIA HPC SDK
+  NVIDIA HPC SDK.
 
 ``OpenBLAS``
   .. versionadded:: 3.6
 
 ``PhiPACK``
-  Portable High Performance ANSI C (PHiPAC)
+  Portable High Performance ANSI C (PHiPAC).
 
 ``SCSL``, ``SCSL_mp``
-  Scientific Computing Software Library
+  Scientific Computing Software Library.
 
 ``SGIMATH``
-  SGI Scientific Mathematical Library
+  SGI Scientific Mathematical Library.
 
 ``SunPerf``
-  Sun Performance Library
+  Sun Performance Library.
 
 .. _`Intel MKL`:
 
@@ -270,6 +275,15 @@
 
     . /opt/intel/oneapi/compiler/latest/env/vars.sh
 
+Examples
+^^^^^^^^
+
+Finding BLAS and linking it to a project target:
+
+.. code-block:: cmake
+
+  find_package(BLAS)
+  target_link_libraries(example PRIVATE BLAS::BLAS)
 #]=======================================================================]
 
 # The approach follows that of the ``autoconf`` macro file, ``acx_blas.m4``
@@ -313,7 +327,7 @@
     set(BLA_PKGCONFIG_BLAS "blas")
   endif()
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(PKGC_BLAS QUIET ${BLA_PKGCONFIG_BLAS})
     if(PKGC_BLAS_FOUND)
       set(BLAS_FOUND ${PKGC_BLAS_FOUND})
@@ -1108,9 +1122,9 @@
   else()
     file(GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples")
   endif()
-  list(GET _ACML_ROOT 0 _ACML_ROOT)
-  list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
   if(_ACML_ROOT)
+    list(GET _ACML_ROOT 0 _ACML_ROOT)
+    list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
     get_filename_component(_ACML_ROOT ${_ACML_ROOT} PATH)
     if(_blas_sizeof_integer EQUAL 8)
       set(_ACML_PATH_SUFFIX "_int64")
diff --git a/Modules/FindBZip2.cmake b/Modules/FindBZip2.cmake
index 0b9f3fe..344aa1b 100644
--- a/Modules/FindBZip2.cmake
+++ b/Modules/FindBZip2.cmake
@@ -28,8 +28,15 @@
 This module defines the following variables:
 
 ``BZip2_FOUND``
-  Boolean indicating whether the BZip2 library is found.  For backward
-  compatibility, the ``BZIP2_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) BZip2 library was
+  found.
+
+``BZip2_VERSION``
+  .. versionadded:: 4.2
+
+  The version of BZip2 found.
 
 ``BZIP2_INCLUDE_DIRS``
   .. versionadded:: 3.12
@@ -39,11 +46,6 @@
 ``BZIP2_LIBRARIES``
   Libraries needed for linking to use BZip2.
 
-``BZIP2_VERSION``
-  .. versionadded:: 3.26
-
-  The version of BZip2 found.
-
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -63,14 +65,29 @@
   (e.g., ``BZ2_bzCompressInit()``).  Versions of BZip2 prior to 1.0.0 used
   unprefixed function names (e.g., ``bzCompressInit()``).
 
-Legacy Variables
-^^^^^^^^^^^^^^^^
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
 
 The following variables are provided for backward compatibility:
 
+``BZIP2_FOUND``
+  .. deprecated:: 4.2
+    Use ``BZip2_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) BZip2 library was
+  found.
+
 ``BZIP2_VERSION_STRING``
-  .. versionchanged:: 3.26
-    Superseded by ``BZIP2_VERSION``.
+  .. deprecated:: 3.26
+    Superseded by the ``BZIP2_VERSION`` (and ``BZip2_VERSION``).
+
+  The version of BZip2 found.
+
+``BZIP2_VERSION``
+  .. versionadded:: 3.26
+
+  .. deprecated:: 4.2
+    Superseded by the ``BZip2_VERSION``.
 
   The version of BZip2 found.
 
@@ -108,12 +125,13 @@
     file(STRINGS "${BZIP2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ")
     string(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}")
     set(BZIP2_VERSION ${BZIP2_VERSION_STRING})
+    set(BZip2_VERSION ${BZIP2_VERSION_STRING})
 endif ()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(BZip2
                                   REQUIRED_VARS BZIP2_LIBRARIES BZIP2_INCLUDE_DIR
-                                  VERSION_VAR BZIP2_VERSION)
+                                  VERSION_VAR BZip2_VERSION)
 
 if (BZip2_FOUND)
   set(BZIP2_INCLUDE_DIRS ${BZIP2_INCLUDE_DIR})
@@ -126,7 +144,7 @@
 
   # Versions before 1.0.2 required <stdio.h> for the FILE definition.
   set(BZip2_headers "bzlib.h")
-  if(BZIP2_VERSION VERSION_LESS "1.0.2")
+  if(BZip2_VERSION VERSION_LESS "1.0.2")
     list(PREPEND BZip2_headers "stdio.h")
   endif()
   check_symbol_exists(BZ2_bzCompressInit "${BZip2_headers}" BZIP2_NEED_PREFIX)
diff --git a/Modules/FindBacktrace.cmake b/Modules/FindBacktrace.cmake
index 0674c5f..052e6b5 100644
--- a/Modules/FindBacktrace.cmake
+++ b/Modules/FindBacktrace.cmake
@@ -6,7 +6,11 @@
 -------------
 
 Finds `backtrace(3) <https://man7.org/linux/man-pages/man3/backtrace.3.html>`_,
-a library that provides functions for application self-debugging.
+a library that provides functions for application self-debugging:
+
+.. code-block:: cmake
+
+  find_package(Backtrace [...])
 
 This module checks whether ``backtrace(3)`` is supported, either through the
 standard C library (``libc``), or a separate library.
@@ -14,11 +18,11 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.30
-
 This module provides the following :ref:`Imported Targets`:
 
 ``Backtrace::Backtrace``
+  .. versionadded:: 3.30
+
   An interface library encapsulating the usage requirements of Backtrace.  This
   target is available only when Backtrace is found.
 
@@ -27,13 +31,15 @@
 
 This module defines the following variables:
 
-``Backtrace_INCLUDE_DIRS``
-  The include directories needed to use ``backtrace(3)`` header.
-``Backtrace_LIBRARIES``
-  The libraries (linker flags) needed to use ``backtrace(3)``, if any.
 ``Backtrace_FOUND``
   Boolean indicating whether the ``backtrace(3)`` support is available.
 
+``Backtrace_INCLUDE_DIRS``
+  The include directories needed to use ``backtrace(3)`` header.
+
+``Backtrace_LIBRARIES``
+  The libraries (linker flags) needed to use ``backtrace(3)``, if any.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -43,18 +49,20 @@
   The header file needed for ``backtrace(3)``.  This variable allows dynamic
   usage of the header in the project code.  It can also be overridden by the
   user.
-``Backtrace_LIBRARY``
-  The external library providing backtrace, if any.
+
 ``Backtrace_INCLUDE_DIR``
   The directory holding the ``backtrace(3)`` header.
 
+``Backtrace_LIBRARY``
+  The external library providing backtrace, if any.
+
 Examples
 ^^^^^^^^
 
 Finding Backtrace and linking it to a project target as of CMake 3.30:
 
 .. code-block:: cmake
-  :caption: CMakeLists.txt
+  :caption: ``CMakeLists.txt``
 
   find_package(Backtrace)
   target_link_libraries(app PRIVATE Backtrace::Backtrace)
@@ -63,7 +71,7 @@
 header file created by :command:`configure_file`:
 
 .. code-block:: cmake
-  :caption: CMakeLists.txt
+  :caption: ``CMakeLists.txt``
 
   add_library(app app.c)
 
@@ -73,7 +81,7 @@
   configure_file(config.h.in config.h)
 
 .. code-block:: c
-  :caption: config.h.in
+  :caption: ``config.h.in``
 
   #cmakedefine01 Backtrace_FOUND
   #if Backtrace_FOUND
@@ -81,7 +89,7 @@
   #endif
 
 .. code-block:: c
-  :caption: app.c
+  :caption: ``app.c``
 
   #include "config.h"
 
@@ -89,7 +97,7 @@
 be defined manually:
 
 .. code-block:: cmake
-  :caption: CMakeLists.txt
+  :caption: ``CMakeLists.txt``
 
   find_package(Backtrace)
   if(Backtrace_FOUND AND NOT TARGET Backtrace::Backtrace)
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 8ae4223..78df671 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -47,7 +47,7 @@
 This module defines the following variables:
 
 ``Boost_FOUND``
-  True if headers and requested libraries were found.
+  Boolean indicating whether headers and requested libraries were found.
 
 ``Boost_INCLUDE_DIRS``
   Boost include directories.
@@ -59,7 +59,8 @@
   Boost component libraries to be linked.
 
 ``Boost_<COMPONENT>_FOUND``
-  True if component ``<COMPONENT>`` was found (``<COMPONENT>`` name is upper-case).
+  Boolean indicating whether the component ``<COMPONENT>`` was found
+  (``<COMPONENT>`` name is upper-case).
 
 ``Boost_<COMPONENT>_LIBRARY``
   Libraries to link for component ``<COMPONENT>`` (may include
@@ -102,7 +103,7 @@
 .. versionadded:: 3.15
   The ``Boost_VERSION_<PART>`` variables.
 
-Cache variables
+Cache Variables
 ^^^^^^^^^^^^^^^
 
 Search results are saved persistently in CMake cache entries:
@@ -172,7 +173,7 @@
 
 .. versionadded:: 3.5
 
-This module defines the following :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
 
 ``Boost::boost``
   Target for header-only dependencies. (Boost include directory).
diff --git a/Modules/FindBullet.cmake b/Modules/FindBullet.cmake
index 61a5fb3..d2ef0d4 100644
--- a/Modules/FindBullet.cmake
+++ b/Modules/FindBullet.cmake
@@ -5,7 +5,11 @@
 FindBullet
 ----------
 
-Finds the Bullet physics engine.
+Finds the Bullet physics engine:
+
+.. code-block:: cmake
+
+  find_package(Bullet [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -13,10 +17,13 @@
 This module defines the following variables:
 
 ``Bullet_FOUND``
-  Boolean true if Bullet was found.  For backward compatibility, the
-  ``BULLET_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Bullet was found.
+
 ``BULLET_INCLUDE_DIRS``
   The Bullet include directories.
+
 ``BULLET_LIBRARIES``
   Libraries needed to link to Bullet.  By default, all Bullet components
   (Dynamics, Collision, LinearMath, and SoftBody) are added.
@@ -30,14 +37,39 @@
   Can be set to Bullet install path or Windows build path to specify where to
   find Bullet.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``BULLET_FOUND``
+  .. deprecated:: 4.2
+    Use ``Bullet_FOUND``, which has the same value.
+
+  Boolean indicating whether Bullet was found.
+
 Examples
 ^^^^^^^^
 
-Finding Bullet:
+Finding Bullet and conditionally creating an interface :ref:`imported target
+<Imported Targets>` that encapsulates its usage requirements for linking to a
+project target:
 
 .. code-block:: cmake
 
   find_package(Bullet)
+
+  if(Bullet_FOUND AND NOT TARGET Bullet::Bullet)
+    add_library(Bullet::Bullet INTERFACE IMPORTED)
+    set_target_properties(
+      Bullet::Bullet
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${BULLET_INCLUDE_DIRS}"
+        INTERFACE_LINK_LIBRARIES "${BULLET_LIBRARIES}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE Bullet::Bullet)
 #]=======================================================================]
 
 macro(_FIND_BULLET_LIBRARY _var)
diff --git a/Modules/FindCABLE.cmake b/Modules/FindCABLE.cmake
index af0e6b6..aa68ff4 100644
--- a/Modules/FindCABLE.cmake
+++ b/Modules/FindCABLE.cmake
@@ -8,7 +8,11 @@
 .. versionchanged:: 4.1
   This module is available only if policy :policy:`CMP0191` is not set to ``NEW``.
 
-Finds the CABLE installation and determines its include paths and libraries.
+Finds the CABLE installation and determines its include paths and libraries:
+
+.. code-block:: cmake
+
+  find_package(CABLE [...])
 
 Package called CABLE (CABLE Automates Bindings for Language Extension) was
 initially developed by Kitware to generate bindings to C++ classes for use in
@@ -25,7 +29,7 @@
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be set when using this module:
+The following cache variables may also be set:
 
 ``CABLE``
   Path to the ``cable`` executable.
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index bceb615..96b1659 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -584,10 +584,8 @@
 # This macro helps us find the location of helper files we will need the full path to
 macro(CUDA_FIND_HELPER_FILE _name _extension)
   set(_full_name "${_name}.${_extension}")
-  # CMAKE_CURRENT_LIST_FILE contains the full path to the file currently being
-  # processed.  Using this variable, we can pull out the current path, and
+  # Using CMAKE_CURRENT_LIST_DIR, we can pull out the current path, and
   # provide a way to get access to the other files we need local to here.
-  get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
   set(CUDA_${_name} "${CMAKE_CURRENT_LIST_DIR}/FindCUDA/${_full_name}")
   if(NOT EXISTS "${CUDA_${_name}}")
     set(error_message "${_full_name} not found in ${CMAKE_CURRENT_LIST_DIR}/FindCUDA")
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index b00cd26..1a7e806 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -7,9 +7,14 @@
 
 .. versionadded:: 3.17
 
-This script locates the NVIDIA CUDA toolkit and the associated libraries, but
-does not require the ``CUDA`` language be enabled for a given project. This
-module does not search for the NVIDIA CUDA Samples.
+Finds the NVIDIA CUDA toolkit and the associated libraries, but does not
+require the ``CUDA`` language be enabled for a given project:
+
+.. code-block:: cmake
+
+  find_package(CUDAToolkit [<version>] [QUIET] [REQUIRED] [EXACT] [...])
+
+This module does not search for the NVIDIA CUDA Samples.
 
 .. versionadded:: 3.19
   QNX support.
@@ -107,7 +112,7 @@
 
 An :ref:`imported target <Imported targets>` named ``CUDA::toolkit`` is provided.
 
-This module defines :prop_tgt:`IMPORTED` targets for each
+This module provides :ref:`Imported Targets` for each
 of the following libraries that are part of the CUDAToolkit:
 
 - `CUDA Runtime Library`_
@@ -519,9 +524,11 @@
 
 **Note**: direct usage of this target by consumers should not be necessary.
 
-Result variables
+Result Variables
 ^^^^^^^^^^^^^^^^
 
+This module defines the following variables:
+
 ``CUDAToolkit_FOUND``
     A boolean specifying whether or not the CUDA Toolkit was found.
 
@@ -568,8 +575,6 @@
     found to determine the CUDA Toolkit version as well as determining other
     features of the Toolkit.  This variable is set for the convenience of
     modules that depend on this one.
-
-
 #]=======================================================================]
 
 # NOTE: much of this was simply extracted from FindCUDA.cmake.
@@ -660,29 +665,65 @@
             PATHS ${possible_nvcc_path}
           )
         endif()
-      endif()
+      else()
+        if(NOT CUDAToolkit_SENTINEL_FILE)
+          find_program(CUDAToolkit_NVCC_EXECUTABLE
+            NAMES nvcc nvcc.exe
+            PATHS ${arg_SEARCH_PATHS}
+            ${arg_FIND_FLAGS}
+          )
+        endif()
 
-      if(NOT CUDAToolkit_SENTINEL_FILE)
-        find_program(CUDAToolkit_NVCC_EXECUTABLE
-          NAMES nvcc nvcc.exe
-          PATHS ${arg_SEARCH_PATHS}
-          ${arg_FIND_FLAGS}
-        )
-      endif()
-
-      if(NOT CUDAToolkit_NVCC_EXECUTABLE)
-        find_file(CUDAToolkit_SENTINEL_FILE
-          NAMES version.txt version.json
-          PATHS ${arg_SEARCH_PATHS}
-          NO_DEFAULT_PATH
-        )
+        if(NOT CUDAToolkit_NVCC_EXECUTABLE)
+          find_file(CUDAToolkit_SENTINEL_FILE
+            NAMES version.txt version.json
+            PATHS ${arg_SEARCH_PATHS}
+            NO_DEFAULT_PATH
+          )
+        endif()
       endif()
 
       if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}")
         # If NVCC exists  then invoke it to find the toolkit location.
         # This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit,
         # NVIDIA HPC SDK, and distro's splayed layouts
-        execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
+
+
+        #Allow the user to specify a host compiler except for Visual Studio
+        if(NOT $ENV{CUDAHOSTCXX} STREQUAL "")
+          get_filename_component(CUDAToolkit_CUDA_HOST_COMPILER $ENV{CUDAHOSTCXX} PROGRAM)
+          if(NOT EXISTS ${CUDAToolkit_CUDA_HOST_COMPILER})
+            message(FATAL_ERROR "Could not find compiler set in environment variable CUDAHOSTCXX:\n$ENV{CUDAHOSTCXX}.\n${CUDAToolkit_CUDA_HOST_COMPILER}")
+          endif()
+        elseif(CUDAToolkit_CUDA_HOST_COMPILER)
+          # We get here if CUDAToolkit_CUDA_HOST_COMPILER was specified by the user or toolchain file.
+          if(IS_ABSOLUTE "${CUDAToolkit_CUDA_HOST_COMPILER}")
+            # Convert to forward slashes.
+            cmake_path(CONVERT "${CUDAToolkit_CUDA_HOST_COMPILER}" TO_CMAKE_PATH_LIST CUDAToolkit_CUDA_HOST_COMPILER NORMALIZE)
+          else()
+            # Convert to absolute path so changes in `PATH` do not impact CUDA compilation.
+            find_program(_CUDAToolkit_CUDA_HOST_COMPILER_PATH NO_CACHE NAMES "${CUDAToolkit_CUDA_HOST_COMPILER}")
+            if(_CUDAToolkit_CUDA_HOST_COMPILER_PATH)
+              set(CUDAToolkit_CUDA_HOST_COMPILER "${_CUDAToolkit_CUDA_HOST_COMPILER_PATH}")
+            endif()
+            unset(_CUDAToolkit_CUDA_HOST_COMPILER_PATH)
+          endif()
+          if(NOT EXISTS "${CUDAToolkit_CUDA_HOST_COMPILER}")
+            message(FATAL_ERROR "Could not find compiler set in variable CUDAToolkit_CUDA_HOST_COMPILER:\n  ${CUDAToolkit_CUDA_HOST_COMPILER}")
+          endif()
+          # If the value was cached, update the cache entry with our modifications.
+          get_property(_CUDAToolkit_CUDA_HOST_COMPILER_CACHED CACHE CUDAToolkit_CUDA_HOST_COMPILER PROPERTY TYPE)
+          if(_CUDAToolkit_CUDA_HOST_COMPILER_CACHED)
+            set_property(CACHE CUDAToolkit_CUDA_HOST_COMPILER PROPERTY VALUE "${CUDAToolkit_CUDA_HOST_COMPILER}")
+            mark_as_advanced(CUDAToolkit_CUDA_HOST_COMPILER)
+          endif()
+          unset(_CUDAToolkit_CUDA_HOST_COMPILER_CACHED)
+        endif()
+
+        if(CUDAToolkit_CUDA_HOST_COMPILER)
+          set(nvcc_ccbin_flag "-ccbin=${CUDAToolkit_CUDA_HOST_COMPILER}")
+        endif()
+        execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "${nvcc_ccbin_flag}" "-v" "__cmake_determine_cuda"
           OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
         message(CONFIGURE_LOG
           "Executed nvcc to extract CUDAToolkit information:\n${_CUDA_NVCC_OUT}\n\n")
@@ -766,6 +807,65 @@
 
   endfunction()
 
+  function(_CUDAToolkit_guess_root_dir)
+    # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
+    #
+    # - Linux: /usr/local/cuda-X.Y
+    # - macOS: /Developer/NVIDIA/CUDA-X.Y
+    # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
+    #
+    # We will also search the default symlink location /usr/local/cuda first since
+    # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
+    # directory is the desired location.
+    if(UNIX)
+      if(NOT APPLE)
+        set(platform_base "/usr/local/cuda-")
+      else()
+        set(platform_base "/Developer/NVIDIA/CUDA-")
+      endif()
+    else()
+      set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
+    endif()
+
+    # Build out a descending list of possible cuda installations, e.g.
+    file(GLOB possible_paths "${platform_base}*")
+    # Iterate the glob results and create a descending list.
+    set(versions)
+    foreach(p ${possible_paths})
+      # Extract version number from end of string
+      string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
+      if(IS_DIRECTORY ${p} AND p_version)
+        list(APPEND versions ${p_version})
+      endif()
+    endforeach()
+
+    # Sort numerically in descending order, so we try the newest versions first.
+    list(SORT versions COMPARE NATURAL ORDER DESCENDING)
+
+    # With a descending list of versions, populate possible paths to search.
+    set(search_paths)
+    foreach(v ${versions})
+      list(APPEND search_paths "${platform_base}${v}")
+    endforeach()
+
+    # Force the global default /usr/local/cuda to the front on Unix.
+    if(UNIX)
+      list(INSERT search_paths 0 "/usr/local/cuda")
+    endif()
+
+    # Now search for the toolkit again using the platform default search paths.
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
+    if(CUDAToolkit_ROOT_DIR)
+      set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
+    endif()
+
+    # We are done with these variables now, cleanup for caller.
+    unset(platform_base)
+    unset(possible_paths)
+    unset(versions)
+    unset(search_paths)
+  endfunction()
+
   function(_CUDAToolkit_find_version_file result_variable)
     # We first check for a non-scattered installation to prefer it over a scattered installation.
     set(version_files version.txt version.json)
@@ -807,6 +907,28 @@
     endif()
   endfunction()
 
+  macro(_CUDAToolkit_find_failure_message _CUDAToolkit_fail_mode)
+    # Declare error messages now, print later depending on find_package args.
+    if("${_CUDAToolkit_fail_mode}" STREQUAL "GUESS")
+      set(_CUDAToolkit_fail_message "Could not find `nvcc` executable in any searched paths, please set CUDAToolkit_ROOT")
+    elseif("${_CUDAToolkit_fail_mode}" STREQUAL "VARIABLE")
+      set(_CUDAToolkit_fail_message "Could not find `nvcc` executable in path specified by variable CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
+    else()
+      set(_CUDAToolkit_fail_message "Could not find `nvcc` executable in path specified by environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
+    endif()
+
+    if(CUDAToolkit_FIND_REQUIRED)
+      message(FATAL_ERROR ${_CUDAToolkit_fail_message})
+    else()
+      if(NOT CUDAToolkit_FIND_QUIETLY)
+        message(STATUS ${_CUDAToolkit_fail_message})
+      endif()
+      set(CUDAToolkit_FOUND FALSE)
+      unset(_CUDAToolkit_fail_message)
+      return()
+    endif()
+  endmacro()
+
   # For NVCC we can easily deduce the SDK binary directory from the compiler path.
   if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
     get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
@@ -816,108 +938,38 @@
     mark_as_advanced(CUDAToolkit_BIN_DIR)
   endif()
 
-  # Try user provided path
-  _CUDAToolkit_find_root_dir(COMPILER_PATHS)
-  if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
-    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
+  # Try `CMAKE_CUDA_COMPILER` and `ENV{CUDACXX}`
+  if(NOT CUDAToolkit_ROOT_DIR)
+    _CUDAToolkit_find_root_dir(COMPILER_PATHS)
   endif()
+
+  # Try user provided path
+  if(NOT CUDAToolkit_ROOT_DIR AND DEFINED CUDAToolkit_ROOT)
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
+    if(NOT CUDAToolkit_ROOT_DIR)
+      # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
+      _CUDAToolkit_find_failure_message(VARIABLE)
+    endif()
+  endif()
+
+  if(NOT CUDAToolkit_ROOT_DIR AND DEFINED ENV{CUDAToolkit_ROOT})
+    _CUDAToolkit_find_root_dir(SEARCH_PATHS "$ENV{CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
+    if(NOT CUDAToolkit_ROOT_DIR)
+      # If the user specified ENV{CUDAToolkit_ROOT} but the toolkit could not be found, this is an error.
+      _CUDAToolkit_find_failure_message(ENV)
+    endif()
+  endif()
+
+  # Try users PATH, and CUDA_PATH env variable
   if(NOT CUDAToolkit_ROOT_DIR)
     _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS ENV CUDA_PATH PATH_SUFFIXES bin)
   endif()
 
-  # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
-  if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
-    # Declare error messages now, print later depending on find_package args.
-    set(fail_base "Could not find nvcc executable in path specified by")
-    set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
-    set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
-
-    if(CUDAToolkit_FIND_REQUIRED)
-      if(DEFINED CUDAToolkit_ROOT)
-        message(FATAL_ERROR ${cuda_root_fail})
-      elseif(DEFINED ENV{CUDAToolkit_ROOT})
-        message(FATAL_ERROR ${env_cuda_root_fail})
-      endif()
-    else()
-      if(NOT CUDAToolkit_FIND_QUIETLY)
-        if(DEFINED CUDAToolkit_ROOT)
-          message(STATUS ${cuda_root_fail})
-        elseif(DEFINED ENV{CUDAToolkit_ROOT})
-          message(STATUS ${env_cuda_root_fail})
-        endif()
-      endif()
-      set(CUDAToolkit_FOUND FALSE)
-      unset(fail_base)
-      unset(cuda_root_fail)
-      unset(env_cuda_root_fail)
-      return()
-    endif()
-  endif()
-
-  # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
-  #
-  # - Linux: /usr/local/cuda-X.Y
-  # - macOS: /Developer/NVIDIA/CUDA-X.Y
-  # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
-  #
-  # We will also search the default symlink location /usr/local/cuda first since
-  # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
-  # directory is the desired location.
+  # Try guessing where CUDA is installed
   if(NOT CUDAToolkit_ROOT_DIR)
-    if(UNIX)
-      if(NOT APPLE)
-        set(platform_base "/usr/local/cuda-")
-      else()
-        set(platform_base "/Developer/NVIDIA/CUDA-")
-      endif()
-    else()
-      set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
-    endif()
-
-    # Build out a descending list of possible cuda installations, e.g.
-    file(GLOB possible_paths "${platform_base}*")
-    # Iterate the glob results and create a descending list.
-    set(versions)
-    foreach(p ${possible_paths})
-      # Extract version number from end of string
-      string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
-      if(IS_DIRECTORY ${p} AND p_version)
-        list(APPEND versions ${p_version})
-      endif()
-    endforeach()
-
-    # Sort numerically in descending order, so we try the newest versions first.
-    list(SORT versions COMPARE NATURAL ORDER DESCENDING)
-
-    # With a descending list of versions, populate possible paths to search.
-    set(search_paths)
-    foreach(v ${versions})
-      list(APPEND search_paths "${platform_base}${v}")
-    endforeach()
-
-    # Force the global default /usr/local/cuda to the front on Unix.
-    if(UNIX)
-      list(INSERT search_paths 0 "/usr/local/cuda")
-    endif()
-
-    # Now search for the toolkit again using the platform default search paths.
-    _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
-
-    # We are done with these variables now, cleanup for caller.
-    unset(platform_base)
-    unset(possible_paths)
-    unset(versions)
-    unset(search_paths)
-
+    _CUDAToolkit_guess_root_dir()
     if(NOT CUDAToolkit_ROOT_DIR)
-      if(CUDAToolkit_FIND_REQUIRED)
-        message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
-      elseif(NOT CUDAToolkit_FIND_QUIETLY)
-        message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
-      endif()
-
-      set(CUDAToolkit_FOUND FALSE)
-      return()
+      _CUDAToolkit_find_failure_message(GUESS)
     endif()
   endif()
 
@@ -955,8 +1007,9 @@
   endif()
 endif()
 
-# Find target directory when crosscompiling.
-if(CMAKE_CROSSCOMPILING)
+# Figure out the target directory when either crosscompiling
+# or if we don't have `nvcc` and need to deduce the target arch
+if(CMAKE_CROSSCOMPILING OR NOT CUDAToolkit_NVCC_EXECUTABLE)
   # When a language is enabled we can use its compiler's target architecture.
   if(CMAKE_CUDA_COMPILER_LOADED AND CMAKE_CUDA_COMPILER_ARCHITECTURE_ID)
     set(_CUDA_TARGET_PROCESSOR "${CMAKE_CUDA_COMPILER_ARCHITECTURE_ID}")
@@ -966,7 +1019,7 @@
     set(_CUDA_TARGET_PROCESSOR "${CMAKE_C_COMPILER_ARCHITECTURE_ID}")
   elseif(CMAKE_SYSTEM_PROCESSOR)
     set(_CUDA_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
-  else()
+  elseif(CMAKE_CROSSCOMPILING)
     message(FATAL_ERROR "Cross-compiling with the CUDA toolkit requires CMAKE_SYSTEM_PROCESSOR to be set.")
   endif()
   # Keep in sync with equivalent table in CMakeDetermineCUDACompiler and FindCUDA!
@@ -997,13 +1050,18 @@
       # Mark that we need to pop the root search path changes after we have
       # found all cuda libraries so that searches for our cross-compilation
       # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or
-      # PATh
+      # PATH
       set(_CUDAToolkit_Pop_ROOT_PATH True)
       break()
     endif()
   endforeach()
 endif()
 
+ #If not already set we simply use the toolkit root
+if(NOT CUDAToolkit_TARGET_DIR)
+  set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
+endif()
+
 # Determine windows search path suffix for libraries
 if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
   if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
@@ -1012,19 +1070,6 @@
   endif()
 endif()
 
-# If not already set we can simply use the toolkit root or it's a scattered installation.
-if(NOT CUDAToolkit_TARGET_DIR)
-  # Not cross compiling
-  set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
-  # Now that we have the real ROOT_DIR, find components inside it.
-  list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
-
-  # Mark that we need to pop the prefix path changes after we have
-  # found the cudart library.
-  set(_CUDAToolkit_Pop_Prefix True)
-endif()
-
-
 # We don't need to verify the cuda_runtime header when we are using `nvcc` include paths
 # as the compiler being enabled means the header was found
 if(NOT CUDAToolkit_INCLUDE_DIRECTORIES)
@@ -1054,7 +1099,8 @@
   cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR)
 
   find_path(CUDAToolkit_CUBLAS_INCLUDE_DIR cublas_v2.h PATHS
-    ${CUDAToolkit_INCLUDE_DIRECTORIES}
+    ${CUDAToolkit_MATH_INCLUDE_DIR}
+    NO_DEFAULT_PATH
     )
   if(CUDAToolkit_CUBLAS_INCLUDE_DIR)
     list(APPEND CUDAToolkit_INCLUDE_DIRECTORIES "${CUDAToolkit_CUBLAS_INCLUDE_DIR}")
@@ -1066,12 +1112,12 @@
 # Find the CUDA Runtime Library libcudart
 find_library(CUDA_CUDART
   NAMES cudart
-  PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES}
+  PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES} ${CUDAToolkit_TARGET_DIR}
   PATH_SUFFIXES lib64 ${_CUDAToolkit_win_search_dirs}
 )
 find_library(CUDA_CUDART
   NAMES cudart
-  PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES}
+  PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES} ${CUDAToolkit_TARGET_DIR}
   PATH_SUFFIXES lib64/stubs ${_CUDAToolkit_win_stub_search_dirs} lib/stubs stubs
 )
 
@@ -1079,11 +1125,6 @@
   message(STATUS "Unable to find cudart library.")
 endif()
 
-if(_CUDAToolkit_Pop_Prefix)
-  list(REMOVE_AT CMAKE_PREFIX_PATH -1)
-  unset(_CUDAToolkit_Pop_Prefix)
-endif()
-
 #-----------------------------------------------------------------------------
 # Perform version comparison and validate all required variables are set.
 include(FindPackageHandleStandardArgs)
@@ -1114,7 +1155,10 @@
 
   # Detect we are in a splayed nvhpc toolkit layout and add extra
   # search paths without symlinks
-  if(CUDAToolkit_LIBRARY_DIR  MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64$")
+  #
+  # When the `nvcc` compiler output is parsed we have already resolved
+  # symlinks so we have `cuda/12.X/targets/....` and not `cuda/12.X/lib64`.
+  if(CUDAToolkit_LIBRARY_DIR  MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/(lib64$|targets/)")
     # Search location for math_libs/
     block(SCOPE_FOR POLICIES)
       cmake_policy(SET CMP0152 NEW)
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index 1488412..9af420f 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -6,7 +6,11 @@
 --------
 
 Finds the native curl installation (include directories and libraries) for
-transferring data with URLS.
+transferring data with URLS:
+
+.. code-block:: cmake
+
+  find_package(CURL [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.17
   If curl is built using its CMake-based build system, it will provide its own
@@ -68,8 +72,8 @@
 This module defines the following variables:
 
 ``CURL_FOUND``
-  Boolean indicating whether the (requested version of) curl and all required
-  components are found.
+  Boolean indicating whether (the requested version of) curl and all required
+  components were found.
 
 ``CURL_VERSION``
   .. versionadded:: 4.0
@@ -80,7 +84,7 @@
   .. versionadded:: 3.14
 
   Boolean indicating whether the specified component (curl protocol or feature)
-  is found.
+  was found.
 
 ``CURL_INCLUDE_DIRS``
   Include directories containing the ``curl/curl.h`` and other headers needed to
@@ -183,7 +187,7 @@
 endif()
 
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_CURL QUIET libcurl)
   if(PC_CURL_FOUND)
     pkg_get_variable(CURL_SUPPORTED_PROTOCOLS_STRING libcurl supported_protocols)
diff --git a/Modules/FindCVS.cmake b/Modules/FindCVS.cmake
index d50a758..b79f5f1 100644
--- a/Modules/FindCVS.cmake
+++ b/Modules/FindCVS.cmake
@@ -5,7 +5,11 @@
 FindCVS
 -------
 
-Finds the Concurrent Versions System (CVS).
+Finds the Concurrent Versions System (CVS):
+
+.. code-block:: cmake
+
+  find_package(CVS [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -13,7 +17,7 @@
 This module defines the following variables:
 
 ``CVS_FOUND``
-  True if the command-line client was found.
+  Boolean indicating whether the ``cvs`` command-line client was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -78,8 +82,5 @@
   )
 mark_as_advanced(CVS_EXECUTABLE)
 
-# Handle the QUIETLY and REQUIRED arguments and set CVS_FOUND to TRUE if
-# all listed variables are TRUE
-
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(CVS DEFAULT_MSG CVS_EXECUTABLE)
diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake
index 1d89c60..07cbb69 100644
--- a/Modules/FindCoin3D.cmake
+++ b/Modules/FindCoin3D.cmake
@@ -5,7 +5,11 @@
 FindCoin3D
 ----------
 
-Finds Coin3D (Open Inventor).
+Finds Coin3D (Open Inventor):
+
+.. code-block:: cmake
+
+  find_package(Coin3D [...])
 
 Coin3D is an implementation of the Open Inventor API.  It provides
 data structures and algorithms for 3D visualization.
@@ -16,8 +20,9 @@
 This module defines the following variables:
 
 ``Coin3D_FOUND``
-  True if Coin3D, Open Inventor was found.  For backward compatibility, the
-  ``COIN3D_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Coin3D, Open Inventor was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -29,14 +34,39 @@
 ``COIN3D_LIBRARIES``
   Coin3D libraries required for linking.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``COIN3D_FOUND``
+  .. deprecated:: 4.2
+    Use ``Coin3D_FOUND``, which has the same value.
+
+  Boolean indicating whether Coin3D, Open Inventor was found.
+
 Examples
 ^^^^^^^^
 
-Finding Coin3D:
+Finding Coin3D and conditionally creating an interface :ref:`imported target
+<Imported Targets>` that encapsulates its usage requirements for linking to a
+project target:
 
 .. code-block:: cmake
 
   find_package(Coin3D)
+
+  if(Coin3D_FOUND AND NOT TARGET Coin3D::Coin3D)
+    add_library(Coin3D::Coin3D INTERFACE IMPORTED)
+    set_target_properties(
+      Coin3D::Coin3D
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${COIN3D_INCLUDE_DIRS}"
+        INTERFACE_LINK_LIBRARIES "${COIN3D_LIBRARIES}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE Coin3D::Coin3D)
 #]=======================================================================]
 
 if (WIN32)
diff --git a/Modules/FindCups.cmake b/Modules/FindCups.cmake
index 871a809..e9c5587 100644
--- a/Modules/FindCups.cmake
+++ b/Modules/FindCups.cmake
@@ -5,7 +5,11 @@
 FindCups
 --------
 
-Finds the Common UNIX Printing System (CUPS).
+Finds the Common UNIX Printing System (CUPS):
+
+.. code-block:: cmake
+
+  find_package(Cups [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -24,12 +28,17 @@
 This module defines the following variables:
 
 ``Cups_FOUND``
-  Boolean indicating whether the CUPS is found.  For backward compatibility, the
-  ``CUPS_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) CUPS was found.
+
+``Cups_VERSION``
+  .. versionadded:: 4.2
+
+  The version of CUPS found.
+
 ``CUPS_INCLUDE_DIRS``
   Include directories needed for using CUPS.
-``CUPS_VERSION_STRING``
-  The version of CUPS found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -38,6 +47,7 @@
 
 ``CUPS_INCLUDE_DIR``
   The directory containing the CUPS headers.
+
 ``CUPS_LIBRARIES``
   Libraries needed to link against to use CUPS.
 
@@ -50,6 +60,23 @@
   Set this variable to ``TRUE`` to require CUPS version which features the
   ``ippDeleteAttribute()`` function (i.e. at least of CUPS ``1.1.19``).
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``CUPS_FOUND``
+  .. deprecated:: 4.2
+    Use ``Cups_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) CUPS was found.
+
+``CUPS_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Cups_VERSION``.
+
+  The version of CUPS found.
+
 Examples
 ^^^^^^^^
 
@@ -83,19 +110,20 @@
     file(STRINGS "${CUPS_INCLUDE_DIR}/cups/cups.h" cups_version_str
          REGEX "^#[\t ]*define[\t ]+CUPS_VERSION_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
 
-    unset(CUPS_VERSION_STRING)
+    unset(Cups_VERSION)
     foreach(VPART MAJOR MINOR PATCH)
         foreach(VLINE ${cups_version_str})
             if(VLINE MATCHES "^#[\t ]*define[\t ]+CUPS_VERSION_${VPART}[\t ]+([0-9]+)$")
                 set(CUPS_VERSION_PART "${CMAKE_MATCH_1}")
-                if(CUPS_VERSION_STRING)
-                    string(APPEND CUPS_VERSION_STRING ".${CUPS_VERSION_PART}")
+                if(Cups_VERSION)
+                    string(APPEND Cups_VERSION ".${CUPS_VERSION_PART}")
                 else()
-                    set(CUPS_VERSION_STRING "${CUPS_VERSION_PART}")
+                    set(Cups_VERSION "${CUPS_VERSION_PART}")
                 endif()
             endif()
         endforeach()
     endforeach()
+    set(CUPS_VERSION_STRING ${Cups_VERSION})
 endif ()
 
 include(FindPackageHandleStandardArgs)
@@ -103,11 +131,11 @@
 if (CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
     find_package_handle_standard_args(Cups
                                       REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR CUPS_HAS_IPP_DELETE_ATTRIBUTE
-                                      VERSION_VAR CUPS_VERSION_STRING)
+                                      VERSION_VAR Cups_VERSION)
 else ()
     find_package_handle_standard_args(Cups
                                       REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR
-                                      VERSION_VAR CUPS_VERSION_STRING)
+                                      VERSION_VAR Cups_VERSION)
 endif ()
 
 mark_as_advanced(CUPS_INCLUDE_DIR CUPS_LIBRARIES)
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index 64600c6..de79bbb 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -5,7 +5,11 @@
 FindCurses
 ----------
 
-Finds the curses or ncurses library.
+Finds the curses or ncurses library:
+
+.. code-block:: cmake
+
+  find_package(Curses [...])
 
 Curses is a terminal control library for Unix-like systems, used to build text
 user interface (TUI) applications.  Originally developed in 1978, it has since
@@ -18,8 +22,9 @@
 This module defines the following variables:
 
 ``Curses_FOUND``
-  Boolean indicating whether the Curses is found.  For backward compatibility,
-  the ``CURSES_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Curses was found.
 
 ``CURSES_INCLUDE_DIRS``
   .. versionadded:: 3.1
@@ -64,7 +69,13 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-The following legacy variables are provided for backward compatibility:
+The following variables are provided for backward compatibility:
+
+``CURSES_FOUND``
+  .. deprecated:: 4.2
+    Use ``Curses_FOUND``, which has the same value.
+
+  Boolean indicating whether Curses was found.
 
 ``CURSES_INCLUDE_DIR``
   .. deprecated:: 3.1
@@ -318,7 +329,7 @@
 set(CURSES_INCLUDE_DIR ${CURSES_INCLUDE_PATH}) # compatibility
 
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(NCURSES QUIET ${NCURSES_LIBRARY_NAME})
   set(CURSES_CFLAGS ${NCURSES_CFLAGS_OTHER})
 endif()
diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake
index 37f1e7a..8978e3e 100644
--- a/Modules/FindCxxTest.cmake
+++ b/Modules/FindCxxTest.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds `CxxTest`_, a C++ unit testing framework suite, and provides a helper
-command to create test runners and integrate them with CTest.
+command to create test runners and integrate them with CTest:
+
+.. code-block:: cmake
+
+  find_package(CxxTest [...])
 
 .. _`CxxTest`: https://github.com/CxxTest/cxxtest
 
@@ -15,8 +19,10 @@
 
 This module defines the following variables:
 
-``CXXTEST_FOUND``
-  Boolean indicating whether the CxxTest framework is found.
+``CxxTest_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether the CxxTest framework was found.
 
 ``CXXTEST_INCLUDE_DIRS``
   Include directories containing headers needed to use CxxTest.
@@ -35,11 +41,15 @@
 
 The following cache variables may also be set:
 
+``CXXTEST_PYTHON_TESTGEN_EXECUTABLE``
+  The path to the Python-based CxxTest test generator script.
+
 ``CXXTEST_PERL_TESTGEN_EXECUTABLE``
   The path to the Perl-based CxxTest test generator script.
 
-``CXXTEST_PYTHON_TESTGEN_EXECUTABLE``
-  The path to the Python-based CxxTest test generator script.
+  .. note::
+    Perl-based test generator script has been removed in CxxTest version
+    4.0 in favor of Python-based script.
 
 Hints
 ^^^^^
@@ -76,7 +86,7 @@
     This must be a relative path.  It is interpreted relative to the
     current binary directory (:variable:`CMAKE_CURRENT_BINARY_DIR`).
 
-  ``<input-files-to-testgen>``
+  ``<input-files-to-testgen>...``
     A list of header files containing test suite classes derived from the C++
     class ``CxxTest::TestSuite``, to be included in the test runner.  These must
     be given as absolute paths.
@@ -84,7 +94,13 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-The following variables are deprecated and provided for backward compatibility:
+The following variables are provided for backward compatibility:
+
+``CXXTEST_FOUND``
+  .. deprecated:: 4.2
+    Use ``CxxTest_FOUND``, which has the same value.
+
+  Boolean indicating whether the CxxTest framework was found.
 
 ``CXXTEST_USE_PYTHON``
   .. deprecated:: 2.8.3
@@ -121,7 +137,7 @@
   find_package(CxxTest)
 
   # Create interface imported target:
-  if(CXXTEST_FOUND AND NOT TARGET CxxTest::CxxTest)
+  if(CxxTest_FOUND AND NOT TARGET CxxTest::CxxTest)
     add_library(CxxTest::CxxTest INTERFACE IMPORTED)
     set_target_properties(
       CxxTest::CxxTest
@@ -130,7 +146,7 @@
   endif()
 
   # Add test:
-  if(CXXTEST_FOUND)
+  if(CxxTest_FOUND)
     enable_testing()
 
     cxxtest_add_test(
@@ -164,8 +180,11 @@
   };
 #]=======================================================================]
 
+# CMake 4.2
+#     Module now consistently defines the CxxTest_FOUND result variable.
+#
 # Version 1.4 (11/18/10) (CMake 2.8.4)
-#     Issue 11384: Added support to the CXX_ADD_TEST macro so header
+#     Issue 11384: Added support to the cxxtest_add_test() macro so header
 #                  files (containing the tests themselves) show up in
 #                  Visual Studio and other IDEs.
 #
@@ -177,17 +196,21 @@
 #
 #     Also added support for CXXTEST_TESTGEN_ARGS, for manually specifying
 #     options to the CxxTest code generator.
-# Version 1.2 (3/2/08)
+#
+# Version 1.2 (3/2/08) (CMake 2.8.0)
 #     Included patch from Tyler Roscoe to have the perl & python binaries
-#     detected based on CXXTEST_INCLUDE_DIR
-# Version 1.1 (2/9/08)
-#     Clarified example to illustrate need to call target_link_libraries()
-#     Changed commands to lowercase
-#     Added licensing info
-# Version 1.0 (1/8/08)
-#     Fixed CXXTEST_INCLUDE_DIRS so it will work properly
-#     Eliminated superfluous CXXTEST_FOUND assignment
-#     Cleaned up and added more documentation
+#     detected based on CXXTEST_INCLUDE_DIR.
+#
+# Version 1.1 (2/9/08) (CMake 2.8.0)
+#     Clarified example to illustrate need to call target_link_libraries().
+#     Changed commands to lowercase.
+#     Added licensing info.
+#
+# Version 1.0 (1/8/08) (CMake 2.6.3)
+#     Module added to CMake.
+#     Fixed CXXTEST_INCLUDE_DIRS so it will work properly.
+#     Eliminated superfluous CXXTEST_FOUND assignment.
+#     Cleaned up and added more documentation.
 
 #=============================================================
 # cxxtest_add_test (public macro)
@@ -214,7 +237,6 @@
     else()
         add_test(${_cxxtest_testname} ${CMAKE_CURRENT_BINARY_DIR}/${_cxxtest_testname})
     endif()
-
 endmacro()
 
 #=============================================================
@@ -234,10 +256,10 @@
 find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl
          PATHS ${CXXTEST_INCLUDE_DIR})
 
-if(PYTHON_FOUND OR Perl_FOUND)
+if(Python_FOUND OR Perl_FOUND)
   include(FindPackageHandleStandardArgs)
 
-  if(PYTHON_FOUND AND (CXXTEST_USE_PYTHON OR NOT Perl_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON))
+  if(Python_FOUND AND (CXXTEST_USE_PYTHON OR NOT Perl_FOUND OR NOT DEFINED CXXTEST_USE_PYTHON))
     set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE})
     execute_process(COMMAND ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE} --version
       OUTPUT_VARIABLE _CXXTEST_OUT ERROR_VARIABLE _CXXTEST_OUT RESULT_VARIABLE _CXXTEST_RESULT)
@@ -256,13 +278,14 @@
         CXXTEST_INCLUDE_DIR CXXTEST_PERL_TESTGEN_EXECUTABLE)
   endif()
 
-  if(CXXTEST_FOUND)
+  if(CxxTest_FOUND)
     set(CXXTEST_INCLUDE_DIRS ${CXXTEST_INCLUDE_DIR})
   endif()
 
 else()
+  set(CxxTest_FOUND FALSE)
+  set(CXXTEST_FOUND ${CxxTest_FOUND})
 
-  set(CXXTEST_FOUND false)
   if(NOT CxxTest_FIND_QUIETLY)
     if(CxxTest_FIND_REQUIRED)
       message(FATAL_ERROR "Neither Python nor Perl found, cannot use CxxTest, aborting!")
diff --git a/Modules/FindCygwin.cmake b/Modules/FindCygwin.cmake
index ba26980..102f2fe 100644
--- a/Modules/FindCygwin.cmake
+++ b/Modules/FindCygwin.cmake
@@ -6,7 +6,11 @@
 ----------
 
 Finds Cygwin, a POSIX-compatible environment that runs natively on Microsoft
-Windows.
+Windows:
+
+.. code-block:: cmake
+
+  find_package(Cygwin [...])
 
 .. note::
 
@@ -21,6 +25,11 @@
 
 This module defines the following variables:
 
+``Cygwin_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether Cygwin was found.
+
 ``CYGWIN_INSTALL_PATH``
   The path to the Cygwin root installation directory.
 
@@ -30,7 +39,7 @@
 Finding the Cygwin installation and using its path in a custom find module:
 
 .. code-block:: cmake
-  :caption: FindFoo.cmake
+  :caption: ``FindFoo.cmake``
 
   find_package(Cygwin)
   find_program(Foo_EXECUTABLE NAMES foo PATHS ${CYGWIN_INSTALL_PATH}/bin)
@@ -61,3 +70,9 @@
   mark_as_advanced(CYGWIN_BAT)
 
 endif ()
+
+if(CYGWIN_BAT AND CYGWIN_INSTALL_PATH)
+  set(Cygwin_FOUND TRUE)
+else()
+  set(Cygwin_FOUND FALSE)
+endif()
diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake
index 4e0ff47..181142c 100644
--- a/Modules/FindDCMTK.cmake
+++ b/Modules/FindDCMTK.cmake
@@ -5,79 +5,149 @@
 FindDCMTK
 ---------
 
-Find DICOM ToolKit (DCMTK) libraries and applications
+Finds the DICOM ToolKit (DCMTK) libraries and applications:
 
-The module defines the following variables::
+.. code-block:: cmake
 
- DCMTK_INCLUDE_DIRS  - Directories to include to use DCMTK
- DCMTK_LIBRARIES     - Files to link against to use DCMTK
- DCMTK_FOUND         - If false, don't try to use DCMTK
- DCMTK_DIR           - (optional) Source directory for DCMTK
+  find_package(DCMTK [...])
 
-Compatibility
-^^^^^^^^^^^^^
+DCMTK is a set of libraries and applications implementing large parts of
+the DICOM Standard (Digital Imaging and Communications in Medicine).
 
-This module is able to find a version of DCMTK that does or does not export
-a ``DCMTKConfig.cmake`` file. It applies a two step process:
+.. versionadded:: 3.5
+  This module is now able to find a version of DCMTK that does or does not
+  export a ``DCMTKConfig.cmake`` file.
 
-* Step 1:  Attempt to find DCMTK version providing a ``DCMTKConfig.cmake`` file.
-* Step 2:  If step 1 failed, rely on ``FindDCMTK.cmake`` to set ``DCMTK_*``
-  variables details below.
+  DCMTK since its version `3.6.1_20140617
+  <https://git.dcmtk.org/?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_
+  supports and installs :ref:`package configuration file
+  <Config File Packages>` (``DCMTKConfig.cmake``) for use with the
+  :command:`find_package` command in *config mode*.
 
+  This module now applies a two-step process:
 
-`Recent DCMTK
-<https://git.dcmtk.org/?p=dcmtk.git;a=commit;h=662ae187c493c6b9a73dd5e3875372cebd0c11fe>`_
-provides a ``DCMTKConfig.cmake`` :manual:`package configuration file
-<cmake-packages(7)>`. To exclusively use the package configuration file
-(recommended when possible), pass the `NO_MODULE` option to
-:command:`find_package`. For example, `find_package(DCMTK NO_MODULE)`.
-This requires official DCMTK snapshot *3.6.1_20140617* or newer.
+  * Step 1: Attempts to find DCMTK version providing a ``DCMTKConfig.cmake``
+    file and, if found, returns the results without further action.
+  * Step 2: If step 1 failed, this module falls back to *module mode*
+    (it searches standard locations) and sets the ``DCMTK_*`` result
+    variables.
 
+  Until all clients update to the more recent DCMTK, build systems will need
+  to support different versions of DCMTK.
 
-Until all clients update to the more recent DCMTK, build systems will need
-to support different versions of DCMTK.
+  On any given system, the following combinations of DCMTK versions could
+  be considered for the DCMTK installed on the system (for example, via a
+  system package manager), or locally (for example, a custom installation,
+  or through the :module:`FetchContent` module):
 
-On any given system, the following combinations of DCMTK versions could be
-considered:
+  ===== ================== =================== ============
+  Case  System DCMTK       Local DCMTK         Supported?
+  ===== ================== =================== ============
+  A     N/A                [ ] DCMTKConfig     YES
+  B     N/A                [X] DCMTKConfig     YES
+  C     [ ] DCMTKConfig    N/A                 YES
+  D     [X] DCMTKConfig    N/A                 YES
+  E     [ ] DCMTKConfig    [ ] DCMTKConfig     YES (*)
+  F     [X] DCMTKConfig    [ ] DCMTKConfig     NO
+  G     [ ] DCMTKConfig    [X] DCMTKConfig     YES
+  H     [X] DCMTKConfig    [X] DCMTKConfig     YES
+  ===== ================== =================== ============
 
-+--------+---------------------+-----------------------+-------------------+
-|        |   SYSTEM DCMTK      |      LOCAL DCMTK      |     Supported ?   |
-+--------+---------------------+-----------------------+-------------------+
-| Case A |   NA                |      [ ] DCMTKConfig  |         YES       |
-+--------+---------------------+-----------------------+-------------------+
-| Case B |   NA                |      [X] DCMTKConfig  |         YES       |
-+--------+---------------------+-----------------------+-------------------+
-| Case C |   [ ] DCMTKConfig   |      NA               |         YES       |
-+--------+---------------------+-----------------------+-------------------+
-| Case D |   [X] DCMTKConfig   |      NA               |         YES       |
-+--------+---------------------+-----------------------+-------------------+
-| Case E |   [ ] DCMTKConfig   |      [ ] DCMTKConfig  |         YES (*)   |
-+--------+---------------------+-----------------------+-------------------+
-| Case F |   [X] DCMTKConfig   |      [ ] DCMTKConfig  |         NO        |
-+--------+---------------------+-----------------------+-------------------+
-| Case G |   [ ] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
-+--------+---------------------+-----------------------+-------------------+
-| Case H |   [X] DCMTKConfig   |      [X] DCMTKConfig  |         YES       |
-+--------+---------------------+-----------------------+-------------------+
+  Legend:
 
- (*) See Troubleshooting section.
+    (*)
+      See the `Troubleshooting`_ section.
 
-Legend:
+    N/A
+      DCMTK is not available.
 
-  NA ...............: Means that no System or Local DCMTK is available
+    [ ] DCMTKConfig
+      DCMTK does NOT export a ``DCMTKConfig.cmake`` file.
 
-  [ ] DCMTKConfig ..: Means that the version of DCMTK does NOT export a DCMTKConfig.cmake file.
+    [X] DCMTKConfig
+      DCMTK exports a ``DCMTKConfig.cmake`` file.
 
-  [X] DCMTKConfig ..: Means that the version of DCMTK exports a DCMTKConfig.cmake file.
+Result Variables
+^^^^^^^^^^^^^^^^
 
+This module defines the following variables:
+
+``DCMTK_FOUND``
+  Boolean indicating whether DCMTK was found.
+
+``DCMTK_INCLUDE_DIRS``
+  Include directories containing headers needed to use DCMTK.
+
+``DCMTK_LIBRARIES``
+  Libraries needed to link against to use DCMTK.
+
+Hints
+^^^^^
+
+This module accepts the following variables:
+
+``DCMTK_DIR``
+  (optional) Source directory for DCMTK.
 
 Troubleshooting
 ^^^^^^^^^^^^^^^
 
-What to do if my project finds a different version of DCMTK?
+.. rubric:: What to do if project finds a different version of DCMTK?
 
 Remove DCMTK entry from the CMake cache per :command:`find_package`
-documentation.
+documentation, and re-run configuration.  To find DCMTK on custom location
+use variables such as :variable:`CMAKE_PREFIX_PATH`, or ``DCMTK_DIR``.
+
+Examples
+^^^^^^^^
+
+Example: Finding DCMTK
+""""""""""""""""""""""
+
+Finding DCMTK with this module:
+
+.. code-block:: cmake
+
+  find_package(DCMTK)
+
+Example: Finding DCMTK Without This Module
+""""""""""""""""""""""""""""""""""""""""""
+
+To explicitly use the ``DCMTKConfig.cmake`` package configuration file
+(recommended when possible) and find DCMTK in *config mode* without using
+this module, the ``NO_MODULE`` option can be given to
+:command:`find_package`:
+
+.. code-block:: cmake
+
+  find_package(DCMTK NO_MODULE)
+
+Example: Creating Imported Target
+"""""""""""""""""""""""""""""""""
+
+In the following example, DCMTK is searched with this module and
+an :ref:`imported target <Imported Targets>` is conditionally created to
+provide DCMTK usage requirements which can be easily linked to project
+targets.  For example, if DCMTK is found in *config mode*, the
+``DCMTK::DCMTK`` imported target will be available through the found config
+files instead:
+
+.. code-block:: cmake
+
+  find_package(DCMTK)
+
+  # Upstream DCMTKConfig.cmake already provides DCMTK::DCMTK imported target
+  if(DCMTK_FOUND AND NOT TARGET DCMTK::DCMTK)
+    add_library(DCMTK::DCMTK INTERFACE IMPORTED)
+    set_target_properties(
+      DCMTK:DCMTK
+      PROPERTIES
+        INTERFACE_LINK_LIBRARIES "${DCMTK_LIBRARIES}"
+        INTERFACE_INCLUDE_DIRECTORIES "${DCMTK_INCLUDE_DIRS}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE DCMTK::DCMTK)
 #]=======================================================================]
 
 #
diff --git a/Modules/FindDart.cmake b/Modules/FindDart.cmake
index 96cce45..6d4b9a3 100644
--- a/Modules/FindDart.cmake
+++ b/Modules/FindDart.cmake
@@ -8,10 +8,32 @@
 .. deprecated:: 3.27
   This module is available only if policy :policy:`CMP0145` is not set to ``NEW``.
 
-Find DART
+Finds DART:
 
-This module looks for the dart testing software and sets DART_ROOT to
+.. code-block:: cmake
+
+  find_package(DART [...])
+
+This module looks for the dart testing software and sets ``DART_ROOT`` to
 point to where it found it.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``Dart_FOUND``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether DART was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``DART_ROOT``
+  The path to the Dart root installation.
 #]=======================================================================]
 
 if(_FindDart_testing)
diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake
index 9e195d3..923fe45 100644
--- a/Modules/FindDevIL.cmake
+++ b/Modules/FindDevIL.cmake
@@ -5,7 +5,15 @@
 FindDevIL
 ---------
 
-Finds the Developer's Image Library, `DevIL <https://openil.sourceforge.net/>`_.
+Finds the Developer's Image Library, `DevIL <https://openil.sourceforge.net/>`_:
+
+.. code-block:: cmake
+
+  find_package(DevIL [<version>] [...])
+
+.. versionadded:: 4.2
+  Support for the ``<version>`` argument in the :command:`find_package`
+  call.  Version can be also specified as a range.
 
 The DevIL package internally consists of the following libraries, all
 distributed as part of the same release:
@@ -58,14 +66,21 @@
 This module defines the following variables:
 
 ``DevIL_FOUND``
-  Boolean indicating whether the DevIL package is found, including the IL and
-  ILU libraries.
+  .. versionadded:: 3.8
+
+  Boolean indicating whether the (requested version of) DevIL package was
+  found, including the IL and ILU libraries.
+
+``DevIL_VERSION``
+  .. versionadded:: 4.2
+
+  The version of the DevIL found.
 
 ``DevIL_ILUT_FOUND``
   .. versionadded:: 3.21
 
-  Boolean indicating whether the ILUT library is found.  On most systems, ILUT
-  is found when both IL and ILU are available.
+  Boolean indicating whether the ILUT library was found.  On most systems,
+  ILUT is found when both IL and ILU are available.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -109,8 +124,8 @@
   target_link_libraries(app PRIVATE DevIL::ILUT)
 #]=======================================================================]
 
-# TODO: Add version support.
-# Tested under Linux and Windows (MSVC)
+cmake_policy(PUSH)
+cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
 
 include(FindPackageHandleStandardArgs)
 
@@ -119,35 +134,62 @@
   DOC "The path to the directory that contains il.h"
 )
 
-#message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}")
-
 find_library(IL_LIBRARIES
   NAMES IL DEVIL
   PATH_SUFFIXES libx32 lib64 lib lib32
   DOC "The file that corresponds to the base il library."
 )
 
-#message("IL_LIBRARIES is ${IL_LIBRARIES}")
-
 find_library(ILUT_LIBRARIES
   NAMES ILUT
   PATH_SUFFIXES libx32 lib64 lib lib32
   DOC "The file that corresponds to the il (system?) utility library."
 )
 
-#message("ILUT_LIBRARIES is ${ILUT_LIBRARIES}")
-
 find_library(ILU_LIBRARIES
   NAMES ILU
   PATH_SUFFIXES libx32 lib64 lib lib32
   DOC "The file that corresponds to the il utility library."
 )
 
-#message("ILU_LIBRARIES is ${ILU_LIBRARIES}")
+# Get version.
+block(PROPAGATE DevIL_VERSION)
+  if(IL_INCLUDE_DIR AND EXISTS "${IL_INCLUDE_DIR}/il.h")
+    set(regex "^[ \t]*#[ \t]*define[ \t]+IL_VERSION[ \t]+([0-9]+)[ \t]*$")
 
-find_package_handle_standard_args(DevIL DEFAULT_MSG
-                                  IL_LIBRARIES ILU_LIBRARIES
-                                  IL_INCLUDE_DIR)
+    file(STRINGS ${IL_INCLUDE_DIR}/il.h result REGEX "${regex}")
+
+    if(result MATCHES "${regex}")
+      set(DevIL_VERSION "${CMAKE_MATCH_1}")
+
+      math(EXPR DevIL_VERSION_MAJOR "${DevIL_VERSION} / 100")
+      math(EXPR DevIL_VERSION_MINOR "${DevIL_VERSION} / 10 % 10")
+      math(EXPR DevIL_VERSION_PATCH "${DevIL_VERSION} % 10")
+
+      set(DevIL_VERSION "")
+      foreach(part MAJOR MINOR PATCH)
+        if(DevIL_VERSION)
+          string(APPEND ".${DevIL_VERSION_${part}}")
+        else()
+          set(DevIL_VERSION "${DevIL_VERSION_${part}}")
+        endif()
+
+        set(
+          DevIL_VERSION
+          "${DevIL_VERSION_MAJOR}.${DevIL_VERSION_MINOR}.${DevIL_VERSION_PATCH}"
+        )
+      endforeach()
+    endif()
+  endif()
+endblock()
+
+find_package_handle_standard_args(
+  DevIL
+  REQUIRED_VARS IL_LIBRARIES ILU_LIBRARIES IL_INCLUDE_DIR
+  VERSION_VAR DevIL_VERSION
+  HANDLE_VERSION_RANGE
+)
+
 # provide legacy variable for compatibility
 set(IL_FOUND ${DevIL_FOUND})
 
@@ -183,3 +225,5 @@
     target_link_libraries(DevIL::ILUT INTERFACE DevIL::ILU)
   endif()
 endif()
+
+cmake_policy(POP)
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index 2d43099..e72110c 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -11,7 +11,7 @@
 
 .. code-block:: cmake
 
-  find_package(Doxygen [<version>] [...] [COMPONENTS <components>...] [...])
+  find_package(Doxygen [<version>] [COMPONENTS <components>...] [...])
 
 Components
 ^^^^^^^^^^
@@ -90,12 +90,14 @@
 This module defines the following variables:
 
 ``Doxygen_FOUND``
-  Boolean indicating whether (the requested version of) ``doxygen`` executable
-  and all requested required components are found.  For backward compatibility,
-  the ``DOXYGEN_FOUND`` variable is also set, except it has boolean value of
-  ``YES`` or ``NO``.
+  .. versionadded:: 3.3
 
-``DOXYGEN_VERSION``
+  Boolean indicating whether the (requested version of) ``doxygen`` executable
+  and all requested required components were found.
+
+``Doxygen_VERSION``
+  .. versionadded:: 4.2
+
   The version of Doxygen found (as reported by ``doxygen --version``).
 
 Commands
@@ -490,6 +492,14 @@
 For compatibility with previous versions of CMake, the following variables
 are also defined but they are deprecated and should no longer be used:
 
+``DOXYGEN_FOUND``
+  .. deprecated:: 4.2
+    Use ``Doxygen_FOUND``.
+
+  Boolean indicating whether the (requested version of) ``doxygen`` executable
+  and all requested required components were found.  It has a boolean value
+  of ``YES`` or ``NO``.
+
 ``DOXYGEN_EXECUTABLE``
   .. deprecated:: 3.9
     Use ``Doxygen::doxygen`` imported target instead of referring to the
@@ -499,8 +509,9 @@
 
 ``DOXYGEN_DOT_FOUND``
   .. deprecated:: 3.9
+    Use ``Doxygen_dot_FOUND``.
 
-  Boolean result variable indicating whether ``dot`` executable is found.
+  Boolean result variable indicating whether ``dot`` executable was found.
 
 ``DOXYGEN_DOT_EXECUTABLE``
   .. deprecated:: 3.9
@@ -529,6 +540,12 @@
   (i.e. without specifying components) it prevents this find module from
   searching for Graphviz's ``dot`` utility.
 
+``DOXYGEN_VERSION``
+  .. deprecated:: 4.2
+    Superseded by the ``Doxygen_VERSION``.
+
+  The version of Doxygen found.
+
 Examples
 ^^^^^^^^
 
@@ -653,7 +670,7 @@
 
 In the following example, a custom ``Doxyfile`` configuration file is created
 in the current binary directory (:variable:`CMAKE_CURRENT_BINARY_DIR`) prior
-to calling the ``doxygen_add_doxs()``.  This allows project-specific
+to calling the ``doxygen_add_docs()``.  This allows project-specific
 configuration tags to be customized as needed:
 
 .. code-block:: cmake
@@ -664,7 +681,7 @@
   if(Doxygen_FOUND)
     configure_file(Doxyfile.in Doxyfile)
 
-    doxygen_add_doxs(
+    doxygen_add_docs(
       example_docs
       foo.c bar.c
       ALL
@@ -765,7 +782,8 @@
     mark_as_advanced(DOXYGEN_EXECUTABLE)
 
     if(DOXYGEN_EXECUTABLE)
-        _Doxygen_get_version(DOXYGEN_VERSION _Doxygen_version_result "${DOXYGEN_EXECUTABLE}")
+        _Doxygen_get_version(Doxygen_VERSION _Doxygen_version_result "${DOXYGEN_EXECUTABLE}")
+        set(DOXYGEN_VERSION "${Doxygen_VERSION}")
 
         if(_Doxygen_version_result)
             if(NOT Doxygen_FIND_QUIETLY)
@@ -959,7 +977,7 @@
 find_package_handle_standard_args(
     Doxygen
     REQUIRED_VARS DOXYGEN_EXECUTABLE
-    VERSION_VAR DOXYGEN_VERSION
+    VERSION_VAR Doxygen_VERSION
     HANDLE_VERSION_RANGE
     HANDLE_COMPONENTS
 )
diff --git a/Modules/FindEXPAT.cmake b/Modules/FindEXPAT.cmake
index dd45e58..bcb604f 100644
--- a/Modules/FindEXPAT.cmake
+++ b/Modules/FindEXPAT.cmake
@@ -5,8 +5,13 @@
 FindEXPAT
 ---------
 
-Finds the native Expat headers and library.  Expat is a stream-oriented XML
-parser library written in C.
+Finds the native Expat headers and library:
+
+.. code-block:: cmake
+
+  find_package(EXPAT [<version>] [...])
+
+Expat is a stream-oriented XML parser library written in C.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -22,15 +27,22 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
+
+``EXPAT_FOUND``
+  Boolean indicating whether (the requested version of) Expat was found.
+
+``EXPAT_VERSION``
+  .. versionadded:: 4.2
+
+  The version of Expat found.
 
 ``EXPAT_INCLUDE_DIRS``
   Include directories containing ``expat.h`` and related headers needed to use
   Expat.
+
 ``EXPAT_LIBRARIES``
   Libraries needed to link against to use Expat.
-``EXPAT_FOUND``
-  Boolean indicating whether the Expat is found.
 
 Hints
 ^^^^^
@@ -46,6 +58,17 @@
 
     Implemented on non-Windows platforms.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``EXPAT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``EXPAT_VERSION``.
+
+  The version of Expat found.
+
 Examples
 ^^^^^^^^
 
@@ -61,7 +84,7 @@
 cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
 
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_EXPAT QUIET expat)
 endif()
 
@@ -135,25 +158,26 @@
   file(STRINGS "${EXPAT_INCLUDE_DIR}/expat.h" expat_version_str
     REGEX "^#[\t ]*define[\t ]+XML_(MAJOR|MINOR|MICRO)_VERSION[\t ]+[0-9]+$")
 
-  unset(EXPAT_VERSION_STRING)
+  unset(EXPAT_VERSION)
   foreach(VPART MAJOR MINOR MICRO)
     foreach(VLINE ${expat_version_str})
       if(VLINE MATCHES "^#[\t ]*define[\t ]+XML_${VPART}_VERSION[\t ]+([0-9]+)$")
         set(EXPAT_VERSION_PART "${CMAKE_MATCH_1}")
-        if(EXPAT_VERSION_STRING)
-          string(APPEND EXPAT_VERSION_STRING ".${EXPAT_VERSION_PART}")
+        if(EXPAT_VERSION)
+          string(APPEND EXPAT_VERSION ".${EXPAT_VERSION_PART}")
         else()
-          set(EXPAT_VERSION_STRING "${EXPAT_VERSION_PART}")
+          set(EXPAT_VERSION "${EXPAT_VERSION_PART}")
         endif()
       endif()
     endforeach()
   endforeach()
+  set(EXPAT_VERSION_STRING ${EXPAT_VERSION})
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(EXPAT
                                   REQUIRED_VARS EXPAT_LIBRARY EXPAT_INCLUDE_DIR
-                                  VERSION_VAR EXPAT_VERSION_STRING)
+                                  VERSION_VAR EXPAT_VERSION)
 
 # Copy the results to the output variables and target.
 if(EXPAT_FOUND)
diff --git a/Modules/FindEnvModules.cmake b/Modules/FindEnvModules.cmake
index 3e7d800..bb19d04 100644
--- a/Modules/FindEnvModules.cmake
+++ b/Modules/FindEnvModules.cmake
@@ -43,7 +43,7 @@
 This module defines the following variables:
 
 ``EnvModules_FOUND``
-  Boolean indicating whether a compatible Environment Modules framework is
+  Boolean indicating whether a compatible Environment Modules framework was
   found.
 
 Cache Variables
diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake
index 11c53a9..c76e052 100644
--- a/Modules/FindFLEX.cmake
+++ b/Modules/FindFLEX.cmake
@@ -10,7 +10,7 @@
 
 .. code-block:: cmake
 
-  find_package(FLEX [<version>] ...)
+  find_package(FLEX [<version>] [...])
 
 Flex generates lexical analyzers, also known as *scanners* or *lexers*.  It also
 includes a runtime library (``fl``) that supplies support functions for the
@@ -23,7 +23,7 @@
 This module defines the following variables:
 
 ``FLEX_FOUND``
-  Boolean indicating whether (the requested version of) Flex is found.
+  Boolean indicating whether (the requested version of) Flex was found.
 
 ``FLEX_VERSION``
   The version of Flex found.
diff --git a/Modules/FindFLTK.cmake b/Modules/FindFLTK.cmake
index 6b3438c..eed585c 100644
--- a/Modules/FindFLTK.cmake
+++ b/Modules/FindFLTK.cmake
@@ -6,7 +6,11 @@
 --------
 
 Finds the Fast Light Toolkit (FLTK), a cross-platform toolkit for GUI
-development.
+development:
+
+.. code-block:: cmake
+
+  find_package(FLTK [...])
 
 FLTK uses CMake-based build system and provides a package configuration file for
 projects to find it.  As of its 1.4.0 version it also provides
@@ -18,8 +22,8 @@
 documentation for more information, how to use FLTK with CMake.
 
 .. versionadded:: 3.11
-  Debug and Release library variants are found separately and use
-  per-configuration variables.
+  Debug and release (optimized) library variants are found separately and use
+  :ref:`per-configuration <Build Configurations>` variables.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -27,7 +31,7 @@
 This module defines the following variables:
 
 ``FLTK_FOUND``
-  Boolean indicating whether FLTK is found.
+  Boolean indicating whether FLTK was found.
 
 ``FLTK_LIBRARIES``
   Libraries needed to link against to use FLTK.
diff --git a/Modules/FindFLTK2.cmake b/Modules/FindFLTK2.cmake
index c839d3f..a276ed8 100644
--- a/Modules/FindFLTK2.cmake
+++ b/Modules/FindFLTK2.cmake
@@ -14,7 +14,11 @@
   modern versions, use the :module:`FindFLTK` module instead.
 
 Finds the Fast Light Toolkit (FLTK) version 2.x, a cross-platform toolkit for
-GUI development.
+GUI development:
+
+.. code-block:: cmake
+
+  find_package(FLTK2 [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -22,7 +26,7 @@
 This module defines the following variables:
 
 ``FLTK2_FOUND``
-  Boolean indicating whether FLTK 2.x is found.
+  Boolean indicating whether FLTK 2.x was found.
 
 ``FLTK2_LIBRARIES``
   Libraries needed to link against to use FLTK 2.x.
diff --git a/Modules/FindFontconfig.cmake b/Modules/FindFontconfig.cmake
index 218ad2f..1e37c7c 100644
--- a/Modules/FindFontconfig.cmake
+++ b/Modules/FindFontconfig.cmake
@@ -7,7 +7,11 @@
 
 .. versionadded:: 3.14
 
-Finds Fontconfig, a library for font configuration and customization.
+Finds Fontconfig, a library for font configuration and customization:
+
+.. code-block:: cmake
+
+  find_package(Fontconfig [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -24,7 +28,7 @@
 This module defines the following variables:
 
 ``Fontconfig_FOUND``
-  Boolean indicating whether the (requested version of) Fontconfig is found.
+  Boolean indicating whether (the requested version of) Fontconfig was found.
 ``Fontconfig_VERSION``
   The version of Fontconfig found.
 ``Fontconfig_LIBRARIES``
@@ -53,7 +57,7 @@
 # use pkg-config to get the directories and then use these values
 # in the find_path() and find_library() calls
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PKG_FONTCONFIG QUIET fontconfig)
 endif()
 set(Fontconfig_COMPILE_OPTIONS ${PKG_FONTCONFIG_CFLAGS_OTHER})
diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake
index 0a4d9a3..436a62a 100644
--- a/Modules/FindFreetype.cmake
+++ b/Modules/FindFreetype.cmake
@@ -5,7 +5,14 @@
 FindFreetype
 ------------
 
-Finds the FreeType font renderer library.
+Finds the FreeType font renderer library:
+
+.. code-block:: cmake
+
+  find_package(Freetype [<version>] [...])
+
+.. versionadded:: 3.7
+  Debug and Release (optimized) library variants are found separately.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -24,9 +31,14 @@
 This module defines the following variables:
 
 ``Freetype_FOUND``
-  Boolean indicating whether the (requested version of) Freetype is found.  For
-  backward compatibility, the ``FREETYPE_FOUND`` variable is also set to the
-  same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Freetype was found.
+
+``Freetype_VERSION``
+  .. versionadded:: 4.2
+
+  The version of Freetype found.
 
 ``FREETYPE_INCLUDE_DIRS``
   Include directories containing headers needed to use Freetype.  This is the
@@ -36,9 +48,6 @@
 ``FREETYPE_LIBRARIES``
   Libraries needed to link against for using Freetype.
 
-``FREETYPE_VERSION_STRING``
-  The version of Freetype found.
-
 .. versionadded:: 3.7
   Debug and Release library variants are found separately.
 
@@ -62,6 +71,23 @@
   The user may set this environment variable to the root directory of a Freetype
   installation to find Freetype in non-standard locations.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``FREETYPE_FOUND``
+  .. deprecated:: 4.2
+    Use ``Freetype_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Freetype was found.
+
+``FREETYPE_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Freetype_VERSION``.
+
+  The version of Freetype found.
+
 Examples
 ^^^^^^^^
 
@@ -170,20 +196,21 @@
   file(STRINGS "${FREETYPE_H}" freetype_version_str
        REGEX "^#[\t ]*define[\t ]+FREETYPE_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
 
-  unset(FREETYPE_VERSION_STRING)
+  unset(Freetype_VERSION)
   foreach(VPART MAJOR MINOR PATCH)
     foreach(VLINE ${freetype_version_str})
       if(VLINE MATCHES "^#[\t ]*define[\t ]+FREETYPE_${VPART}[\t ]+([0-9]+)$")
         set(FREETYPE_VERSION_PART "${CMAKE_MATCH_1}")
-        if(FREETYPE_VERSION_STRING)
-          string(APPEND FREETYPE_VERSION_STRING ".${FREETYPE_VERSION_PART}")
+        if(Freetype_VERSION)
+          string(APPEND Freetype_VERSION ".${FREETYPE_VERSION_PART}")
         else()
-          set(FREETYPE_VERSION_STRING "${FREETYPE_VERSION_PART}")
+          set(Freetype_VERSION "${FREETYPE_VERSION_PART}")
         endif()
         unset(FREETYPE_VERSION_PART)
       endif()
     endforeach()
   endforeach()
+  set(FREETYPE_VERSION_STRING ${Freetype_VERSION})
 endif()
 
 include(FindPackageHandleStandardArgs)
@@ -194,7 +221,7 @@
     FREETYPE_LIBRARY
     FREETYPE_INCLUDE_DIRS
   VERSION_VAR
-    FREETYPE_VERSION_STRING
+    Freetype_VERSION
 )
 
 mark_as_advanced(
diff --git a/Modules/FindGCCXML.cmake b/Modules/FindGCCXML.cmake
index fdab959..cf4a96f 100644
--- a/Modules/FindGCCXML.cmake
+++ b/Modules/FindGCCXML.cmake
@@ -7,14 +7,30 @@
 
 .. versionchanged:: 4.1
   This module is available only if policy :policy:`CMP0188` is not set to ``NEW``.
-  Port projects to search for CastXML by calling ``find_program`` directly.
+  Port projects to search for CastXML by calling :command:`find_program` directly.
 
-Find the GCC-XML front-end executable.
+Finds the GCC-XML front-end executable:
 
-This module will define the following variables:
+.. code-block:: cmake
+
+  find_package(GCCXML [...])
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
 
 ``GCCXML``
   The GCC-XML front-end executable.
+
+Examples
+^^^^^^^^
+
+In new code, find CastXML with :command:`find_program` instead:
+
+.. code-block:: cmake
+
+  find_program(CASTXML_EXECUTABLE castxml)
 #]=======================================================================]
 
 cmake_policy(GET CMP0188 _FindGCCXML_CMP0188)
diff --git a/Modules/FindGDAL.cmake b/Modules/FindGDAL.cmake
index b952949..71883da 100644
--- a/Modules/FindGDAL.cmake
+++ b/Modules/FindGDAL.cmake
@@ -5,61 +5,86 @@
 FindGDAL
 --------
 
-Find Geospatial Data Abstraction Library (GDAL).
-
 .. deprecated:: 4.0
   GDAL 3.5 and above provide a ``GDALConfig.cmake`` package configuration file.
   Call ``find_package(GDAL CONFIG)`` to find it directly and avoid using this
   find module.  For further details, see `GDAL's documentation on CMake
   integration <https://gdal.org/en/latest/development/cmake.html>`_.
 
+Finds Geospatial Data Abstraction Library (GDAL):
+
+.. code-block:: cmake
+
+  find_package(GDAL [<version>] [...])
+
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.14
+This module provides the following :ref:`Imported Targets`:
 
-This module defines :prop_tgt:`IMPORTED` target ``GDAL::GDAL``
-if GDAL has been found.
+``GDAL::GDAL``
+  .. versionadded:: 3.14
+
+  Target encapsulating the GDAL usage requirements, available only if GDAL
+  has been found.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in your project:
+This module defines the following variables:
 
 ``GDAL_FOUND``
-  True if GDAL is found.
-``GDAL_INCLUDE_DIRS``
-  Include directories for GDAL headers.
-``GDAL_LIBRARIES``
-  Libraries to link to GDAL.
+  Boolean indicating whether (the requested version of) GDAL was found.
+
 ``GDAL_VERSION``
   .. versionadded:: 3.14
-    The version of GDAL found.
 
-Cache variables
+  The version of GDAL found.
+
+``GDAL_INCLUDE_DIRS``
+  Include directories for GDAL headers.
+
+``GDAL_LIBRARIES``
+  Libraries to link to GDAL.
+
+Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
+``GDAL_INCLUDE_DIR``
+  The directory containing ``<gdal.h>``.
+
 ``GDAL_LIBRARY``
   The libgdal library file.
-``GDAL_INCLUDE_DIR``
-  The directory containing ``gdal.h``.
 
 Hints
 ^^^^^
 
-Set ``GDAL_DIR`` or ``GDAL_ROOT`` in the environment to specify the
-GDAL installation prefix.
-
 The following variables may be set to modify the search strategy:
 
+``GDAL_DIR`` or ``GDAL_ROOT``
+  Set one of these environment variables to specify the GDAL installation
+  prefix.
+
 ``FindGDAL_SKIP_GDAL_CONFIG``
-  If set, ``gdal-config`` will not be used. This can be useful if there are
+  If set, ``gdal-config`` will not be used.  This can be useful if there are
   GDAL libraries built with autotools (which provide the tool) and CMake (which
   do not) in the same environment.
+
 ``GDAL_ADDITIONAL_LIBRARY_VERSIONS``
   Extra versions of library names to search for.
+
+Examples
+^^^^^^^^
+
+Finding GDAL in config mode without using this module and linking its
+imported target to a project target:
+
+.. code-block:: cmake
+
+  find_package(GDAL CONFIG)
+  target_link_libraries(example PRIVATE GDAL::GDAL)
 #]=======================================================================]
 
 # $GDALDIR is an environment variable that would
diff --git a/Modules/FindGIF.cmake b/Modules/FindGIF.cmake
index 585b846..7005954 100644
--- a/Modules/FindGIF.cmake
+++ b/Modules/FindGIF.cmake
@@ -5,7 +5,11 @@
 FindGIF
 -------
 
-Finds the Graphics Interchange Format (GIF) library (``giflib``).
+Finds the Graphics Interchange Format (GIF) library (``giflib``):
+
+.. code-block:: cmake
+
+  find_package(GIF [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -21,19 +25,22 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``GIF_FOUND``
-  Boolean indicating whether the GIF library was found.
-``GIF_INCLUDE_DIRS``
-  Include directories needed to use the GIF library.
-``GIF_LIBRARIES``
-  Libraries needed to link to the GIF library.
+  Boolean indicating whether the (requested version of) GIF library was found.
+
 ``GIF_VERSION``
   Version string of the GIF library found (for example, ``5.1.4``).  For GIF
   library versions prior to 4.1.6, version string will be set only to ``3`` or
   ``4`` as these versions did not provide version information in their headers.
 
+``GIF_INCLUDE_DIRS``
+  Include directories needed to use the GIF library.
+
+``GIF_LIBRARIES``
+  Libraries needed to link to the GIF library.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -41,6 +48,7 @@
 
 ``GIF_INCLUDE_DIR``
   Directory containing the ``gif_lib.h`` and other GIF library headers.
+
 ``GIF_LIBRARY``
   Path to the GIF library.
 
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index 03d19bf..644b332 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -5,7 +5,11 @@
 FindGLEW
 --------
 
-Finds the OpenGL Extension Wrangler Library (GLEW).
+Finds the OpenGL Extension Wrangler Library (GLEW):
+
+.. code-block:: cmake
+
+  find_package(GLEW [<version>] [...])
 
 GLEW is a cross-platform C/C++ library that helps manage OpenGL extensions by
 providing efficient run-time mechanisms to query and load OpenGL functionality
@@ -53,7 +57,7 @@
 This module defines the following variables:
 
 ``GLEW_FOUND``
-  Boolean indicating whether GLEW is found.
+  Boolean indicating whether (the requested version of) GLEW was found.
 
 ``GLEW_VERSION``
   .. versionadded:: 3.15
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
index e29758d..dcb0359 100644
--- a/Modules/FindGLUT.cmake
+++ b/Modules/FindGLUT.cmake
@@ -5,8 +5,13 @@
 FindGLUT
 --------
 
-Finds the OpenGL Utility Toolkit (GLUT) library, which provides a simple API for
-creating windows, handling input, and managing events in OpenGL applications.
+Finds the OpenGL Utility Toolkit (GLUT) library, which provides a simple API
+for creating windows, handling input, and managing events in OpenGL
+applications:
+
+.. code-block:: cmake
+
+  find_package(GLUT [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -24,7 +29,7 @@
 This module defines the following variables:
 
 ``GLUT_FOUND``
-  Boolean indicating whether GLUT is found.
+  Boolean indicating whether GLUT was found.
 
 ``GLUT_INCLUDE_DIRS``
   .. versionadded:: 3.23
@@ -72,7 +77,7 @@
 include(FindPackageHandleStandardArgs)
 
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_GLUT QUIET glut)
   if(NOT PC_GLUT_FOUND)
     pkg_check_modules(PC_GLUT QUIET freeglut)
diff --git a/Modules/FindGSL.cmake b/Modules/FindGSL.cmake
index a3cd654..041e9d1 100644
--- a/Modules/FindGSL.cmake
+++ b/Modules/FindGSL.cmake
@@ -7,7 +7,11 @@
 
 .. versionadded:: 3.2
 
-Finds the native GNU Scientific Library (GSL) includes and libraries.
+Finds the native GNU Scientific Library (GSL) includes and libraries:
+
+.. code-block:: cmake
+
+  find_package(GSL [<version>] [...])
 
 The GNU Scientific Library (GSL) is a numerical library for C and C++
 programmers. It is free software under the GNU General Public
@@ -16,43 +20,31 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-If GSL is found, this module defines the following :ref:`Imported Targets`:
+This module provides the following :ref:`Imported Targets`:
 
 ``GSL::gsl``
-  The main GSL library that provides all usage requirements to use GSL.
+  Target encapsulating the main GSL library and all usage requirements,
+  available only if GSL is found.
+
 ``GSL::gslcblas``
-  The CBLAS support library used by GSL.  It is linked also into the
-  ``GSL::gsl`` target but provided separately for granularity.
+  Target encapsulating the usage requirements of the CBLAS support library
+  used by GSL.  This target is available if GSL is found.  It is linked also
+  into the ``GSL::gsl`` target but provided separately for granularity.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in the project:
+This module defines the following variables:
 
 ``GSL_FOUND``
-  True if GSL is found on the local system.
+  Boolean indicating whether (the requested version of) GSL was found on the
+  local system.
+``GSL_VERSION``
+  The version of the discovered GSL installation.
 ``GSL_INCLUDE_DIRS``
   Directory containing GSL header files.
 ``GSL_LIBRARIES``
   The GSL libraries.
-``GSL_VERSION``
-  The version of the discovered GSL installation.
-
-Hints
-^^^^^
-
-``GSL_ROOT_DIR``
-  Set this variable to a directory that contains a GSL installation.
-
-  If this variable is not set, this module will use pkg-config and default paths
-  to find GSL.  If this variable is provided, then this module expects to find
-  libraries at ``${GSL_ROOT_DIR}/lib`` and the GSL headers at
-  ``${GSL_ROOT_DIR}/include/gsl``.
-
-  The library directory may optionally provide Release and Debug folders.  If
-  available, the libraries named ``gsld``, ``gslblasd`` or ``cblasd`` are
-  recognized as debug libraries.  For Unix-like systems, this module will also
-  use ``gsl-config`` (if found) to aid in the discovery of GSL.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -72,6 +64,24 @@
 ``GSL_LIBRARY_DEBUG``
   Location of the debug GSL library (if any).
 
+Hints
+^^^^^
+
+This module accepts the following variables:
+
+``GSL_ROOT_DIR``
+  Set this variable to a directory that contains a GSL installation.
+
+  If this variable is not set, this module will use pkg-config and default paths
+  to find GSL.  If this variable is provided, then this module expects to find
+  libraries at ``${GSL_ROOT_DIR}/lib`` and the GSL headers at
+  ``${GSL_ROOT_DIR}/include/gsl``.
+
+  The library directory may optionally provide Release and Debug folders.  If
+  available, the libraries named ``gsld``, ``gslblasd`` or ``cblasd`` are
+  recognized as debug libraries.  For Unix-like systems, this module will also
+  use ``gsl-config`` (if found) to aid in the discovery of GSL.
+
 Examples
 ^^^^^^^^
 
@@ -105,7 +115,7 @@
 # This will return ``GSL_INCLUDEDIR`` and ``GSL_LIBDIR`` used below.
 if( GSL_USE_PKGCONFIG )
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules( GSL QUIET gsl )
     if( EXISTS "${GSL_INCLUDEDIR}" )
       get_filename_component( GSL_ROOT_DIR "${GSL_INCLUDEDIR}" DIRECTORY CACHE)
@@ -174,8 +184,6 @@
 endif()
 
 #=============================================================================
-# handle the QUIETLY and REQUIRED arguments and set GSL_FOUND to TRUE if all
-# listed variables are TRUE
 find_package_handle_standard_args( GSL
   REQUIRED_VARS
     GSL_INCLUDE_DIR
diff --git a/Modules/FindGTK.cmake b/Modules/FindGTK.cmake
index 6e39f5a..87325e2 100644
--- a/Modules/FindGTK.cmake
+++ b/Modules/FindGTK.cmake
@@ -5,10 +5,6 @@
 FindGTK
 -------
 
-Finds GTK, glib and GTKGLArea.
-
-GTK is a multi-platform toolkit for creating graphical user interfaces.
-
 .. note::
 
   This module works only on Unix-like systems and was intended for early GTK
@@ -22,15 +18,23 @@
     pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
     target_link_libraries(example PRIVATE PkgConfig::GTK)
 
+Finds GTK, glib and GTKGLArea:
+
+.. code-block:: cmake
+
+  find_package(GTK [...])
+
+GTK is a multi-platform toolkit for creating graphical user interfaces.
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
 This module defines the following variables:
 
 ``GTK_FOUND``
-  Boolean indicating whether GTK is found.
+  Boolean indicating whether GTK was found.
 ``GTK_GL_FOUND``
-  Boolean indicating whether GTK's GL features are found.
+  Boolean indicating whether GTK's GL features were found.
 ``GTK_INCLUDE_DIR``
   Include directories containing headers needed to use GTK.
 ``GTK_LIBRARIES``
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 9c5bc63..2cbb3a6 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -5,14 +5,10 @@
 FindGTK2
 --------
 
-Finds the GTK widget libraries and several of its other optional components.
-
-GTK is a multi-platform toolkit for creating graphical user interfaces.
-
 .. note::
 
-  This module is specifically for GTK version 2.x, which is obsolete and no
-  longer maintained.  Use the latest supported GTK version and
+  This module is intended specifically for GTK version 2.x, which is obsolete
+  and no longer maintained.  Use the latest supported GTK version and
   :module:`FindPkgConfig` module to find GTK in CMake instead of this module.
   For example:
 
@@ -22,6 +18,14 @@
     pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
     target_link_libraries(example PRIVATE PkgConfig::GTK)
 
+Finds the GTK widget libraries and several of its other optional components:
+
+.. code-block:: cmake
+
+  find_package(GTK2 [<version>] [COMPONENTS <components>...] [...])
+
+GTK is a multi-platform toolkit for creating graphical user interfaces.
+
 Components
 ^^^^^^^^^^
 
@@ -93,7 +97,8 @@
 This module defines the following variables:
 
 ``GTK2_FOUND``
-  Boolean indicating whether GTK and all specified components are found.
+  Boolean indicating whether (the requested version of) GTK 2 and all
+  specified components were found.
 ``GTK2_VERSION``
   The version of GTK found (x.y.z).
 ``GTK2_MAJOR_VERSION``
@@ -703,7 +708,7 @@
 # used to compute the arch-specific include prefixes. While at it,
 # also retrieve their INCLUDEDIR, to accommodate non-standard layouts.
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_GTK2 QUIET gtk+-2.0)
   if(PC_GTK2_FOUND)
     pkg_get_variable(PC_GTK2_INCLUDEDIR gtk+-2.0 includedir)
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index 3043768..f8fda89 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -78,7 +78,9 @@
 This module defines the following variables:
 
 ``GTest_FOUND``
-  Boolean indicating whether GoogleTest is found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether GoogleTest was found.
 
 Hints
 ^^^^^
@@ -150,6 +152,12 @@
   Result variable providing both ``gtest`` and ``gtest_main`` libraries
   combined.
 
+``GTEST_FOUND``
+  .. deprecated:: 4.2
+    Use ``GTest_FOUND``, which has the same value.
+
+  Boolean indicating whether GoogleTest was found.
+
 Deprecated Imported Targets
 """""""""""""""""""""""""""
 
diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake
index 71d41e0..347d30d 100644
--- a/Modules/FindGettext.cmake
+++ b/Modules/FindGettext.cmake
@@ -10,7 +10,7 @@
 
 .. code-block:: cmake
 
-  find_package(Gettext [<version>] ...)
+  find_package(Gettext [<version>] [...])
 
 GNU gettext is a system for internationalization (i18n) and localization
 (l10n), consisting of command-line tools and a runtime library (``libintl``).
@@ -36,11 +36,13 @@
 This module defines the following variables:
 
 ``Gettext_FOUND``
-  Boolean indicating whether (the requested version of) gettext is found.  For
-  backward compatibility, the ``GETTEXT_FOUND`` variable is also set to the same
-  value.
+  .. versionadded:: 3.3
 
-``GETTEXT_VERSION_STRING``
+  Boolean indicating whether (the requested version of) gettext was found.
+
+``Gettext_VERSION``
+  .. versionadded:: 4.2
+
   The version of gettext found.
 
 Cache Variables
@@ -194,6 +196,23 @@
     For better control over build and installation behavior, use
     :command:`gettext_process_po_files` instead.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``GETTEXT_FOUND``
+  .. deprecated:: 4.2
+    Use ``Gettext_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) gettext was found.
+
+``GETTEXT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Gettext_VERSION``.
+
+  The version of gettext found.
+
 Examples
 ^^^^^^^^
 
@@ -398,7 +417,8 @@
   get_filename_component(msgmerge_name ${GETTEXT_MSGMERGE_EXECUTABLE} NAME)
   get_filename_component(msgmerge_namewe ${GETTEXT_MSGMERGE_EXECUTABLE} NAME_WE)
   if(gettext_version MATCHES "^(${msgmerge_name}|${msgmerge_namewe}) \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
-    set(GETTEXT_VERSION_STRING "${CMAKE_MATCH_2}")
+    set(Gettext_VERSION "${CMAKE_MATCH_2}")
+    set(GETTEXT_VERSION_STRING "${Gettext_VERSION}")
   endif()
   unset(gettext_version)
   unset(msgmerge_name)
@@ -408,7 +428,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Gettext
                                   REQUIRED_VARS GETTEXT_MSGMERGE_EXECUTABLE GETTEXT_MSGFMT_EXECUTABLE
-                                  VERSION_VAR GETTEXT_VERSION_STRING)
+                                  VERSION_VAR Gettext_VERSION)
 
 function(_GETTEXT_GET_UNIQUE_TARGET_NAME _name _unique_name)
   set(propertyName "_GETTEXT_UNIQUE_COUNTER_${_name}")
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake
index 2b6187e..978746b 100644
--- a/Modules/FindGit.cmake
+++ b/Modules/FindGit.cmake
@@ -5,7 +5,11 @@
 FindGit
 -------
 
-Finds the Git distributed version control system.
+Finds the Git distributed version control system:
+
+.. code-block:: cmake
+
+  find_package(Git [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -27,9 +31,13 @@
 This module defines the following variables:
 
 ``Git_FOUND``
-  Boolean indicating whether the Git was found.  For backward compatibility, the
-  ``GIT_FOUND`` variable is also set to the same value.
-``GIT_VERSION_STRING``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Git was found.
+
+``Git_VERSION``
+  .. versionadded:: 4.2
+
   The version of Git found.
 
 Cache Variables
@@ -40,6 +48,23 @@
 ``GIT_EXECUTABLE``
   Path to the ``git`` command-line client executable.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``GIT_FOUND``
+  .. deprecated:: 4.2
+    Use ``Git_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Git was found.
+
+``GIT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Git_VERSION``, which has the same value.
+
+  The version of Git found.
+
 Examples
 ^^^^^^^^
 
@@ -124,7 +149,8 @@
     list(GET __gitVersionProp 0 __gitExe)
     list(GET __gitVersionProp 1 __gitVersion)
     if(__gitExe STREQUAL GIT_EXECUTABLE AND NOT __gitVersion STREQUAL "")
-      set(GIT_VERSION_STRING "${__gitVersion}")
+      set(Git_VERSION "${__gitVersion}")
+      set(GIT_VERSION_STRING "${Git_VERSION}")
       set(__doGitVersionCheck FALSE)
     endif()
     unset(__gitExe)
@@ -138,9 +164,10 @@
                     ERROR_QUIET
                     OUTPUT_STRIP_TRAILING_WHITESPACE)
     if (git_version MATCHES "^git version [0-9]")
-      string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}")
+      string(REPLACE "git version " "" Git_VERSION "${git_version}")
+      set(GIT_VERSION_STRING "${Git_VERSION}")
       set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
-        "${GIT_EXECUTABLE};${GIT_VERSION_STRING}"
+        "${GIT_EXECUTABLE};${Git_VERSION}"
       )
     endif()
     unset(git_version)
@@ -158,4 +185,4 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Git
                                   REQUIRED_VARS GIT_EXECUTABLE
-                                  VERSION_VAR GIT_VERSION_STRING)
+                                  VERSION_VAR Git_VERSION)
diff --git a/Modules/FindGnuTLS.cmake b/Modules/FindGnuTLS.cmake
index d9d8260..a0c2c85 100644
--- a/Modules/FindGnuTLS.cmake
+++ b/Modules/FindGnuTLS.cmake
@@ -5,12 +5,17 @@
 FindGnuTLS
 ----------
 
-Finds the GNU Transport Layer Security library (GnuTLS).  The GnuTLS
-package includes the main libraries (libgnutls and libdane), as well as the
-optional gnutls-openssl compatibility extra library.  They are all distributed
-as part of the same release.  This module checks for the presence of the main
-libgnutls library and provides usage requirements for integrating GnuTLS into
-CMake projects.
+Finds the GNU Transport Layer Security library (GnuTLS):
+
+.. code-block:: cmake
+
+  find_package(GnuTLS [<version>] [...])
+
+The GnuTLS package includes the main libraries (libgnutls and libdane), as
+well as the optional gnutls-openssl compatibility extra library.  They are
+all distributed as part of the same release.  This module checks for the
+presence of the main libgnutls library and provides usage requirements for
+integrating GnuTLS into CMake projects.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -29,12 +34,12 @@
 This module defines the following variables:
 
 ``GnuTLS_FOUND``
-  Boolean indicating whether the (requested version of) GnuTLS is found.  For
-  backward compatibility, the ``GNUTLS_FOUND`` variable is also set to the same
-  value.
+  .. versionadded:: 3.3
 
-``GNUTLS_VERSION``
-  .. versionadded:: 3.16
+  Boolean indicating whether (the requested version of) GnuTLS was found.
+
+``GnuTLS_VERSION``
+  .. versionadded:: 4.2
 
   The version of GnuTLS found.
 
@@ -61,13 +66,22 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-These variables are provided for backward compatibility:
+The following variables are provided for backward compatibility:
+
+``GNUTLS_FOUND``
+  .. deprecated:: 4.2
+    Use ``GnuTLS_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) GnuTLS was found.
 
 ``GNUTLS_VERSION_STRING``
   .. deprecated:: 3.16
-    Superseded by ``GNUTLS_VERSION``.
+    Use the ``GnuTLS_VERSION``, which has the same value.
 
-  The version of GnuTLS found.
+``GNUTLS_VERSION``
+  .. versionadded:: 3.16
+  .. deprecated:: 4.2
+    Use the ``GnuTLS_VERSION``, which has the same value.
 
 Examples
 ^^^^^^^^
@@ -80,6 +94,9 @@
   target_link_libraries(project_target PRIVATE GnuTLS::GnuTLS)
 #]=======================================================================]
 
+cmake_policy(PUSH)
+cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
+
 if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY)
   # in cache already
   set(gnutls_FIND_QUIETLY TRUE)
@@ -90,13 +107,10 @@
   # in the find_path() and find_library() calls
   # also fills in GNUTLS_DEFINITIONS, although that isn't normally useful
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(PC_GNUTLS QUIET gnutls)
   endif()
   set(GNUTLS_DEFINITIONS ${PC_GNUTLS_CFLAGS_OTHER})
-  set(GNUTLS_VERSION ${PC_GNUTLS_VERSION})
-  # keep for backward compatibility
-  set(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION})
 endif ()
 
 find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h
@@ -113,10 +127,43 @@
 
 mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY)
 
+if(GNUTLS_INCLUDE_DIR AND EXISTS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h")
+  file(
+    STRINGS
+    "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h"
+    gnutls_version
+    # GnuTLS versions prior to 2.7.2 defined LIBGNUTLS_VERSION instead of the
+    # current GNUTLS_VERSION.
+    REGEX "^#define[\t ]+(LIB)?GNUTLS_VERSION[\t ]+\".*\""
+  )
+
+  string(
+    REGEX REPLACE
+    "^.*GNUTLS_VERSION[\t ]+\"([^\"]*)\".*$"
+    "\\1"
+    GnuTLS_VERSION
+    "${gnutls_version}"
+  )
+  unset(gnutls_version)
+
+  # Fallback to version defined by pkg-config if not successful.
+  if(
+    NOT GnuTLS_VERSION
+    AND PC_GNUTLS_VERSION
+    AND GNUTLS_INCLUDE_DIR IN_LIST PC_GNUTLS_INCLUDE_DIRS
+  )
+    set(GnuTLS_VERSION "${PC_GNUTLS_VERSION}")
+  endif()
+
+  # For backward compatibility.
+  set(GNUTLS_VERSION "${GnuTLS_VERSION}")
+  set(GNUTLS_VERSION_STRING "${GnuTLS_VERSION}")
+endif()
+
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(GnuTLS
                                   REQUIRED_VARS GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR
-                                  VERSION_VAR GNUTLS_VERSION_STRING)
+                                  VERSION_VAR GnuTLS_VERSION)
 
 if(GnuTLS_FOUND)
   set(GNUTLS_LIBRARIES    ${GNUTLS_LIBRARY})
@@ -131,3 +178,5 @@
       IMPORTED_LOCATION "${GNUTLS_LIBRARIES}")
   endif()
 endif()
+
+cmake_policy(POP)
diff --git a/Modules/FindGnuplot.cmake b/Modules/FindGnuplot.cmake
index abbb681..f5bf309 100644
--- a/Modules/FindGnuplot.cmake
+++ b/Modules/FindGnuplot.cmake
@@ -6,18 +6,25 @@
 -----------
 
 Finds the Gnuplot command-line graphing utility for generating two- and
-three-dimensional plots (``gnuplot``).
+three-dimensional plots (``gnuplot``):
+
+.. code-block:: cmake
+
+  find_package(Gnuplot [<version>] [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``Gnuplot_FOUND``
-  Boolean indicating whether Gnuplot has been found.  For backward
-  compatibility, the ``GNUPLOT_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
 
-``GNUPLOT_VERSION_STRING``
+  Boolean indicating whether (the requested version of) Gnuplot was found.
+
+``Gnuplot_VERSION``
+  .. versionadded:: 4.2
+
   The version of Gnuplot found.
 
   .. note::
@@ -33,14 +40,34 @@
 ``GNUPLOT_EXECUTABLE``
   Absolute path to the ``gnuplot`` executable.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``GNUPLOT_FOUND``
+  .. deprecated:: 4.2
+    Use ``Gnuplot_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Gnuplot was found.
+
+``GNUPLOT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Gnuplot_VERSION``.
+
+  The version of Gnuplot found.
+
 Examples
 ^^^^^^^^
 
-Finding Gnuplot:
+Finding Gnuplot and executing it in a process:
 
 .. code-block:: cmake
 
   find_package(Gnuplot)
+  if(Gnuplot_FOUND)
+    execute_process(COMMAND ${GNUPLOT_EXECUTABLE} --help)
+  endif()
 #]=======================================================================]
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
@@ -62,8 +89,9 @@
                   ERROR_QUIET
                   OUTPUT_STRIP_TRAILING_WHITESPACE)
 
-    string(REGEX REPLACE "^gnuplot ([0-9\\.]+)( patchlevel )?" "\\1." GNUPLOT_VERSION_STRING "${GNUPLOT_OUTPUT_VARIABLE}")
-    string(REGEX REPLACE "\\.$" "" GNUPLOT_VERSION_STRING "${GNUPLOT_VERSION_STRING}")
+    string(REGEX REPLACE "^gnuplot ([0-9\\.]+)( patchlevel )?" "\\1." Gnuplot_VERSION "${GNUPLOT_OUTPUT_VARIABLE}")
+    string(REGEX REPLACE "\\.$" "" Gnuplot_VERSION "${Gnuplot_VERSION}")
+    set(GNUPLOT_VERSION_STRING "${Gnuplot_VERSION}")
     unset(GNUPLOT_OUTPUT_VARIABLE)
 endif()
 
@@ -73,6 +101,6 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Gnuplot
                                   REQUIRED_VARS GNUPLOT_EXECUTABLE
-                                  VERSION_VAR GNUPLOT_VERSION_STRING)
+                                  VERSION_VAR Gnuplot_VERSION)
 
 mark_as_advanced( GNUPLOT_EXECUTABLE )
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index a49e994..380b9fa 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -10,7 +10,7 @@
 
 .. code-block:: cmake
 
-  find_package(HDF5 [<version>] ... [COMPONENTS <components>...] ...)
+  find_package(HDF5 [<version>] [COMPONENTS <components>...] [...])
 
 If the HDF5 library is built using its CMake-based build system, it will as
 of HDF5 version 1.8.15 provide its own CMake Package Configuration file
@@ -71,8 +71,9 @@
 ``HDF5::HDF5``
   .. versionadded:: 3.19
 
-  Target encapsulating the usage requirements for all found HDF5 libraries
-  (``HDF5_LIBRARIES``), available if HDF5 and all required components are found.
+  Target encapsulating the usage requirements for all found HDF5 binding
+  libraries (``HDF5_LIBRARIES``), available if HDF5 and all required components
+  are found.
 
 ``hdf5::hdf5``
   .. versionadded:: 3.19
@@ -126,7 +127,7 @@
 This module defines the following variables:
 
 ``HDF5_FOUND``
-  Boolean indicating whether (the requested version of) HDF5 is found.
+  Boolean indicating whether (the requested version of) HDF5 was found.
 
 ``HDF5_VERSION``
   .. versionadded:: 3.3
diff --git a/Modules/FindHSPELL.cmake b/Modules/FindHSPELL.cmake
index f326f33..d759216 100644
--- a/Modules/FindHSPELL.cmake
+++ b/Modules/FindHSPELL.cmake
@@ -5,7 +5,11 @@
 FindHSPELL
 ----------
 
-Finds Hebrew spell-checker (Hspell) and morphology engine.
+Finds the Hebrew spell-checker and morphology engine (Hspell):
+
+.. code-block:: cmake
+
+  find_package(HSPELL [<version>] [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -13,13 +17,18 @@
 This module defines the following variables:
 
 ``HSPELL_FOUND``
-  Boolean indicating whether the Hspell is found.
-``HSPELL_VERSION_STRING``
+  Boolean indicating whether (the requested version of) Hspell was found.
+
+``HSPELL_VERSION``
+  .. versionadded:: 4.2
+
   The version of Hspell found (x.y).
-``HSPELL_MAJOR_VERSION``
-  The major version of Hspell.
-``HSPELL_MINOR_VERSION``
-  The minor version of Hspell.
+
+``HSPELL_VERSION_MAJOR``
+  The major version of Hspell found.
+
+``HSPELL_VERSION_MINOR``
+  The minor version of Hspell found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -28,9 +37,21 @@
 
 ``HSPELL_INCLUDE_DIR``
   The Hspell include directory.
+
 ``HSPELL_LIBRARIES``
   The libraries needed to use Hspell.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``HSPELL_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``HSPELL_VERSION``, which has the same value.
+
+  The version of Hspell found (x.y).
+
 Examples
 ^^^^^^^^
 
@@ -52,14 +73,15 @@
     file(STRINGS "${HSPELL_INCLUDE_DIR}/hspell.h" HSPELL_H REGEX "#define HSPELL_VERSION_M(AJO|INO)R [0-9]+")
     string(REGEX REPLACE ".*#define HSPELL_VERSION_MAJOR ([0-9]+).*" "\\1" HSPELL_VERSION_MAJOR "${HSPELL_H}")
     string(REGEX REPLACE ".*#define HSPELL_VERSION_MINOR ([0-9]+).*" "\\1" HSPELL_VERSION_MINOR "${HSPELL_H}")
-    set(HSPELL_VERSION_STRING "${HSPELL_VERSION_MAJOR}.${HSPELL_VERSION_MINOR}")
+    set(HSPELL_VERSION "${HSPELL_VERSION_MAJOR}.${HSPELL_VERSION_MINOR}")
+    set(HSPELL_VERSION_STRING "${HSPELL_VERSION}")
     unset(HSPELL_H)
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(HSPELL
                                   REQUIRED_VARS HSPELL_LIBRARIES HSPELL_INCLUDE_DIR
-                                  VERSION_VAR HSPELL_VERSION_STRING)
+                                  VERSION_VAR HSPELL_VERSION)
 
 mark_as_advanced(HSPELL_INCLUDE_DIR HSPELL_LIBRARIES)
 
diff --git a/Modules/FindHTMLHelp.cmake b/Modules/FindHTMLHelp.cmake
index 76b3dcf..cb9b62c 100644
--- a/Modules/FindHTMLHelp.cmake
+++ b/Modules/FindHTMLHelp.cmake
@@ -5,8 +5,12 @@
 FindHTMLHelp
 ------------
 
-This module finds the Microsoft HTML Help Compiler and its API.  It is part of
-the HTML Help Workshop.
+Finds the Microsoft HTML Help Compiler and its API which is part of the HTML
+Help Workshop:
+
+.. code-block:: cmake
+
+  find_package(HTMLHelp [...])
 
 .. note::
 
@@ -14,10 +18,20 @@
   For modern documentation, consider alternatives such as Microsoft Help Viewer
   for producing ``.mshc`` files or web-based documentation tools.
 
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``HTMLHelp_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether HTML Help was found.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-This module may set the following cache variables:
+The following cache variables may also be set:
 
 ``HTML_HELP_COMPILER``
   Full path to the HTML Help Compiler (``hhc.exe``), used to compile ``.chm``
@@ -74,3 +88,9 @@
     )
 
 endif()
+
+if(HTML_HELP_COMPILER AND HTML_HELP_INCLUDE_PATH AND HTML_HELP_LIBRARY)
+  set(HTMLHelp_FOUND TRUE)
+else()
+  set(HTMLHelp_FOUND FALSE)
+endif()
diff --git a/Modules/FindHg.cmake b/Modules/FindHg.cmake
index f4f3074..06fe7dc 100644
--- a/Modules/FindHg.cmake
+++ b/Modules/FindHg.cmake
@@ -18,11 +18,14 @@
 This module defines the following variables:
 
 ``Hg_FOUND``
-  Boolean indicating whether (the requested version of) Mercurial client is
-  found.  For backward compatibility, the ``HG_FOUND`` variable is also set
-  to the same value.
+  .. versionadded:: 3.3
 
-``HG_VERSION_STRING``
+  Boolean indicating whether the (requested version of) Mercurial client was
+  found.
+
+``Hg_VERSION``
+  .. versionadded:: 4.2
+
   The version of Mercurial found.
 
 Cache Variables
@@ -58,6 +61,24 @@
   ``<var-prefix>_WC_REVISION``
     Current revision.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``HG_FOUND``
+  .. deprecated:: 4.2
+    Use ``Hg_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Mercurial client was
+  found.
+
+``HG_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Hg_VERSION``, which has the same value.
+
+  The version of Mercurial found.
+
 Examples
 ^^^^^^^^
 
@@ -103,7 +124,8 @@
     set_property(CACHE HG_EXECUTABLE PROPERTY VALUE "HG_EXECUTABLE-NOTFOUND")
   endif()
   if(hg_version MATCHES "^Mercurial Distributed SCM \\(version ([0-9][^)]*)\\)")
-    set(HG_VERSION_STRING "${CMAKE_MATCH_1}")
+    set(Hg_VERSION "${CMAKE_MATCH_1}")
+    set(HG_VERSION_STRING "${Hg_VERSION}")
   endif()
   unset(hg_version)
 
@@ -126,4 +148,4 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Hg
                                   REQUIRED_VARS HG_EXECUTABLE
-                                  VERSION_VAR HG_VERSION_STRING)
+                                  VERSION_VAR Hg_VERSION)
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index 942a0ae..97d766d 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -7,7 +7,11 @@
 
 .. versionadded:: 3.7
 
-Finds the International Components for Unicode (ICU) libraries and programs.
+Finds the International Components for Unicode (ICU) libraries and programs:
+
+.. code-block:: cmake
+
+  find_package(ICU [<version>] COMPONENTS <components>... [...])
 
 .. versionadded:: 3.11
   Support for static libraries on Windows.
@@ -15,7 +19,13 @@
 Components
 ^^^^^^^^^^
 
-This module supports the following components:
+This module supports components, which can be specified with:
+
+.. code-block:: cmake
+
+  find_package(ICU COMPONENTS <components>...)
+
+The following components are supported:
 
 ``data``
   Finds the ICU Data library.  On Windows, this library component is named
@@ -49,12 +59,8 @@
   all other ICU libraries and is recommended to include when working with ICU
   components.
 
-At least one component should be specified for this module to successfully find
-ICU:
-
-.. code-block:: cmake
-
-  find_package(ICU COMPONENTS <components>...)
+At least one component should be specified for this module to successfully
+find ICU.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -74,13 +80,14 @@
 This module defines the following variables:
 
 ``ICU_FOUND``
-  Boolean indicating whether the main programs and libraries were found.
+  Boolean indicating whether the (requested version of) main ICU programs
+  and libraries were found.
+``ICU_VERSION``
+  The version of the ICU release found.
 ``ICU_INCLUDE_DIRS``
   The include directories containing the ICU headers.
 ``ICU_LIBRARIES``
   Component libraries to be linked.
-``ICU_VERSION``
-  The version of the ICU release found.
 
 ICU programs are defined in the following variables:
 
diff --git a/Modules/FindIce.cmake b/Modules/FindIce.cmake
index 8215674..a0be791 100644
--- a/Modules/FindIce.cmake
+++ b/Modules/FindIce.cmake
@@ -7,7 +7,12 @@
 
 .. versionadded:: 3.1
 
-Finds the Internet Communication Engine (Ice) programs, libraries and datafiles.
+Finds the Internet Communication Engine (Ice) programs, libraries and datafiles:
+
+.. code-block:: cmake
+
+  find_package(Ice [<version>] COMPONENTS <components>... [...])
+
 Ice is an open-source remote procedure call (RPC) framework developed by ZeroC
 and provides SDKs for various languages to develop network applications.
 
@@ -88,8 +93,8 @@
 This module defines the following variables:
 
 ``Ice_FOUND``
-  Boolean indicating whether the main programs, libraries and all requested
-  components for using Ice were found.
+  Boolean indicating whether the (requested version of) main programs,
+  libraries and all requested components for using Ice were found.
 
 ``Ice_VERSION``
   The version of Ice release found.
@@ -107,7 +112,7 @@
 Ice component libraries are stored in:
 
 ``Ice_<COMPONENT>_FOUND``
-  Boolean indicating whether the specified Ice component is found.  The
+  Boolean indicating whether the specified Ice component was found.  The
   ``<COMPONENT>`` should be written in uppercase.
 
 ``Ice_<COMPONENT>_LIBRARIES``
diff --git a/Modules/FindIconv.cmake b/Modules/FindIconv.cmake
index a11d746..d49c2db 100644
--- a/Modules/FindIconv.cmake
+++ b/Modules/FindIconv.cmake
@@ -7,9 +7,14 @@
 
 .. versionadded:: 3.11
 
-This module finds the ``iconv()`` POSIX.1 functions on the system.  These
-functions might be provided in the standard C library or externally in the form
-of an additional library.
+Finds the ``iconv()`` POSIX.1 functions on the system:
+
+.. code-block:: cmake
+
+  find_package(Iconv [<version>] [...])
+
+Iconv functions might be provided in the standard C library or externally
+in the form of an additional library.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -26,13 +31,8 @@
 This module defines the following variables:
 
 ``Iconv_FOUND``
-  Boolean indicating if the iconv support was found.
-
-``Iconv_INCLUDE_DIRS``
-  The include directories containing the iconv headers.
-
-``Iconv_LIBRARIES``
-  The iconv libraries to be linked.
+  Boolean indicating whether the (requested version of) iconv support was
+  found.
 
 ``Iconv_VERSION``
   .. versionadded:: 3.21
@@ -53,17 +53,23 @@
 
   The minor version of iconv.
 
-``Iconv_IS_BUILT_IN``
-  A boolean variable indicating whether iconv support is stemming from the C
-  standard library or not.  Even if the C library provides ``iconv()``, the
-  presence of an external ``libiconv`` implementation might lead to this being
-  false.
+``Iconv_INCLUDE_DIRS``
+  The include directories containing the iconv headers.
+
+``Iconv_LIBRARIES``
+  The iconv libraries to be linked.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
+``Iconv_IS_BUILT_IN``
+  A boolean variable indicating whether iconv support is stemming from the C
+  standard library or not.  Even if the C library provides ``iconv()``, the
+  presence of an external ``libiconv`` implementation might lead to this being
+  false.
+
 ``Iconv_INCLUDE_DIR``
   The directory containing the iconv headers.
 
diff --git a/Modules/FindIcotool.cmake b/Modules/FindIcotool.cmake
index 92dfe7f..ea9cb04 100644
--- a/Modules/FindIcotool.cmake
+++ b/Modules/FindIcotool.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds ``icotool``, command-line program for converting and creating Win32 icon
-and cursor files.
+and cursor files:
+
+.. code-block:: cmake
+
+  find_package(Icotool [<version>] [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -14,9 +18,14 @@
 This module defines the following variables:
 
 ``Icotool_FOUND``
-  True if ``icotool`` has been found.  For backward compatibility, the
-  ``ICOTOOL_FOUND`` variable is also set to the same value.
-``ICOTOOL_VERSION_STRING``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) ``icotool`` was
+  found.
+
+``Icotool_VERSION``
+  .. versionadded:: 4.2
+
   The version of ``icotool`` found.
 
 Cache Variables
@@ -27,6 +36,24 @@
 ``ICOTOOL_EXECUTABLE``
   The full path to the ``icotool`` tool.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``ICOTOOL_FOUND``
+  .. deprecated:: 4.2
+    Use ``Icotool_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) ``icotool`` was
+  found.
+
+``ICOTOOL_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Icotool_VERSION``, which has the same value.
+
+  The version of ``icotool`` found.
+
 Examples
 ^^^^^^^^
 
@@ -51,27 +78,23 @@
 if(ICOTOOL_EXECUTABLE)
   execute_process(
     COMMAND ${ICOTOOL_EXECUTABLE} --version
-    OUTPUT_VARIABLE _icotool_version
+    OUTPUT_VARIABLE Icotool_VERSION
     ERROR_QUIET
     OUTPUT_STRIP_TRAILING_WHITESPACE
   )
-  if("${_icotool_version}" MATCHES "^icotool \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
-    set( ICOTOOL_VERSION_STRING
-      "${CMAKE_MATCH_1}"
-    )
+  if("${Icotool_VERSION}" MATCHES "^icotool \\([^\\)]*\\) ([0-9\\.]+[^ \n]*)")
+    set(Icotool_VERSION "${CMAKE_MATCH_1}")
   else()
-    set( ICOTOOL_VERSION_STRING
-      ""
-    )
+    set(Icotool_VERSION "")
   endif()
-  unset(_icotool_version)
+  set(ICOTOOL_VERSION_STRING "${Icotool_VERSION}")
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(
   Icotool
   REQUIRED_VARS ICOTOOL_EXECUTABLE
-  VERSION_VAR ICOTOOL_VERSION_STRING
+  VERSION_VAR Icotool_VERSION
 )
 
 mark_as_advanced(
diff --git a/Modules/FindImageMagick.cmake b/Modules/FindImageMagick.cmake
index 8289d6d..c34ebdb 100644
--- a/Modules/FindImageMagick.cmake
+++ b/Modules/FindImageMagick.cmake
@@ -6,7 +6,11 @@
 ---------------
 
 Finds ImageMagick, a software suite for displaying, converting, and manipulating
-raster images.
+raster images:
+
+.. code-block:: cmake
+
+  find_package(ImageMagick [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.9
   Support for ImageMagick 7.
@@ -78,11 +82,15 @@
 This module defines the following variables:
 
 ``ImageMagick_FOUND``
-  Boolean indicating whether ImageMagick and all its requested components are
-  found.
+  Boolean indicating whether (the requested version of) ImageMagick and all
+  its requested components were found.
 
-``ImageMagick_VERSION_STRING``
-  The version of ImageMagick found.
+``ImageMagick_VERSION``
+  .. versionadded:: 4.2
+
+  The version of ImageMagick found in form of
+  ``<major>.<minor>.<patch>-<addendum>`` (e.g., ``6.9.12-98``, where ``98``
+  is the addendum release number).
 
   .. note::
 
@@ -127,6 +135,17 @@
 ``ImageMagick_EXECUTABLE_DIR``
   The full path to directory containing ImageMagick executables.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``ImageMagick_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``ImageMagick_VERSION``, which has the same value.
+
+  The version of ImageMagick found.
+
 Examples
 ^^^^^^^^
 
@@ -139,6 +158,10 @@
   target_link_libraries(example PRIVATE ImageMagick::Magick++)
 #]=======================================================================]
 
+cmake_policy(PUSH)
+cmake_policy(SET CMP0140 NEW)
+cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
+
 find_package(PkgConfig QUIET)
 
 #---------------------------------------------------------------------
@@ -147,7 +170,7 @@
 function(FIND_IMAGEMAGICK_API component header)
   set(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
 
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(PC_${component} QUIET ${component})
   endif()
 
@@ -253,6 +276,66 @@
   endif()
 endfunction()
 
+function(_ImageMagick_GetVersion)
+  unset(version)
+
+  if(ImageMagick_mogrify_EXECUTABLE)
+    execute_process(
+      COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
+      OUTPUT_VARIABLE version
+      ERROR_QUIET
+      OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+
+    if(version MATCHES "^Version: ImageMagick ([-0-9.]+)")
+      set(version "${CMAKE_MATCH_1}")
+    endif()
+  elseif(ImageMagick_INCLUDE_DIRS)
+    # MagickLibSubversion was used in ImageMagick <= 6.5.
+    set(
+      regex
+      "^[\t ]*#[\t ]*define[\t ]+(MagickLibVersionText|MagickLibAddendum|MagickLibSubversion)[\t ]+\"([-0-9.]+)\""
+    )
+
+    foreach(dir IN LISTS ImageMagick_INCLUDE_DIRS)
+      foreach(subdir IN ITEMS MagickCore magick)
+        if(EXISTS ${dir}/${subdir}/version.h)
+          file(STRINGS "${dir}/${subdir}/version.h" results REGEX "${regex}")
+
+          foreach(line ${results})
+            if(line MATCHES "${regex}")
+              if(DEFINED version)
+                string(APPEND version "${CMAKE_MATCH_2}")
+              else()
+                set(version "${CMAKE_MATCH_2}")
+              endif()
+
+              if(CMAKE_MATCH_1 STREQUAL "MagickLibAddendum")
+                break()
+              endif()
+            endif()
+          endforeach()
+        endif()
+
+        if(DEFINED version)
+          break()
+        endif()
+      endforeach()
+
+      if(DEFINED version)
+        break()
+      endif()
+    endforeach()
+  endif()
+
+  if(DEFINED version)
+    set(ImageMagick_VERSION "${version}")
+    set(ImageMagick_VERSION_STRING "${ImageMagick_VERSION}")
+  endif()
+
+  return(PROPAGATE ImageMagick_VERSION ImageMagick_VERSION_STRING)
+endfunction()
+
 #---------------------------------------------------------------------
 # Start Actual Work
 #---------------------------------------------------------------------
@@ -340,16 +423,7 @@
 set(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
 set(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
 
-if(ImageMagick_mogrify_EXECUTABLE)
-  execute_process(COMMAND ${ImageMagick_mogrify_EXECUTABLE} -version
-                  OUTPUT_VARIABLE imagemagick_version
-                  ERROR_QUIET
-                  OUTPUT_STRIP_TRAILING_WHITESPACE)
-  if(imagemagick_version MATCHES "^Version: ImageMagick ([-0-9\\.]+)")
-    set(ImageMagick_VERSION_STRING "${CMAKE_MATCH_1}")
-  endif()
-  unset(imagemagick_version)
-endif()
+_ImageMagick_GetVersion()
 
 #---------------------------------------------------------------------
 # Standard Package Output
@@ -357,7 +431,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(ImageMagick
                                   REQUIRED_VARS ${ImageMagick_REQUIRED_VARS}
-                                  VERSION_VAR ImageMagick_VERSION_STRING
+                                  VERSION_VAR ImageMagick_VERSION
   )
 
 #---------------------------------------------------------------------
@@ -383,3 +457,5 @@
   IMAGEMAGICK_MONTAGE_EXECUTABLE
   IMAGEMAGICK_COMPOSITE_EXECUTABLE
   )
+
+cmake_policy(POP)
diff --git a/Modules/FindIntl.cmake b/Modules/FindIntl.cmake
index cdc6541..7fd0afd 100644
--- a/Modules/FindIntl.cmake
+++ b/Modules/FindIntl.cmake
@@ -8,9 +8,15 @@
 .. versionadded:: 3.2
 
 Finds internationalization support that includes message translation functions
-such as ``gettext()``.  These functions originate from the GNU ``libintl``
-library, which is part of the GNU gettext utilities, but may also be provided by
-the standard C library.
+such as ``gettext()``:
+
+.. code-block:: cmake
+
+  find_package(Intl [<version>] [...])
+
+These functions originate from the GNU ``libintl`` library, which is part
+of the GNU gettext utilities, but may also be provided by the standard C
+library.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -28,13 +34,7 @@
 This module defines the following variables:
 
 ``Intl_FOUND``
-  Boolean indicating whether the Intl is found.
-
-``Intl_INCLUDE_DIRS``
-  Include directories containing headers needed to use Intl.
-
-``Intl_LIBRARIES``
-  The libraries needed to link against to use Intl.
+  Boolean indicating whether (the requested version of) Intl was found.
 
 ``Intl_VERSION``
   .. versionadded:: 3.21
@@ -61,23 +61,29 @@
 
   The patch version of Intl found.
 
+``Intl_INCLUDE_DIRS``
+  Include directories containing headers needed to use Intl.
+
+``Intl_LIBRARIES``
+  The libraries needed to link against to use Intl.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
-``Intl_INCLUDE_DIR``
-  The directory containing the ``libintl.h`` header file.
-
-``Intl_LIBRARY``
-  The path to the Intl library (if any).
-
 ``Intl_IS_BUILT_IN``
   .. versionadded:: 3.20
 
   Boolean indicating whether the found Intl functionality is provided by the
   standard C library rather than a separate ``libintl`` library.
 
+``Intl_INCLUDE_DIR``
+  The directory containing the ``libintl.h`` header file.
+
+``Intl_LIBRARY``
+  The path to the Intl library (if any).
+
 .. note::
   On some platforms, such as Linux with GNU libc, the gettext functions are
   present in the C standard library and libintl is not required.  The
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
index 10dcc51..a70b00f 100644
--- a/Modules/FindJNI.cmake
+++ b/Modules/FindJNI.cmake
@@ -5,7 +5,11 @@
 FindJNI
 -------
 
-Finds the Java Native Interface (JNI) include directories and libraries.
+Finds the Java Native Interface (JNI) include directories and libraries:
+
+.. code-block:: cmake
+
+  find_package(JNI [<version>] [COMPONENTS <components>...] [...])
 
 JNI enables Java code running in a Java Virtual Machine (JVM) or Dalvik Virtual
 Machine (DVM) on Android to call and be called by native applications and
@@ -95,12 +99,12 @@
 This module defines the following variables:
 
 ``JNI_FOUND``
-  Boolean indicating whether the JNI is found.
+  Boolean indicating whether (the requested version of) JNI was found.
 
 ``JNI_<component>_FOUND``
   .. versionadded:: 3.24
 
-  Boolean indicating whether the ``<component>`` is found.
+  Boolean indicating whether the ``<component>`` was found.
 
 ``JNI_VERSION``
   Full Android NDK package version (including suffixes such as ``-beta3`` and
@@ -381,6 +385,11 @@
   # Arch Linux specific paths for default JVM
   /usr/lib/jvm/default
   # Ubuntu specific paths for default JVM
+  /usr/lib/jvm/java-26-openjdk-{libarch}
+  /usr/lib/jvm/java-25-openjdk-{libarch}    # Ubuntu 24.04 LTS
+  /usr/lib/jvm/java-24-openjdk-{libarch}
+  /usr/lib/jvm/java-23-openjdk-{libarch}
+  /usr/lib/jvm/java-22-openjdk-{libarch}
   /usr/lib/jvm/java-21-openjdk-{libarch}    # Ubuntu 23.04
   /usr/lib/jvm/java-20-openjdk-{libarch}    # Ubuntu 22.10
   /usr/lib/jvm/java-19-openjdk-{libarch}    # Ubuntu 22.04 LTS
diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake
index 9d43f58..c5687ea 100644
--- a/Modules/FindJPEG.cmake
+++ b/Modules/FindJPEG.cmake
@@ -5,7 +5,11 @@
 FindJPEG
 --------
 
-Finds the Joint Photographic Experts Group (JPEG) library (``libjpeg``).
+Finds the Joint Photographic Experts Group (JPEG) library (``libjpeg``):
+
+.. code-block:: cmake
+
+  find_package(JPEG [<version>] [...])
 
 .. versionchanged:: 3.12
   Debug and Release JPEG library variants are now found separately.
@@ -24,10 +28,16 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``JPEG_FOUND``
-  Boolean indicating whether the JPEG is found.
+  Boolean indicating whether the (requested version of) JPEG library was
+  found.
+
+``JPEG_VERSION``
+  .. versionadded:: 3.12
+
+  The version of JPEG library found.
 
 ``JPEG_INCLUDE_DIRS``
   Include directories containing headers needed to use JPEG.
@@ -35,18 +45,13 @@
 ``JPEG_LIBRARIES``
   Libraries needed to link to JPEG.
 
-``JPEG_VERSION``
-  .. versionadded:: 3.12
-
-  The version of the JPEG library found.
-
 Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
 ``JPEG_INCLUDE_DIR``
-  Directory containing the ``jpeglib.h`` and related header files.
+  Directory containing the ``<jpeglib.h>`` and related header files.
 
 ``JPEG_LIBRARY_RELEASE``
   .. versionadded:: 3.12
@@ -58,13 +63,13 @@
 
   Path to the debug variant of the JPEG library.
 
-Obsolete Variables
-^^^^^^^^^^^^^^^^^^
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
 
-The following legacy variables are provided for backward compatibility:
+The following variables are provided for backward compatibility:
 
 ``JPEG_LIBRARY``
-  .. versionchanged:: 3.12
+  .. deprecated:: 3.12
     This variable has been superseded by the ``JPEG_LIBRARY_RELEASE`` and
     ``JPEG_LIBRARY_DEBUG`` variables.
 
diff --git a/Modules/FindJasper.cmake b/Modules/FindJasper.cmake
index 3902f6d..a19179c 100644
--- a/Modules/FindJasper.cmake
+++ b/Modules/FindJasper.cmake
@@ -6,7 +6,11 @@
 ----------
 
 Finds the JasPer Image Coding Toolkit for handling image data in a variety of
-formats, such as the JPEG-2000.
+formats, such as the JPEG-2000:
+
+.. code-block:: cmake
+
+  find_package(Jasper [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -25,8 +29,14 @@
 This module defines the following variables:
 
 ``Jasper_FOUND``
-  Boolean indicating whether the JasPer is found.  For backward compatibility,
-  the ``JASPER_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) JasPer was found.
+
+``Jasper_VERSION``
+  .. versionadded:: 4.2
+
+  The version of JasPer found.
 
 ``JASPER_INCLUDE_DIRS``
   .. versionadded:: 3.22
@@ -36,9 +46,6 @@
 ``JASPER_LIBRARIES``
   The libraries needed to use JasPer.
 
-``JASPER_VERSION_STRING``
-  The version of JasPer found.
-
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -54,6 +61,23 @@
 ``JASPER_LIBRARY_DEBUG``
   The path to the debug variant of the JasPer library.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``JASPER_FOUND``
+  .. deprecated:: 4.2
+    Use ``Jasper_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) JasPer was found.
+
+``JASPER_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Jasper_VERSION``.
+
+  The version of JasPer found.
+
 Examples
 ^^^^^^^^
 
@@ -81,13 +105,14 @@
 
 if(JASPER_INCLUDE_DIR AND EXISTS "${JASPER_INCLUDE_DIR}/jasper/jas_config.h")
   file(STRINGS "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" jasper_version_str REGEX "^#define[\t ]+JAS_VERSION[\t ]+\".*\".*")
-  string(REGEX REPLACE "^#define[\t ]+JAS_VERSION[\t ]+\"([^\"]+)\".*" "\\1" JASPER_VERSION_STRING "${jasper_version_str}")
+  string(REGEX REPLACE "^#define[\t ]+JAS_VERSION[\t ]+\"([^\"]+)\".*" "\\1" Jasper_VERSION "${jasper_version_str}")
+  set(JASPER_VERSION_STRING "${Jasper_VERSION}")
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Jasper
                                   REQUIRED_VARS JASPER_LIBRARIES JASPER_INCLUDE_DIR
-                                  VERSION_VAR JASPER_VERSION_STRING)
+                                  VERSION_VAR Jasper_VERSION)
 
 if(Jasper_FOUND)
   set(JASPER_LIBRARIES ${JASPER_LIBRARIES})
diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake
index 1587ce6..09e9fd7 100644
--- a/Modules/FindJava.cmake
+++ b/Modules/FindJava.cmake
@@ -6,7 +6,11 @@
 --------
 
 Finds the Java installation and determines its runtime tools and development
-components.
+components:
+
+.. code-block:: cmake
+
+  find_package(Java [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.10
   Support for Java 9+ version parsing.
@@ -14,7 +18,14 @@
 Components
 ^^^^^^^^^^
 
-This module supports the following components:
+This module supports optional components, which can be specified with the
+:command:`find_package` command:
+
+.. code-block:: cmake
+
+  find_package(Java [COMPONENTS <components>...])
+
+Supported components include:
 
 ``Runtime``
   Finds the Java Runtime Environment used to execute Java byte-compiled
@@ -35,13 +46,7 @@
 
   Finds the signer and verifier tool for Java Archive (JAR) files.
 
-Components can optionally be specified using the standard syntax with:
-
-.. code-block:: cmake
-
-  find_package(Java [COMPONENTS <components>...])
-
-If no ``COMPONENTS`` are specified, the module searches for the ``Runtime``
+If no components are specified, the module searches for the ``Runtime``
 component by default.
 
 Result Variables
@@ -50,10 +55,13 @@
 This module defines the following variables:
 
 ``Java_FOUND``
-  Boolean indicating whether Java with all specified components is found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Java with all
+  specified components was found.
 
 ``Java_<component>_FOUND``
-  Boolean indicating whether the ``<component>`` is found.
+  Boolean indicating whether the ``<component>`` was found.
 
 ``Java_VERSION``
   Version of Java found.  This is set to:
diff --git a/Modules/FindKDE3.cmake b/Modules/FindKDE3.cmake
index ccfad5e..bc6b0e4 100644
--- a/Modules/FindKDE3.cmake
+++ b/Modules/FindKDE3.cmake
@@ -13,9 +13,15 @@
   `KDE documentation
   <https://develop.kde.org/docs/getting-started/building/cmake-build/>`_.
 
-This module finds KDE 3 include directories, libraries, and KDE-specific
-preprocessor tools.  It provides usage requirements for building KDE 3 software
-and defines several helper commands to simplify working with KDE 3 in CMake.
+Finds KDE 3 include directories, libraries, and KDE-specific preprocessor
+tools:
+
+.. code-block:: cmake
+
+  find_package(KDE3 [...])
+
+This module provides usage requirements for building KDE 3 software and
+defines several helper commands to simplify working with KDE 3 in CMake.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -23,7 +29,7 @@
 This module defines the following variables:
 
 ``KDE3_FOUND``
-  Boolean indicating whether KDE 3 is found.
+  Boolean indicating whether KDE 3 was found.
 ``KDE3_DEFINITIONS``
   Compiler definitions required for compiling KDE 3 software.
 ``KDE3_INCLUDE_DIRS``
@@ -206,7 +212,7 @@
 endif()
 
 # If Qt4 has already been found, fail.
-if(QT4_FOUND)
+if(Qt4_FOUND)
   if(KDE3_FIND_REQUIRED)
     message( FATAL_ERROR "KDE3/Qt3 and Qt4 cannot be used together in one project.")
   else()
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake
index 220906b..04c76da 100644
--- a/Modules/FindKDE4.cmake
+++ b/Modules/FindKDE4.cmake
@@ -5,27 +5,223 @@
 FindKDE4
 --------
 
+.. note::
+
+  This module is specifically intended for KDE version 4, which is obsolete
+  and no longer maintained.  For modern application development using KDE
+  technologies with CMake, use a newer version of KDE, and refer to the
+  `KDE documentation
+  <https://develop.kde.org/docs/getting-started/building/cmake-build/>`_.
+
+Finds the KDE 4 installation:
+
+.. code-block:: cmake
+
+  find_package(KDE4 [...])
+
+This module is a wrapper around the following upstream KDE 4 modules:
+
+``FindKDE4Internal.cmake``
+
+  Upstream internal module, which finds the KDE 4 include directories,
+  libraries, and KDE-specific preprocessor tools.  It provides usage
+  requirements for building KDE 4 software and defines several helper
+  commands to simplify working with KDE 4 in CMake.
+
+``KDE4Macros.cmake``
+  Upstream utility module that defines all additional KDE4-specific
+  commands to use KDE 4 in CMake.  For example:
+  ``kde4_automoc()``, ``kde4_add_executable()``, ``kde4_add_library()``,
+  ``kde4_add_ui_files()``, ``kde4_add_ui3_files()``,
+  ``kde4_add_kcfg_files()``, ``kde4_add_kdeinit_executable()``, etc.
+
+Upstream KDE 4 modules are installed by the KDE 4 distribution package in
+``$KDEDIRS/share/apps/cmake/modules/``.  This path is automatically
+appended to the :variable:`CMAKE_MODULE_PATH` variable when calling
+``find_package(KDE4)``, so any additional KDE 4 modules can be included in
+the project with :command:`include`.  For example:
+
+``KDE4Defaults.cmake``
+  Upstream internal module that sets some CMake options which are useful,
+  but not required for building KDE 4 software.  If these settings should
+  be used, include this module after finding KDE 4:
+
+  .. code-block:: cmake
+
+    find_package(KDE4)
+    include(KDE4Defaults)
+
+For usage details, refer to the upstream KDE 4 documentation.  For example,
+at the top of the ``FindKDE4Internal`` module a complete documentation is
+available for all variables and commands these modules provide.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``KDE4_FOUND``
+  Boolean indicating whether KDE 4 was found.  This variable is set by the
+  upstream ``FindKDE4Internal`` module.
+
+Hints
+^^^^^
+
+This module accepts the following variables before calling the
+``find_package(KDE4)``:
+
+``ENV{KDEDIRS}``
+  Environment variable containing the path to the KDE 4 installation.
+
+KDE 4 is searched in the following directories in the given order:
+
+* :variable:`CMAKE_INSTALL_PREFIX` variable
+* ``KDEDIRS`` environment variable
+* ``/opt/kde4`` path
+
+Examples
+^^^^^^^^
+
+Example: Basic Usage
+""""""""""""""""""""
+
+Finding KDE 4 as required and using it in CMake:
+
+.. code-block:: cmake
+
+  find_package(KDE4 REQUIRED)
+
+  set(sources main.cpp mywidget.cpp mypart.cpp)
+
+  # The kde4_*() commands are provided by the KDE4Macros module, which is
+  # included automatically by FindKDE4, if KDE4 is found:
+  kde4_automoc(${sources})
+  kde4_add_executable(example ${sources})
+
+  target_include_directories(example PRIVATE ${KDE4_INCLUDES})
+  target_link_libraries(example PRIVATE ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS})
+
+  install(TARGETS example DESTINATION ${CMAKE_INSTALL_BINDIR})
+  install(FILES kfoo.desktop DESTINATION ${XDG_APPS_DIR})
+
+Example: Full Featured Example
+""""""""""""""""""""""""""""""
+
+In the following example this module is used to find KDE 4 installation.
+
+.. code-block:: cmake
+
+  project(kfoo)
+
+  find_package(KDE4 REQUIRED)
+
+  # Append path from where to include local project modules if any:
+  list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
+
+  include_directories(${KDE4_INCLUDE_DIRS})
+  add_definitions(${KDE4_DEFINITIONS})
+
+  set(sources main.cpp myappl.cpp view.cpp)
+
+  # If Qt designer UI files version 3 or 4 are available add them to the
+  # sources variable:
+  kde4_add_ui_files(sources maindialog.ui logindialog.ui)
+  kde4_add_ui3_files(sources printerdlg.ui previewdlg.ui)
+
+  # If there are files for the kconfig_compiler add them this way:
+  kde4_add_kcfg_files(sources settings.kcfg)
+
+  # When everything is listed, probably automoc is wanted:
+  kde4_automoc(${sources})
+
+  # Finally, specify what to build:
+  kde4_add_executable(kfoo ${sources})
 
 
-Find KDE4 and provide all necessary variables and macros to compile
-software for it.  It looks for KDE 4 in the following directories in
-the given order:
+The ``kde4_add_executable()`` command is a slightly extended version of the
+CMake command :command:`add_executable`.  Additionally, it does some more
+``RPATH`` handling and supports the ``KDE4_ENABLE_FINAL`` variable.  The
+first argument is the name of the executable followed by a list of source
+files.  If a library needs to be created instead of an executable, the
+``kde4_add_library()`` can be used.  It is an extended version of the
+:command:`add_library` command.  It adds support for the
+``KDE4_ENABLE_FINAL`` variable and under Windows it adds the
+``-DMAKE_KFOO_LIB`` to the compile flags.
 
-::
+.. code-block:: cmake
 
-  CMAKE_INSTALL_PREFIX
-  KDEDIRS
-  /opt/kde4
+  find_package(KDE4 REQUIRED)
 
+  # ...
 
+  kde4_add_library(kfoo ${sources})
 
-Please look in ``FindKDE4Internal.cmake`` and ``KDE4Macros.cmake`` for more
-information.  They are installed with the KDE 4 libraries in
-$KDEDIRS/share/apps/cmake/modules/.
+  # Optionally, set the library version number if needed:
+  set_target_properties(kfoo PROPERTIES VERSION 5.0.0 SOVERSION 5)
 
-Author: Alexander Neundorf <neundorf@kde.org>
+KDE is very modular, so if a KPart, a control center module, or an ioslave
+needs to be created, here's how to do it:
+
+.. code-block:: cmake
+
+  find_package(KDE4 REQUIRED)
+  # ...
+  kde4_add_plugin(kfoo ${sources})
+
+Now, the application/library/plugin probably needs to link to some
+libraries.  For this use the standard :command:`target_link_libraries`
+command.  For every KDE library there are variables available in the form
+of ``KDE4_FOO_LIBS``.  Use them to get also all depending libraries:
+
+.. code-block:: cmake
+
+  target_link_libraries(kfoo ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS})
+
+Example: The kdeinit Executable
+"""""""""""""""""""""""""""""""
+
+In the following example, the so called kdeinit executable is created.
+The ``kde4_add_kdeinit_executable()`` command creates both an executable
+with the given name and a library with the given name prefixed with
+``kdeinit_``.  The :command:`target_link_libraries` command adds all
+required libraries to the ``kdeinit_kbar`` library, and then links the
+``kbar`` against the ``kdeinit_kbar``:
+
+.. code-block:: cmake
+
+  find_package(KDE4 REQUIRED)
+
+  # ...
+
+  kde4_add_kdeinit_executable(kbar ${kbarSources})
+  target_link_libraries(kdeinit_kbar ${KDE4_KIO_LIBS})
+  target_link_libraries(kbar kdeinit_kbar)
+
+  install(TARGETS kbar DESTINATION ${CMAKE_INSTALL_BINDIR})
+  install(TARGETS kdeinit_kbar DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+Example: Removing Compile Definitions
+"""""""""""""""""""""""""""""""""""""
+
+Sometimes, a default compile definition passed to the compiler needs to be
+removed.  The :command:`remove_definitions` command can be used.  For
+example, by default, the KDE4 build system sets the ``-DQT_NO_STL`` flag.
+If the project code uses some of the Qt STL compatibility layer, this flag
+should be removed:
+
+.. code-block:: cmake
+
+  find_package(KDE4 REQUIRED)
+
+  add_definitions(${KDE4_DEFINITIONS})
+
+  # ...
+
+  remove_definitions(-DQT_NO_STL)
 #]=======================================================================]
 
+# Author: Alexander Neundorf <neundorf@kde.org>
+
 # If Qt3 has already been found, fail.
 if(QT_QT_LIBRARY)
   if(KDE4_FIND_REQUIRED)
@@ -100,4 +296,6 @@
   if (KDE4_FIND_REQUIRED)
     message(FATAL_ERROR "ERROR: cmake/modules/FindKDE4Internal.cmake not found in ${_data_DIR}")
   endif ()
+
+  set(KDE4_FOUND FALSE)
 endif ()
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 8bd5121..52b13d9 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -5,35 +5,68 @@
 FindLAPACK
 ----------
 
-Find Linear Algebra PACKage (LAPACK) library
+Finds the installed Linear Algebra PACKage (LAPACK) Fortran library that
+implements the `LAPACK linear-algebra interface`_:
 
-This module finds an installed Fortran library that implements the
-`LAPACK linear-algebra interface`_.
+.. code-block:: cmake
+
+  find_package(LAPACK [...])
 
 At least one of the ``C``, ``CXX``, or ``Fortran`` languages must be enabled.
 
 .. _`LAPACK linear-algebra interface`: https://netlib.org/lapack/
 
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following :ref:`Imported Targets`:
+
+``LAPACK::LAPACK``
+  .. versionadded:: 3.18
+
+  Target encapsulating the LAPACK usage requirements, available only if
+  LAPACK is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``LAPACK_FOUND``
+  Boolean indicating whether the library implementing the LAPACK interface
+  was found.
+``LAPACK_LINKER_FLAGS``
+  Uncached list of required linker flags (excluding ``-l`` and ``-L``).
+``LAPACK_LIBRARIES``
+  Uncached list of libraries (using full path name) to link against to use
+  LAPACK.
+``LAPACK95_LIBRARIES``
+  Uncached list of libraries (using full path name) to link against to use
+  LAPACK95.
+``LAPACK95_FOUND``
+  Boolean indicating whether the library implementing the LAPACK95 interface
+  was found.
+
 Input Variables
 ^^^^^^^^^^^^^^^
 
 The following variables may be set to influence this module's behavior:
 
 ``BLA_STATIC``
-  if ``ON`` use static linkage
+  If ``ON``, the static linkage will be used.
 
 ``BLA_VENDOR``
   Set to one of the :ref:`BLAS/LAPACK Vendors` to search for BLAS only
   from the specified vendor.  If not set, all vendors are considered.
 
 ``BLA_F95``
-  if ``ON`` tries to find the BLAS95/LAPACK95 interfaces
+  If ``ON``, the module tries to find the BLAS95/LAPACK95 interfaces.
 
 ``BLA_PREFER_PKGCONFIG``
   .. versionadded:: 3.20
 
-  if set ``pkg-config`` will be used to search for a LAPACK library first
-  and if one is found that is preferred
+  If set, ``pkg-config`` will be used to search for a LAPACK library first
+  and if one is found that is preferred.
 
 ``BLA_PKGCONFIG_LAPACK``
   .. versionadded:: 3.25
@@ -41,7 +74,6 @@
   If set, the ``pkg-config`` method will look for this module name instead of
   just ``lapack``.
 
-
 ``BLA_SIZEOF_INTEGER``
   .. versionadded:: 3.22
 
@@ -70,34 +102,6 @@
 
   This is currently only supported by NVIDIA NVPL.
 
-Imported Targets
-^^^^^^^^^^^^^^^^
-
-This module defines the following :prop_tgt:`IMPORTED` targets:
-
-``LAPACK::LAPACK``
-  .. versionadded:: 3.18
-
-  The libraries to use for LAPACK, if found.
-
-Result Variables
-^^^^^^^^^^^^^^^^
-
-This module defines the following variables:
-
-``LAPACK_FOUND``
-  library implementing the LAPACK interface is found
-``LAPACK_LINKER_FLAGS``
-  uncached list of required linker flags (excluding ``-l`` and ``-L``).
-``LAPACK_LIBRARIES``
-  uncached list of libraries (using full path name) to link against
-  to use LAPACK
-``LAPACK95_LIBRARIES``
-  uncached list of libraries (using full path name) to link against
-  to use LAPACK95
-``LAPACK95_FOUND``
-  library implementing the LAPACK95 interface is found
-
 Intel MKL
 ^^^^^^^^^
 
@@ -115,6 +119,15 @@
 establish an Intel MKL environment.  See the :module:`FindBLAS` module
 section on :ref:`Intel MKL` for details.
 
+Examples
+^^^^^^^^
+
+Finding LAPACK and linking it to a project target:
+
+.. code-block:: cmake
+
+  find_package(LAPACK)
+  target_link_libraries(project_target PRIVATE LAPACK::LAPACK)
 #]=======================================================================]
 
 # The approach follows that of the ``autoconf`` macro file, ``acx_lapack.m4``
@@ -314,7 +327,7 @@
     set(BLA_PKGCONFIG_LAPACK "lapack")
   endif()
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(PKGC_LAPACK QUIET ${BLA_PKGCONFIG_LAPACK})
     if(PKGC_LAPACK_FOUND)
       set(LAPACK_FOUND TRUE)
diff --git a/Modules/FindLATEX.cmake b/Modules/FindLATEX.cmake
index e272770..4400a05 100644
--- a/Modules/FindLATEX.cmake
+++ b/Modules/FindLATEX.cmake
@@ -5,8 +5,14 @@
 FindLATEX
 ---------
 
-Finds LaTeX compiler and Latex-related software like BibTeX.  LaTeX is a
-typesetting system for the production of technical and scientific documentation.
+Finds LaTeX compiler and Latex-related software like BibTeX:
+
+.. code-block:: cmake
+
+  find_package(LATEX [...])
+
+LaTeX is a typesetting system for the production of technical and scientific
+documentation.
 
 Components
 ^^^^^^^^^^
@@ -40,7 +46,7 @@
   Finds the MakeIndex compiler.
 
 ``XINDY``
-  Find the xindy compiler.
+  Finds the xindy compiler.
 
 ``DVIPS``
   Finds the DVI-to-PostScript (DVIPS) converter.
@@ -67,10 +73,10 @@
 
 ``LATEX_FOUND``
   Boolean indicating whether the LaTex compiler and all its required components
-  are found.
+  were found.
 
 ``LATEX_<component>_FOUND``
-  Boolean indicating whether the LaTeX ``<component>`` is found.
+  Boolean indicating whether the LaTeX ``<component>`` was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -84,12 +90,12 @@
   The path to the PdfLaTeX compiler.
 
 ``XELATEX_COMPILER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the XeLaTeX compiler.
 
 ``LUALATEX_COMPILER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the LuaLaTeX compiler.
 
@@ -97,7 +103,7 @@
   The path to the BibTeX compiler.
 
 ``BIBER_COMPILER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the Biber compiler.
 
@@ -105,7 +111,7 @@
   The path to the MakeIndex compiler.
 
 ``XINDY_COMPILER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the xindy compiler.
 
@@ -119,7 +125,7 @@
   The path to the PS2PDF converter.
 
 ``PDFTOPS_CONVERTER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the pdftops converter.
 
@@ -127,7 +133,7 @@
   The path to the LaTeX2Html converter.
 
 ``HTLATEX_COMPILER``
-  .. versionadded: 3.2
+  .. versionadded:: 3.2
 
   The path to the htlatex compiler.
 
diff --git a/Modules/FindLTTngUST.cmake b/Modules/FindLTTngUST.cmake
index 14aa766..6d024bc 100644
--- a/Modules/FindLTTngUST.cmake
+++ b/Modules/FindLTTngUST.cmake
@@ -8,12 +8,16 @@
 .. versionadded:: 3.6
 
 Finds the `LTTng <https://lttng.org/>`_ (Linux Trace Toolkit: next generation)
-user space tracing library (LTTng-UST).
+user space tracing library (LTTng-UST):
+
+.. code-block:: cmake
+
+  find_package(LTTngUST [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-This module defines the following :ref:`Imported Targets`:
+This module provides the following :ref:`Imported Targets`:
 
 ``LTTng::UST``
   Target providing the LTTng-UST library usage requirements.  This target is
@@ -22,15 +26,20 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``LTTngUST_FOUND``
-  Boolean indicating whether the LTTng-UST library is found.  For backward
-  compatibility, the ``LTTNGUST_FOUND`` variable is also set to the same value.
-``LTTNGUST_VERSION_STRING``
+  Boolean indicating whether the (requested version of) LTTng-UST library
+  was found.
+
+``LTTngUST_VERSION``
+  .. versionadded:: 4.2
+
   The LTTng-UST version.
+
 ``LTTNGUST_HAS_TRACEF``
   ``TRUE`` if the ``tracef()`` API is available in the system's LTTng-UST.
+
 ``LTTNGUST_HAS_TRACELOG``
   ``TRUE`` if the ``tracelog()`` API is available in the system's LTTng-UST.
 
@@ -44,6 +53,24 @@
 ``LTTNGUST_LIBRARIES``
   The libraries needed to use LTTng-UST.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LTTNGUST_FOUND``
+  .. deprecated:: 4.2
+    Use ``LTTngUST_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) LTTng-UST library
+  was found.
+
+``LTTNGUST_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``LTTngUST_VERSION``.
+
+  The LTTng-UST version.
+
 Examples
 ^^^^^^^^
 
@@ -90,8 +117,9 @@
            lttngust_v_minor "${lttngust_version_minor_string}")
     string(REGEX REPLACE ".*[\t ]+([0-9]+).*" "\\1"
            lttngust_v_patch "${lttngust_version_patch_string}")
-    set(LTTNGUST_VERSION_STRING
+    set(LTTngUST_VERSION
         "${lttngust_v_major}.${lttngust_v_minor}.${lttngust_v_patch}")
+    set(LTTNGUST_VERSION_STRING "${LTTngUST_VERSION}")
     unset(lttngust_version_major_string)
     unset(lttngust_version_minor_string)
     unset(lttngust_version_patch_string)
@@ -119,7 +147,7 @@
 find_package_handle_standard_args(LTTngUST
                                   REQUIRED_VARS LTTNGUST_LIBRARIES
                                                 LTTNGUST_INCLUDE_DIRS
-                                  VERSION_VAR LTTNGUST_VERSION_STRING)
+                                  VERSION_VAR LTTngUST_VERSION)
 mark_as_advanced(LTTNGUST_LIBRARIES LTTNGUST_INCLUDE_DIRS)
 
 cmake_policy(POP)
diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake
index 9072d95..5f006e6 100644
--- a/Modules/FindLibArchive.cmake
+++ b/Modules/FindLibArchive.cmake
@@ -5,18 +5,24 @@
 FindLibArchive
 --------------
 
-Finds the libarchive library and include directories.  Libarchive is a
-multi-format archive and compression library.
+Finds the libarchive library and include directories:
 
-Import Targets
-^^^^^^^^^^^^^^
+.. code-block:: cmake
 
-This module defines the following :ref:`Imported Targets`:
+  find_package(LibArchive [<version>] [...])
+
+Libarchive is a multi-format archive and compression library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following :ref:`Imported Targets`:
 
 ``LibArchive::LibArchive``
   .. versionadded:: 3.17
 
-  A target for linking against libarchive.
+  A target encapsulating the libarchive usage requirements, available only
+  if libarchive is found.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -24,11 +30,8 @@
 This module defines the following variables:
 
 ``LibArchive_FOUND``
-  Boolean indicating whether libarchive was found.
-``LibArchive_INCLUDE_DIRS``
-  Include search path for using libarchive.
-``LibArchive_LIBRARIES``
-  Libraries to link against libarchive.
+  Boolean indicating whether (the requested version of) libarchive was found.
+
 ``LibArchive_VERSION``
   A 3-component version string (``major.minor.patch``) of libarchive found.
 
@@ -40,10 +43,16 @@
     only for libarchive versions 3.1 and earlier.  In CMake 3.6 and newer, this
     variable will be set for all libarchive versions.
 
+``LibArchive_INCLUDE_DIRS``
+  Include search path for using libarchive.
+
+``LibArchive_LIBRARIES``
+  Libraries to link against libarchive.
+
 Examples
 ^^^^^^^^
 
-Finding LibArchive and linking it to a project target:
+Finding libarchive and linking it to a project target:
 
 .. code-block:: cmake
 
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 3711214..4a39d2c 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -5,8 +5,12 @@
 FindLibLZMA
 -----------
 
-Finds the data compression library that implements the LZMA (Lempel–Ziv–Markov
-chain algorithm) - liblzma.
+Finds the liblzma, a data compression library that implements the LZMA
+(Lempel–Ziv–Markov chain algorithm):
+
+.. code-block:: cmake
+
+  find_package(LibLZMA [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -25,17 +29,21 @@
 This module defines the following variables:
 
 ``LibLZMA_FOUND``
-  Boolean indicating whether the liblzma is found.  For backward compatibility,
-  the ``LIBLZMA_FOUND`` variable is also set to the same value.
-``LIBLZMA_INCLUDE_DIRS``
-  Include directories containing headers needed to use liblzma.
-``LIBLZMA_LIBRARIES``
-  Libraries needed to link against to use liblzma.
-``LIBLZMA_VERSION``
-  .. versionadded:: 3.26
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) liblzma was found.
+
+``LibLZMA_VERSION``
+  .. versionadded:: 4.2
 
   The version of liblzma found (available as a string, for example, ``5.0.3``).
 
+``LIBLZMA_INCLUDE_DIRS``
+  Include directories containing headers needed to use liblzma.
+
+``LIBLZMA_LIBRARIES``
+  Libraries needed to link against to use liblzma.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -44,29 +52,53 @@
 ``LIBLZMA_HAS_AUTO_DECODER``
   Boolean sanity check result indicating whether the ``lzma_auto_decoder()``
   function (automatic decoder functionality) is found in liblzma (required).
+
 ``LIBLZMA_HAS_EASY_ENCODER``
   Boolean sanity check result indicating whether the ``lzma_easy_encoder()``
   function (basic encoder API) is found in liblzma (required).
+
 ``LIBLZMA_HAS_LZMA_PRESET``
   Boolean sanity check result indicating whether the ``lzma_lzma_preset()``
   function (preset compression configuration) is found in liblzma (required).
 
-Legacy Variables
-^^^^^^^^^^^^^^^^
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
 
 The following variables are provided for backward compatibility:
 
-``LIBLZMA_VERSION_MAJOR``
-  The major version of liblzma found.
-``LIBLZMA_VERSION_MINOR``
-  The minor version of liblzma found.
-``LIBLZMA_VERSION_PATCH``
-  The patch version of liblzma found.
-``LIBLZMA_VERSION_STRING``
+``LIBLZMA_FOUND``
+  .. deprecated:: 4.2
+    Use ``LibLZMA_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) liblzma was found.
+
+``LIBLZMA_VERSION``
+  .. versionadded:: 3.26
+  .. deprecated:: 4.2
+    Superseded by the ``LibLZMA_VERSION``.
+
   The version of liblzma found.
 
-  .. versionchanged:: 3.26
-    Superseded by ``LIBLZMA_VERSION``.
+``LIBLZMA_VERSION_STRING``
+  .. deprecated:: 3.26
+    Superseded by the ``LIBLZMA_VERSION`` (and ``LibLZMA_VERSION``).
+
+  The version of liblzma found.
+
+``LIBLZMA_VERSION_MAJOR``
+  .. deprecated:: 3.26
+
+  The major version of liblzma found.
+
+``LIBLZMA_VERSION_MINOR``
+  .. deprecated:: 3.26
+
+  The minor version of liblzma found.
+
+``LIBLZMA_VERSION_PATCH``
+  .. deprecated:: 3.26
+
+  The patch version of liblzma found.
 
 Examples
 ^^^^^^^^
@@ -99,8 +131,9 @@
     string(REGEX REPLACE ".*#define LZMA_VERSION_MINOR ([0-9]+).*" "\\1" LIBLZMA_VERSION_MINOR "${LIBLZMA_HEADER_CONTENTS}")
     string(REGEX REPLACE ".*#define LZMA_VERSION_PATCH ([0-9]+).*" "\\1" LIBLZMA_VERSION_PATCH "${LIBLZMA_HEADER_CONTENTS}")
 
-    set(LIBLZMA_VERSION_STRING "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
-    set(LIBLZMA_VERSION ${LIBLZMA_VERSION_STRING})
+    set(LibLZMA_VERSION "${LIBLZMA_VERSION_MAJOR}.${LIBLZMA_VERSION_MINOR}.${LIBLZMA_VERSION_PATCH}")
+    set(LIBLZMA_VERSION "${LibLZMA_VERSION}")
+    set(LIBLZMA_VERSION_STRING "${LibLZMA_VERSION}")
     unset(LIBLZMA_HEADER_CONTENTS)
 endif()
 
@@ -131,7 +164,7 @@
                                                           LIBLZMA_HAS_AUTO_DECODER
                                                           LIBLZMA_HAS_EASY_ENCODER
                                                           LIBLZMA_HAS_LZMA_PRESET
-                                           VERSION_VAR    LIBLZMA_VERSION
+                                           VERSION_VAR    LibLZMA_VERSION
                                  )
 mark_as_advanced( LIBLZMA_INCLUDE_DIR LIBLZMA_LIBRARY )
 
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
index f453021..67d20e4 100644
--- a/Modules/FindLibXml2.cmake
+++ b/Modules/FindLibXml2.cmake
@@ -5,7 +5,11 @@
 FindLibXml2
 -----------
 
-Finds the XML processing library (libxml2).
+Finds the XML processing library (libxml2):
+
+.. code-block:: cmake
+
+  find_package(LibXml2 [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -30,15 +34,24 @@
 This module defines the following variables:
 
 ``LibXml2_FOUND``
-  Boolean indicating whether the libxml2 library is found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) libxml2 library was
+  found.
+
+``LibXml2_VERSION``
+  .. versionadded:: 4.2
+
+  The version of the libxml2 found.
+
 ``LIBXML2_INCLUDE_DIRS``
   Include directories needed to use the libxml2 library.
+
 ``LIBXML2_LIBRARIES``
   Libraries needed to link against to use the libxml2 library.
+
 ``LIBXML2_DEFINITIONS``
   The compiler switches required for using libxml2.
-``LIBXML2_VERSION_STRING``
-  The version of the libxml2 found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -47,11 +60,31 @@
 
 ``LIBXML2_INCLUDE_DIR``
   The include directory containing libxml2 headers.
+
 ``LIBXML2_LIBRARY``
   The path to the libxml2 library.
+
 ``LIBXML2_XMLLINT_EXECUTABLE``
   The path to the XML checking tool ``xmllint`` coming with libxml2.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LIBXML2_FOUND``
+  .. deprecated:: 4.2
+    Use ``LibXml2_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) libxml2 library was
+  found.
+
+``LIBXML2_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``LibXml2_VERSION``.
+
+  The version of the libxml2 found.
+
 Examples
 ^^^^^^^^
 
@@ -69,7 +102,7 @@
 # use pkg-config to get the directories and then use these values
 # in the find_path() and find_library() calls
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_LIBXML QUIET libxml-2.0)
 endif()
 
@@ -102,7 +135,8 @@
          REGEX "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\".*\"")
 
     string(REGEX REPLACE "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
-           LIBXML2_VERSION_STRING "${libxml2_version_str}")
+           LibXml2_VERSION "${libxml2_version_str}")
+    set(LIBXML2_VERSION_STRING "${LibXml2_VERSION}")
     unset(libxml2_version_str)
 endif()
 
@@ -123,7 +157,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(LibXml2
                                   REQUIRED_VARS LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR
-                                  VERSION_VAR LIBXML2_VERSION_STRING)
+                                  VERSION_VAR LibXml2_VERSION)
 
 mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY LIBXML2_XMLLINT_EXECUTABLE)
 
diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake
index d612c7d..c102e93 100644
--- a/Modules/FindLibXslt.cmake
+++ b/Modules/FindLibXslt.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds the XSL Transformations, Extensible Stylesheet Language Transformations
-(XSLT) library (libxslt).
+(XSLT) library (libxslt):
+
+.. code-block:: cmake
+
+  find_package(LibXslt [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -33,11 +37,17 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``LibXslt_FOUND``
-  Boolean indicating whether the libxslt is found.  For backward compatibility,
-  the ``LIBXSLT_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) libxslt was found.
+
+``LibXslt_VERSION``
+  .. versionadded:: 4.2
+
+  The version of libxslt found.
 
 ``LIBXSLT_LIBRARIES``
   Libraries needed to link to libxslt.
@@ -45,9 +55,6 @@
 ``LIBXSLT_DEFINITIONS``
   Compiler switches required for using libxslt.
 
-``LIBXSLT_VERSION_STRING``
-  Version of libxslt found.
-
 ``LIBXSLT_EXSLT_LIBRARIES``
   Libraries needed when linking against the exslt library.  These are available
   and needed only when using exslt library.
@@ -70,6 +77,23 @@
   Full path to the XSLT processor executable ``xsltproc`` if found.  This path
   is optional.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LIBXSLT_FOUND``
+  .. deprecated:: 4.2
+    Use ``LibXslt_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) libxslt was found.
+
+``LIBXSLT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``LibXslt_VERSION``.
+
+  The version of libxslt found.
+
 Examples
 ^^^^^^^^
 
@@ -109,7 +133,7 @@
 # use pkg-config to get the directories and then use these values
 # in the find_path() and find_library() calls
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_LIBXSLT QUIET libxslt)
 endif()
 set(LIBXSLT_DEFINITIONS ${PC_LIBXSLT_CFLAGS_OTHER})
@@ -135,7 +159,7 @@
 
 set(LIBXSLT_LIBRARIES ${LIBXSLT_LIBRARY})
 
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_LIBXSLT_EXSLT QUIET libexslt)
 endif()
 set(LIBXSLT_EXSLT_DEFINITIONS ${PC_LIBXSLT_EXSLT_CFLAGS_OTHER})
@@ -159,20 +183,22 @@
 find_program(LIBXSLT_XSLTPROC_EXECUTABLE xsltproc)
 
 if(PC_LIBXSLT_VERSION)
-    set(LIBXSLT_VERSION_STRING ${PC_LIBXSLT_VERSION})
+    set(LibXslt_VERSION ${PC_LIBXSLT_VERSION})
+    set(LIBXSLT_VERSION_STRING "${LibXslt_VERSION}")
 elseif(LIBXSLT_INCLUDE_DIR AND EXISTS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h")
     file(STRINGS "${LIBXSLT_INCLUDE_DIR}/libxslt/xsltconfig.h" libxslt_version_str
          REGEX "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\".*\"")
 
     string(REGEX REPLACE "^#define[\t ]+LIBXSLT_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
-           LIBXSLT_VERSION_STRING "${libxslt_version_str}")
+           LibXslt_VERSION "${libxslt_version_str}")
+    set(LIBXSLT_VERSION_STRING "${LibXslt_VERSION}")
     unset(libxslt_version_str)
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(LibXslt
                                   REQUIRED_VARS LIBXSLT_LIBRARIES LIBXSLT_INCLUDE_DIR
-                                  VERSION_VAR LIBXSLT_VERSION_STRING)
+                                  VERSION_VAR LibXslt_VERSION)
 
 mark_as_advanced(LIBXSLT_INCLUDE_DIR
                  LIBXSLT_LIBRARY
diff --git a/Modules/FindLibinput.cmake b/Modules/FindLibinput.cmake
index f3e66af..5c420e9 100644
--- a/Modules/FindLibinput.cmake
+++ b/Modules/FindLibinput.cmake
@@ -8,7 +8,11 @@
 .. versionadded:: 3.14
 
 Finds the libinput library which handles input devices in Wayland compositors
-and provides a generic X.Org input driver.
+and provides a generic X.Org input driver:
+
+.. code-block:: cmake
+
+  find_package(Libinput [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -25,7 +29,7 @@
 This module defines the following variables:
 
 ``Libinput_FOUND``
-  Boolean indicating whether the (requested version of) libinput library is
+  Boolean indicating whether the (requested version of) libinput library was
   found.
 ``Libinput_VERSION``
   The version of the libinput found.
@@ -53,7 +57,7 @@
 # Use pkg-config to get the directories and then use these values
 # in the FIND_PATH() and FIND_LIBRARY() calls
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PKG_Libinput QUIET libinput)
 endif()
 
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
index 50f37f6..33fd8fd 100644
--- a/Modules/FindLua.cmake
+++ b/Modules/FindLua.cmake
@@ -5,7 +5,13 @@
 FindLua
 -------
 
-Finds the Lua library.  Lua is a embeddable scripting language.
+Finds the Lua library:
+
+.. code-block:: cmake
+
+  find_package(Lua [<version>] [...])
+
+Lua is a embeddable scripting language.
 
 .. versionadded:: 3.18
   Support for Lua 5.4.
@@ -32,17 +38,30 @@
 This module defines the following variables:
 
 ``Lua_FOUND``
-  Boolean indicating whether (the requested version of) Lua is found.  For
-  backward compatibility, the ``LUA_FOUND`` variable is also set to the same
-  value.
-``LUA_VERSION_STRING``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Lua was found.
+
+``Lua_VERSION``
+  .. versionadded:: 4.2
+
   The version of Lua found.
-``LUA_VERSION_MAJOR``
+
+``Lua_VERSION_MAJOR``
+  .. versionadded:: 4.2
+
   The major version of Lua found.
-``LUA_VERSION_MINOR``
+
+``Lua_VERSION_MINOR``
+  .. versionadded:: 4.2
+
   The minor version of Lua found.
-``LUA_VERSION_PATCH``
+
+``Lua_VERSION_PATCH``
+  .. versionadded:: 4.2
+
   The patch version of Lua found.
+
 ``LUA_LIBRARIES``
   Libraries needed to link against to use Lua.  This list includes both ``lua``
   and ``lualib`` libraries.
@@ -56,6 +75,41 @@
   The directory containing the Lua header files, such as ``lua.h``,
   ``lualib.h``, and ``lauxlib.h``, needed to use Lua.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LUA_FOUND``
+  .. deprecated:: 4.2
+    Use ``Lua_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Lua was found.
+
+``LUA_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Lua_VERSION``.
+
+  The version of Lua found.
+
+``LUA_VERSION_MAJOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Lua_VERSION_MAJOR``.
+
+  The major version of Lua found.
+
+``LUA_VERSION_MINOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Lua_VERSION_MINOR``.
+
+  The minor version of Lua found.
+
+``LUA_VERSION_PATCH``
+  .. deprecated:: 4.2
+    Superseded by the ``Lua_VERSION_PATCH``.
+
+  The patch version of Lua found.
+
 Examples
 ^^^^^^^^
 
@@ -81,6 +135,7 @@
 #]=======================================================================]
 
 cmake_policy(PUSH)  # Policies apply to functions at definition-time
+cmake_policy(SET CMP0140 NEW)
 cmake_policy(SET CMP0159 NEW)  # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
 
 unset(_lua_include_subdirs)
@@ -146,7 +201,7 @@
 endfunction()
 
 function(_lua_get_header_version)
-  unset(LUA_VERSION_STRING PARENT_SCOPE)
+  unset(Lua_VERSION PARENT_SCOPE)
   set(_hdr_file "${LUA_INCLUDE_DIR}/lua.h")
 
   if (NOT EXISTS "${_hdr_file}")
@@ -159,27 +214,39 @@
   file(STRINGS "${_hdr_file}" lua_version_strings
        REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
 
-  string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
-  if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
-    string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
-    string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
-    set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
+  string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_MAJOR ";${lua_version_strings};")
+
+  if (Lua_VERSION_MAJOR MATCHES "^[0-9]+$")
+    string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_MINOR ";${lua_version_strings};")
+    string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_PATCH ";${lua_version_strings};")
+    set(Lua_VERSION "${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}.${Lua_VERSION_PATCH}")
   else ()
-    string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
-    if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
-      string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
+    string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" Lua_VERSION ";${lua_version_strings};")
+    if (NOT Lua_VERSION MATCHES "^[0-9.]+$")
+      string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" Lua_VERSION ";${lua_version_strings};")
     endif ()
-    string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
-    string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
-    string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
+    string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" Lua_VERSION_MAJOR "${Lua_VERSION}")
+    string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" Lua_VERSION_MINOR "${Lua_VERSION}")
+    string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" Lua_VERSION_PATCH "${Lua_VERSION}")
   endif ()
   foreach (ver IN LISTS _lua_append_versions)
-    if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
-      set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE)
-      set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE)
-      set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE)
-      set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
-      return()
+    if (ver STREQUAL "${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}")
+      set(LUA_VERSION_STRING "${Lua_VERSION}")
+      set(LUA_VERSION_MAJOR "${Lua_VERSION_MAJOR}")
+      set(LUA_VERSION_MINOR "${Lua_VERSION_MINOR}")
+      set(LUA_VERSION_PATCH "${Lua_VERSION_PATCH}")
+
+      return(
+        PROPAGATE
+          Lua_VERSION
+          Lua_VERSION_MAJOR
+          Lua_VERSION_MINOR
+          Lua_VERSION_PATCH
+          LUA_VERSION_STRING
+          LUA_VERSION_MAJOR
+          LUA_VERSION_MINOR
+          LUA_VERSION_PATCH
+      )
     endif ()
   endforeach ()
 endfunction()
@@ -208,9 +275,9 @@
     endif()
     _lua_get_header_version()
     # Found accepted version -> Ok
-    if (LUA_VERSION_STRING)
+    if (Lua_VERSION)
       if (LUA_Debug)
-        message(STATUS "Found suitable version ${LUA_VERSION_STRING} in ${LUA_INCLUDE_DIR}/lua.h")
+        message(STATUS "Found suitable version ${Lua_VERSION} in ${LUA_INCLUDE_DIR}/lua.h")
       endif()
       return()
     endif()
@@ -230,12 +297,12 @@
 _lua_get_header_version()
 unset(_lua_append_versions)
 
-if (LUA_VERSION_STRING)
+if (Lua_VERSION)
   set(_lua_library_names
-    lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR}
-    lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
-    lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
-    lua.${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}
+    lua${Lua_VERSION_MAJOR}${Lua_VERSION_MINOR}
+    lua${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}
+    lua-${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}
+    lua.${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}
     )
 endif ()
 
@@ -270,7 +337,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Lua
                                   REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
-                                  VERSION_VAR LUA_VERSION_STRING)
+                                  VERSION_VAR Lua_VERSION)
 
 mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY)
 
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake
index ac36c86..0651a56 100644
--- a/Modules/FindLua50.cmake
+++ b/Modules/FindLua50.cmake
@@ -7,11 +7,17 @@
 
 .. note::
 
-  This module is specifically for Lua version branch 5.0, which is obsolete and
-  not maintained anymore.  In new code use the latest supported Lua version and
-  the version-agnostic module :module:`FindLua` instead.
+  This module is intended specifically for Lua version branch 5.0, which is
+  obsolete and not maintained anymore.  In new code use the latest supported
+  Lua version and the version-agnostic module :module:`FindLua` instead.
 
-Finds the Lua library.  Lua is a embeddable scripting language.
+Finds the Lua library:
+
+.. code-block:: cmake
+
+  find_package(Lua50 [...])
+
+Lua is a embeddable scripting language.
 
 When working with Lua, its library headers are intended to be included in
 project source code as:
@@ -35,8 +41,9 @@
 This module defines the following variables:
 
 ``Lua50_FOUND``
-  Boolean indicating whether Lua is found.  For backward compatibility, the
-  ``LUA50_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Lua was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -51,6 +58,17 @@
   Libraries needed to link against to use Lua.  This list includes both ``lua``
   and ``lualib`` libraries.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LUA50_FOUND``
+  .. deprecated:: 4.2
+    Use ``Lua50_FOUND``, which has the same value.
+
+  Boolean indicating whether Lua was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake
index cba30e4..ad8a8ea 100644
--- a/Modules/FindLua51.cmake
+++ b/Modules/FindLua51.cmake
@@ -7,11 +7,17 @@
 
 .. note::
 
-  This module is specifically for Lua version branch 5.1, which is obsolete and
-  not maintained anymore.  In new code use the latest supported Lua version and
-  the version-agnostic module :module:`FindLua` instead.
+  This module is intended specifically for Lua version branch 5.1, which is
+  obsolete and not maintained anymore.  In new code use the latest supported
+  Lua version and the version-agnostic module :module:`FindLua` instead.
 
-Finds the Lua library.  Lua is a embeddable scripting language.
+Finds the Lua library:
+
+.. code-block:: cmake
+
+  find_package(Lua51 [<version>] [...])
+
+Lua is a embeddable scripting language.
 
 When working with Lua, its library headers are intended to be included in
 project source code as:
@@ -35,10 +41,14 @@
 This module defines the following variables:
 
 ``Lua51_FOUND``
-  Boolean indicating whether Lua is found.  For backward compatibility, the
-  ``LUA51_FOUND`` variable is also set to the same value.
-``LUA_VERSION_STRING``
-  The version of Lua found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Lua was found.
+
+``Lua51_VERSION``
+  .. versionadded:: 4.2
+
+  The version of Lua 5.1 found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -48,9 +58,27 @@
 ``LUA_INCLUDE_DIR``
   The directory containing the Lua header files, such as ``lua.h``,
   ``lualib.h``, and ``lauxlib.h``, needed to use Lua.
+
 ``LUA_LIBRARIES``
   Libraries needed to link against to use Lua.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``LUA51_FOUND``
+  .. deprecated:: 4.2
+    Use ``Lua51_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Lua was found.
+
+``LUA_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Lua51_VERSION``, which has the same value.
+
+  The version of Lua 5.1 found.
+
 Examples
 ^^^^^^^^
 
@@ -118,14 +146,15 @@
 if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
   file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
 
-  string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
+  string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" Lua51_VERSION "${lua_version_str}")
+  set(LUA_VERSION_STRING "${Lua51_VERSION}")
   unset(lua_version_str)
 endif()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Lua51
                                   REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
-                                  VERSION_VAR LUA_VERSION_STRING)
+                                  VERSION_VAR Lua51_VERSION)
 
 mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
 
diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake
index 27c5458..77adebf 100644
--- a/Modules/FindMFC.cmake
+++ b/Modules/FindMFC.cmake
@@ -6,7 +6,11 @@
 -------
 
 Finds the native Microsoft Foundation Class Library (MFC) for developing MFC
-applications on Windows.
+applications on Windows:
+
+.. code-block:: cmake
+
+  find_package(MFC [...])
 
 .. note::
 
@@ -22,7 +26,7 @@
 This module defines the following variables:
 
 ``MFC_FOUND``
-  Boolean indicating whether MFC support is found.
+  Boolean indicating whether MFC support was found.
 
 Examples
 ^^^^^^^^
diff --git a/Modules/FindMPEG.cmake b/Modules/FindMPEG.cmake
index 6c49702..824ae14 100644
--- a/Modules/FindMPEG.cmake
+++ b/Modules/FindMPEG.cmake
@@ -5,7 +5,11 @@
 FindMPEG
 --------
 
-Finds the native MPEG library (libmpeg2).
+Finds the native MPEG library (libmpeg2):
+
+.. code-block:: cmake
+
+  find_package(MPEG [...])
 
 .. note::
 
@@ -24,14 +28,14 @@
 This module defines the following variables:
 
 ``MPEG_FOUND``
-  Boolean indicating whether the libmpeg2 library is found.
+  Boolean indicating whether the libmpeg2 library was found.
 ``MPEG_LIBRARIES``
   Libraries needed to link against to use libmpeg2.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be also set:
+The following cache variables may also be set:
 
 ``MPEG_INCLUDE_DIR``
   The directory containing the ``mpeg2.h`` and related headers needed to use
diff --git a/Modules/FindMPEG2.cmake b/Modules/FindMPEG2.cmake
index 103f2c4..2e647ba 100644
--- a/Modules/FindMPEG2.cmake
+++ b/Modules/FindMPEG2.cmake
@@ -5,7 +5,11 @@
 FindMPEG2
 ---------
 
-Finds the native MPEG2 library (libmpeg2).
+Finds the native MPEG2 library (libmpeg2):
+
+.. code-block:: cmake
+
+  find_package(MPEG2 [...])
 
 .. note::
 
@@ -19,14 +23,14 @@
 This module defines the following variables:
 
 ``MPEG2_FOUND``
-  Boolean indicating whether the libmpeg2 library is found.
+  Boolean indicating whether the libmpeg2 library was found.
 ``MPEG2_LIBRARIES``
   Libraries needed to link against to use libmpeg2.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be also set:
+The following cache variables may also be set:
 
 ``MPEG2_INCLUDE_DIR``
   The directory containing the ``mpeg2.h`` and related headers needed to use
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 78b1c5c..ebfd79f 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -5,7 +5,11 @@
 FindMPI
 -------
 
-Find a Message Passing Interface (MPI) implementation.
+Finds a Message Passing Interface (MPI) implementation:
+
+.. code-block:: cmake
+
+  find_package(MPI [<version>] [COMPONENTS <langs>...] [...])
 
 The Message Passing Interface (MPI) is a library used to write
 high-performance distributed-memory parallel applications, and is
@@ -14,253 +18,410 @@
 
 .. versionadded:: 3.10
   Major overhaul of the module: many new variables, per-language components,
-  support for a wider variety of runtimes.
+  and support for a wider variety of runtimes.
 
-Variables for using MPI
-^^^^^^^^^^^^^^^^^^^^^^^
+Components
+^^^^^^^^^^
 
-The module exposes the components ``C``, ``CXX``, ``MPICXX`` and ``Fortran``.
-Each of these controls the various MPI languages to search for.
-The difference between ``CXX`` and ``MPICXX`` is that ``CXX`` refers to the
-MPI C API being usable from C++, whereas ``MPICXX`` refers to the MPI-2 C++ API
-that was removed again in MPI-3.
+This module supports optional components that can be specified with the
+:command:`find_package` command to control which MPI languages to search
+for:
 
-Depending on the enabled components the following variables will be set:
+.. code-block:: cmake
+
+  find_package(MPI [COMPONENTS <langs>...])
+
+Supported components include:
+
+``C``
+  .. versionadded:: 3.10
+
+  Finds MPI C API.
+
+``CXX``
+  .. versionadded:: 3.10
+
+  Finds the MPI C API that is usable from C++.
+
+``MPICXX``
+  .. versionadded:: 3.10
+
+  Finds the MPI-2 C++ API that was removed in MPI-3.
+
+``Fortran``
+  .. versionadded:: 3.10
+
+  Finds the MPI Fortran API.
+
+If no components are specified, module searches for the ``C``, ``CXX``, and
+``Fortran`` components automatically, depending on which languages are
+enabled in the project.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following :ref:`Imported Targets`:
+
+``MPI::MPI_<lang>``
+  .. versionadded:: 3.9
+
+  Target encapsulating usage requirements for using MPI from language
+  ``<lang>``, available if MPI is found.  The ``<lang>`` is a specified
+  component name as listed above.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
 
 ``MPI_FOUND``
-  Variable indicating that MPI settings for all requested languages have been found.
-  If no components are specified, this is true if MPI settings for all enabled languages
-  were detected. Note that the ``MPICXX`` component does not affect this variable.
-``MPI_VERSION``
-  Minimal version of MPI detected among the requested languages, or all enabled languages
-  if no components were specified.
+  Boolean indicating that MPI settings for all requested components
+  (languages) were found.  If no components are specified, this variable is
+  set to boolean true if MPI settings for all enabled languages were
+  detected.  Note that the ``MPICXX`` component does not affect this
+  variable.
 
-This module will set the following variables per language in your
-project, where ``<lang>`` is one of C, CXX, or Fortran:
+``MPI_VERSION``
+  Minimal version of MPI detected among the requested languages, or all
+  enabled languages if no components were specified.
+
+This module will set the following variables per language in CMake project,
+where ``<lang>`` is one of C, CXX, or Fortran:
 
 ``MPI_<lang>_FOUND``
-  Variable indicating the MPI settings for ``<lang>`` were found and that
+  Boolean indicating the MPI settings for ``<lang>`` were found and that
   simple MPI test programs compile with the provided settings.
+
 ``MPI_<lang>_COMPILER``
   MPI compiler for ``<lang>`` if such a program exists.
+
 ``MPI_<lang>_COMPILE_OPTIONS``
-  Compilation options for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
+  Compilation options for MPI programs in ``<lang>``, given as a
+  :ref:`semicolon-separated list <CMake Language Lists>`.
+
 ``MPI_<lang>_COMPILE_DEFINITIONS``
-  Compilation definitions for MPI programs in ``<lang>``, given as a :ref:`;-list <CMake Language Lists>`.
+  Compilation definitions for MPI programs in ``<lang>``, given as a
+  :ref:`semicolon-separated list <CMake Language Lists>`.
+
 ``MPI_<lang>_INCLUDE_DIRS``
   Include path(s) for MPI header.
+
 ``MPI_<lang>_LINK_FLAGS``
   Linker flags for MPI programs.
+
 ``MPI_<lang>_LIBRARIES``
   All libraries to link MPI programs against.
 
-.. versionadded:: 3.9
-  Additionally, the following :prop_tgt:`IMPORTED` targets are defined:
-
-``MPI::MPI_<lang>``
-  Target for using MPI from ``<lang>``.
-
-The following variables indicating which bindings are present will be defined:
+The following variables indicating which bindings are present will be
+defined:
 
 ``MPI_MPICXX_FOUND``
-  Variable indicating whether the MPI-2 C++ bindings are present (introduced in MPI-2, removed with MPI-3).
+  Boolean indicating whether the MPI-2 C++ bindings are present (introduced
+  in MPI-2, removed with MPI-3).
+
 ``MPI_Fortran_HAVE_F77_HEADER``
-  True if the Fortran 77 header ``mpif.h`` is available.
+  True if the Fortran 77 header ``<mpif.h>`` is available.
+
 ``MPI_Fortran_HAVE_F90_MODULE``
-  True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2 and higher only).
+  True if the Fortran 90 module ``mpi`` can be used for accessing MPI (MPI-2
+  and higher only).
+
 ``MPI_Fortran_HAVE_F08_MODULE``
-  True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3 and higher only).
+  True if the Fortran 2008 ``mpi_f08`` is available to MPI programs (MPI-3
+  and higher only).
 
-If possible, the MPI version will be determined by this module. The facilities to detect the MPI version
-were introduced with MPI-1.2, and therefore cannot be found for older MPI versions.
+If possible, the MPI version will be determined by this module.  The
+facilities to detect the MPI version were introduced with MPI-1.2, and
+therefore cannot be found for older MPI versions.
 
-``MPI_<lang>_VERSION_MAJOR``
-  Major version of MPI implemented for ``<lang>`` by the MPI distribution.
-``MPI_<lang>_VERSION_MINOR``
-  Minor version of MPI implemented for ``<lang>`` by the MPI distribution.
 ``MPI_<lang>_VERSION``
   MPI version implemented for ``<lang>`` by the MPI distribution.
 
-Note that there's no variable for the C bindings being accessible through ``mpi.h``, since the MPI standards
-always have required this binding to work in both C and C++ code.
+``MPI_<lang>_VERSION_MAJOR``
+  Major version of MPI implemented for ``<lang>`` by the MPI distribution.
 
-For running MPI programs, the module sets the following variables
+``MPI_<lang>_VERSION_MINOR``
+  Minor version of MPI implemented for ``<lang>`` by the MPI distribution.
+
+Note that there's no variable for the C bindings being accessible through
+``<mpi.h>``, since the MPI standards always have required this binding to
+work in both C and C++ code.
+
+For running MPI programs, the module sets the following variables:
 
 ``MPIEXEC_EXECUTABLE``
   Executable for running MPI programs, if such exists.
+
 ``MPIEXEC_NUMPROC_FLAG``
-  Flag to pass to ``mpiexec`` before giving it the number of processors to run on.
+  Flag to pass to ``mpiexec`` before giving it the number of processors to
+  run on.
+
 ``MPIEXEC_MAX_NUMPROCS``
-  Number of MPI processors to utilize. Defaults to the number
-  of processors detected on the host system.
+  Number of MPI processors to utilize.  Defaults to the number of
+  processors detected on the host system.
+
 ``MPIEXEC_PREFLAGS``
   Flags to pass to ``mpiexec`` directly before the executable to run.
+
 ``MPIEXEC_POSTFLAGS``
   Flags to pass to ``mpiexec`` after other flags.
 
-Variables for locating MPI
+Variables for Locating MPI
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-This module performs a four step search for an MPI implementation:
+This module performs a four-step search for an MPI implementation:
 
-1. Search for ``MPIEXEC_EXECUTABLE`` and, if found, use its base directory.
-2. Check if the compiler has MPI support built-in. This is the case if the user passed a
-   compiler wrapper as ``CMAKE_<LANG>_COMPILER`` or if they use Cray system compiler wrappers.
-3. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
-4. Try to find an MPI implementation that does not ship such a wrapper by guessing settings.
-   Currently, only Microsoft MPI and MPICH2 on Windows are supported.
+1. Searches for ``MPIEXEC_EXECUTABLE`` and, if found, uses its base
+   directory.
+2. Checks if the compiler has MPI support built-in.  This is the case if
+   the user passed a compiler wrapper as :variable:`CMAKE_<LANG>_COMPILER`
+   or if they use Cray system compiler wrappers.
+3. Attempts to find an MPI compiler wrapper and determines the compiler
+   information from it.
+4. Tries to find an MPI implementation that does not ship such a wrapper by
+   guessing settings.  Currently, only Microsoft MPI and MPICH2 on Windows
+   are supported.
 
-For controlling the ``MPIEXEC_EXECUTABLE`` step, the following variables may be set:
+For controlling the ``MPIEXEC_EXECUTABLE`` step, the following variables
+may be set:
 
 ``MPIEXEC_EXECUTABLE``
   Manually specify the location of ``mpiexec``.
+
 ``MPI_HOME``
   Specify the base directory of the MPI installation.
+
 ``ENV{MPI_HOME}``
   Environment variable to specify the base directory of the MPI installation.
+
 ``ENV{I_MPI_ROOT}``
   Environment variable to specify the base directory of the MPI installation.
 
-For controlling the compiler wrapper step, the following variables may be set:
+For controlling the compiler wrapper step, the following variables may be
+set:
 
 ``MPI_<lang>_COMPILER``
   Search for the specified compiler wrapper and use it.
+
 ``MPI_<lang>_COMPILER_FLAGS``
-  Flags to pass to the MPI compiler wrapper during interrogation. Some compiler wrappers
-  support linking debug or tracing libraries if a specific flag is passed and this variable
-  may be used to obtain them.
+  Flags to pass to the MPI compiler wrapper during interrogation.  Some
+  compiler wrappers support linking debug or tracing libraries if a specific
+  flag is passed and this variable may be used to obtain them.
+
 ``MPI_COMPILER_FLAGS``
-  Used to initialize ``MPI_<lang>_COMPILER_FLAGS`` if no language specific flag has been given.
-  Empty by default.
+  Used to initialize ``MPI_<lang>_COMPILER_FLAGS`` if no language specific
+  flag has been given.  Empty by default.
+
 ``MPI_EXECUTABLE_SUFFIX``
-  A suffix which is appended to all names that are being looked for. For instance you may set this
-  to ``.mpich`` or ``.openmpi`` to prefer the one or the other on Debian and its derivatives.
+  A suffix which is appended to all names that are being looked for.  For
+  instance, it may be set to ``.mpich`` or ``.openmpi`` to prefer the one
+  or the other on Debian and its derivatives.
 
 In order to control the guessing step, the following variable may be set:
 
 ``MPI_GUESS_LIBRARY_NAME``
-  Valid values are ``MSMPI`` and ``MPICH2``. If set, only the given library will be searched for.
-  By default, ``MSMPI`` will be preferred over ``MPICH2`` if both are available.
-  This also sets ``MPI_SKIP_COMPILER_WRAPPER`` to ``true``, which may be overridden.
+  Valid values are ``MSMPI`` and ``MPICH2``.  If set, only the given library
+  will be searched for.  By default, ``MSMPI`` will be preferred over
+  ``MPICH2`` if both are available.  This also sets
+  ``MPI_SKIP_COMPILER_WRAPPER`` variable to ``true``, which may be
+  overridden.
 
 Each of the search steps may be skipped with the following control variables:
 
 ``MPI_ASSUME_NO_BUILTIN_MPI``
-  If true, the module assumes that the compiler itself does not provide an MPI implementation and
-  skips to step 2.
+  If true, the module assumes that the compiler itself does not provide an
+  MPI implementation and skips to step 2.
+
 ``MPI_SKIP_COMPILER_WRAPPER``
   If true, no compiler wrapper will be searched for.
+
 ``MPI_SKIP_GUESSING``
   If true, the guessing step will be skipped.
 
-Additionally, the following control variable is available to change search behavior:
+Additionally, the following control variable is available to change search
+behavior:
 
 ``MPI_CXX_SKIP_MPICXX``
   Add some definitions that will disable the MPI-2 C++ bindings.
-  Currently supported are MPICH, Open MPI, Platform MPI and derivatives thereof,
-  for example MVAPICH or Intel MPI.
+  Currently supported are MPICH, Open MPI, Platform MPI and derivatives
+  thereof, for example, MVAPICH or Intel MPI.
 
-If the find procedure fails for a variable ``MPI_<lang>_WORKS``, then the settings detected by or passed to
-the module did not work and even a simple MPI test program failed to compile.
+If the find procedure fails for the module's internal variable
+``MPI_<lang>_WORKS``, then the settings detected by or passed to the module
+did not work and even a simple MPI test program failed to compile.
 
-If all of these parameters were not sufficient to find the right MPI implementation, a user may
-disable the entire autodetection process by specifying both a list of libraries in ``MPI_<lang>_LIBRARIES``
-and a list of include directories in ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``.
-Any other variable may be set in addition to these two. The module will then validate the MPI settings and store the
-settings in the cache.
+If all of these parameters were not sufficient to find the right MPI
+implementation, a user may disable the entire autodetection process by
+specifying both a list of libraries in ``MPI_<lang>_LIBRARIES`` and a list
+of include directories in ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``.  Any other
+variable may be set in addition to these two.  The module will then validate
+the MPI settings and store the settings in the cache.
 
-Cache variables for MPI
-^^^^^^^^^^^^^^^^^^^^^^^
+Cache Variables
+^^^^^^^^^^^^^^^
 
-The variable ``MPI_<lang>_INCLUDE_DIRS`` will be assembled from the following variables.
+The variable ``MPI_<lang>_INCLUDE_DIRS`` will be assembled from the
+following variables.
+
 For C and CXX:
 
 ``MPI_<lang>_HEADER_DIR``
-  Location of the ``mpi.h`` header on disk.
+  Location of the ``<mpi.h>`` header on disk.
 
 For Fortran:
 
 ``MPI_Fortran_F77_HEADER_DIR``
-  Location of the Fortran 77 header ``mpif.h``, if it exists.
+  Location of the Fortran 77 header ``<mpif.h>``, if it exists.
+
 ``MPI_Fortran_MODULE_DIR``
   Location of the ``mpi`` or ``mpi_f08`` modules, if available.
 
 For all languages the following variables are additionally considered:
 
 ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS``
-  A :ref:`;-list <CMake Language Lists>` of paths needed in addition to the normal include directories.
-``MPI_<include_name>_INCLUDE_DIR``
-  Path variables for include folders referred to by ``<include_name>``.
+  A :ref:`semicolon-separated list <CMake Language Lists>` of paths needed
+  in addition to the normal include directories.
+
+``MPI_<include-name>_INCLUDE_DIR``
+  Path variables for include folders referred to by ``<include-name>``.
+
 ``MPI_<lang>_ADDITIONAL_INCLUDE_VARS``
-  A :ref:`;-list <CMake Language Lists>` of ``<include_name>`` that will be added to the include locations of ``<lang>``.
+  A :ref:`semicolon-separated list <CMake Language Lists>` of
+  ``<include-name>`` that will be added to the include locations of
+  ``<lang>``.
 
-The variable ``MPI_<lang>_LIBRARIES`` will be assembled from the following variables:
+The variable ``MPI_<lang>_LIBRARIES`` will be assembled from the following
+variables:
 
-``MPI_<lib_name>_LIBRARY``
-  The location of a library called ``<lib_name>`` for use with MPI.
+``MPI_<lib-name>_LIBRARY``
+  The location of a library called ``<lib-name>`` for use with MPI.
+
 ``MPI_<lang>_LIB_NAMES``
-  A :ref:`;-list <CMake Language Lists>` of ``<lib_name>`` that will be added to the include locations of ``<lang>``.
+  A :ref:`semicolon-separated list <CMake Language Lists>` of ``<lib-name>``
+  that will be added to the include locations of ``<lang>``.
 
-Usage of mpiexec
-^^^^^^^^^^^^^^^^
+Advanced Variables for Using MPI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, you should typically
-use all of the ``MPIEXEC_EXECUTABLE`` flags as follows:
+The module can perform some advanced feature detections upon explicit
+request.
+
+.. note::
+
+  The following checks cannot be performed without *executing* an MPI test
+  program.  Consider the special considerations for the behavior of
+  :command:`try_run` during cross compilation.  Moreover, running an MPI
+  program can cause additional issues, like a firewall notification on some
+  systems.  These detections should be only enabled if information is
+  absolutely needed.
+
+If the following variables are set to true, the respective search will be
+performed:
+
+``MPI_DETERMINE_Fortran_CAPABILITIES``
+  Determine for all available Fortran bindings what the values of
+  ``MPI_SUBARRAYS_SUPPORTED`` and ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are
+  and make their values available as ``MPI_Fortran_<binding>_SUBARRAYS``
+  and ``MPI_Fortran_<binding>_ASYNCPROT``, where ``<binding>`` is one of
+  ``F77_HEADER``, ``F90_MODULE`` and ``F08_MODULE``.
+
+``MPI_DETERMINE_LIBRARY_VERSION``
+  For each language, find the output of ``MPI_Get_library_version`` and
+  make it available as ``MPI_<lang>_LIBRARY_VERSION_STRING``.  This
+  information is usually tied to the runtime component of an MPI
+  implementation and might differ depending on ``<lang>``.
+  Note that the return value is entirely implementation defined.  This
+  information might be used to identify the MPI vendor and for example pick
+  the correct one of multiple third party binaries that matches the MPI
+  vendor.
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``MPI_COMPILER``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_COMPILER`` instead.
+
+``MPI_LIBRARY``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_LIBRARIES`` instead.
+
+``MPI_EXTRA_LIBRARY``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_LIBRARIES`` instead.
+
+``MPI_COMPILE_FLAGS``
+  .. deprecated:: 2.8.5
+    Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS``
+    instead.
+
+``MPI_INCLUDE_PATH``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_INCLUDE_DIRS`` instead.
+
+``MPI_LINK_FLAGS``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_LINK_FLAGS`` instead.
+
+``MPI_LIBRARIES``
+  .. deprecated:: 2.8.5
+    Use the ``MPI_<lang>_LIBRARIES`` instead.
+
+``MPI_<lang>_COMPILE_FLAGS``
+  .. deprecated:: 3.10
+    Use the ``MPI_<lang>_COMPILE_OPTIONS`` and
+    ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
+
+``MPI_<lang>_INCLUDE_PATH``
+  .. deprecated:: 3.10
+    For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying
+    folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
+
+``MPIEXEC``
+  .. deprecated:: 3.10
+    Use ``MPIEXEC_EXECUTABLE`` instead.
+
+Examples
+^^^^^^^^
+
+Example: Basic Usage
+""""""""""""""""""""
+
+Finding MPI and linking imported target to project target:
 
 .. code-block:: cmake
 
-   ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS}
-     ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
+  find_package(MPI)
+  target_link_libraries(example PRIVATE MPI::MPI_C)
 
-where ``EXECUTABLE`` is the MPI program, and ``ARGS`` are the arguments to
-pass to the MPI program.
+Example: Usage of mpiexec
+"""""""""""""""""""""""""
 
-Advanced variables for using MPI
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+When using ``MPIEXEC_EXECUTABLE`` to execute MPI applications, typically
+all of the ``MPIEXEC_EXECUTABLE`` flags should be used as follows.
 
-The module can perform some advanced feature detections upon explicit request.
+In the following example, the command is executed in a process.
+``<executable>`` should be replaced with the MPI program, and ``<args>``
+with the arguments to pass to the MPI program.
 
-**Important notice:** The following checks cannot be performed without *executing* an MPI test program.
-Consider the special considerations for the behavior of :command:`try_run` during cross compilation.
-Moreover, running an MPI program can cause additional issues, like a firewall notification on some systems.
-You should only enable these detections if you absolutely need the information.
+.. code-block:: cmake
 
-If the following variables are set to true, the respective search will be performed:
+  find_package(MPI)
 
-``MPI_DETERMINE_Fortran_CAPABILITIES``
-  Determine for all available Fortran bindings what the values of ``MPI_SUBARRAYS_SUPPORTED`` and
-  ``MPI_ASYNC_PROTECTS_NONBLOCKING`` are and make their values available as ``MPI_Fortran_<binding>_SUBARRAYS``
-  and ``MPI_Fortran_<binding>_ASYNCPROT``, where ``<binding>`` is one of ``F77_HEADER``, ``F90_MODULE`` and
-  ``F08_MODULE``.
-``MPI_DETERMINE_LIBRARY_VERSION``
-  For each language, find the output of ``MPI_Get_library_version`` and make it available as ``MPI_<lang>_LIBRARY_VERSION_STRING``.
-  This information is usually tied to the runtime component of an MPI implementation and might differ depending on ``<lang>``.
-  Note that the return value is entirely implementation defined. This information might be used to identify
-  the MPI vendor and for example pick the correct one of multiple third party binaries that matches the MPI vendor.
-
-Backward Compatibility
-^^^^^^^^^^^^^^^^^^^^^^
-
-.. deprecated:: 3.10
-
-For backward compatibility with older versions of FindMPI, these
-variables are set:
-
-::
-
-   MPI_COMPILER        MPI_LIBRARY        MPI_EXTRA_LIBRARY
-   MPI_COMPILE_FLAGS   MPI_INCLUDE_PATH   MPI_LINK_FLAGS
-   MPI_LIBRARIES
-
-In new projects, please use the ``MPI_<lang>_XXX`` equivalents.
-Additionally, the following variables are deprecated:
-
-``MPI_<lang>_COMPILE_FLAGS``
-  Use ``MPI_<lang>_COMPILE_OPTIONS`` and ``MPI_<lang>_COMPILE_DEFINITIONS`` instead.
-``MPI_<lang>_INCLUDE_PATH``
-  For consumption use ``MPI_<lang>_INCLUDE_DIRS`` and for specifying folders use ``MPI_<lang>_ADDITIONAL_INCLUDE_DIRS`` instead.
-``MPIEXEC``
-  Use ``MPIEXEC_EXECUTABLE`` instead.
+  if(MPI_FOUND)
+    execute_process(
+      COMMAND
+        ${MPIEXEC_EXECUTABLE}
+        ${MPIEXEC_NUMPROC_FLAG}
+        ${MPIEXEC_MAX_NUMPROCS}
+        ${MPIEXEC_PREFLAGS}
+        <executable>
+        ${MPIEXEC_POSTFLAGS}
+        <args>
+    )
+  endif()
 #]=======================================================================]
 
 cmake_policy(PUSH)
@@ -982,7 +1143,7 @@
 
         # Our strategy is now to locate all libraries, but enter msmpifec into the LIB_NAMES array.
         # Should this not be adequate it's a straightforward way for a user to change the LIB_NAMES array and
-        # have his library found. Still, this should not be necessary outside of exceptional cases, as reasoned.
+        # have their library found. Still, this should not be necessary outside of exceptional cases, as reasoned.
         if (LANG STREQUAL "Fortran")
           set(MPI_MSMPI_CALLINGCONVS c)
           if(CMAKE_SIZEOF_VOID_P EQUAL "4")
@@ -1598,7 +1759,7 @@
           else()
             set(_MPI_PKG "")
           endif()
-          if(_MPI_PKG AND PKG_CONFIG_FOUND)
+          if(_MPI_PKG AND PkgConfig_FOUND)
             pkg_check_modules("MPI_${LANG}_PKG" "${_MPI_PKG}")
             if(MPI_${LANG}_PKG_FOUND)
               set(MPI_${LANG}_COMPILE_OPTIONS  ${MPI_${LANG}_PKG_CFLAGS}        CACHE STRING "MPI ${LANG} compilation options"       FORCE)
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 8a7bd80..8acc6f3 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -6,7 +6,11 @@
 ----------
 
 Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools,
-libraries and compilers to CMake.
+libraries and compilers to CMake:
+
+.. code-block:: cmake
+
+  find_package(Matlab [<version>] [COMPONENTS <components>...] [...])
 
 This package primary purpose is to find the libraries associated with Matlab
 or the MCR in order to be able to build Matlab extensions (mex files). It
@@ -148,8 +152,11 @@
 """"""""""""""""
 
 ``Matlab_FOUND``
-  ``TRUE`` if the Matlab installation is found, ``FALSE``
-  otherwise. All variable below are defined if Matlab is found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) Matlab installation
+  was found.  All variables below are defined if Matlab is found.
+
 ``Matlab_VERSION``
   .. versionadded:: 3.27
 
diff --git a/Modules/FindMotif.cmake b/Modules/FindMotif.cmake
index d72b193..1ce164c 100644
--- a/Modules/FindMotif.cmake
+++ b/Modules/FindMotif.cmake
@@ -5,7 +5,11 @@
 FindMotif
 ---------
 
-Finds Motif (or LessTif) graphical user interface toolkit.
+Finds Motif (or LessTif) graphical user interface toolkit:
+
+.. code-block:: cmake
+
+  find_package(Motif [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -13,27 +17,53 @@
 This module defines the following variables:
 
 ``Motif_FOUND``
-  Boolean indicating whether the Motif was found.  For backward compatibility,
-  the ``MOTIF_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Motif was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
-``MOTIF_LIBRARIES``
-  Libraries needed to link to Motif.
 ``MOTIF_INCLUDE_DIR``
   Include directories needed to use Motif.
 
+``MOTIF_LIBRARIES``
+  Libraries needed to link to Motif.
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``MOTIF_FOUND``
+  .. deprecated:: 4.2
+    Use ``Motif_FOUND``, which has the same value.
+
+  Boolean indicating whether Motif was found.
+
 Examples
 ^^^^^^^^
 
-Finding Motif:
+Finding Motif and creating an imported interface target for linking it to a
+project target:
 
 .. code-block:: cmake
 
   find_package(Motif)
+
+  if(Motif_FOUND AND NOT TARGET Motif::Motif)
+    add_library(Motif::Motif INTERFACE IMPORTED)
+    set_target_properties(
+      Motif::Motif
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${MOTIF_INCLUDE_DIR}"
+        INTERFACE_LINK_LIBRARIES "${MOTIF_LIBRARIES}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE Motif::Motif)
 #]=======================================================================]
 
 if(UNIX)
diff --git a/Modules/FindMsys.cmake b/Modules/FindMsys.cmake
index 0d78c9b..fcf62b1 100644
--- a/Modules/FindMsys.cmake
+++ b/Modules/FindMsys.cmake
@@ -8,7 +8,11 @@
 .. versionadded:: 3.21
 
 Finds MSYS, a POSIX-compatible environment that runs natively on Microsoft
-Windows.
+Windows:
+
+.. code-block:: cmake
+
+  find_package(Msys [...])
 
 .. note::
 
@@ -23,6 +27,11 @@
 
 This module defines the following variables:
 
+``Msys_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether MSYS was found.
+
 ``MSYS_INSTALL_PATH``
   The path to the MSYS root installation directory.
 
@@ -32,7 +41,7 @@
 Finding the MSYS installation and using its path in a custom find module:
 
 .. code-block:: cmake
-  :caption: FindFoo.cmake
+  :caption: ``FindFoo.cmake``
 
   find_package(Msys)
   find_program(Foo_EXECUTABLE NAMES foo PATHS ${MSYS_INSTALL_PATH}/usr/bin)
@@ -65,3 +74,9 @@
   mark_as_advanced(MSYS_CMD)
 
 endif ()
+
+if(MSYS_CMD AND MSYS_INSTALL_PATH)
+  set(Msys_FOUND TRUE)
+else()
+  set(Msys_FOUND FALSE)
+endif()
diff --git a/Modules/FindODBC.cmake b/Modules/FindODBC.cmake
index 6e103d2..e8692bd 100644
--- a/Modules/FindODBC.cmake
+++ b/Modules/FindODBC.cmake
@@ -7,11 +7,16 @@
 
 .. versionadded:: 3.12
 
-Finds the Open Database Connectivity (ODBC) library, which implements a standard
-API for accessing database systems.  ODBC enables applications to communicate
-with different database management systems (DBMS) using a common set of
-functions.  Communication with a specific database is handled through ODBC
-drivers, which the library loads at runtime.
+Finds the Open Database Connectivity (ODBC) library, which implements a
+standard API for accessing database systems:
+
+.. code-block:: cmake
+
+  find_package(ODBC [...])
+
+ODBC enables applications to communicate with different database management
+systems (DBMS) using a common set of functions.  Communication with a specific
+database is handled through ODBC drivers, which the library loads at runtime.
 
 On Windows, when building with Visual Studio, this module assumes the ODBC
 library is provided by the available Windows SDK.
@@ -36,7 +41,7 @@
 This module defines the following variables:
 
 ``ODBC_FOUND``
-  Boolean indicating whether ODBC is found.
+  Boolean indicating whether ODBC was found.
 
 ``ODBC_INCLUDE_DIRS``
   Include directories containing headers needed to use ODBC.
@@ -76,19 +81,19 @@
 Examples
 ^^^^^^^^
 
-Finding and using ODBC
-""""""""""""""""""""""
+Example: Finding and Using ODBC
+"""""""""""""""""""""""""""""""
 
 Finding ODBC and linking it to a project target:
 
 .. code-block:: cmake
-  :caption: CMakeLists.txt
+  :caption: ``CMakeLists.txt``
 
   find_package(ODBC)
   target_link_libraries(project_target PRIVATE ODBC::ODBC)
 
-Finding a custom ODBC installation on Unix-like systems
-"""""""""""""""""""""""""""""""""""""""""""""""""""""""
+Example: Finding a Custom ODBC Installation
+"""""""""""""""""""""""""""""""""""""""""""
 
 The following examples are for Unix-like systems and demonstrate how to set hint
 and cache variables during the CMake configuration phase to help this module
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index b78d381..efecb6a 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -7,9 +7,12 @@
 
 .. versionadded:: 3.10
 
-Detect OpenACC support by the compiler.
+Finds and detects the OpenACC support in a compiler:
 
-This module can be used to detect OpenACC support in a compiler.
+.. code-block:: cmake
+
+  find_package(OpenACC [<version>] [...])
+
 If the compiler supports OpenACC, the flags required to compile with
 OpenACC support are returned in variables for the different languages.
 Currently, only NVHPC, PGI, GNU and Cray compilers are supported.
@@ -17,28 +20,32 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.16
-
-The module provides :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
 
 ``OpenACC::OpenACC_<lang>``
-  Target for using OpenACC from ``<lang>``.
+  .. versionadded:: 3.16
 
-Variables
-^^^^^^^^^
+  Target encapsulating the usage requirements for using OpenACC from
+  ``<lang>``.  This target is available only if OpenACC support is found.
+  ``<lang>`` is one of C, CXX, or Fortran.
 
-The module defines the following variables:
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
 
 ``OpenACC_FOUND``
   .. versionadded:: 3.25
 
-  Variable indicating that OpenACC flags for at least one languages have been found.
+  Boolean indicating that OpenACC flags for at least one language were
+  found.
 
-This module will set the following variables per language in your
+This module will set the following variables per language in the
 project, where ``<lang>`` is one of C, CXX, or Fortran:
 
 ``OpenACC_<lang>_FOUND``
-  Variable indicating if OpenACC support for ``<lang>`` was detected.
+  Boolean indicating whether OpenACC support for language ``<lang>`` was
+  detected.
 ``OpenACC_<lang>_FLAGS``
   OpenACC compiler flags for ``<lang>``, separated by spaces.
 ``OpenACC_<lang>_OPTIONS``
@@ -65,9 +72,21 @@
 Input Variables
 ^^^^^^^^^^^^^^^
 
+This module accepts the following variables:
+
 ``OpenACC_ACCEL_TARGET=<target>``
-If set, will the correct target accelerator flag set to the <target> will
-be returned with OpenACC_<lang>_FLAGS.
+  If set, the correct target accelerator flag set to the ``<target>``
+  will be returned with the ``OpenACC_<lang>_FLAGS`` variable.
+
+Examples
+^^^^^^^^
+
+Finding OpenACC support and linking the imported target to a project target:
+
+.. code-block:: cmake
+
+  find_package(OpenACC)
+  target_link_libraries(example PRIVATE OpenACC::OpenACC_C)
 #]=======================================================================]
 
 cmake_policy(PUSH)
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index dad9ada..766c563 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -5,7 +5,11 @@
 FindOpenAL
 ----------
 
-Finds the Open Audio Library (OpenAL).
+Finds the Open Audio Library (OpenAL):
+
+.. code-block:: cmake
+
+  find_package(OpenAL [...])
 
 OpenAL is a cross-platform 3D audio API designed for efficient rendering of
 multichannel three-dimensional positional audio.  It is commonly used in games
@@ -34,10 +38,9 @@
 This module defines the following variables:
 
 ``OpenAL_FOUND``
-  Boolean indicating whether the OpenAL is found.  For backward compatibility,
-  the ``OPENAL_FOUND`` variable is also set to the same value.
-``OPENAL_VERSION_STRING``
-  Human-readable string containing the version of OpenAL found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether OpenAL was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -69,6 +72,17 @@
   5. Manually compiled framework: ``/Library/Frameworks``.
   6. Add-on package: ``/opt``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OPENAL_FOUND``
+  .. deprecated:: 4.2
+    Use ``OpenAL_FOUND``, which has the same value.
+
+  Boolean indicating whether OpenAL was found.
+
 Examples
 ^^^^^^^^
 
@@ -126,7 +140,6 @@
 find_package_handle_standard_args(
   OpenAL
   REQUIRED_VARS OPENAL_LIBRARY OPENAL_INCLUDE_DIR
-  VERSION_VAR OPENAL_VERSION_STRING
   )
 
 mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake
index 3be945b..ff4e1d2 100644
--- a/Modules/FindOpenCL.cmake
+++ b/Modules/FindOpenCL.cmake
@@ -7,7 +7,17 @@
 
 .. versionadded:: 3.1
 
-Finds Open Computing Language (OpenCL).
+Finds Open Computing Language (OpenCL):
+
+.. code-block:: cmake
+
+  find_package(OpenCL [<version>] [...])
+
+OpenCL is a framework for writing programs that execute across heterogeneous
+platforms, such as CPUs, GPUs, and other accelerators.
+
+.. versionadded:: 3.24
+  Detection of OpenCL 3.0.
 
 .. versionadded:: 3.10
   Detection of OpenCL 2.1 and 2.2.
@@ -15,13 +25,13 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.7
-
-This module provides the following :ref:`Imported Targets`, if OpenCL has been
-found:
+This module provides the following :ref:`Imported Targets`:
 
 ``OpenCL::OpenCL``
-  Target providing OpenCL usage requirements.
+  .. versionadded:: 3.7
+
+  Target encapsulating the OpenCL usage requirements, available if OpenCL
+  has been found.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -29,18 +39,26 @@
 This module defines the following variables:
 
 ``OpenCL_FOUND``
-  True if OpenCL was found.
-``OpenCL_INCLUDE_DIRS``
-  Include directories needed to use OpenCL.
-``OpenCL_LIBRARIES``
-  Libraries needed to link to OpenCL.
-``OpenCL_VERSION_STRING``
-  Highest supported OpenCL version (e.g., ``1.2``).
+  Boolean indicating whether (the requested version of) OpenCL was found.
+
+``OpenCL_VERSION``
+  .. versionadded:: 4.2
+
+  Highest supported OpenCL version found in form of ``<major>.<minor>``
+  (e.g., ``1.2``).
+
 ``OpenCL_VERSION_MAJOR``
   The major version of the OpenCL implementation.
+
 ``OpenCL_VERSION_MINOR``
   The minor version of the OpenCL implementation.
 
+``OpenCL_INCLUDE_DIRS``
+  Include directories needed to use OpenCL.
+
+``OpenCL_LIBRARIES``
+  Libraries needed to link to OpenCL.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -48,9 +66,21 @@
 
 ``OpenCL_INCLUDE_DIR``
   The OpenCL include directory.
+
 ``OpenCL_LIBRARY``
   The path to the OpenCL library.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OpenCL_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``OpenCL_VERSION``, which has the same value.
+
+  Highest supported OpenCL version found in form of ``<major>.<minor>``.
+
 Examples
 ^^^^^^^^
 
@@ -62,21 +92,28 @@
   target_link_libraries(project_target PRIVATE OpenCL::OpenCL)
 #]=======================================================================]
 
+cmake_policy(PUSH)
+cmake_policy(SET CMP0140 NEW)
+
 set(_OPENCL_x86 "(x86)")
 
 function(_FIND_OPENCL_VERSION)
+  include(CheckIncludeFiles)
   include(CheckSymbolExists)
   include(CMakePushCheckState)
-  set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY})
 
   cmake_push_check_state()
-  foreach(VERSION "3_0" "2_2" "2_1" "2_0" "1_2" "1_1" "1_0")
-    set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}")
 
-    if(EXISTS ${OpenCL_INCLUDE_DIR}/Headers/cl.h)
+  set(CMAKE_REQUIRED_QUIET ${OpenCL_FIND_QUIETLY})
+  set(CMAKE_REQUIRED_INCLUDES "${OpenCL_INCLUDE_DIR}")
+
+  check_include_files(OpenCL/cl.h OpenCL_HAVE_OPENCL_CL_H)
+
+  foreach(VERSION "3_0" "2_2" "2_1" "2_0" "1_2" "1_1" "1_0")
+    if(OpenCL_HAVE_OPENCL_CL_H)
       check_symbol_exists(
         CL_VERSION_${VERSION}
-        "Headers/cl.h"
+        "OpenCL/cl.h"
         OPENCL_VERSION_${VERSION})
     else()
       check_symbol_exists(
@@ -87,16 +124,25 @@
 
     if(OPENCL_VERSION_${VERSION})
       string(REPLACE "_" "." VERSION "${VERSION}")
-      set(OpenCL_VERSION_STRING ${VERSION} PARENT_SCOPE)
+      set(OpenCL_VERSION ${VERSION})
+      set(OpenCL_VERSION_STRING "${OpenCL_VERSION}")
       string(REGEX MATCHALL "[0-9]+" version_components "${VERSION}")
       list(GET version_components 0 major_version)
       list(GET version_components 1 minor_version)
-      set(OpenCL_VERSION_MAJOR ${major_version} PARENT_SCOPE)
-      set(OpenCL_VERSION_MINOR ${minor_version} PARENT_SCOPE)
+      set(OpenCL_VERSION_MAJOR ${major_version})
+      set(OpenCL_VERSION_MINOR ${minor_version})
       break()
     endif()
   endforeach()
   cmake_pop_check_state()
+
+  return(
+    PROPAGATE
+      OpenCL_VERSION
+      OpenCL_VERSION_MAJOR
+      OpenCL_VERSION_MINOR
+      OpenCL_VERSION_STRING
+  )
 endfunction()
 
 find_path(OpenCL_INCLUDE_DIR
@@ -200,7 +246,8 @@
 find_package_handle_standard_args(
   OpenCL
   REQUIRED_VARS OpenCL_LIBRARY OpenCL_INCLUDE_DIR
-  VERSION_VAR OpenCL_VERSION_STRING)
+  VERSION_VAR OpenCL_VERSION
+)
 
 mark_as_advanced(
   OpenCL_INCLUDE_DIR
@@ -219,3 +266,5 @@
   set_target_properties(OpenCL::OpenCL PROPERTIES
     INTERFACE_INCLUDE_DIRECTORIES "${OpenCL_INCLUDE_DIRS}")
 endif()
+
+cmake_policy(POP)
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index a842756..da01072 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -5,28 +5,56 @@
 FindOpenGL
 ----------
 
-FindModule for OpenGL and OpenGL Utility Library (GLU).
+Finds the OpenGL and OpenGL Utility Library (GLU), for using OpenGL in a
+CMake project:
+
+.. code-block:: cmake
+
+  find_package(OpenGL [COMPONENTS <components>...] [...])
+
+OpenGL (Open Graphics Library) is a cross-platform API for rendering 2D and
+3D graphics.  It is widely used in CAD, games, and visualization software.
+
+* *GL* refers to the core OpenGL library, which provides the fundamental
+  graphics rendering API.
+
+* *GLU* (OpenGL Utility Library) is a companion library that offers utility
+  functions built on top of OpenGL, such as tessellation and more complex
+  shape drawing.
 
 .. versionchanged:: 3.2
   X11 is no longer added as a dependency on Unix/Linux systems.
 
 .. versionadded:: 3.10
-  GLVND support on Linux.  See the :ref:`Linux Specific` section below.
+  GLVND (GL Vendor-Neutral Dispatch library) support on Linux.  See the
+  :ref:`Linux Specific` section below.
 
-Optional COMPONENTS
-^^^^^^^^^^^^^^^^^^^
+Components
+^^^^^^^^^^
 
-.. versionadded:: 3.10
+This module supports optional components which can be specified with the
+:command:`find_package` command:
 
-This module respects several optional COMPONENTS:
+.. code-block:: cmake
+
+  find_package(OpenGL [COMPONENTS <components>...])
+
+Supported components are:
 
 ``EGL``
-  The EGL interface between OpenGL, OpenGL ES and the underlying windowing system.
+  .. versionadded:: 3.10
+
+  The EGL interface between OpenGL, OpenGL ES and the underlying windowing
+  system.
 
 ``GLX``
+  .. versionadded:: 3.10
+
   An extension to X that interfaces OpenGL, OpenGL ES with X window system.
 
 ``OpenGL``
+  .. versionadded:: 3.10
+
   The cross platform API for 3D graphics.
 
 ``GLES2``
@@ -42,103 +70,177 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.8
-
-This module defines the :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
 
 ``OpenGL::GL``
-  Defined to the platform-specific OpenGL libraries if the system has OpenGL.
-``OpenGL::GLU``
-  Defined if the system has OpenGL Utility Library (GLU).
+  .. versionadded:: 3.8
 
-.. versionadded:: 3.10
-  Additionally, the following GLVND-specific library targets are defined:
+  Target encapsulating the usage requirements of platform-specific OpenGL
+  libraries, available if OpenGL is found.
+
+``OpenGL::GLU``
+  .. versionadded:: 3.8
+
+  Target encapsulating the OpenGL Utility Library (GLU) usage requirements,
+  available if GLU is found.
+
+Additionally, the following GLVND-specific library imported targets are
+provided:
 
 ``OpenGL::OpenGL``
-  Defined to libOpenGL if the system is GLVND-based.
+  .. versionadded:: 3.10
+
+  Target encapsulating the libOpenGL usage requirements, available if
+  system is GLVND-based and OpenGL is found.
+
 ``OpenGL::GLX``
-  Defined if the system has OpenGL Extension to the X Window System (GLX).
+  .. versionadded:: 3.10
+
+  Target encapsulating the usage requirements of the OpenGL Extension to the
+  the X Window System (GLX), available if OpenGL and GLX are found.
+
 ``OpenGL::EGL``
-  Defined if the system has EGL.
+  .. versionadded:: 3.10
+
+  Target encapsulating the EGL usage requirements, available if OpenGL and EGL
+  are found.
+
 ``OpenGL::GLES2``
   .. versionadded:: 3.27
 
-  Defined if the system has GLES2.
+  Target encapsulating the GLES2 usage requirements, available if OpenGL and
+  GLES2 are found.
+
 ``OpenGL::GLES3``
   .. versionadded:: 3.27
 
-  Defined if the system has GLES3.
+  Target encapsulating the GLES3 usage requirements, available if OpenGL and
+  GLES3 are found.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
-``OPENGL_FOUND``
- True, if the system has OpenGL and all components are found.
+``OpenGL_FOUND``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether OpenGL and all requested components were found.
+
 ``OPENGL_XMESA_FOUND``
- True, if the system has XMESA.
+  Boolean indicating whether OpenGL XMESA was found.
+
 ``OPENGL_GLU_FOUND``
- True, if the system has GLU.
+  Boolean indicating whether GLU was found.
+
 ``OpenGL_OpenGL_FOUND``
- True, if the system has an OpenGL library.
+  .. versionadded:: 3.10
+
+  Boolean indicating whether the GLVND OpenGL library was found.
+
 ``OpenGL_GLX_FOUND``
- True, if the system has GLX.
+  .. versionadded:: 3.10
+
+  Boolean indicating whether GLVND GLX was found.
+
 ``OpenGL_EGL_FOUND``
- True, if the system has EGL.
-``OpenGL::GLES2``
- Defined if the system has GLES2.
-``OpenGL::GLES3``
- Defined if the system has GLES3.
-``OPENGL_INCLUDE_DIR``
- Path to the OpenGL include directory.
- The ``OPENGL_INCLUDE_DIRS`` variable is preferred.
-``OPENGL_EGL_INCLUDE_DIRS``
- Path to the EGL include directory.
-``OPENGL_LIBRARIES``
- Paths to the OpenGL library, windowing system libraries, and GLU libraries.
- On Linux, this assumes GLX and is never correct for EGL-based targets.
- Clients are encouraged to use the ``OpenGL::*`` import targets instead.
+  .. versionadded:: 3.10
+
+  Boolean indicating whether GLVND EGL was found.
+
+``OpenGL_GLES2_FOUND``
+  .. versionadded:: 3.27
+
+  Boolean indicating whether GLES2 was found.
+
+``OpenGL_GLES3_FOUND``
+  .. versionadded:: 3.27
+
+  Boolean indicating whether GLES3 was found.
+
 ``OPENGL_INCLUDE_DIRS``
   .. versionadded:: 3.29
 
   Paths to the OpenGL include directories.
 
-.. versionadded:: 3.10
-  Variables for GLVND-specific libraries ``OpenGL``, ``EGL`` and ``GLX``.
+``OPENGL_EGL_INCLUDE_DIRS``
+  .. versionadded:: 3.10
 
-Cache variables
+  Path to the EGL include directory.
+
+``OPENGL_LIBRARIES``
+  Paths to the OpenGL library, windowing system libraries, and GLU libraries.
+  On Linux, this assumes GLX and is never correct for EGL-based targets.
+  Clients are encouraged to use the ``OpenGL::*`` imported targets instead.
+
+Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
-``OPENGL_egl_LIBRARY``
- Path to the EGL library.
-``OPENGL_glu_LIBRARY``
- Path to the GLU library.
-``OPENGL_glx_LIBRARY``
- Path to the GLVND 'GLX' library.
-``OPENGL_opengl_LIBRARY``
- Path to the GLVND 'OpenGL' library
-``OPENGL_gl_LIBRARY``
- Path to the OpenGL library.  New code should prefer the ``OpenGL::*`` import
- targets.
-``OPENGL_gles2_LIBRARY``
-  .. versionadded:: 3.27
-
-  Path to the OpenGL GLES2 library.
-``OPENGL_gles3_LIBRARY``
-  .. versionadded:: 3.27
-
-  Path to the OpenGL GLES3 library.
+``OPENGL_INCLUDE_DIR``
+  The path to the OpenGL include directory.
+  The ``OPENGL_INCLUDE_DIRS`` variable is preferred.
 
 ``OPENGL_GLU_INCLUDE_DIR``
   .. versionadded:: 3.29
 
   Path to the OpenGL GLU include directory.
 
-.. versionadded:: 3.10
-  Variables for GLVND-specific libraries ``OpenGL``, ``EGL`` and ``GLX``.
+``OPENGL_egl_LIBRARY``
+  .. versionadded:: 3.10
+
+  Path to the GLVND EGL library.
+
+``OPENGL_glu_LIBRARY``
+  Path to the GLU library.
+
+``OPENGL_glx_LIBRARY``
+  .. versionadded:: 3.10
+
+  Path to the GLVND GLX library.
+
+``OPENGL_opengl_LIBRARY``
+  .. versionadded:: 3.10
+
+  Path to the GLVND OpenGL library
+
+``OPENGL_gl_LIBRARY``
+  Path to the OpenGL library.
+
+``OPENGL_gles2_LIBRARY``
+  .. versionadded:: 3.27
+
+  Path to the OpenGL GLES2 library.
+
+``OPENGL_gles3_LIBRARY``
+  .. versionadded:: 3.27
+
+  Path to the OpenGL GLES3 library.
+
+Hints
+^^^^^
+
+This module accepts the following variables:
+
+``OpenGL_GL_PREFERENCE``
+  .. versionadded:: 3.10
+
+  This variable is supported on Linux systems to specify the preferred way to
+  provide legacy GL interfaces in case multiple choices are available.  The
+  value may be one of:
+
+  ``GLVND``
+    If the GLVND OpenGL and GLX libraries are available, prefer them.
+    This forces ``OPENGL_gl_LIBRARY`` to be empty.
+
+    .. versionchanged:: 3.11
+      This is the default, unless policy :policy:`CMP0072` is set to ``OLD``
+      and no components are requested (since components
+      correspond to GLVND libraries).
+
+  ``LEGACY``
+    Prefer to use the legacy libGL library, if available.
 
 .. _`Linux Specific`:
 
@@ -160,21 +262,8 @@
 variable will use the corresponding libraries).  Thus, for non-EGL-based
 Linux targets, the ``OpenGL::GL`` target is most portable.
 
-A ``OpenGL_GL_PREFERENCE`` variable may be set to specify the preferred way
+The ``OpenGL_GL_PREFERENCE`` variable may be set to specify the preferred way
 to provide legacy GL interfaces in case multiple choices are available.
-The value may be one of:
-
-``GLVND``
- If the GLVND OpenGL and GLX libraries are available, prefer them.
- This forces ``OPENGL_gl_LIBRARY`` to be empty.
-
- .. versionchanged:: 3.11
-  This is the default, unless policy :policy:`CMP0072` is set to ``OLD``
-  and no components are requested (since components
-  correspond to GLVND libraries).
-
-``LEGACY``
- Prefer to use the legacy libGL library, if available.
 
 For EGL targets the client must rely on GLVND support on the user's system.
 Linking should use the ``OpenGL::OpenGL OpenGL::EGL`` targets.  Using GLES*
@@ -189,7 +278,8 @@
 
 On macOS this module defaults to using the macOS-native framework
 version of OpenGL.  To use the X11 version of OpenGL on macOS, one
-can disable searching of frameworks.  For example:
+can disable searching of frameworks using the :variable:`CMAKE_FIND_FRAMEWORK`
+variable.  For example:
 
 .. code-block:: cmake
 
@@ -205,6 +295,35 @@
 An end user building this project may need to point CMake at their
 X11 installation, e.g., with ``-DOpenGL_ROOT=/opt/X11``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OPENGL_FOUND``
+  .. deprecated:: 4.2
+    Use ``OpenGL_FOUND``, which has the same value.
+
+  Boolean indicating whether OpenGL and all requested components were found.
+
+Examples
+^^^^^^^^
+
+Finding the OpenGL library and linking it to a project target:
+
+.. code-block:: cmake
+
+  find_package(OpenGL)
+  target_link_libraries(project_target PRIVATE OpenGL::OpenGL)
+
+See Also
+^^^^^^^^
+
+* The :module:`FindGLEW` module to find OpenGL Extension Wrangler Library
+  (GLEW).
+* The :module:`FindGLUT` module to find OpenGL Utility Toolkit (GLUT)
+  library.
+* The :module:`FindVulkan` module to find Vulkan graphics API.
 #]=======================================================================]
 
 set(_OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY)
@@ -582,7 +701,7 @@
 unset(_OpenGL_REQUIRED_VARS)
 
 # OpenGL:: targets
-if(OPENGL_FOUND)
+if(OpenGL_FOUND)
   set(OPENGL_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
 
   # ::OpenGL is a GLVND library, and thus Linux-only: we don't bother checking
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index c1141c7..19adf40 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -5,17 +5,60 @@
 FindOpenMP
 ----------
 
-Finds Open Multi-Processing (OpenMP) support.
+Finds Open Multi-Processing (OpenMP) support in a compiler:
 
-This module can be used to detect OpenMP support in a compiler.  If
-the compiler supports OpenMP, the flags required to compile with
-OpenMP support are returned in variables for the different languages.
-The variables may be empty if the compiler does not need a special
-flag to support OpenMP.
+.. code-block:: cmake
+
+  find_package(OpenMP [<version>] [COMPONENTS <langs>...] [...])
+
+If the compiler supports OpenMP, the flags required to compile with OpenMP
+support are returned in variables for the different languages.  The variables
+may be empty if the compiler does not need a special flag to support OpenMP.
 
 .. versionadded:: 3.5
   Clang support.
 
+Components
+^^^^^^^^^^
+
+This module supports components that can be specified using the standard
+syntax:
+
+.. code-block:: cmake
+
+  find_package(OpenMP [COMPONENTS <langs>...])
+
+Each of these components controls the various languages to search OpenMP
+support for.  The following components are exposed:
+
+``C``
+  .. versionadded:: 3.10
+
+``CXX``
+  .. versionadded:: 3.10
+
+``Fortran``
+  .. versionadded:: 3.10
+
+``CUDA``
+  .. versionadded:: 3.31
+
+  The ``CUDA`` language component is supported when using a CUDA compiler
+  that supports OpenMP on the host.
+
+If no components are specified, module checks for all of them automatically,
+depending on the enabled languages in the project.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+This module provides the following :ref:`Imported Targets`:
+
+``OpenMP::OpenMP_<lang>``
+  .. versionadded:: 3.9
+
+  Target encapsulating the OpenMP usage requirements for language ``<lang>``.
+
 Input Variables
 ^^^^^^^^^^^^^^^
 
@@ -33,32 +76,63 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.10
-  The module exposes the components ``C``, ``CXX``, and ``Fortran``.
-  Each of these controls the various languages to search OpenMP support for.
-
-.. versionadded:: 3.31
-  The ``CUDA`` language component is supported when using a CUDA compiler
-  that supports OpenMP on the host.
-
-Depending on the enabled components the following variables will be set:
+This module defines the following variables:
 
 ``OpenMP_FOUND``
-  Variable indicating that OpenMP flags for all requested languages have been found.
-  If no components are specified, this is true if OpenMP settings for all enabled languages
-  were detected.
-``OpenMP_VERSION``
-  Minimal version of the OpenMP standard detected among the requested languages,
-  or all enabled languages if no components were specified.
+  .. versionadded:: 3.10
 
-This module will set the following variables per language in your
+  Boolean indicating that OpenMP flags for all requested languages were
+  found.  If no components are specified, this variable is set to boolean
+  true if OpenMP settings for all enabled languages were detected.
+
+``OpenMP_VERSION``
+  .. versionadded:: 4.2
+
+  Minimal version of the OpenMP standard detected among the requested
+  languages, or all enabled languages if no components were specified.
+
+This module will set the following variables per language in the
 project, where ``<lang>`` is one of C, CXX, CUDA, or Fortran:
 
 ``OpenMP_<lang>_FOUND``
-  Variable indicating if OpenMP support for ``<lang>`` was detected.
+  .. versionadded:: 3.9
+
+  Boolean indicating whether the (requested version of) OpenMP support for
+  ``<lang>`` was detected.
+
+``OpenMP_<lang>_VERSION``
+  .. versionadded:: 3.9
+
+  OpenMP version implemented by the ``<lang>`` compiler, if available.
+
+``OpenMP_<lang>_VERSION_MAJOR``
+  .. versionadded:: 3.9
+
+  Major version of OpenMP implemented by the ``<lang>`` compiler, if
+  available.
+
+``OpenMP_<lang>_VERSION_MINOR``
+  .. versionadded:: 3.9
+
+  Minor version of OpenMP implemented by the ``<lang>`` compiler, if
+  available.
+
+``OpenMP_<lang>_SPEC_DATE``
+  .. versionadded:: 3.7
+
+  Date of the OpenMP specification implemented by the ``<lang>`` compiler,
+  if available.
+
+  The specification date is formatted as given in the OpenMP standard:
+  ``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of the
+  OpenMP specification implemented by the ``<lang>`` compiler.
+
 ``OpenMP_<lang>_FLAGS``
   OpenMP compiler flags for ``<lang>``, separated by spaces.
+
 ``OpenMP_<lang>_INCLUDE_DIRS``
+  .. versionadded:: 3.16
+
   Directories that must be added to the header search path for ``<lang>``
   when using OpenMP.
 
@@ -66,48 +140,56 @@
 variables are provided:
 
 ``OpenMP_<lang>_LIB_NAMES``
-  :ref:`;-list <CMake Language Lists>` of libraries for OpenMP programs for ``<lang>``.
+  .. versionadded:: 3.9
+
+  A :ref:`semicolon-separated list <CMake Language Lists>` of OpenMP
+  programs libraries for ``<lang>``.
+
 ``OpenMP_<libname>_LIBRARY``
-  Location of the individual libraries needed for OpenMP support in ``<lang>``.
+  .. versionadded:: 3.9
+
+  Location of the individual libraries needed for OpenMP support in
+  ``<lang>``.  The ``<libname>`` names are stored in the
+  ``OpenMP_<lang>_LIB_NAMES`` list.
+
 ``OpenMP_<lang>_LIBRARIES``
+  .. versionadded:: 3.9
+
   A list of libraries needed to link with OpenMP code written in ``<lang>``.
 
-Additionally, the module provides :prop_tgt:`IMPORTED` targets:
-
-``OpenMP::OpenMP_<lang>``
-  Target for using OpenMP from ``<lang>``.
-
 Specifically for Fortran, the module sets the following variables:
 
 ``OpenMP_Fortran_HAVE_OMPLIB_HEADER``
-  Boolean indicating if OpenMP is accessible through ``omp_lib.h``.
+  .. versionadded:: 3.9
+
+  Boolean indicating whether OpenMP is accessible through the ``omp_lib.h``
+  Fortran header.
+
 ``OpenMP_Fortran_HAVE_OMPLIB_MODULE``
-  Boolean indicating if OpenMP is accessible through the ``omp_lib`` Fortran module.
+  .. versionadded:: 3.9
 
-The module will also try to provide the OpenMP version variables:
-
-``OpenMP_<lang>_SPEC_DATE``
-  .. versionadded:: 3.7
-
-  Date of the OpenMP specification implemented by the ``<lang>`` compiler.
-``OpenMP_<lang>_VERSION_MAJOR``
-  Major version of OpenMP implemented by the ``<lang>`` compiler.
-``OpenMP_<lang>_VERSION_MINOR``
-  Minor version of OpenMP implemented by the ``<lang>`` compiler.
-``OpenMP_<lang>_VERSION``
-  OpenMP version implemented by the ``<lang>`` compiler.
-
-The specification date is formatted as given in the OpenMP standard:
-``yyyymm`` where ``yyyy`` and ``mm`` represents the year and month of
-the OpenMP specification implemented by the ``<lang>`` compiler.
+  Boolean indicating whether OpenMP is accessible through the ``omp_lib``
+  Fortran module.
 
 For some compilers, it may be necessary to add a header search path to find
 the relevant OpenMP headers.  This location may be language-specific.  Where
 this is needed, the module may attempt to find the location, but it can be
 provided directly by setting the ``OpenMP_<lang>_INCLUDE_DIR`` cache variable.
-Note that this variable is an _input_ control to the module.  Project code
-should use the ``OpenMP_<lang>_INCLUDE_DIRS`` _output_ variable if it needs
-to know what include directories are needed.
+Note that this variable is an *input* control to the module.  Project code
+should use the ``OpenMP_<lang>_INCLUDE_DIRS`` *output* variable if it needs
+to know what include directories are needed, or preferably the
+``OpenMP::OpenMP_<lang>`` imported target.
+
+Examples
+^^^^^^^^
+
+Finding OpenMP support and linking the imported target to a project target
+using the C language component:
+
+.. code-block:: cmake
+
+  find_package(OpenMP)
+  target_link_libraries(project_target PRIVATE OpenMP::OpenMP_C)
 #]=======================================================================]
 
 cmake_policy(PUSH)
@@ -376,7 +458,7 @@
           break()
         endif()
       endif()
-    elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "LLVMFlang" AND WIN32)
+    elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "LLVMFlang")
       find_library(OpenMP_libomp_LIBRARY
         NAMES omp
         HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
@@ -622,7 +704,7 @@
   set(OpenMP_FINDLIST ${OpenMP_FIND_COMPONENTS})
 endif()
 
-unset(_OpenMP_MIN_VERSION)
+unset(OpenMP_VERSION)
 
 include(FindPackageHandleStandardArgs)
 
@@ -657,8 +739,8 @@
 
     if(OpenMP_${LANG}_FOUND)
       if(DEFINED OpenMP_${LANG}_VERSION)
-        if(NOT _OpenMP_MIN_VERSION OR _OpenMP_MIN_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
-          set(_OpenMP_MIN_VERSION OpenMP_${LANG}_VERSION)
+        if(NOT OpenMP_VERSION OR OpenMP_VERSION VERSION_GREATER OpenMP_${LANG}_VERSION)
+          set(OpenMP_VERSION "${OpenMP_${LANG}_VERSION}")
         endif()
       endif()
       set(OpenMP_${LANG}_LIBRARIES "")
@@ -705,7 +787,7 @@
 
 find_package_handle_standard_args(OpenMP
     REQUIRED_VARS ${_OpenMP_REQ_VARS}
-    VERSION_VAR ${_OpenMP_MIN_VERSION}
+    VERSION_VAR OpenMP_VERSION
     HANDLE_COMPONENTS)
 
 if(CMAKE_Fortran_COMPILER_LOADED AND OpenMP_Fortran_FOUND)
diff --git a/Modules/FindOpenSP.cmake b/Modules/FindOpenSP.cmake
index 3ff6a99..8609210 100644
--- a/Modules/FindOpenSP.cmake
+++ b/Modules/FindOpenSP.cmake
@@ -7,8 +7,14 @@
 
 .. versionadded:: 3.25
 
-Finds the OpenSP library.  OpenSP is an open-source implementation of the SGML
-(Standard Generalized Markup Language) parser.
+Finds the OpenSP library:
+
+.. code-block:: cmake
+
+  find_package(OpenSP [<version>] [...])
+
+OpenSP is an open-source implementation of the SGML (Standard Generalized
+Markup Language) parser.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -25,7 +31,7 @@
 This module defines the following variables:
 
 ``OpenSP_FOUND``
-  Boolean indicating whether the (requested version of) OpenSP is available.
+  Boolean indicating whether (the requested version of) OpenSP is available.
 
 ``OpenSP_VERSION``
   The version of found OpenSP.
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index af137d4..458eac3 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -5,7 +5,11 @@
 FindOpenSSL
 -----------
 
-Finds the installed OpenSSL encryption library and determines its version.
+Finds the installed OpenSSL encryption library and determines its version:
+
+.. code-block:: cmake
+
+  find_package(OpenSSL [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.20
   Support for specifying version range when calling the :command:`find_package`
@@ -95,23 +99,35 @@
 This module defines the following variables:
 
 ``OpenSSL_FOUND``
-  Boolean indicating whether the OpenSSL library has been found.  For backward
-  compatibility, the ``OPENSSL_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) OpenSSL library was
+  found.
+
+``OpenSSL_VERSION``
+  .. versionadded:: 4.2
+
+  The OpenSSL version found.  This is set to
+  ``<major>.<minor>.<revision><patch>`` (e.g., ``0.9.8s``).
+
 ``OPENSSL_INCLUDE_DIR``
   The OpenSSL include directory.
+
 ``OPENSSL_CRYPTO_LIBRARY``
   The OpenSSL ``crypto`` library.
+
 ``OPENSSL_CRYPTO_LIBRARIES``
   The OpenSSL ``crypto`` library and its dependencies.
+
 ``OPENSSL_SSL_LIBRARY``
   The OpenSSL ``ssl`` library.
+
 ``OPENSSL_SSL_LIBRARIES``
   The OpenSSL ``ssl`` library and its dependencies.
+
 ``OPENSSL_LIBRARIES``
   All OpenSSL libraries and their dependencies.
-``OPENSSL_VERSION``
-  The OpenSSL version found.  This is set to
-  ``<major>.<minor>.<revision><patch>`` (e.g. ``0.9.8s``).
+
 ``OPENSSL_APPLINK_SOURCE``
   The sources in the target ``OpenSSL::applink`` mentioned above.  This variable
   is only defined if found OpenSSL version is at least 0.9.8 and the platform is
@@ -142,6 +158,24 @@
   ``PKG_CONFIG_PATH`` environment variable to specify alternate locations, which
   is useful on systems with multiple library installations.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OPENSSL_FOUND``
+  .. deprecated:: 4.2
+    Use ``OpenSSL_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) OpenSSL library was
+  found.
+
+``OPENSSL_VERSION``
+  .. deprecated:: 4.2
+    Superseded by the ``OpenSSL_VERSION``.
+
+  The version of OpenSSL found.
+
 Examples
 ^^^^^^^^
 
@@ -259,7 +293,7 @@
 
 if (UNIX)
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(_OPENSSL QUIET openssl)
   endif()
 endif ()
@@ -661,7 +695,8 @@
       string(ASCII "${OPENSSL_VERSION_PATCH_ASCII}" OPENSSL_VERSION_PATCH_STRING)
     endif ()
 
-    set(OPENSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
+    set(OpenSSL_VERSION "${OPENSSL_VERSION_MAJOR}.${OPENSSL_VERSION_MINOR}.${OPENSSL_VERSION_FIX}${OPENSSL_VERSION_PATCH_STRING}")
+    set(OPENSSL_VERSION "${OpenSSL_VERSION}")
   else ()
     # Since OpenSSL 3.0.0, the new version format is MAJOR.MINOR.PATCH and
     # a new OPENSSL_VERSION_STR macro contains exactly that
@@ -670,10 +705,11 @@
     string(REGEX REPLACE "^.*OPENSSL_VERSION_STR[\t ]+\"([0-9]+\\.[0-9]+\\.[0-9]+)\".*$"
            "\\1" OPENSSL_VERSION_STR "${OPENSSL_VERSION_STR}")
 
-    set(OPENSSL_VERSION "${OPENSSL_VERSION_STR}")
+    set(OpenSSL_VERSION "${OPENSSL_VERSION_STR}")
+    set(OPENSSL_VERSION "${OpenSSL_VERSION}")
 
     # Setting OPENSSL_VERSION_MAJOR OPENSSL_VERSION_MINOR and OPENSSL_VERSION_FIX
-    string(REGEX MATCHALL "([0-9])+" OPENSSL_VERSION_NUMBER "${OPENSSL_VERSION}")
+    string(REGEX MATCHALL "([0-9])+" OPENSSL_VERSION_NUMBER "${OpenSSL_VERSION}")
     list(POP_FRONT OPENSSL_VERSION_NUMBER
       OPENSSL_VERSION_MAJOR
       OPENSSL_VERSION_MINOR
@@ -718,7 +754,7 @@
     OPENSSL_CRYPTO_LIBRARY
     OPENSSL_INCLUDE_DIR
   VERSION_VAR
-    OPENSSL_VERSION
+    OpenSSL_VERSION
   HANDLE_VERSION_RANGE
   HANDLE_COMPONENTS
   FAIL_MESSAGE
diff --git a/Modules/FindOpenSceneGraph.cmake b/Modules/FindOpenSceneGraph.cmake
index 26f406d..4bcedc0 100644
--- a/Modules/FindOpenSceneGraph.cmake
+++ b/Modules/FindOpenSceneGraph.cmake
@@ -5,7 +5,11 @@
 FindOpenSceneGraph
 ------------------
 
-Finds `OpenSceneGraph`_ (OSG), a 3D graphics application programming interface.
+Finds `OpenSceneGraph`_ (OSG), a 3D graphics application programming interface:
+
+.. code-block:: cmake
+
+  find_package(OpenSceneGraph [<version>] [COMPONENTS <components>...] [...])
 
 .. note::
 
@@ -153,12 +157,15 @@
 This module defines the following variables:
 
 ``OpenSceneGraph_FOUND``
-  Boolean indicating whether the (requested version of) OpenSceneGraph with all
-  specified components is found.  For backward compatibility, the
-  ``OPENSCENEGRAPH_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
 
-``OPENSCENEGRAPH_VERSION``
-  The version of the OSG which was found.
+  Boolean indicating whether (the requested version of) OpenSceneGraph with
+  all specified components was found.
+
+``OpenSceneGraph_VERSION``
+  .. versionadded:: 4.2
+
+  The version of OpenSceneGraph found.
 
 ``OPENSCENEGRAPH_INCLUDE_DIRS``
   Include directories containing headers needed to use OpenSceneGraph.
@@ -197,6 +204,24 @@
 ``OSG_ROOT``
   Environment variable treated the same as ``OSG_DIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OPENSCENEGRAPH_FOUND``
+  .. deprecated:: 4.2
+    Use ``OpenSceneGraph_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) OpenSceneGraph with
+  all specified components was found.
+
+``OPENSCENEGRAPH_VERSION``
+  .. deprecated:: 4.2
+    Superseded by the ``OpenSceneGraph_VERSION``.
+
+  The version of OpenSceneGraph found.
+
 Examples
 ^^^^^^^^
 
@@ -324,9 +349,11 @@
 
     set(OPENSCENEGRAPH_VERSION "${_osg_VERSION_MAJOR}.${_osg_VERSION_MINOR}.${_osg_VERSION_PATCH}"
                                 CACHE INTERNAL "The version of OSG which was detected")
+    set(OpenSceneGraph_VERSION "${OPENSCENEGRAPH_VERSION}")
+
     if(OpenSceneGraph_DEBUG)
         message(STATUS "[ FindOpenSceneGraph.cmake:${CMAKE_CURRENT_LIST_LINE} ] "
-            "Detected version ${OPENSCENEGRAPH_VERSION}")
+            "Detected version ${OpenSceneGraph_VERSION}")
     endif()
 endif()
 
@@ -374,7 +401,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(OpenSceneGraph
                                   REQUIRED_VARS OPENSCENEGRAPH_LIBRARIES OPENSCENEGRAPH_INCLUDE_DIR ${_osg_component_founds}
-                                  VERSION_VAR OPENSCENEGRAPH_VERSION)
+                                  VERSION_VAR OpenSceneGraph_VERSION)
 
 unset(_osg_component_founds)
 
diff --git a/Modules/FindOpenThreads.cmake b/Modules/FindOpenThreads.cmake
index 2e7c84f..5e01ac2 100644
--- a/Modules/FindOpenThreads.cmake
+++ b/Modules/FindOpenThreads.cmake
@@ -5,7 +5,11 @@
 FindOpenThreads
 ---------------
 
-Finds the OpenThreads C++ based threading library.
+Finds the OpenThreads C++ based threading library:
+
+.. code-block:: cmake
+
+  find_package(OpenThreads [...])
 
 OpenThreads header files are intended to be included as:
 
@@ -20,9 +24,9 @@
 This module defines the following variables:
 
 ``OpenThreads_FOUND``
-  Boolean indicating whether OpenThreads library is found.  For backward
-  compatibility, the ``OPENTHREADS_FOUND`` variable is also set to the same
-  value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the OpenThreads library was found.
 
 ``OPENTHREADS_LIBRARY``
   Libraries needed to link against to use OpenThreads.  This provides either
@@ -67,6 +71,17 @@
 ``OSGDIR``
   Environment variable treated the same as ``OPENTHREADS_DIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OPENTHREADS_FOUND``
+  .. deprecated:: 4.2
+    Use ``OpenThreads_FOUND``, which has the same value.
+
+  Boolean indicating whether the OpenThreads library was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindPHP4.cmake b/Modules/FindPHP4.cmake
index edef791..46509fe 100644
--- a/Modules/FindPHP4.cmake
+++ b/Modules/FindPHP4.cmake
@@ -5,7 +5,11 @@
 FindPHP4
 --------
 
-Finds PHP version 4, a general-purpose scripting language.
+Finds PHP version 4, a general-purpose scripting language:
+
+.. code-block:: cmake
+
+  find_package(PHP4 [...])
 
 .. note::
 
@@ -15,6 +19,14 @@
 This module checks if PHP 4 is installed and determines the locations of the
 include directories and the PHP command-line interpreter.
 
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``PHP4_FOUND``
+  Boolean indicating whether PHP 4 was found.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index 1a72f7d..f7d5eb9 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -5,7 +5,11 @@
 FindPNG
 -------
 
-Finds libpng, the official reference library for the PNG image format.
+Finds libpng, the official reference library for the PNG image format:
+
+.. code-block:: cmake
+
+  find_package(PNG [<version>] [...])
 
 .. note::
 
@@ -15,41 +19,61 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.5
-
-This module defines the following :ref:`Imported Targets`:
+This module provides the following :ref:`Imported Targets`:
 
 ``PNG::PNG``
-  The libpng library, if found.
+  .. versionadded:: 3.5
+
+  Target encapsulating the libpng library usage requirements, available if
+  libpng is found.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
+
+``PNG_FOUND``
+  Boolean indicating whether the (requested version of) PNG library was found.
+
+``PNG_VERSION``
+  .. versionadded:: 4.2
+
+  The version of the PNG library found.
 
 ``PNG_INCLUDE_DIRS``
   Directory containing the PNG headers (e.g., ``png.h``).
+
 ``PNG_LIBRARIES``
   PNG libraries required for linking.
+
 ``PNG_DEFINITIONS``
   Compile definitions for using PNG, if any.  They can be added with
   :command:`target_compile_definitions` command when not using the ``PNG::PNG``
   imported target.
-``PNG_FOUND``
-  True if PNG library is found.
-``PNG_VERSION_STRING``
-  The version of the PNG library found.
 
-Obsolete Variables
-^^^^^^^^^^^^^^^^^^
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
 
 The following variables may also be set for backward compatibility:
 
 ``PNG_LIBRARY``
+  .. deprecated:: 3.0
+    Use the ``PNG::PNG`` imported target.
+
   Path to the PNG library.
+
 ``PNG_INCLUDE_DIR``
+  .. deprecated:: 3.0
+    Use the ``PNG::PNG`` imported target.
+
   Directory containing the PNG headers (same as ``PNG_INCLUDE_DIRS``).
 
+``PNG_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``PNG_VERSION``.
+
+  The version of the PNG library found.
+
 Examples
 ^^^^^^^^
 
@@ -184,7 +208,8 @@
   if (PNG_PNG_INCLUDE_DIR AND EXISTS "${PNG_PNG_INCLUDE_DIR}/png.h")
       file(STRINGS "${PNG_PNG_INCLUDE_DIR}/png.h" png_version_str REGEX "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\".+\"")
 
-      string(REGEX REPLACE "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\"([^\"]+)\".*" "\\1" PNG_VERSION_STRING "${png_version_str}")
+      string(REGEX REPLACE "^#define[ \t]+PNG_LIBPNG_VER_STRING[ \t]+\"([^\"]+)\".*" "\\1" PNG_VERSION "${png_version_str}")
+      set(PNG_VERSION_STRING "${PNG_VERSION}")
       unset(png_version_str)
   endif ()
 endif()
@@ -192,6 +217,6 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(PNG
                                   REQUIRED_VARS PNG_LIBRARY PNG_PNG_INCLUDE_DIR
-                                  VERSION_VAR PNG_VERSION_STRING)
+                                  VERSION_VAR PNG_VERSION)
 
 cmake_policy(POP)
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 5081936..70c634b 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -5,28 +5,42 @@
 FindPackageHandleStandardArgs
 -----------------------------
 
-This module provides functions intended to be used in :ref:`Find Modules`
+This module provides commands intended for use in :ref:`Find Modules`
 implementing :command:`find_package(<PackageName>)` calls.
 
+Load this module in a CMake find module with:
+
+.. code-block:: cmake
+  :caption: ``FindFoo.cmake``
+
+  include(FindPackageHandleStandardArgs)
+
+Commands
+^^^^^^^^
+
+This module provides the following commands:
+
+* :command:`find_package_handle_standard_args`
+* :command:`find_package_check_version`
+
 .. command:: find_package_handle_standard_args
 
-  This command handles the ``REQUIRED``, ``QUIET`` and version-related
-  arguments of :command:`find_package`.  It also sets the
-  ``<PackageName>_FOUND`` variable.  The package is considered found if all
-  variables listed contain valid results, e.g. valid filepaths.
+  Handles the ``REQUIRED``, ``QUIET`` and version-related arguments of
+  :command:`find_package`.
 
   There are two signatures:
 
   .. code-block:: cmake
 
-    find_package_handle_standard_args(<PackageName>
+    find_package_handle_standard_args(
+      <PackageName>
       (DEFAULT_MSG|<custom-failure-message>)
-      <required-var>...
-      )
+      <required-vars>...
+    )
 
-    find_package_handle_standard_args(<PackageName>
-      [FOUND_VAR <result-var>]
-      [REQUIRED_VARS <required-var>...]
+    find_package_handle_standard_args(
+      <PackageName>
+      [REQUIRED_VARS <required-vars>...]
       [VERSION_VAR <version-var>]
       [HANDLE_VERSION_RANGE]
       [HANDLE_COMPONENTS]
@@ -34,37 +48,33 @@
       [NAME_MISMATCHED]
       [REASON_FAILURE_MESSAGE <reason-failure-message>]
       [FAIL_MESSAGE <custom-failure-message>]
-      )
+      [FOUND_VAR <result-var>] # Deprecated
+    )
 
-  The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all
-  the variables ``<required-var>...`` are valid and any optional
-  constraints are satisfied, and ``FALSE`` otherwise.  A success or
-  failure message may be displayed based on the results and on
-  whether the ``REQUIRED`` and/or ``QUIET`` option was given to
-  the :command:`find_package` call.
+  This command sets the ``<PackageName>_FOUND`` variable to ``TRUE`` if all
+  the variables listed in ``<required-vars>...`` contain valid results
+  (e.g., valid filepaths) and any optional constraints are satisfied, and
+  ``FALSE`` otherwise.  A success or failure message may be displayed based
+  on the results and on whether the ``REQUIRED`` and/or ``QUIET`` option
+  was given to the :command:`find_package` call.
 
-  The options are:
+  The arguments are:
+
+  ``<PackageName>``
+    The name of the package.  For example, as written in the
+    ``Find<PackageName>.cmake`` find module filename.
 
   ``(DEFAULT_MSG|<custom-failure-message>)``
     In the simple signature this specifies the failure message.
     Use ``DEFAULT_MSG`` to ask for a default message to be computed
     (recommended).  Not valid in the full signature.
 
-  ``FOUND_VAR <result-var>``
-    .. deprecated:: 3.3
-
-    Specifies either ``<PackageName>_FOUND`` or
-    ``<PACKAGENAME>_FOUND`` as the result variable.  This exists only
-    for compatibility with older versions of CMake and is now ignored.
-    Result variables of both names are now always set for compatibility
-    also with or without this option.
-
-  ``REQUIRED_VARS <required-var>...``
+  ``REQUIRED_VARS <required-vars>...``
     Specify the variables which are required for this package.
     These may be named in the generated failure message asking the
     user to set the missing variable values.  Therefore these should
-    typically be cache entries such as ``FOO_LIBRARY`` and not output
-    variables like ``FOO_LIBRARIES``.
+    typically be cache entries such as ``Foo_LIBRARY`` and not output
+    variables like ``Foo_LIBRARIES``.
 
     .. versionchanged:: 3.18
       If ``HANDLE_COMPONENTS`` is specified, this option can be omitted.
@@ -100,6 +110,14 @@
     will automatically check whether the package configuration file
     was found.
 
+  ``NAME_MISMATCHED``
+    .. versionadded:: 3.17
+
+    Indicate that the ``<PackageName>`` does not match the value of
+    :variable:`CMAKE_FIND_PACKAGE_NAME` variable. This is usually a mistake
+    and raises a warning, but it may be intentional for usage of the
+    command for components of a larger package.
+
   ``REASON_FAILURE_MESSAGE <reason-failure-message>``
     .. versionadded:: 3.16
 
@@ -110,48 +128,76 @@
     Specify a custom failure message instead of using the default
     generated message.  Not recommended.
 
-  ``NAME_MISMATCHED``
-    .. versionadded:: 3.17
+  ``FOUND_VAR <result-var>``
+    .. deprecated:: 3.3
+      This option should no longer be used.
 
-    Indicate that the ``<PackageName>`` does not match
-    ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
-    warning, but it may be intentional for usage of the command for components
-    of a larger package.
+    Specifies either ``<PackageName>_FOUND`` or ``<PACKAGENAME>_FOUND`` as the
+    result variable.  This exists only for backward compatibility with older
+    versions of CMake and is now ignored.  Result variables of both names are
+    now always set for compatibility also with or without this option.
 
-Example for the simple signature:
+  .. note::
+
+    If ``<PackageName>`` does not match :variable:`CMAKE_FIND_PACKAGE_NAME`
+    for the calling module, a warning that there is a mismatch is given.  The
+    ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
+    the old signature and the ``NAME_MISMATCHED`` argument using the new
+    signature.  To avoid forcing the caller to require newer versions of CMake
+    for usage, the variable's value will be used if defined when the
+    ``NAME_MISMATCHED`` argument is not passed for the new signature (but using
+    both is an error).
+
+.. command:: find_package_check_version
+
+  .. versionadded:: 3.19
+
+  Checks if a given version is valid against the version-related arguments
+  of :command:`find_package`:
+
+  .. code-block:: cmake
+
+    find_package_check_version(
+      <version>
+      <result-var>
+      [HANDLE_VERSION_RANGE]
+      [RESULT_MESSAGE_VARIABLE <message-var>]
+    )
+
+  The arguments are:
+
+  ``<version>``
+    The version string to check.
+
+  ``<result-var>``
+    Name of the result variable that will hold a boolean value giving the
+    result of the check.
+
+  ``HANDLE_VERSION_RANGE``
+    Enable handling of a version range, if one is specified.  Without this
+    option, a developer warning will be displayed if a version range is
+    specified.
+
+  ``RESULT_MESSAGE_VARIABLE <message-var>``
+    Specify a variable to get back a message describing the result of the check.
+
+Examples
+^^^^^^^^
+
+Examples: Full Signature
+""""""""""""""""""""""""
+
+Example for using a full signature of ``find_package_handle_standard_args()``:
 
 .. code-block:: cmake
+  :caption: ``FindLibArchive.cmake``
 
-  find_package_handle_standard_args(LibXml2 DEFAULT_MSG
-    LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR)
-
-The ``LibXml2`` package is considered to be found if both
-``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid.
-Then also ``LibXml2_FOUND`` is set to ``TRUE``.  If it is not found
-and ``REQUIRED`` was used, it fails with a
-:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was
-used or not.  If it is found, success will be reported, including
-the content of the first ``<required-var>``.  On repeated CMake runs,
-the same message will not be printed again.
-
-.. note::
-
-  If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
-  calling module, a warning that there is a mismatch is given. The
-  ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
-  the old signature and the ``NAME_MISMATCHED`` argument using the new
-  signature. To avoid forcing the caller to require newer versions of CMake for
-  usage, the variable's value will be used if defined when the
-  ``NAME_MISMATCHED`` argument is not passed for the new signature (but using
-  both is an error)..
-
-Example for the full signature:
-
-.. code-block:: cmake
-
-  find_package_handle_standard_args(LibArchive
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(
+    LibArchive
     REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR
-    VERSION_VAR LibArchive_VERSION)
+    VERSION_VAR LibArchive_VERSION
+  )
 
 In this case, the ``LibArchive`` package is considered to be found if
 both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid.
@@ -159,56 +205,73 @@
 contained in ``LibArchive_VERSION``.  Since no ``FAIL_MESSAGE`` is given,
 the default messages will be printed.
 
-Another example for the full signature:
+Another example for the full signature of
+``find_package_handle_standard_args()``:
 
 .. code-block:: cmake
+  :caption: ``FindAutomoc4.cmake``
 
   find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4)
-  find_package_handle_standard_args(Automoc4  CONFIG_MODE)
 
-In this case, a ``FindAutmoc4.cmake`` module wraps a call to
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(Automoc4 CONFIG_MODE)
+
+In this case, a ``FindAutomoc4.cmake`` module wraps a call to
 ``find_package(Automoc4 NO_MODULE)`` and adds an additional search
 directory for ``automoc4``.  Then the call to
-``find_package_handle_standard_args`` produces a proper success/failure
+``find_package_handle_standard_args()`` produces a proper success/failure
 message.
 
-.. command:: find_package_check_version
+Example: Simple Signature
+"""""""""""""""""""""""""
 
-  .. versionadded:: 3.19
-
-  Helper function which can be used to check if a ``<version>`` is valid
-  against version-related arguments of :command:`find_package`.
-
-  .. code-block:: cmake
-
-    find_package_check_version(<version> <result-var>
-      [HANDLE_VERSION_RANGE]
-      [RESULT_MESSAGE_VARIABLE <message-var>]
-      )
-
-  The ``<result-var>`` will hold a boolean value giving the result of the check.
-
-  The options are:
-
-  ``HANDLE_VERSION_RANGE``
-    Enable handling of a version range, if one is specified. Without this
-    option, a developer warning will be displayed if a version range is
-    specified.
-
-  ``RESULT_MESSAGE_VARIABLE <message-var>``
-    Specify a variable to get back a message describing the result of the check.
-
-Example for the usage:
+Example for using a simple signature of ``find_package_handle_standard_args()``:
 
 .. code-block:: cmake
+  :caption: ``FindLibXml2.cmake``
 
-  find_package_check_version(1.2.3 result HANDLE_VERSION_RANGE
-    RESULT_MESSAGE_VARIABLE reason)
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(
+    LibXml2
+    DEFAULT_MSG
+    LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR
+  )
+
+In this example, the ``LibXml2`` package is considered to be found if both
+``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` variables are valid.  Then
+also ``LibXml2_FOUND`` is set to ``TRUE``.  If it is not found and
+``REQUIRED`` was used, it fails with a :command:`message(FATAL_ERROR)`,
+independent whether ``QUIET`` was used or not.  If it is found, success will
+be reported, including the content of the first required variable specified
+in ``<required-vars>...``.  On repeated CMake runs, the same message will
+not be printed again.
+
+Example: Checking Version
+"""""""""""""""""""""""""
+
+Example for the ``find_package_check_version()`` usage:
+
+.. code-block:: cmake
+  :caption: ``FindFoo.cmake``
+
+  include(FindPackageHandleStandardArgs)
+  find_package_check_version(
+    1.2.3
+    result
+    HANDLE_VERSION_RANGE
+    RESULT_MESSAGE_VARIABLE reason
+  )
   if(result)
     message(STATUS "${reason}")
   else()
-    message(FATAL_ERROR "${reason}")
+    # Logic when version check is not successful.
+    message(WARNING "${reason}")
   endif()
+
+See Also
+^^^^^^^^
+
+* :ref:`Find Modules` for details how to write a find module.
 #]=======================================================================]
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
diff --git a/Modules/FindPackageMessage.cmake b/Modules/FindPackageMessage.cmake
index 29db756..859b0b6 100644
--- a/Modules/FindPackageMessage.cmake
+++ b/Modules/FindPackageMessage.cmake
@@ -6,11 +6,13 @@
 ------------------
 
 This module provides a command for printing find result messages and is
-intended for use in :ref:`Find Modules`.
+intended for use in :ref:`Find Modules` implementing
+:command:`find_package(<PackageName>)` calls.
 
-Load it in a CMake find module with:
+Load this module in a CMake find module with:
 
 .. code-block:: cmake
+  :caption: ``FindFoo.cmake``
 
   include(FindPackageMessage)
 
diff --git a/Modules/FindPatch.cmake b/Modules/FindPatch.cmake
index c6ca07b..cb81b6f 100644
--- a/Modules/FindPatch.cmake
+++ b/Modules/FindPatch.cmake
@@ -8,7 +8,11 @@
 .. versionadded:: 3.10
 
 Finds the ``patch`` command-line executable for applying diff patches to
-original files.
+original files:
+
+.. code-block:: cmake
+
+  find_package(Patch [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -29,7 +33,7 @@
 This module defines the following variables:
 
 ``Patch_FOUND``
-  Boolean indicating whether the ``patch`` command-line executable is found.
+  Boolean indicating whether the ``patch`` command-line executable was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake
index 06a2e62..1214a18 100644
--- a/Modules/FindPerl.cmake
+++ b/Modules/FindPerl.cmake
@@ -5,8 +5,13 @@
 FindPerl
 --------
 
-Finds a Perl interpreter.  Perl is a general-purpose, interpreted, dynamic
-programming language.
+Finds a Perl interpreter:
+
+.. code-block:: cmake
+
+  find_package(Perl [<version>] [...])
+
+Perl is a general-purpose, interpreted, dynamic programming language.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -14,10 +19,14 @@
 This module defines the following variables:
 
 ``Perl_FOUND``
-  True if the Perl executable was found.  For backward compatibility, the
-  ``PERL_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
 
-``PERL_VERSION_STRING``
+  Boolean indicating whether the (requested version of) Perl executable was
+  found.
+
+``Perl_VERSION``
+  .. versionadded:: 4.2
+
   The version of Perl found.
 
 Cache Variables
@@ -28,14 +37,41 @@
 ``PERL_EXECUTABLE``
   Full path to the ``perl`` executable.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PERL_FOUND``
+  .. deprecated:: 4.2
+    Use ``Perl_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Perl executable was
+  found.
+
+``PERL_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``Perl_VERSION``.
+
+  The version of Perl found.
+
 Examples
 ^^^^^^^^
 
-Finding the Perl interpreter:
+Finding the Perl interpreter and executing it in a process:
 
 .. code-block:: cmake
 
   find_package(Perl)
+
+  if(Perl_FOUND)
+    execute_process(COMMAND ${PERL_EXECUTABLE} --help)
+  endif()
+
+See Also
+^^^^^^^^
+
+* The :module:`FindPerlLibs` to find Perl libraries.
 #]=======================================================================]
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
@@ -64,7 +100,6 @@
   )
 
 if(PERL_EXECUTABLE)
-  ### PERL_VERSION
   execute_process(
     COMMAND
       ${PERL_EXECUTABLE} -V:version
@@ -76,7 +111,8 @@
       OUTPUT_STRIP_TRAILING_WHITESPACE
   )
   if(NOT PERL_VERSION_RESULT_VARIABLE AND NOT PERL_VERSION_OUTPUT_VARIABLE MATCHES "^version='UNKNOWN'")
-    string(REGEX REPLACE "version='([^']+)'.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE})
+    string(REGEX REPLACE "version='([^']+)'.*" "\\1" Perl_VERSION ${PERL_VERSION_OUTPUT_VARIABLE})
+    set(PERL_VERSION_STRING "${Perl_VERSION}")
   else()
     execute_process(
       COMMAND ${PERL_EXECUTABLE} -v
@@ -86,9 +122,11 @@
       OUTPUT_STRIP_TRAILING_WHITESPACE
     )
     if(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl.*[ \\(]v([0-9\\._]+)[ \\)]")
-      set(PERL_VERSION_STRING "${CMAKE_MATCH_1}")
+      set(Perl_VERSION "${CMAKE_MATCH_1}")
+      set(PERL_VERSION_STRING "${Perl_VERSION}")
     elseif(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl, version ([0-9\\._]+) +")
-      set(PERL_VERSION_STRING "${CMAKE_MATCH_1}")
+      set(Perl_VERSION "${CMAKE_MATCH_1}")
+      set(PERL_VERSION_STRING "${Perl_VERSION}")
     endif()
   endif()
 endif()
@@ -105,7 +143,7 @@
 endif ()
 find_package_handle_standard_args(Perl
                                   REQUIRED_VARS PERL_EXECUTABLE
-                                  VERSION_VAR PERL_VERSION_STRING)
+                                  VERSION_VAR Perl_VERSION)
 unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(PERL_EXECUTABLE)
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake
index 330700e..fbe1aad 100644
--- a/Modules/FindPerlLibs.cmake
+++ b/Modules/FindPerlLibs.cmake
@@ -5,18 +5,34 @@
 FindPerlLibs
 ------------
 
-Finds Perl libraries.  Perl is a general-purpose, interpreted, dynamic
-programming language.  This module detects whether Perl is installed and
-determines the locations of include paths, libraries, and the library name.
+Finds Perl libraries:
+
+.. code-block:: cmake
+
+  find_package(PerlLibs [<version>] [...])
+
+Perl is a general-purpose, interpreted, dynamic programming language.
+
+This module detects whether Perl interpreter is installed via the
+:module:`FindPerl` module and determines the locations of Perl include paths,
+libraries, and the library name.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``PerlLibs_FOUND``
-  True if ``perl.h`` and ``libperl`` were found.  For backward compatibility,
-  the ``PERLLIBS_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) ``<perl.h>`` and
+  ``libperl`` were found.
+
+``PerlLibs_VERSION``
+  .. versionadded:: 4.2
+
+  The version of Perl library found.
+
 ``PERL_SITESEARCH``
   Path to the sitesearch install directory (``-V:installsitesearch``).
 ``PERL_SITEARCH``
@@ -50,6 +66,18 @@
 ``PERL_EXECUTABLE``
   Full path to the ``perl`` executable.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PERLLIBS_FOUND``
+  .. deprecated:: 4.2
+    Use ``PerlLibs_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) ``<perl.h>`` and
+  ``libperl`` were found.
+
 Examples
 ^^^^^^^^
 
@@ -58,11 +86,18 @@
 .. code-block:: cmake
 
   find_package(PerlLibs 6.0)
+
+See Also
+^^^^^^^^
+
+* The :module:`FindPerl` module to find the Perl interpreter.
 #]=======================================================================]
 
 # find the perl executable
 include(${CMAKE_CURRENT_LIST_DIR}/FindPerl.cmake)
 
+set(PerlLibs_VERSION "${Perl_VERSION}")
+
 if (PERL_EXECUTABLE)
 
   function (perl_get_info _pgi_info tag)
@@ -122,10 +157,10 @@
   ### PERL_POSSIBLE_LIBRARY_NAMES
   perl_get_info(PERL_POSSIBLE_LIBRARY_NAMES libperl)
   if (NOT PERL_POSSIBLE_LIBRARY_NAMES)
-    set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl)
+    set(PERL_POSSIBLE_LIBRARY_NAMES perl${PerlLibs_VERSION} perl)
   endif()
   if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
-    list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING})
+    list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PerlLibs_VERSION})
   endif()
   if (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN")
     # On MSYS and CYGWIN environments, current perl -V:libperl gives shared
@@ -141,10 +176,10 @@
     PATHS
       "${PERL_UPDATE_ARCHLIB}/CORE"
       "${PERL_ARCHLIB}/CORE"
-      /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
-      /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
-      /usr/lib/perl5/${PERL_VERSION_STRING}/CORE
-      /usr/lib/perl/${PERL_VERSION_STRING}/CORE
+      /usr/lib/perl5/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE
+      /usr/lib/perl/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE
+      /usr/lib/perl5/${PerlLibs_VERSION}/CORE
+      /usr/lib/perl/${PerlLibs_VERSION}/CORE
   )
 
   ### PERL_LIBRARY
@@ -154,24 +189,24 @@
     PATHS
       "${PERL_UPDATE_ARCHLIB}/CORE"
       "${PERL_ARCHLIB}/CORE"
-      /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
-      /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE
-      /usr/lib/perl5/${PERL_VERSION_STRING}/CORE
-      /usr/lib/perl/${PERL_VERSION_STRING}/CORE
+      /usr/lib/perl5/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE
+      /usr/lib/perl/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE
+      /usr/lib/perl5/${PerlLibs_VERSION}/CORE
+      /usr/lib/perl/${PerlLibs_VERSION}/CORE
   )
 
 endif ()
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(PerlLibs REQUIRED_VARS PERL_LIBRARY PERL_INCLUDE_PATH
-                                           VERSION_VAR PERL_VERSION_STRING)
+                                           VERSION_VAR PerlLibs_VERSION)
 
 # Introduced after CMake 2.6.4 to bring module into compliance
 set(PERL_INCLUDE_DIR  ${PERL_INCLUDE_PATH})
 set(PERL_INCLUDE_DIRS ${PERL_INCLUDE_PATH})
 set(PERL_LIBRARIES    ${PERL_LIBRARY})
 # For backward compatibility with CMake before 2.8.8
-set(PERL_VERSION ${PERL_VERSION_STRING})
+set(PERL_VERSION ${PerlLibs_VERSION})
 
 mark_as_advanced(
   PERL_INCLUDE_PATH
diff --git a/Modules/FindPhysFS.cmake b/Modules/FindPhysFS.cmake
index 1894498..6031d17 100644
--- a/Modules/FindPhysFS.cmake
+++ b/Modules/FindPhysFS.cmake
@@ -5,7 +5,11 @@
 FindPhysFS
 ----------
 
-Finds the PhysicsFS library (PhysFS) for file I/O abstraction.
+Finds the PhysicsFS library (PhysFS) for file I/O abstraction:
+
+.. code-block:: cmake
+
+  find_package(PhysFS [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -13,19 +17,20 @@
 This module defines the following variables:
 
 ``PhysFS_FOUND``
-  Boolean indicating whether PhysicsFS library is found.  For backward
-  compatibility, the ``PHYSFS_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the PhysicsFS library was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
 
 The following cache variables may also be set:
 
+``PHYSFS_INCLUDE_DIR``
+  Directory containing the ``<physfs.h>`` and related headers needed for using
+  the library.
 ``PHYSFS_LIBRARY``
   Path to the PhysicsFS library needed to link against.
-``PHYSFS_INCLUDE_DIR``
-  Directory containing the ``physfs.h`` and related headers needed for using
-  the library.
 
 Hints
 ^^^^^
@@ -38,6 +43,17 @@
   destination that was used when configuring, building, and installing PhysicsFS
   library: ``./configure --prefix=$PHYSFSDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PHYSFS_FOUND``
+  .. deprecated:: 4.2
+    Use the ``PhysFS_FOUND``, which has the same value.
+
+  Boolean indicating whether the PhysicsFS library was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindPike.cmake b/Modules/FindPike.cmake
index 457e82a..08eb3f4 100644
--- a/Modules/FindPike.cmake
+++ b/Modules/FindPike.cmake
@@ -5,8 +5,24 @@
 FindPike
 --------
 
-Finds the Pike compiler and interpreter.  Pike is interpreted, general purpose,
-high-level, dynamic programming language.
+Finds the Pike compiler and interpreter:
+
+.. code-block:: cmake
+
+  find_package(Pike [...])
+
+Pike is interpreted, general purpose, high-level, dynamic programming
+language.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``Pike_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether Pike was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -40,3 +56,9 @@
   PIKE_EXECUTABLE
   PIKE_INCLUDE_PATH
   )
+
+if(PIKE_EXECUTABLE AND PIKE_INCLUDE_PATH)
+  set(Pike_FOUND TRUE)
+else()
+  set(Pike_FOUND FALSE)
+endif()
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index b230eb5..924284a 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -7,28 +7,476 @@
 
 A ``pkg-config`` module for CMake.
 
-Finds the ``pkg-config`` executable and adds the :command:`pkg_get_variable`,
-:command:`pkg_check_modules` and :command:`pkg_search_module` commands. The
-following variables will also be set:
+Finds the ``pkg-config`` executable and provides commands to use it in
+CMake:
 
-``PKG_CONFIG_FOUND``
-  True if a pkg-config executable was found.
+.. code-block:: cmake
 
-``PKG_CONFIG_VERSION_STRING``
-  The version of pkg-config that was found.
+  find_package(PkgConfig [<version>] [QUIET] [REQUIRED] [...])
+
+``pkg-config`` is a command-line program for configuring build dependency
+information.  Initially developed by FreeDesktop, it is also available in
+several implementations, such as pkgconf, u-config, and similar.  It reads
+package data from the so-called PC metadata files (``<module-name>.pc``)
+that may come installed with packages.  This module is a wrapper around the
+``pkg-config`` command-line executable.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``PkgConfig_FOUND``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) ``pkg-config``
+  executable was found.
+
+``PkgConfig_VERSION``
+  .. versionadded:: 4.2
+
+  The version of ``pkg-config`` that was found.
 
 ``PKG_CONFIG_EXECUTABLE``
-  The pathname of the pkg-config program.
+  The pathname of the ``pkg-config`` program.
 
 ``PKG_CONFIG_ARGN``
   .. versionadded:: 3.22
 
-  A list of arguments to pass to pkg-config.
+  A list of arguments to pass to ``pkg-config``.
 
 Both ``PKG_CONFIG_EXECUTABLE`` and ``PKG_CONFIG_ARGN`` are initialized by the
-module, but may be overridden by the user.  See `Variables Affecting Behavior`_
-for how these variables are initialized.
+module, but may be overridden by the user.  See `Hints`_ for how these
+variables are initialized.
 
+Commands
+^^^^^^^^
+
+This module provides the following commands, if ``pkg-config`` is found:
+
+* :command:`pkg_check_modules`
+* :command:`pkg_search_module`
+* :command:`pkg_get_variable`
+
+.. command:: pkg_check_modules
+
+  Checks for all the given modules, setting a variety of result variables
+  in the calling scope:
+
+  .. code-block:: cmake
+
+    pkg_check_modules(
+      <prefix>
+      [QUIET]
+      [REQUIRED]
+      [NO_CMAKE_PATH]
+      [NO_CMAKE_ENVIRONMENT_PATH]
+      [IMPORTED_TARGET [GLOBAL]]
+      <module-spec> [<module-spec>...]
+    )
+
+  .. rubric:: The arguments are:
+
+  ``<prefix>``
+    Prefix string prepended to result variables for the specified modules.
+
+  ``QUIET``
+    When this argument is given, no status messages will be printed.
+
+  ``REQUIRED``
+    When this argument is given, the command will fail with an error if any
+    of the specified module(s) could not be found.
+
+  ``NO_CMAKE_PATH``, ``NO_CMAKE_ENVIRONMENT_PATH``
+    .. versionadded:: 3.3
+
+    The :variable:`CMAKE_PREFIX_PATH`,
+    :variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH` cache
+    and environment variables will be added to the ``pkg-config`` search path.
+    The ``NO_CMAKE_PATH`` and ``NO_CMAKE_ENVIRONMENT_PATH`` arguments
+    disable this behavior for the cache variables and environment variables
+    respectively.
+    The ``PKG_CONFIG_USE_CMAKE_PREFIX_PATH`` variable set to ``FALSE``
+    disables this behavior globally.
+
+    .. This was actually added in 3.1, but didn't work until 3.3.
+
+  ``IMPORTED_TARGET [GLOBAL]``
+    .. versionadded:: 3.7
+
+    This argument will create an :ref:`imported target <Imported Targets>`
+    named ``PkgConfig::<prefix>`` that can be passed directly as an argument
+    to :command:`target_link_libraries`.  It will encapsulate usage
+    requirements for all specified modules ``<module-spec>...`` at once.
+
+    .. This was actually added in 3.6, but didn't work until 3.7.
+
+    ``GLOBAL``
+      .. versionadded:: 3.13
+
+      This argument is used together with ``IMPORTED_TARGET`` and will make
+      the imported target available in global scope.
+
+    .. versionadded:: 3.15
+      Non-library linker options reported by ``pkg-config`` are stored in the
+      :prop_tgt:`INTERFACE_LINK_OPTIONS` target property.
+
+    .. versionchanged:: 3.18
+      Include directories specified with ``-isystem`` are stored in the
+      :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property.  Previous
+      versions of CMake left them in the :prop_tgt:`INTERFACE_COMPILE_OPTIONS`
+      property.
+
+  ``<module-spec>``
+    Each ``<module-spec>`` can be either a bare module name (as defined in
+    its PC metadata file name ``<module-name>.pc``) or it can be a module
+    name with a version constraint (operators ``=``, ``<``, ``>``, ``<=``
+    and ``>=`` are supported).  The following are examples for a module
+    named ``foo`` with various constraints:
+
+    - ``foo`` matches any version.
+    - ``foo<2`` only matches versions before 2.
+    - ``foo>=3.1`` matches any version from 3.1 or later.
+    - ``foo=1.2.3`` requires that foo must be exactly version 1.2.3.
+
+  .. rubric:: Result Variables
+
+  The following variables may be set upon return.  Two sets of values exist:
+  One for the common case (``<XXX> = <prefix>``) and another for the
+  information ``pkg-config`` provides when called with the ``--static``
+  option (``<XXX> = <prefix>_STATIC``).
+
+  ``<XXX>_FOUND``
+    Boolean variable set to 1 if module(s) exist.
+  ``<XXX>_LIBRARIES``
+    A list of only the libraries (without the ``-l``).
+  ``<XXX>_LINK_LIBRARIES``
+    The libraries and their absolute paths.
+  ``<XXX>_LIBRARY_DIRS``
+    The paths of the libraries (without the ``-L``).
+  ``<XXX>_LDFLAGS``
+    All required linker flags.
+  ``<XXX>_LDFLAGS_OTHER``
+    All other linker flags.
+  ``<XXX>_INCLUDE_DIRS``
+    The ``-I`` preprocessor flags (without the ``-I``).
+  ``<XXX>_CFLAGS``
+    All required cflags.
+  ``<XXX>_CFLAGS_OTHER``
+    The other compiler flags.
+
+  All but ``<XXX>_FOUND`` may be a :ref:`semicolon-separated list
+  <CMake Language Lists>` if the
+  associated variable returned from ``pkg-config`` has multiple values.
+
+  .. versionchanged:: 3.18
+    Include directories specified with ``-isystem`` are stored in the
+    ``<XXX>_INCLUDE_DIRS`` variable.  Previous versions of CMake left them
+    in ``<XXX>_CFLAGS_OTHER``.
+
+  There are some special variables whose prefix depends on the number of
+  ``<module-spec>`` given.  When there is only one ``<module-spec>``,
+  ``<YYY>`` will simply be ``<prefix>``, but if two or more ``<module-spec>``
+  items are given, ``<YYY>`` will be ``<prefix>_<module-name>``.
+
+  ``<YYY>_VERSION``
+    The version of the module.
+  ``<YYY>_PREFIX``
+    The prefix directory of the module.
+  ``<YYY>_INCLUDEDIR``
+    The include directory of the module.
+  ``<YYY>_LIBDIR``
+    The lib directory of the module.
+
+  .. versionchanged:: 3.8
+    For any given ``<prefix>``, ``pkg_check_modules()`` can be called multiple
+    times with different parameters.  Previous versions of CMake cached and
+    returned the first successful result.
+
+  .. versionchanged:: 3.16
+    If a full path to the found library can't be determined, but it's still
+    visible to the linker, pass it through as ``-l<name>``.  Previous versions
+    of CMake failed in this case.
+
+.. command:: pkg_search_module
+
+  Searches for the first successful match from one or more provided module
+  specifications:
+
+  .. code-block:: cmake
+
+    pkg_search_module(
+      <prefix>
+      [QUIET]
+      [REQUIRED]
+      [NO_CMAKE_PATH]
+      [NO_CMAKE_ENVIRONMENT_PATH]
+      [IMPORTED_TARGET [GLOBAL]]
+      <module-spec> [<module-spec>...]
+    )
+
+  The behavior and arguments of this command are the same as
+  :command:`pkg_check_modules`, except that rather than checking for all
+  the specified modules, it searches for just the first successful match.
+
+  This command can be used, for example, when some package is known to have
+  possible multiple ``<module-spec>`` on different platforms or versions for
+  the same package.
+
+  .. rubric:: Result Variables
+
+  This command defines the same variables as described above with addition
+  to:
+
+  ``<prefix>_MODULE_NAME``
+    .. versionadded:: 3.16
+
+    If a module is found, the ``<prefix>_MODULE_NAME`` variable will contain
+    the name of the matching module. This variable can be used if the
+    :command:`pkg_get_variable` command needs to be called with the
+    ``<module-name>`` argument that was found by the
+    :command:`pkg_search_module`.
+
+.. command:: pkg_get_variable
+
+  .. versionadded:: 3.4
+
+  Retrieves the value of a ``pkg-config`` variable and stores it in the
+  result variable in the calling scope:
+
+  .. code-block:: cmake
+
+    pkg_get_variable(
+      <result-var>
+      <module-name>
+      <var-name>
+      [DEFINE_VARIABLES <key>=<value>...]
+    )
+
+  .. rubric:: The arguments are:
+
+  ``<result-var>``
+    Name of the result variable that will contain the value of ``pkg-config``
+    variable.  If ``pkg-config`` returns multiple values for the specified
+    variable ``<var-name>``, ``<result-var>`` will contain a
+    :ref:`semicolon-separated list <CMake Language Lists>`.
+
+  ``<module-name>``
+    Name of the module as defined in its PC metadata file name
+    (``<module-name>.pc``).
+
+  ``<var-name>``
+    The ``pkg-config`` variable name from the PC metadata file
+    ``<module-name>.pc``.
+
+  ``DEFINE_VARIABLES <key>=<value>...``
+    .. versionadded:: 3.28
+
+    Specify key-value pairs to redefine variables affecting the variable
+    retrieved with ``pkg-config``.
+
+Hints
+^^^^^
+
+This module accepts the following variables before calling
+``find_package(PkgConfig)`` to influence this module's behavior:
+
+``ENV{PKG_CONFIG_PATH}``
+  Environment variable that specifies additional paths in which
+  ``pkg-config`` will search for its ``.pc`` files.  The ``pkg-config``
+  tool by default uses this variable, while CMake also provides more common
+  :variable:`CMAKE_PREFIX_PATH` variable to specify additional paths where
+  to look for packages and their ``.pc`` files.
+
+``ENV{PKG_CONFIG}``
+  .. versionadded:: 3.1
+
+  Environment variable that can be set to the path of the ``pkg-config``
+  executable and can be used to initialize the ``PKG_CONFIG_EXECUTABLE``
+  variable, if it has not yet been set.
+
+``PKG_CONFIG_EXECUTABLE``
+
+  This cache variable can be set to the path of the ``pkg-config``
+  executable.  :command:`find_program` is called internally by the module
+  with this variable.
+
+  .. versionchanged:: 3.22
+    If the ``PKG_CONFIG`` environment variable is set, only the first
+    argument is taken from it when using it as a hint.
+
+``PKG_CONFIG_ARGN``
+
+  .. versionadded:: 3.22
+
+  This cache variable can be set to a list of arguments to additionally pass
+  to ``pkg-config`` if needed. If not provided, it will be initialized from
+  the ``PKG_CONFIG`` environment variable, if set. The first argument in that
+  environment variable is assumed to be the ``pkg-config`` program, while all
+  remaining arguments after that are used to initialize ``PKG_CONFIG_ARGN``.
+  If no such environment variable is defined, ``PKG_CONFIG_ARGN`` is
+  initialized to an empty string. The module does not update the variable once
+  it has been set in the cache.
+
+``PKG_CONFIG_USE_CMAKE_PREFIX_PATH``
+
+  .. versionadded:: 3.1
+
+  Specifies whether :command:`pkg_check_modules` and
+  :command:`pkg_search_module` should add the paths in the
+  :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_FRAMEWORK_PATH` and
+  :variable:`CMAKE_APPBUNDLE_PATH` cache and environment variables to the
+  ``pkg-config`` search path.
+
+  If this variable is not set, this behavior is enabled by default if
+  :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or later, disabled
+  otherwise.
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PKG_CONFIG_FOUND``
+  .. deprecated:: 4.2
+    Use ``PkgConfig_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) ``pkg-config``
+  executable was found.
+
+``PKG_CONFIG_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``PkgConfig_VERSION``, which has the same value.
+
+  The version of ``pkg-config`` that was found.
+
+Examples
+^^^^^^^^
+
+Examples: Finding pkg-config
+""""""""""""""""""""""""""""
+
+Finding ``pkg-config``:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig)
+
+Finding ``pkg-config`` and making it required (if not found, processing stops
+with an error message):
+
+.. code-block:: cmake
+
+  find_package(PkgConfig REQUIRED)
+
+Finding ``pkg-config`` quietly without printing status message as commonly
+used in find modules:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+Examples: Using ``pkg_check_modules()``
+"""""""""""""""""""""""""""""""""""""""
+
+Checking for any version of glib2.  If found, the output variable
+``GLIB2_VERSION`` will hold the actual version found:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+  if(PkgConfig_FOUND)
+    pkg_check_modules(GLIB2 glib-2.0)
+  endif()
+
+The following example looks for at least version 2.10 of glib2.  If found,
+the output variable ``GLIB2_VERSION`` will hold the actual version found:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+  if(PkgConfig_FOUND)
+    pkg_check_modules(GLIB2 glib-2.0>=2.10)
+  endif()
+
+The following example looks for both glib2-2.0 (at least version 2.10) and
+any version of gtk2+-2.0.  Only if both are found will ``FOO`` be considered
+found.  The ``FOO_glib-2.0_VERSION`` and ``FOO_gtk+-2.0_VERSION`` variables
+will be set to their respective found module versions.
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+  if(PkgConfig_FOUND)
+    pkg_check_modules(FOO glib-2.0>=2.10 gtk+-2.0)
+  endif()
+
+The following example requires any version of ``xrender``:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET REQUIRED)
+  pkg_check_modules(XRENDER REQUIRED xrender)
+
+Example output variables set by a successful call::
+
+  XRENDER_LIBRARIES=Xrender;X11
+  XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp
+
+Example: Using ``pkg_search_module()``
+""""""""""""""""""""""""""""""""""""""
+
+Searching for LibXml2 package, which might be provided with different
+module specifications (``libxml-2.0`` or ``libxml2``):
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+  if(PkgConfig_FOUND)
+    pkg_search_module(BAR libxml-2.0 libxml2 libxml>=2)
+  endif()
+
+Example: Creating Imported Target
+"""""""""""""""""""""""""""""""""
+
+In the following example an imported target is created from the module
+specifications to use in the project directly without using a find module.
+These imported targets can be used, for example, in cases, where package is
+known to support ``pkg-config`` on all supported platforms:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET REQUIRED)
+  pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14)
+  target_link_libraries(example PRIVATE PkgConfig::GTK)
+
+Example: Using ``pkg_get_variable()``
+"""""""""""""""""""""""""""""""""""""
+
+Retrieving the value of ``pkg-config`` variable ``girdir`` from the package
+Gobject:
+
+.. code-block:: cmake
+
+  find_package(PkgConfig QUIET)
+
+  if(PkgConfig_FOUND)
+    pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)
+  endif()
+
+  message(STATUS "${GI_GIRDIR}")
+
+See Also
+^^^^^^^^
+
+* The :command:`cmake_pkg_config` command for a modern and more advanced
+  way to work with ``pkg-config`` in CMake without requiring ``pkg-config``
+  executable to be installed.
+* :ref:`Find Modules` for details how to write a find module.
 #]========================================]
 
 ### Common stuff ####
@@ -80,7 +528,7 @@
 set(_PKG_CONFIG_FAILURE_MESSAGE "")
 if (PKG_CONFIG_EXECUTABLE)
   execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} --version
-    OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE
+    OUTPUT_VARIABLE PkgConfig_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE
     ERROR_VARIABLE _PKG_CONFIG_VERSION_ERROR ERROR_STRIP_TRAILING_WHITESPACE
     RESULT_VARIABLE _PKG_CONFIG_VERSION_RESULT
     )
@@ -93,27 +541,33 @@
     string(APPEND _PKG_CONFIG_FAILURE_MESSAGE
       "The command\n"
       "      \"${PKG_CONFIG_EXECUTABLE}\"${PKG_CONFIG_ARGN} --version\n"
-      "    failed with output:\n${PKG_CONFIG_VERSION_STRING}\n"
+      "    failed with output:\n${PkgConfig_VERSION}\n"
       "    stderr: \n${_PKG_CONFIG_VERSION_ERROR}\n"
       "    result: \n${_PKG_CONFIG_VERSION_RESULT}"
       )
     set(PKG_CONFIG_EXECUTABLE "")
     set(PKG_CONFIG_ARGN "")
-    unset(PKG_CONFIG_VERSION_STRING)
+    unset(PkgConfig_VERSION)
   endif ()
   unset(_PKG_CONFIG_VERSION_RESULT)
 endif ()
 
+# For backward compatibility.
+unset(PKG_CONFIG_VERSION_STRING)
+if(DEFINED PkgConfig_VERSION)
+  set(PKG_CONFIG_VERSION_STRING "${PkgConfig_VERSION}")
+endif()
+
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(PkgConfig
                                   REQUIRED_VARS PKG_CONFIG_EXECUTABLE
                                   REASON_FAILURE_MESSAGE "${_PKG_CONFIG_FAILURE_MESSAGE}"
-                                  VERSION_VAR PKG_CONFIG_VERSION_STRING)
+                                  VERSION_VAR PkgConfig_VERSION)
 
 # This is needed because the module name is "PkgConfig" but the name of
 # this variable has always been PKG_CONFIG_FOUND so this isn't automatically
 # handled by FPHSA.
-set(PKG_CONFIG_FOUND "${PKGCONFIG_FOUND}")
+set(PKG_CONFIG_FOUND "${PkgConfig_FOUND}")
 
 # Unsets the given variables
 macro(_pkgconfig_unset var)
@@ -154,8 +608,8 @@
 
     # pkg-config <0.29.1 and pkgconf <1.5.1 prints quoted variables without unquoting
     # unquote only if quotes are first and last characters
-    if((PKG_CONFIG_VERSION_STRING VERSION_LESS 0.29.1) OR
-        (PKG_CONFIG_VERSION_STRING VERSION_GREATER_EQUAL 1.0 AND PKG_CONFIG_VERSION_STRING VERSION_LESS 1.5.1))
+    if((PkgConfig_VERSION VERSION_LESS 0.29.1) OR
+        (PkgConfig_VERSION VERSION_GREATER_EQUAL 1.0 AND PkgConfig_VERSION VERSION_LESS 1.5.1))
       if (_pkgconfig_invoke_result MATCHES "^\"(.*)\"$")
         set(_pkgconfig_invoke_result "${CMAKE_MATCH_1}")
       elseif(_pkgconfig_invoke_result MATCHES "^'(.*)'$")
@@ -703,161 +1157,6 @@
   endif()
 endmacro()
 
-
-#[========================================[.rst:
-.. command:: pkg_check_modules
-
-  Checks for all the given modules, setting a variety of result variables in
-  the calling scope.
-
-  .. code-block:: cmake
-
-    pkg_check_modules(<prefix>
-                      [REQUIRED] [QUIET]
-                      [NO_CMAKE_PATH]
-                      [NO_CMAKE_ENVIRONMENT_PATH]
-                      [IMPORTED_TARGET [GLOBAL]]
-                      <moduleSpec> [<moduleSpec>...])
-
-  When the ``REQUIRED`` argument is given, the command will fail with an error
-  if module(s) could not be found.
-
-  When the ``QUIET`` argument is given, no status messages will be printed.
-
-  .. versionadded:: 3.3
-    The :variable:`CMAKE_PREFIX_PATH`,
-    :variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH` cache
-    and environment variables will be added to the ``pkg-config`` search path.
-    The ``NO_CMAKE_PATH`` and ``NO_CMAKE_ENVIRONMENT_PATH`` arguments
-    disable this behavior for the cache variables and environment variables
-    respectively.
-    The :variable:`PKG_CONFIG_USE_CMAKE_PREFIX_PATH` variable set to ``FALSE``
-    disables this behavior globally.
-
-    .. This was actually added in 3.1, but didn't work until 3.3.
-
-  .. versionadded:: 3.7
-    The ``IMPORTED_TARGET`` argument will create an imported target named
-    ``PkgConfig::<prefix>`` that can be passed directly as an argument to
-    :command:`target_link_libraries`.
-
-    .. This was actually added in 3.6, but didn't work until 3.7.
-
-  .. versionadded:: 3.13
-    The ``GLOBAL`` argument will make the
-    imported target available in global scope.
-
-  .. versionadded:: 3.15
-    Non-library linker options reported by ``pkg-config`` are stored in the
-    :prop_tgt:`INTERFACE_LINK_OPTIONS` target property.
-
-  .. versionchanged:: 3.18
-    Include directories specified with ``-isystem`` are stored in the
-    :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property.  Previous
-    versions of CMake left them in the :prop_tgt:`INTERFACE_COMPILE_OPTIONS`
-    property.
-
-  Each ``<moduleSpec>`` can be either a bare module name or it can be a
-  module name with a version constraint (operators ``=``, ``<``, ``>``,
-  ``<=`` and ``>=`` are supported).  The following are examples for a module
-  named ``foo`` with various constraints:
-
-  - ``foo`` matches any version.
-  - ``foo<2`` only matches versions before 2.
-  - ``foo>=3.1`` matches any version from 3.1 or later.
-  - ``foo=1.2.3`` requires that foo must be exactly version 1.2.3.
-
-  The following variables may be set upon return.  Two sets of values exist:
-  One for the common case (``<XXX> = <prefix>``) and another for the
-  information ``pkg-config`` provides when called with the ``--static``
-  option (``<XXX> = <prefix>_STATIC``).
-
-  ``<XXX>_FOUND``
-    set to 1 if module(s) exist
-  ``<XXX>_LIBRARIES``
-    only the libraries (without the '-l')
-  ``<XXX>_LINK_LIBRARIES``
-    the libraries and their absolute paths
-  ``<XXX>_LIBRARY_DIRS``
-    the paths of the libraries (without the '-L')
-  ``<XXX>_LDFLAGS``
-    all required linker flags
-  ``<XXX>_LDFLAGS_OTHER``
-    all other linker flags
-  ``<XXX>_INCLUDE_DIRS``
-    the '-I' preprocessor flags (without the '-I')
-  ``<XXX>_CFLAGS``
-    all required cflags
-  ``<XXX>_CFLAGS_OTHER``
-    the other compiler flags
-
-  All but ``<XXX>_FOUND`` may be a :ref:`;-list <CMake Language Lists>` if the
-  associated variable returned from ``pkg-config`` has multiple values.
-
-  .. versionchanged:: 3.18
-    Include directories specified with ``-isystem`` are stored in the
-    ``<XXX>_INCLUDE_DIRS`` variable.  Previous versions of CMake left them
-    in ``<XXX>_CFLAGS_OTHER``.
-
-  There are some special variables whose prefix depends on the number of
-  ``<moduleSpec>`` given.  When there is only one ``<moduleSpec>``,
-  ``<YYY>`` will simply be ``<prefix>``, but if two or more ``<moduleSpec>``
-  items are given, ``<YYY>`` will be ``<prefix>_<moduleName>``.
-
-  ``<YYY>_VERSION``
-    version of the module
-  ``<YYY>_PREFIX``
-    prefix directory of the module
-  ``<YYY>_INCLUDEDIR``
-    include directory of the module
-  ``<YYY>_LIBDIR``
-    lib directory of the module
-
-  .. versionchanged:: 3.8
-    For any given ``<prefix>``, ``pkg_check_modules()`` can be called multiple
-    times with different parameters.  Previous versions of CMake cached and
-    returned the first successful result.
-
-  .. versionchanged:: 3.16
-    If a full path to the found library can't be determined, but it's still
-    visible to the linker, pass it through as ``-l<name>``.  Previous versions
-    of CMake failed in this case.
-
-  Examples:
-
-  .. code-block:: cmake
-
-    pkg_check_modules (GLIB2 glib-2.0)
-
-  Looks for any version of glib2.  If found, the output variable
-  ``GLIB2_VERSION`` will hold the actual version found.
-
-  .. code-block:: cmake
-
-    pkg_check_modules (GLIB2 glib-2.0>=2.10)
-
-  Looks for at least version 2.10 of glib2.  If found, the output variable
-  ``GLIB2_VERSION`` will hold the actual version found.
-
-  .. code-block:: cmake
-
-    pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0)
-
-  Looks for both glib2-2.0 (at least version 2.10) and any version of
-  gtk2+-2.0.  Only if both are found will ``FOO`` be considered found.
-  The ``FOO_glib-2.0_VERSION`` and ``FOO_gtk+-2.0_VERSION`` variables will be
-  set to their respective found module versions.
-
-  .. code-block:: cmake
-
-    pkg_check_modules (XRENDER REQUIRED xrender)
-
-  Requires any version of ``xrender``.  Example output variables set by a
-  successful call::
-
-    XRENDER_LIBRARIES=Xrender;X11
-    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})
   # check cached value
@@ -877,34 +1176,6 @@
   endif()
 endmacro()
 
-
-#[========================================[.rst:
-.. command:: pkg_search_module
-
-  The behavior of this command is the same as :command:`pkg_check_modules`,
-  except that rather than checking for all the specified modules, it searches
-  for just the first successful match.
-
-  .. code-block:: cmake
-
-    pkg_search_module(<prefix>
-                      [REQUIRED] [QUIET]
-                      [NO_CMAKE_PATH]
-                      [NO_CMAKE_ENVIRONMENT_PATH]
-                      [IMPORTED_TARGET [GLOBAL]]
-                      <moduleSpec> [<moduleSpec>...])
-
-  .. versionadded:: 3.16
-    If a module is found, the ``<prefix>_MODULE_NAME`` variable will contain the
-    name of the matching module. This variable can be used if you need to run
-    :command:`pkg_get_variable`.
-
-  Example:
-
-  .. code-block:: cmake
-
-    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})
   # check cached value
@@ -939,36 +1210,6 @@
   endif()
 endmacro()
 
-#[========================================[.rst:
-.. command:: pkg_get_variable
-
-  .. versionadded:: 3.4
-
-  Retrieves the value of a pkg-config variable ``varName`` and stores it in the
-  result variable ``resultVar`` in the calling scope.
-
-  .. code-block:: cmake
-
-    pkg_get_variable(<resultVar> <moduleName> <varName>
-                     [DEFINE_VARIABLES <key>=<value>...])
-
-  If ``pkg-config`` returns multiple values for the specified variable,
-  ``resultVar`` will contain a :ref:`;-list <CMake Language Lists>`.
-
-  Options:
-
-  ``DEFINE_VARIABLES <key>=<value>...``
-    .. versionadded:: 3.28
-
-    Specify key-value pairs to redefine variables affecting the variable
-    retrieved with ``pkg-config``.
-
-  For example:
-
-  .. code-block:: cmake
-
-    pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir)
-#]========================================]
 function (pkg_get_variable result pkg variable)
   set(_multiValueArgs DEFINE_VARIABLES)
 
@@ -989,55 +1230,3 @@
     PARENT_SCOPE)
   _pkg_restore_path_internal()
 endfunction ()
-
-
-#[========================================[.rst:
-Variables Affecting Behavior
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. variable:: PKG_CONFIG_EXECUTABLE
-
-  This cache variable can be set to the path of the pkg-config executable.
-  :command:`find_program` is called internally by the module with this
-  variable.
-
-  .. versionadded:: 3.1
-    The ``PKG_CONFIG`` environment variable can be used as a hint if
-    ``PKG_CONFIG_EXECUTABLE`` has not yet been set.
-
-  .. versionchanged:: 3.22
-    If the ``PKG_CONFIG`` environment variable is set, only the first
-    argument is taken from it when using it as a hint.
-
-.. variable:: PKG_CONFIG_ARGN
-
-  .. versionadded:: 3.22
-
-  This cache variable can be set to a list of arguments to additionally pass
-  to pkg-config if needed. If not provided, it will be initialized from the
-  ``PKG_CONFIG`` environment variable, if set. The first argument in that
-  environment variable is assumed to be the pkg-config program, while all
-  remaining arguments after that are used to initialize ``PKG_CONFIG_ARGN``.
-  If no such environment variable is defined, ``PKG_CONFIG_ARGN`` is
-  initialized to an empty string. The module does not update the variable once
-  it has been set in the cache.
-
-.. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH
-
-  .. versionadded:: 3.1
-
-  Specifies whether :command:`pkg_check_modules` and
-  :command:`pkg_search_module` should add the paths in the
-  :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_FRAMEWORK_PATH` and
-  :variable:`CMAKE_APPBUNDLE_PATH` cache and environment variables to the
-  ``pkg-config`` search path.
-
-  If this variable is not set, this behavior is enabled by default if
-  :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or later, disabled
-  otherwise.
-#]========================================]
-
-
-### Local Variables:
-### mode: cmake
-### End:
diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake
index ede8f0d..fd68c73 100644
--- a/Modules/FindPostgreSQL.cmake
+++ b/Modules/FindPostgreSQL.cmake
@@ -6,7 +6,11 @@
 --------------
 
 Finds the PostgreSQL installation - the client library (``libpq``) and
-optionally the server.
+optionally the server:
+
+.. code-block:: cmake
+
+  find_package(PostgreSQL [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -27,15 +31,22 @@
 
 ``PostgreSQL_FOUND``
   Boolean indicating whether the minimum required version and components of
-  PostgreSQL have been found.
+  PostgreSQL were found.
+
+``PostgreSQL_VERSION``
+  .. versionadded:: 4.2
+
+  The version of PostgreSQL found.
+
 ``PostgreSQL_LIBRARIES``
   The PostgreSQL libraries needed for linking.
+
 ``PostgreSQL_INCLUDE_DIRS``
   The include directories containing PostgreSQL headers.
+
 ``PostgreSQL_LIBRARY_DIRS``
   The directories containing PostgreSQL libraries.
-``PostgreSQL_VERSION_STRING``
-  The version of PostgreSQL found.
+
 ``PostgreSQL_TYPE_INCLUDE_DIR``
   The include directory containing PostgreSQL server headers.
 
@@ -51,6 +62,17 @@
   ``PostgreSQL_TYPE_INCLUDE_DIR`` variable is set regardless of whether this
   component is specified in the ``find_package()`` call.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PostgreSQL_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``PostgreSQL_VERSION``.
+
+  The version of PostgreSQL found.
+
 Examples
 ^^^^^^^^
 
@@ -109,6 +131,7 @@
 # In Windows the default installation of PostgreSQL uses that as part of the path.
 # E.g C:\Program Files\PostgreSQL\8.4.
 # Currently, the following version numbers are known to this module:
+# "17"
 # "16" "15" "14" "13" "12" "11" "10" "9.6" "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0"
 #
 # To use this variable just do something like this:
@@ -158,6 +181,7 @@
 
 
 set(PostgreSQL_KNOWN_VERSIONS ${PostgreSQL_ADDITIONAL_VERSIONS}
+    "17"
     "16" "15" "14" "13" "12" "11" "10" "9.6" "9.5" "9.4" "9.3" "9.2" "9.1" "9.0" "8.4" "8.3" "8.2" "8.1" "8.0")
 
 # Define additional search paths for root directories.
@@ -288,14 +312,16 @@
       math(EXPR _PostgreSQL_major_version "${_PostgreSQL_VERSION_NUM} / 10000")
       math(EXPR _PostgreSQL_minor_version "${_PostgreSQL_VERSION_NUM} % 10000 / 100")
       math(EXPR _PostgreSQL_patch_version "${_PostgreSQL_VERSION_NUM} % 100")
-      set(PostgreSQL_VERSION_STRING "${_PostgreSQL_major_version}.${_PostgreSQL_minor_version}.${_PostgreSQL_patch_version}")
+      set(PostgreSQL_VERSION "${_PostgreSQL_major_version}.${_PostgreSQL_minor_version}.${_PostgreSQL_patch_version}")
+      set(PostgreSQL_VERSION_STRING "${PostgreSQL_VERSION}")
       unset(_PostgreSQL_major_version)
       unset(_PostgreSQL_minor_version)
       unset(_PostgreSQL_patch_version)
     else ()
       math(EXPR _PostgreSQL_major_version "${_PostgreSQL_VERSION_NUM} / 10000")
       math(EXPR _PostgreSQL_minor_version "${_PostgreSQL_VERSION_NUM} % 10000")
-      set(PostgreSQL_VERSION_STRING "${_PostgreSQL_major_version}.${_PostgreSQL_minor_version}")
+      set(PostgreSQL_VERSION "${_PostgreSQL_major_version}.${_PostgreSQL_minor_version}")
+      set(PostgreSQL_VERSION_STRING "${PostgreSQL_VERSION}")
       unset(_PostgreSQL_major_version)
       unset(_PostgreSQL_minor_version)
     endif ()
@@ -306,7 +332,8 @@
              REGEX "^#define[\t ]+PG_VERSION[\t ]+\".*\"")
         if(pgsql_version_str)
           string(REGEX REPLACE "^#define[\t ]+PG_VERSION[\t ]+\"([^\"]*)\".*"
-                 "\\1" PostgreSQL_VERSION_STRING "${pgsql_version_str}")
+                 "\\1" PostgreSQL_VERSION "${pgsql_version_str}")
+          set(PostgreSQL_VERSION_STRING "${PostgreSQL_VERSION}")
           break()
         endif()
       endif()
@@ -328,7 +355,7 @@
 find_package_handle_standard_args(PostgreSQL
                                   REQUIRED_VARS PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR
                                   HANDLE_COMPONENTS
-                                  VERSION_VAR PostgreSQL_VERSION_STRING)
+                                  VERSION_VAR PostgreSQL_VERSION)
 
 function(__postgresql_import_library _target _var _config)
   if(_config)
diff --git a/Modules/FindProducer.cmake b/Modules/FindProducer.cmake
index 1d034bc..7fbd837 100644
--- a/Modules/FindProducer.cmake
+++ b/Modules/FindProducer.cmake
@@ -14,8 +14,12 @@
   library became obsolete and is no longer maintained.  For details about
   OpenSceneGraph usage, refer to the :module:`FindOpenSceneGraph` module.
 
-This module finds the Producer library, a windowing and event handling library
-designed primarily for real-time graphics applications.
+Finds the Producer library, a windowing and event handling library designed
+primarily for real-time graphics applications:
+
+.. code-block:: cmake
+
+  find_package(Producer [...])
 
 Producer library headers are intended to be included in C++ project source code
 as:
@@ -31,8 +35,9 @@
 This module defines the following variables:
 
 ``Producer_FOUND``
-  Boolean indicating whether Producer is found.  For backward compatibility, the
-  ``PRODUCER_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Producer was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -68,6 +73,17 @@
 ``OSG_DIR``
   Environment variable treated the same as ``PRODUCER_DIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PRODUCER_FOUND``
+  .. deprecated:: 4.2
+    Use ``Producer_FOUND``, which has the same value.
+
+  Boolean indicating whether Producer was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 4402afa..62baba1 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -78,8 +78,11 @@
 This module defines the following variables:
 
 ``Protobuf_FOUND``
-  Boolean indicating whether (the requested version of) Protobuf library is
-  found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) Protobuf library
+  was found.
+
 ``Protobuf_VERSION``
   .. versionadded:: 3.6
 
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 28f47b4..46a8cbb 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -7,8 +7,12 @@
 
 .. versionadded:: 3.12
 
-Find Python interpreter, compiler and development environment (include
-directories and libraries).
+Finds Python interpreter, compiler and development environment (include
+directories and libraries):
+
+.. code-block:: cmake
+
+  find_package(Python [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.19
   When a version is requested, it can be specified as a simple value or as a
@@ -38,10 +42,14 @@
       `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_.
       This component is available only for version ``3.2`` and upper.
 
-* ``NumPy``: search for NumPy include directories.
-
 .. versionadded:: 3.14
-  Added the ``NumPy`` component.
+
+  * ``NumPy``: search for NumPy include directories. Specifying this component
+    imply also the components ``Interpreter`` and ``Development.Module``.
+
+  .. versionchanged:: 4.2
+    The component ``Development.Module`` is no longer implied when the policy
+    :policy:`CMP0201` is set to ``NEW``.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
@@ -87,7 +95,7 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-This module defines the following :ref:`Imported Targets <Imported Targets>`:
+This module provides the following :ref:`Imported Targets`:
 
 .. versionchanged:: 3.14
   :ref:`Imported Targets <Imported Targets>` are only created when
@@ -134,17 +142,22 @@
   .. versionadded:: 3.14
 
   NumPy Python library. Target defined if component ``NumPy`` is found.
+  Moreover, this target has the ``Python::Module`` target as dependency.
+
+  .. versionchanged:: 4.2
+    This target does not have anymore the ``Python::Module`` target as
+    dependency when the policy :policy:`CMP0201` is set to ``NEW``.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in your project
+This module defines the following variables
 (see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
 
 ``Python_FOUND``
-  System has the Python requested components.
+  Boolean indicating whether system has the Python requested components.
 ``Python_Interpreter_FOUND``
-  System has the Python interpreter.
+  Boolean indicating whether system has the Python interpreter.
 ``Python_EXECUTABLE``
   Path to the Python interpreter.
 ``Python_EXECUTABLE_DEBUG``
@@ -206,7 +219,7 @@
   string.
 
 ``Python_Compiler_FOUND``
-  System has the Python compiler.
+  Boolean indicating whether system has the Python compiler.
 ``Python_COMPILER``
   Path to the Python compiler. Only offered by IronPython.
 ``Python_COMPILER_ID``
@@ -219,23 +232,25 @@
   The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
 
 ``Python_Development_FOUND``
-  System has the Python development artifacts.
+  Boolean indicating whether system has the Python development artifacts.
 
 ``Python_Development.Module_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python development artifacts for Python module.
+  Boolean indicating whether system has the Python development artifacts
+  for Python module.
 
 ``Python_Development.SABIModule_FOUND``
   .. versionadded:: 3.26
 
-  System has the Python development artifacts for Python module using the
-  Stable Application Binary Interface.
+  Boolean indicating whether system has the Python development artifacts
+  for Python module using the Stable Application Binary Interface.
 
 ``Python_Development.Embed_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python development artifacts for Python embedding.
+  Boolean indicating whether system has the Python development artifacts
+  for Python embedding.
 
 ``Python_INCLUDE_DIRS``
 
@@ -293,7 +308,7 @@
 ``Python_NumPy_FOUND``
   .. versionadded:: 3.14
 
-  System has the NumPy.
+  Boolean indicating whether system has the NumPy.
 
 ``Python_NumPy_INCLUDE_DIRS``
   .. versionadded:: 3.14
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 24a3970..2d34332 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -537,6 +537,13 @@
     return()
   endif()
 
+  if (NAME STREQUAL "POSTFIX")
+    if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "_d${CMAKE_IMPORT_LIBRARY_SUFFIX}$")
+      set (${_PYTHON_PGCV_VALUE} "_d" PARENT_SCOPE)
+    endif()
+    return()
+  endif()
+
   if (NAME STREQUAL "SOSABI")
     # assume some default
     if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN")
@@ -667,10 +674,6 @@
       else()
         string (REGEX REPLACE "^\\.(.+)\\.[^.]+$" "\\1" _values "${_values}")
       endif()
-    elseif (NAME STREQUAL "POSTFIX")
-      if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_DEBUG MATCHES "_d${CMAKE_IMPORT_LIBRARY_SUFFIX}$")
-        set (_values "_d")
-      endif()
     elseif (NAME STREQUAL "ABIFLAGS" AND WIN32)
       # config var ABIFLAGS does not exist for version < 3.14, check GIL specific variable
       execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
@@ -1475,12 +1478,16 @@
 
 
 # handle components
+cmake_policy (GET CMP0201 _${_PYTHON_PREFIX}_NUMPY_POLICY)
 if (NOT ${_PYTHON_BASE}_FIND_COMPONENTS)
   set (${_PYTHON_BASE}_FIND_COMPONENTS Interpreter)
   set (${_PYTHON_BASE}_FIND_REQUIRED_Interpreter TRUE)
 endif()
 if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS)
-  list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Interpreter" "Development.Module")
+  list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Interpreter")
+  if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW")
+    list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Development.Module")
+  endif()
 endif()
 if ("Development" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS)
   list (APPEND ${_PYTHON_BASE}_FIND_COMPONENTS "Development.Module" "Development.Embed")
@@ -1515,13 +1522,13 @@
 unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS)
 unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
 if ("Development.Module" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS)
-  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS|Android|AIX)$")
     list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
   endif()
   list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
 endif()
 if ("Development.SABIModule" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS)
-  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+  if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS|Android)$")
     list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "SABI_LIBRARY")
   endif()
   list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_SABIMODULE_ARTIFACTS "INCLUDE_DIR")
@@ -4057,7 +4064,12 @@
     set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
   elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
     # compute numpy signature. Depends on interpreter and development signatures
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+    set(__${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}")
+    if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW")
+      string(APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}")
+    endif()
+    string(APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}")
     if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
         OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
       unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
@@ -4108,8 +4120,12 @@
       unset (${_PYTHON_PREFIX}_NumPy_VERSION)
     endif()
 
-    # final step: set NumPy founded only if Development.Module component is founded as well
-    set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
+    if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW")
+      # final step: set NumPy founded only if Development.Module component is founded as well
+      set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
+    else()
+      set (${_PYTHON_PREFIX}_NumPy_FOUND TRUE)
+    endif()
   else()
     set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
   endif()
@@ -4124,7 +4140,12 @@
     unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE)
 
     # compute and save numpy signature
-    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+    set (__${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}")
+    if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW")
+      string (APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}")
+    endif()
+    string (APPEND __${_PYTHON_PREFIX}_NUMPY_SIGNATURE ":${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+    string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}")
     set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
   else()
     unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
@@ -4333,7 +4354,7 @@
 
     if (${_PYTHON_PREFIX}_Development.Module_FOUND)
       if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
-        # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+        # On Windows/CYGWIN/MSYS/Android/AIX, Python::Module is the same as Python::Python
         # but ALIAS cannot be used because the imported library is not GLOBAL.
         __python_import_library (${_PYTHON_PREFIX}::Module)
       else()
@@ -4461,11 +4482,14 @@
   endif()
 
   if ("NumPy" IN_LIST ${_PYTHON_BASE}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_NumPy_FOUND
-      AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND TARGET ${_PYTHON_PREFIX}::Module)
+      AND NOT TARGET ${_PYTHON_PREFIX}::NumPy AND
+      (_${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW" OR TARGET ${_PYTHON_PREFIX}::Module))
     add_library (${_PYTHON_PREFIX}::NumPy INTERFACE IMPORTED)
     set_property (TARGET ${_PYTHON_PREFIX}::NumPy
                   PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS}")
-    target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module)
+    if(NOT _${_PYTHON_PREFIX}_NUMPY_POLICY STREQUAL "NEW")
+      target_link_libraries (${_PYTHON_PREFIX}::NumPy INTERFACE ${_PYTHON_PREFIX}::Module)
+    endif()
   endif()
 endif()
 
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 869dc70..adcfe63 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -7,8 +7,12 @@
 
 .. versionadded:: 3.12
 
-Find Python 2 interpreter, compiler and development environment (include
-directories and libraries).
+Finds Python 2 interpreter, compiler and development environment (include
+directories and libraries):
+
+.. code-block:: cmake
+
+  find_package(Python2 [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.19
   When a version is requested, it can be specified as a simple value or as a
@@ -31,10 +35,14 @@
     * ``Development.Embed``: search for artifacts for Python 2 embedding
       developments.
 
-* ``NumPy``: search for NumPy include directories.
-
 .. versionadded:: 3.14
-  Added the ``NumPy`` component.
+
+  * ``NumPy``: search for NumPy include directories. Specifying this component
+    imply also the components ``Interpreter`` and ``Development.Module``.
+
+  .. versionchanged:: 4.2
+    The component ``Development.Module`` is no longer implied when the policy
+    :policy:`CMP0201` is set to ``NEW``.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
@@ -81,7 +89,7 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-This module defines the following :ref:`Imported Targets <Imported Targets>`:
+This module provides the following :ref:`Imported Targets`:
 
 .. versionchanged:: 3.14
   :ref:`Imported Targets <Imported Targets>` are only created when
@@ -121,17 +129,22 @@
   .. versionadded:: 3.14
 
   NumPy library for Python 2. Target defined if component ``NumPy`` is found.
+  Moreover, this target has the ``Python2::Module`` target as dependency.
+
+  .. versionchanged:: 4.2
+    This target does not have anymore the ``Python2::Module`` target as
+    dependency when the policy :policy:`CMP0201` is set to ``NEW``.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in your project
+This module defines the following variables
 (see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
 
 ``Python2_FOUND``
-  System has the Python 2 requested components.
+  Boolean indicating whether system has the Python 2 requested components.
 ``Python2_Interpreter_FOUND``
-  System has the Python 2 interpreter.
+  Boolean indicating whether system has the Python 2 interpreter.
 ``Python2_EXECUTABLE``
   Path to the Python 2 interpreter.
 ``Python2_EXECUTABLE_DEBUG``
@@ -177,7 +190,7 @@
   Information returned by ``sysconfig.get_path('platlib')`` or else
   ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
 ``Python2_Compiler_FOUND``
-  System has the Python 2 compiler.
+  Boolean indicating whether system has the Python 2 compiler.
 ``Python2_COMPILER``
   Path to the Python 2 compiler. Only offered by IronPython.
 ``Python2_COMPILER_ID``
@@ -190,17 +203,19 @@
   The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
 
 ``Python2_Development_FOUND``
-  System has the Python 2 development artifacts.
+  Boolean indicating whether system has the Python 2 development artifacts.
 
 ``Python2_Development.Module_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python 2 development artifacts for Python module.
+  Boolean indicating whether system has the Python 2 development artifacts
+  for Python module.
 
 ``Python2_Development.Embed_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python 2 development artifacts for Python embedding.
+  Boolean indicating whether system has the Python 2 development artifacts
+  for Python embedding.
 
 ``Python2_INCLUDE_DIRS``
   The Python 2 include directories.
@@ -240,7 +255,7 @@
 ``Python2_NumPy_FOUND``
   .. versionadded:: 3.14
 
-  System has the NumPy.
+  Boolean indicating whether system has the NumPy.
 
 ``Python2_NumPy_INCLUDE_DIRS``
   .. versionadded:: 3.14
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index 66c325a..ee6715d 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -7,8 +7,12 @@
 
 .. versionadded:: 3.12
 
-Find Python 3 interpreter, compiler and development environment (include
-directories and libraries).
+Finds Python 3 interpreter, compiler and development environment (include
+directories and libraries):
+
+.. code-block:: cmake
+
+  find_package(Python3 [<version>] [COMPONENTS <components>...] [...])
 
 .. versionadded:: 3.19
   When a version is requested, it can be specified as a simple value or as a
@@ -38,10 +42,14 @@
       `Stable Application Binary Interface <https://docs.python.org/3/c-api/stable.html>`_.
       This component is available only for version ``3.2`` and upper.
 
-* ``NumPy``: search for NumPy include directories.
-
 .. versionadded:: 3.14
-  Added the ``NumPy`` component.
+
+  * ``NumPy``: search for NumPy include directories. Specifying this component
+    imply also the components ``Interpreter`` and ``Development.Module``.
+
+  .. versionchanged:: 4.2
+    The component ``Development.Module`` is no longer implied when the policy
+    :policy:`CMP0201` is set to ``NEW``.
 
 If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
 
@@ -89,7 +97,7 @@
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-This module defines the following :ref:`Imported Targets <Imported Targets>`:
+This module provides the following :ref:`Imported Targets`:
 
 .. versionchanged:: 3.14
   :ref:`Imported Targets <Imported Targets>` are only created when
@@ -136,17 +144,22 @@
   .. versionadded:: 3.14
 
   NumPy library for Python 3. Target defined if component ``NumPy`` is found.
+  Moreover, this target has the ``Python3::Module`` target as dependency.
+
+  .. versionchanged:: 4.2
+    This target does not have anymore the ``Python3::Module`` target as
+    dependency when the policy :policy:`CMP0201` is set to ``NEW``.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in your project
+This module defines the following variables
 (see :ref:`Standard Variable Names <CMake Developer Standard Variable Names>`):
 
 ``Python3_FOUND``
-  System has the Python 3 requested components.
+  Boolean indicating whether system has the Python 3 requested components.
 ``Python3_Interpreter_FOUND``
-  System has the Python 3 interpreter.
+  Boolean indicating whether system has the Python 3 interpreter.
 ``Python3_EXECUTABLE``
   Path to the Python 3 interpreter.
 ``Python3_EXECUTABLE_DEBUG``
@@ -208,7 +221,7 @@
   string.
 
 ``Python3_Compiler_FOUND``
-  System has the Python 3 compiler.
+  Boolean indicating whether system has the Python 3 compiler.
 ``Python3_COMPILER``
   Path to the Python 3 compiler. Only offered by IronPython.
 ``Python3_COMPILER_ID``
@@ -222,23 +235,25 @@
 
 ``Python3_Development_FOUND``
 
-  System has the Python 3 development artifacts.
+  Boolean indicating whether system has the Python 3 development artifacts.
 
 ``Python3_Development.Module_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python 3 development artifacts for Python module.
+  Boolean indicating whether system has the Python 3 development artifacts
+  for Python module.
 
 ``Python3_Development.SABIModule_FOUND``
   .. versionadded:: 3.26
 
-  System has the Python 3 development artifacts for Python module using the
-  Stable Application Binary Interface.
+  Boolean indicating whether system has the Python 3 development artifacts
+  for Python module using the Stable Application Binary Interface.
 
 ``Python3_Development.Embed_FOUND``
   .. versionadded:: 3.18
 
-  System has the Python 3 development artifacts for Python embedding.
+  Boolean indicating whether system has the Python 3 development artifacts
+  for Python embedding.
 
 ``Python3_INCLUDE_DIRS``
 
@@ -296,7 +311,7 @@
 ``Python3_NumPy_FOUND``
   .. versionadded:: 3.14
 
-  System has the NumPy.
+  Boolean indicating whether system has the NumPy.
 
 ``Python3_NumPy_INCLUDE_DIRS``
   .. versionadded:: 3.14
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index 4f4b85f..81d61a8 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -13,8 +13,11 @@
   Use :module:`FindPython3`, :module:`FindPython2`, or :module:`FindPython`
   instead.
 
-This module finds the Python interpreter and determines the location of its
-executable.
+Finds the Python interpreter and determines the location of its executable:
+
+.. code-block:: cmake
+
+  find_package(PythonInterp [<version>] [...])
 
 .. note::
 
@@ -36,9 +39,11 @@
 This module defines the following variables:
 
 ``PythonInterp_FOUND``
-  Boolean indicating whether the (requested version of) Python executable is
-  found.  For backward compatibility, the ``PYTHONINTERP_FOUND`` variable is
-  also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) Python executable
+  was found.
+
 ``PYTHON_VERSION_STRING``
   Python version found (e.g., ``2.5.2``).
 ``PYTHON_VERSION_MAJOR``
@@ -66,6 +71,18 @@
   This variable can be used to specify a list of version numbers that should be
   taken into account when searching for Python.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``PYTHONINTERP_FOUND``
+  .. deprecated:: 3.12
+    Use ``PythonInterp_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Python executable
+  was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindPythonLibs.cmake b/Modules/FindPythonLibs.cmake
index bf2b2dc..272b176 100644
--- a/Modules/FindPythonLibs.cmake
+++ b/Modules/FindPythonLibs.cmake
@@ -13,9 +13,13 @@
   Use :module:`FindPython3`, :module:`FindPython2`, or :module:`FindPython`
   instead.
 
-This module finds the Python installation and determines the location of its
-include directories and libraries, as well as the name of the Python library to
-link against.
+Finds the Python installation and determines the location of its include
+directories and libraries, as well as the name of the Python library to
+link against:
+
+.. code-block:: cmake
+
+  find_package(PythonLibs [<version>] [...])
 
 .. note::
 
@@ -30,9 +34,10 @@
 This module defines the following variables:
 
 ``PythonLibs_FOUND``
-  Boolean indicating whether the (requested version of) Python libraries have
-  been found.  For backward compatibility, the ``PYTHONLIBS_FOUND`` variable is
-  also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) Python libraries
+  were found.
 
 ``PYTHONLIBS_VERSION_STRING``
   The version of the Python libraries found.
@@ -68,7 +73,14 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-These variables are provided for backward compatibility:
+The following variables are provided for backward compatibility:
+
+``PYTHONLIBS_FOUND``
+  .. deprecated:: 3.12
+    Use ``PythonLibs_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Python libraries
+  were found.
 
 ``PYTHON_DEBUG_LIBRARIES``
   .. deprecated:: 2.8.8
diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake
index 98cd1e2..9fc83e6 100644
--- a/Modules/FindQt.cmake
+++ b/Modules/FindQt.cmake
@@ -11,9 +11,14 @@
   ``NEW``.  It supports only Qt3 and Qt4.  For Qt5 or later versions see
   :manual:`cmake-qt(7)`.
 
-This module finds an installed version of Qt3 or Qt4.  Qt is a cross-platform
-application development framework for creating graphical user interfaces and
-applications.
+Finds an installed version of Qt3 or Qt4:
+
+.. code-block:: cmake
+
+  find_package(Qt [...])
+
+Qt is a cross-platform application development framework for creating
+graphical user interfaces and applications.
 
 Use this module only if the project can work with both Qt3 and Qt4
 versions.  If a specific version is required, use :module:`FindQt4` or
@@ -31,12 +36,12 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``QT4_INSTALLED``
-  ``TRUE`` if Qt4 is found.
+  ``TRUE`` if Qt4 was found.
 ``QT3_INSTALLED``
-  ``TRUE`` if Qt3 is found.
+  ``TRUE`` if Qt3 was found.
 
 Hints
 ^^^^^
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake
index 2c62a5f..f72261e 100644
--- a/Modules/FindQt3.cmake
+++ b/Modules/FindQt3.cmake
@@ -5,8 +5,12 @@
 FindQt3
 -------
 
-This module finds Qt3, a cross-platform application development framework for
-creating graphical user interfaces and applications.
+Finds Qt3, a cross-platform application development framework for creating
+graphical user interfaces and applications:
+
+.. code-block:: cmake
+
+  find_package(Qt3 [<version>] [...])
 
 .. note::
 
@@ -17,17 +21,26 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``Qt3_FOUND``
-  True if Qt3 has been found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) Qt3 was found.
+
 ``QT_FOUND``
-  True if Qt3 has been found.  This variable is for compatibility with other Qt
-  find modules.
-``QT_VERSION_STRING``
+  Same as ``Qt3_FOUND``.  Boolean indicating whether (the requested version
+  of) Qt3 was found.  This variable is provided for compatibility with other
+  Qt find modules.
+
+``Qt3_VERSION``
+  .. versionadded:: 4.2
+
   The version of Qt3 that was found.
+
 ``QT_LIBRARIES``
   Libraries needed to link against for using Qt3.
+
 ``QT_DEFINITIONS``
   A list of compile definitions to use when compiling code that uses Qt3.
 
@@ -57,6 +70,17 @@
   To search for the multithreaded version of Qt3, set this variable to ``TRUE``
   before looking for Qt3.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``QT_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Qt3_VERSION``, which has the same value.
+
+  The version of Qt3 that was found.
+
 Examples
 ^^^^^^^^
 
@@ -88,7 +112,7 @@
 #  QT_WRAP_UI set true if QT_UIC_EXECUTABLE is found
 
 # If Qt4 has already been found, fail.
-if(QT4_FOUND)
+if(Qt4_FOUND)
   if(Qt3_FIND_REQUIRED)
     message( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project.")
   else()
@@ -134,7 +158,8 @@
   # Under windows the qt library (MSVC) has the format qt-mtXYZ where XYZ is the
   # version X.Y.Z, so we need to remove the dots from version
   string(REGEX REPLACE "\\." "" qt_version_str_lib "${qt_version_str}")
-  set(QT_VERSION_STRING "${qt_version_str}")
+  set(Qt3_VERSION "${qt_version_str}")
+  set(QT_VERSION_STRING "${Qt3_VERSION}")
 endif()
 
 file(GLOB GLOB_PATHS_LIB /usr/lib/qt-3*/lib/)
@@ -261,9 +286,9 @@
 endif ()
 find_package_handle_standard_args(Qt3
                                   REQUIRED_VARS QT_QT_LIBRARY QT_INCLUDE_DIR QT_MOC_EXECUTABLE
-                                  VERSION_VAR QT_VERSION_STRING)
+                                  VERSION_VAR Qt3_VERSION)
 unset(FPHSA_NAME_MISMATCHED)
-set(QT_FOUND ${QT3_FOUND} )
+set(QT_FOUND ${Qt3_FOUND})
 
 if(QT_FOUND)
   set( QT_LIBRARIES ${QT_LIBRARIES} ${QT_QT_LIBRARY} )
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 2c9e39f..4951175 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -5,9 +5,15 @@
 FindQt4
 -------
 
-This module finds Qt4, a cross-platform application development framework for
-creating graphical user interfaces and applications.  It defines a number of
-imported targets, macros, and variables to use Qt4 in the project.
+Finds Qt4, a cross-platform application development framework for creating
+graphical user interfaces and applications:
+
+.. code-block:: cmake
+
+  find_package(Qt4 [<version>] [...])
+
+This module defines a number of imported targets, macros, and variables to
+use Qt4 in the project.
 
 .. note::
 
@@ -39,7 +45,7 @@
 ^^^^^^^^^^^^^^^^
 
 Qt libraries can be linked using their corresponding
-:ref:`IMPORTED target <Imported Targets>` with the
+:ref:`Imported Target <Imported Targets>` with the
 :command:`target_link_libraries` command:
 
 .. code-block:: cmake
@@ -118,20 +124,22 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
 
 ``Qt4_FOUND``
-  Boolean whether Qt4 has been found.  If false, don't try to use Qt4.
+  Boolean indicating whether (the requested version of) Qt4 was found.
+
 ``QT_FOUND``
-  Boolean whether Qt4 has been found.  If false, don't try to use Qt4.  This
-  variable is for compatibility with other Qt find modules.
-``QT4_FOUND``
-  Boolean whether Qt4 has been found.  If false, don't try to use Qt4.  This
-  variable is for backward compatibility only.
+  Same as ``Qt4_FOUND``.  Boolean indicating whether (the requested version
+  of) Qt4 was found.  This variable is available for compatibility with
+  other Qt find modules.
+
 ``QT_VERSION_MAJOR``
   The major version of Qt found.
+
 ``QT_VERSION_MINOR``
   The minor version of Qt found.
+
 ``QT_VERSION_PATCH``
   The patch version of Qt found.
 
@@ -432,6 +440,15 @@
   the ``QtCore``, ``QtGui`` and ``QtDeclarative`` components on the project
   target ``myexe``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``QT4_FOUND``
+  .. deprecated:: 2.8.11
+    Use ``Qt4_FOUND``, which has the same value.
+
 Examples
 ^^^^^^^^
 
@@ -1310,19 +1327,13 @@
     QT_LUPDATE_EXECUTABLE QT_LRELEASE_EXECUTABLE QT_QCOLLECTIONGENERATOR_EXECUTABLE
     QT_DESIGNER_EXECUTABLE QT_LINGUIST_EXECUTABLE)
 
-
-  # get the directory of the current file, used later on in the file
-  get_filename_component( _qt4_current_dir  "${CMAKE_CURRENT_LIST_FILE}" PATH)
-
-
   ###############################################
   #
   #       configuration/system dependent settings
   #
   ###############################################
 
-  include("${_qt4_current_dir}/Qt4ConfigDependentSettings.cmake")
-
+  include(${CMAKE_CURRENT_LIST_DIR}/Qt4ConfigDependentSettings.cmake)
 
   #######################################
   #
@@ -1409,14 +1420,13 @@
     endforeach()
   endforeach()
 
-
   ######################################
   #
   #       Macros for building Qt files
   #
   ######################################
 
-  include("${_qt4_current_dir}/Qt4Macros.cmake")
+  include(${CMAKE_CURRENT_LIST_DIR}/Qt4Macros.cmake)
 
 endif()
 
diff --git a/Modules/FindQuickTime.cmake b/Modules/FindQuickTime.cmake
index 3f6b5ee..640efa0 100644
--- a/Modules/FindQuickTime.cmake
+++ b/Modules/FindQuickTime.cmake
@@ -6,7 +6,11 @@
 -------------
 
 Finds the QuickTime multimedia framework, which provides support for video,
-audio, and interactive media.
+audio, and interactive media:
+
+.. code-block:: cmake
+
+  find_package(QuickTime [...])
 
 .. note::
 
@@ -20,8 +24,9 @@
 This module defines the following variables:
 
 ``QuickTime_FOUND``
-  Boolean indicating whether the QuickTime is found.  For backward
-  compatibility, the ``QUICKTIME_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether QuickTime was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -45,14 +50,38 @@
   destination that was used when configuring, building, and installing QuickTime
   library: ``./configure --prefix=$QUICKTIME_DIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``QUICKTIME_FOUND``
+  .. deprecated:: 4.2
+    Use ``QuickTime_FOUND``, which has the same value.
+
+  Boolean indicating whether QuickTime was found.
+
 Examples
 ^^^^^^^^
 
-Finding QuickTime library:
+Finding QuickTime library and creating an imported interface target for
+linking it to a project target:
 
 .. code-block:: cmake
 
   find_package(QuickTime)
+
+  if(QuickTime_FOUND AND NOT TARGET QuickTime::QuickTime)
+    add_library(QuickTime::QuickTime INTERFACE IMPORTED)
+    set_target_properties(
+      QuickTime::QuickTime
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${QUICKTIME_INCLUDE_DIR}"
+        INTERFACE_LINK_LIBRARIES "${QUICKTIME_LIBRARY}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE QuickTime::QuickTime)
 #]=======================================================================]
 
 find_path(QUICKTIME_INCLUDE_DIR QuickTime/QuickTime.h QuickTime.h
diff --git a/Modules/FindRTI.cmake b/Modules/FindRTI.cmake
index 6a1a024..aad4c20 100644
--- a/Modules/FindRTI.cmake
+++ b/Modules/FindRTI.cmake
@@ -5,7 +5,11 @@
 FindRTI
 -------
 
-Finds HLA RTI standard libraries and their include directories.
+Finds HLA RTI standard libraries and their include directories:
+
+.. code-block:: cmake
+
+  find_package(RTI [...])
 
 `RTI <https://en.wikipedia.org/wiki/Run-time_infrastructure_(simulation)>`_
 (Run-Time Infrastructure) is a simulation infrastructure standardized by IEEE
@@ -19,7 +23,7 @@
 This module defines the following variables:
 
 ``RTI_FOUND``
-  Set to FALSE if any HLA RTI was not found.
+  Boolean indicating whether HLA RTI was found.
 ``RTI_LIBRARIES``
   The libraries to link against to use RTI.
 ``RTI_DEFINITIONS``
@@ -37,11 +41,25 @@
 Examples
 ^^^^^^^^
 
-Finding RTI:
+Finding RTI and creating an imported interface target for linking it to a
+project target:
 
 .. code-block:: cmake
 
   find_package(RTI)
+
+  if(RTI_FOUND AND NOT TARGET RTI::RTI)
+    add_library(RTI::RTI INTERFACE IMPORTED)
+    set_target_properties(
+      RTI::RTI
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${RTI_INCLUDE_DIR}"
+        INTERFACE_LINK_LIBRARIES "${RTI_LIBRARIES}"
+        INTERFACE_COMPILE_DEFINITIONS "${RTI_DEFINITIONS}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE RTI::RTI)
 #]=======================================================================]
 
 macro(RTI_MESSAGE_QUIETLY QUIET TYPE MSG)
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index 18b9e35..0ede27a 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -5,65 +5,57 @@
 FindRuby
 --------
 
-This module determines if Ruby is installed and finds the locations of its
-include files and libraries. Ruby 1.8 through 3.4 are supported.
-
-The minimum required version of Ruby can be specified using the
-standard syntax, e.g.
+Finds Ruby installation and the locations of its include files and libraries:
 
 .. code-block:: cmake
 
-  find_package(Ruby 3.2.6 EXACT REQUIRED)
-  # OR
-  find_package(Ruby 3.2)
+  find_package(Ruby [<version>] [...])
 
-Virtual environments, such as RVM or RBENV, are supported.
+Ruby is a general-purpose programming language.  This module supports Ruby
+1.8 through 3.4.  Virtual environments, such as RVM or RBENV, are also
+supported.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module will set the following variables in your project:
+This module defines the following variables:
 
 ``Ruby_FOUND``
-  set to true if ruby was found successfully
-``Ruby_EXECUTABLE``
-  full path to the ruby binary
-``Ruby_INCLUDE_DIRS``
-  include dirs to be used when using the ruby library
-``Ruby_LIBRARIES``
-  .. versionadded:: 3.18
-    libraries needed to use ruby from C.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether (the requested version of) ruby was found.
+
 ``Ruby_VERSION``
-  the version of ruby which was found, e.g. "3.2.6"
+  The version of ruby which was found, e.g. ``3.2.6``.
+
 ``Ruby_VERSION_MAJOR``
   Ruby major version.
+
 ``Ruby_VERSION_MINOR``
   Ruby minor version.
+
 ``Ruby_VERSION_PATCH``
   Ruby patch version.
 
+``Ruby_EXECUTABLE``
+  The full path to the ruby binary.
+
+``Ruby_INCLUDE_DIRS``
+  Include dirs to be used when using the ruby library.
+
+``Ruby_LIBRARIES``
+  .. versionadded:: 3.18
+
+  Libraries needed to use ruby from C.
+
 .. versionchanged:: 3.18
   Previous versions of CMake used the ``RUBY_`` prefix for all variables.
 
-.. deprecated:: 4.0
-  The following variables are deprecated.  See policy :policy:`CMP0185`.
-
-  ``RUBY_EXECUTABLE``
-    same as ``Ruby_EXECUTABLE``.
-  ``RUBY_INCLUDE_DIRS``
-    same as ``Ruby_INCLUDE_DIRS``.
-  ``RUBY_INCLUDE_PATH``
-    same as ``Ruby_INCLUDE_DIRS``.
-  ``RUBY_LIBRARY``
-    same as ``Ruby_LIBRARY``.
-  ``RUBY_VERSION``
-    same as ``Ruby_VERSION``.
-  ``RUBY_FOUND``
-    same as ``Ruby_FOUND``.
-
 Hints
 ^^^^^
 
+This module accepts the following variables:
+
 ``Ruby_FIND_VIRTUALENV``
   .. versionadded:: 3.18
 
@@ -84,6 +76,38 @@
   ``rbenv``
     Requires that ``rbenv`` is installed in ``~/.rbenv/bin``
     or that the ``RBENV_ROOT`` environment variable is defined.
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+.. deprecated:: 4.0
+  The following variables are deprecated.  See policy :policy:`CMP0185`.
+
+  ``RUBY_FOUND``
+    Same as ``Ruby_FOUND``.
+  ``RUBY_VERSION``
+    Same as ``Ruby_VERSION``.
+  ``RUBY_EXECUTABLE``
+    Same as ``Ruby_EXECUTABLE``.
+  ``RUBY_INCLUDE_DIRS``
+    Same as ``Ruby_INCLUDE_DIRS``.
+  ``RUBY_INCLUDE_PATH``
+    Same as ``Ruby_INCLUDE_DIRS``.
+  ``RUBY_LIBRARY``
+    Same as ``Ruby_LIBRARY``.
+
+Examples
+^^^^^^^^
+
+Finding Ruby and specifying the minimum required version:
+
+.. code-block:: cmake
+
+  find_package(Ruby 3.2.6 EXACT REQUIRED)
+  # or
+  find_package(Ruby 3.2)
 #]=======================================================================]
 
 cmake_policy(GET CMP0185 _Ruby_CMP0185)
diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake
index a720dcc..5bd34bb 100644
--- a/Modules/FindSDL.cmake
+++ b/Modules/FindSDL.cmake
@@ -5,8 +5,14 @@
 FindSDL
 -------
 
-Finds the SDL (Simple DirectMedia Layer) library.  SDL is a cross-platform
-library for developing multimedia software, such as games and emulators.
+Finds the SDL (Simple DirectMedia Layer) library:
+
+.. code-block:: cmake
+
+  find_package(SDL [<version>] [...])
+
+SDL is a cross-platform library for developing multimedia software, such as
+games and emulators.
 
 .. note::
 
@@ -45,7 +51,7 @@
 This module defines the following variables:
 
 ``SDL_FOUND``
-  Boolean indicating whether the (requested version of) SDL is found.
+  Boolean indicating whether (the requested version of) SDL was found.
 
 ``SDL_VERSION``
   .. versionadded:: 3.19
@@ -127,7 +133,7 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-These variables are obsolete and provided for backwards compatibility:
+The following variables are provided for backward compatibility:
 
 ``SDL_VERSION_STRING``
   .. deprecated:: 3.19
@@ -288,7 +294,7 @@
 
 find_package_handle_standard_args(SDL
                                   REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR
-                                  VERSION_VAR SDL_VERSION_STRING)
+                                  VERSION_VAR SDL_VERSION)
 
 if(SDL_FOUND)
   set(SDL_LIBRARIES ${SDL_LIBRARY})
diff --git a/Modules/FindSDL_gfx.cmake b/Modules/FindSDL_gfx.cmake
index c7f489e..04a32b6 100644
--- a/Modules/FindSDL_gfx.cmake
+++ b/Modules/FindSDL_gfx.cmake
@@ -8,7 +8,11 @@
 .. versionadded:: 3.25
 
 Finds the SDL_gfx library that provides graphics support in SDL (Simple
-DirectMedia Layer) applications.
+DirectMedia Layer) applications:
+
+.. code-block:: cmake
+
+  find_package(SDL_gfx [<version>] [...])
 
 .. note::
 
@@ -30,10 +34,12 @@
 This module defines the following variables:
 
 ``SDL_gfx_FOUND``
-  Boolean indicating whether the (requested version of) SDL_gfx library is
-  found.  For backward compatibility, the ``SDL_GFX_FOUND`` variable is also set
-  to the same value.
-``SDL_GFX_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_gfx library was
+  found.
+
+``SDL_gfx_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_gfx found.
 
 Cache Variables
@@ -43,6 +49,7 @@
 
 ``SDL_GFX_INCLUDE_DIRS``
   The directory containing the headers needed to use SDL_gfx.
+
 ``SDL_GFX_LIBRARIES``
   The path to the SDL_gfx library needed to link against to use SDL_gfx.
 
@@ -57,6 +64,24 @@
   was used when configuring, building, and installing SDL library:
   ``./configure --prefix=$SDLDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``SDL_GFX_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_gfx_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) SDL_gfx library was
+  found.
+
+``SDL_GFX_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use the ``SDL_gfx_VERSION``.
+
+  The human-readable string containing the version of SDL_gfx found.
+
 Examples
 ^^^^^^^^
 
@@ -113,7 +138,8 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MAJOR "${SDL_GFX_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MINOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MINOR "${SDL_GFX_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MICRO[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_PATCH "${SDL_GFX_VERSION_PATCH_LINE}")
-  set(SDL_GFX_VERSION_STRING ${SDL_GFX_VERSION_MAJOR}.${SDL_GFX_VERSION_MINOR}.${SDL_GFX_VERSION_PATCH})
+  set(SDL_gfx_VERSION ${SDL_GFX_VERSION_MAJOR}.${SDL_GFX_VERSION_MINOR}.${SDL_GFX_VERSION_PATCH})
+  set(SDL_GFX_VERSION_STRING "${SDL_gfx_VERSION}")
   unset(SDL_GFX_VERSION_MAJOR_LINE)
   unset(SDL_GFX_VERSION_MINOR_LINE)
   unset(SDL_GFX_VERSION_PATCH_LINE)
@@ -126,7 +152,7 @@
 
 find_package_handle_standard_args(SDL_gfx
                                   REQUIRED_VARS SDL_GFX_LIBRARIES SDL_GFX_INCLUDE_DIRS
-                                  VERSION_VAR SDL_GFX_VERSION_STRING)
+                                  VERSION_VAR SDL_gfx_VERSION)
 
 if(SDL_gfx_FOUND)
   if(NOT TARGET SDL::SDL_gfx)
diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake
index 5835532..404d5aa 100644
--- a/Modules/FindSDL_image.cmake
+++ b/Modules/FindSDL_image.cmake
@@ -6,7 +6,11 @@
 -------------
 
 Finds the SDL_image library that loads images of various formats as SDL (Simple
-DirectMedia Layer) surfaces.
+DirectMedia Layer) surfaces:
+
+.. code-block:: cmake
+
+  find_package(SDL_image [<version>] [...])
 
 .. note::
 
@@ -23,11 +27,14 @@
 This module defines the following variables:
 
 ``SDL_image_FOUND``
-  Boolean indicating whether the (requested version of) SDL_image library is
-  found.  For backward compatibility, the ``SDL_IMAGE_FOUND`` variable is also
-  set to the same value.
+  .. versionadded:: 3.3
 
-``SDL_IMAGE_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_image library
+  was found.
+
+``SDL_image_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_image found.
 
 ``SDL_IMAGE_INCLUDE_DIRS``
@@ -50,19 +57,29 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-For backward compatibility the following variables are also set:
+The following variables are provided for backward compatibility:
+
+``SDL_IMAGE_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``SDL_image_VERSION``, which has the same value.
+
+  The human-readable string containing the version of SDL_image found.
+
+``SDL_IMAGE_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_image_FOUND``, which has the same value.
 
 ``SDLIMAGE_FOUND``
   .. deprecated:: 2.8.10
-    Use the ``SDL_image_FOUND``, which has the same value.
+    Use ``SDL_image_FOUND``, which has the same value.
 
 ``SDLIMAGE_INCLUDE_DIR``
   .. deprecated:: 2.8.10
-    Use the ``SDL_IMAGE_INCLUDE_DIRS``, which has the same value.
+    Use ``SDL_IMAGE_INCLUDE_DIRS``, which has the same value.
 
 ``SDLIMAGE_LIBRARY``
   .. deprecated:: 2.8.10
-    Use the ``SDL_IMAGE_LIBRARIES``, which has the same value.
+    Use ``SDL_IMAGE_LIBRARIES``, which has the same value.
 
 Examples
 ^^^^^^^^
@@ -149,7 +166,8 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_IMAGE_VERSION_MAJOR "${SDL_IMAGE_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_IMAGE_VERSION_MINOR "${SDL_IMAGE_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_IMAGE_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_IMAGE_VERSION_PATCH "${SDL_IMAGE_VERSION_PATCH_LINE}")
-  set(SDL_IMAGE_VERSION_STRING ${SDL_IMAGE_VERSION_MAJOR}.${SDL_IMAGE_VERSION_MINOR}.${SDL_IMAGE_VERSION_PATCH})
+  set(SDL_image_VERSION ${SDL_IMAGE_VERSION_MAJOR}.${SDL_IMAGE_VERSION_MINOR}.${SDL_IMAGE_VERSION_PATCH})
+  set(SDL_IMAGE_VERSION_STRING "${SDL_image_VERSION}")
   unset(SDL_IMAGE_VERSION_MAJOR_LINE)
   unset(SDL_IMAGE_VERSION_MINOR_LINE)
   unset(SDL_IMAGE_VERSION_PATCH_LINE)
@@ -165,7 +183,7 @@
 
 find_package_handle_standard_args(SDL_image
                                   REQUIRED_VARS SDL_IMAGE_LIBRARIES SDL_IMAGE_INCLUDE_DIRS
-                                  VERSION_VAR SDL_IMAGE_VERSION_STRING)
+                                  VERSION_VAR SDL_image_VERSION)
 
 # for backward compatibility
 set(SDLIMAGE_LIBRARY ${SDL_IMAGE_LIBRARIES})
diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake
index a9bafbc..7bfbc4f 100644
--- a/Modules/FindSDL_mixer.cmake
+++ b/Modules/FindSDL_mixer.cmake
@@ -6,7 +6,11 @@
 -------------
 
 Finds the SDL_mixer library that provides an audio mixer with support for
-various file formats in SDL (Simple DirectMedia Layer) applications.
+various file formats in SDL (Simple DirectMedia Layer) applications:
+
+.. code-block:: cmake
+
+  find_package(SDL_mixer [<version>] [...])
 
 .. note::
 
@@ -22,11 +26,14 @@
 This module defines the following variables:
 
 ``SDL_mixer_FOUND``
-  Boolean indicating whether the (requested version of) SDL_mixer library is
-  found.  For backward compatibility, the ``SDL_MIXER_FOUND`` variable is also
-  set to the same value.
+  .. versionadded:: 3.3
 
-``SDL_MIXER_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_mixer library
+  was found.
+
+``SDL_mixer_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_mixer found.
 
 ``SDL_MIXER_INCLUDE_DIRS``
@@ -49,7 +56,17 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-For backward compatibility the following variables are also set:
+The following variables are provided for backward compatibility:
+
+``SDL_MIXER_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``SDL_mixer_VERSION``, which has the same value.
+
+  The human-readable string containing the version of SDL_mixer found.
+
+``SDL_MIXER_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_mixer_FOUND``, which has the same value.
 
 ``SDLMIXER_FOUND``
   .. deprecated:: 2.8.10
@@ -141,7 +158,8 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_MIXER_VERSION_MAJOR "${SDL_MIXER_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_MIXER_VERSION_MINOR "${SDL_MIXER_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_MIXER_VERSION_PATCH "${SDL_MIXER_VERSION_PATCH_LINE}")
-  set(SDL_MIXER_VERSION_STRING ${SDL_MIXER_VERSION_MAJOR}.${SDL_MIXER_VERSION_MINOR}.${SDL_MIXER_VERSION_PATCH})
+  set(SDL_mixer_VERSION ${SDL_MIXER_VERSION_MAJOR}.${SDL_MIXER_VERSION_MINOR}.${SDL_MIXER_VERSION_PATCH})
+  set(SDL_MIXER_VERSION_STRING "${SDL_mixer_VERSION}")
   unset(SDL_MIXER_VERSION_MAJOR_LINE)
   unset(SDL_MIXER_VERSION_MINOR_LINE)
   unset(SDL_MIXER_VERSION_PATCH_LINE)
@@ -157,7 +175,7 @@
 
 find_package_handle_standard_args(SDL_mixer
                                   REQUIRED_VARS SDL_MIXER_LIBRARIES SDL_MIXER_INCLUDE_DIRS
-                                  VERSION_VAR SDL_MIXER_VERSION_STRING)
+                                  VERSION_VAR SDL_mixer_VERSION)
 
 # for backward compatibility
 set(SDLMIXER_LIBRARY ${SDL_MIXER_LIBRARIES})
diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake
index c5ba976..4d90c07 100644
--- a/Modules/FindSDL_net.cmake
+++ b/Modules/FindSDL_net.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds the SDL_net library, a cross-platform network library for use with the
-SDL (Simple DirectMedia Layer) applications.
+SDL (Simple DirectMedia Layer) applications:
+
+.. code-block:: cmake
+
+  find_package(SDL_net [<version>] [...])
 
 .. note::
 
@@ -22,11 +26,14 @@
 This module defines the following variables:
 
 ``SDL_net_FOUND``
-  Boolean indicating whether the (requested version of) SDL_net library is
-  found.  For backward compatibility, the ``SDL_NET_FOUND`` variable is also set
-  to the same value.
+  .. versionadded:: 3.3
 
-``SDL_NET_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_net library was
+  found.
+
+``SDL_net_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_net found.
 
 ``SDL_NET_INCLUDE_DIRS``
@@ -35,23 +42,6 @@
 ``SDL_NET_LIBRARIES``
   Libraries needed to link against to use the SDL_net library.
 
-Deprecated Variables
-^^^^^^^^^^^^^^^^^^^^
-
-For backward compatibility the following variables are also set:
-
-``SDLNET_FOUND``
-  .. deprecated:: 2.8.10
-    Use the ``SDL_net_FOUND``, which has the same value.
-
-``SDLNET_INCLUDE_DIR``
-  .. deprecated:: 2.8.10
-    Use the ``SDL_NET_INCLUDE_DIRS``, which has the same value.
-
-``SDLNET_LIBRARY``
-  .. deprecated:: 2.8.10
-    Use the ``SDL_NET_LIBRARIES``, which has the same value.
-
 Hints
 ^^^^^
 
@@ -63,6 +53,33 @@
   was used when configuring, building, and installing SDL library:
   ``./configure --prefix=$SDLDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``SDL_NET_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``SDL_net_VERSION``, which has the same value.
+
+  The human-readable string containing the version of SDL_net found.
+
+``SDL_NET_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_net_FOUND``, which has the same value.
+
+``SDLNET_FOUND``
+  .. deprecated:: 2.8.10
+    Use ``SDL_net_FOUND``, which has the same value.
+
+``SDLNET_INCLUDE_DIR``
+  .. deprecated:: 2.8.10
+    Use ``SDL_NET_INCLUDE_DIRS``, which has the same value.
+
+``SDLNET_LIBRARY``
+  .. deprecated:: 2.8.10
+    Use ``SDL_NET_LIBRARIES``, which has the same value.
+
 Examples
 ^^^^^^^^
 
@@ -141,7 +158,8 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_NET_VERSION_MAJOR "${SDL_NET_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_NET_VERSION_MINOR "${SDL_NET_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_NET_VERSION_PATCH "${SDL_NET_VERSION_PATCH_LINE}")
-  set(SDL_NET_VERSION_STRING ${SDL_NET_VERSION_MAJOR}.${SDL_NET_VERSION_MINOR}.${SDL_NET_VERSION_PATCH})
+  set(SDL_net_VERSION ${SDL_NET_VERSION_MAJOR}.${SDL_NET_VERSION_MINOR}.${SDL_NET_VERSION_PATCH})
+  set(SDL_NET_VERSION_STRING "${SDL_net_VERSION}")
   unset(SDL_NET_VERSION_MAJOR_LINE)
   unset(SDL_NET_VERSION_MINOR_LINE)
   unset(SDL_NET_VERSION_PATCH_LINE)
@@ -157,7 +175,7 @@
 
 find_package_handle_standard_args(SDL_net
                                   REQUIRED_VARS SDL_NET_LIBRARIES SDL_NET_INCLUDE_DIRS
-                                  VERSION_VAR SDL_NET_VERSION_STRING)
+                                  VERSION_VAR SDL_net_VERSION)
 
 # for backward compatibility
 set(SDLNET_LIBRARY ${SDL_NET_LIBRARIES})
diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake
index 954303f..19fc2cd 100644
--- a/Modules/FindSDL_sound.cmake
+++ b/Modules/FindSDL_sound.cmake
@@ -6,7 +6,11 @@
 -------------
 
 Finds the SDL_sound library, an abstract soundfile decoder for use in SDL
-(Simple DirectMedia Layer) applications.
+(Simple DirectMedia Layer) applications:
+
+.. code-block:: cmake
+
+  find_package(SDL_sound [<version>] [...])
 
 .. note::
 
@@ -31,11 +35,14 @@
 This module defines the following variables:
 
 ``SDL_sound_FOUND``
-  Boolean indicating whether the (requested version of) SDL_sound library is
-  found.  For backward compatibility, the ``SDL_SOUND_FOUND`` variable is also
-  set to the same value.
+  .. versionadded:: 3.3
 
-``SDL_SOUND_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_sound library
+  was found.
+
+``SDL_sound_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_sound found.
 
 ``SDL_SOUND_LIBRARIES``
@@ -100,6 +107,24 @@
   available mostly for cases this module failed to anticipate for and additional
   flags must be added.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``SDL_SOUND_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_sound_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) SDL_sound library
+  was found.
+
+``SDL_SOUND_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``SDL_sound_VERSION``, which has the same value.
+
+  The human-readable string containing the version of SDL_sound found.
+
 Examples
 ^^^^^^^^
 
@@ -441,7 +466,8 @@
   string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MAJOR "${SDL_SOUND_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MINOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MINOR "${SDL_SOUND_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SOUND_VER_PATCH[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_PATCH "${SDL_SOUND_VERSION_PATCH_LINE}")
-  set(SDL_SOUND_VERSION_STRING ${SDL_SOUND_VERSION_MAJOR}.${SDL_SOUND_VERSION_MINOR}.${SDL_SOUND_VERSION_PATCH})
+  set(SDL_sound_VERSION ${SDL_SOUND_VERSION_MAJOR}.${SDL_SOUND_VERSION_MINOR}.${SDL_SOUND_VERSION_PATCH})
+  set(SDL_SOUND_VERSION_STRING "${SDL_sound_VERSION}")
   unset(SDL_SOUND_VERSION_MAJOR_LINE)
   unset(SDL_SOUND_VERSION_MINOR_LINE)
   unset(SDL_SOUND_VERSION_PATCH_LINE)
@@ -454,6 +480,6 @@
 
 find_package_handle_standard_args(SDL_sound
                                   REQUIRED_VARS SDL_SOUND_LIBRARY SDL_SOUND_INCLUDE_DIR
-                                  VERSION_VAR SDL_SOUND_VERSION_STRING)
+                                  VERSION_VAR SDL_sound_VERSION)
 
 cmake_policy(POP)
diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake
index 2569588..bac3478 100644
--- a/Modules/FindSDL_ttf.cmake
+++ b/Modules/FindSDL_ttf.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds the SDL_ttf library that provides support for rendering text with TrueType
-fonts in SDL (Simple DirectMedia Layer) applications.
+fonts in SDL (Simple DirectMedia Layer) applications:
+
+.. code-block:: cmake
+
+  find_package(SDL_ttf [<version>] [...])
 
 .. note::
 
@@ -23,11 +27,14 @@
 This module defines the following variables:
 
 ``SDL_ttf_FOUND``
-  Boolean indicating whether the (requested version of) SDL_ttf library is
-  found.  For backward compatibility, the ``SDL_TTF_FOUND`` variable is also set
-  to the same value.
+  .. versionadded:: 3.3
 
-``SDL_TTF_VERSION_STRING``
+  Boolean indicating whether the (requested version of) SDL_ttf library was
+  found.
+
+``SDL_ttf_VERSION``
+  .. versionadded:: 4.2
+
   The human-readable string containing the version of SDL_ttf found.
 
 ``SDL_TTF_INCLUDE_DIRS``
@@ -36,10 +43,31 @@
 ``SDL_TTF_LIBRARIES``
   Libraries needed to link against to use SDL_ttf.
 
+Hints
+^^^^^
+
+This module accepts the following variables:
+
+``SDLDIR``
+  Environment variable that can be set to help locate an SDL library installed
+  in a custom location.  It should point to the installation destination that
+  was used when configuring, building, and installing SDL library:
+  ``./configure --prefix=$SDLDIR``.
+
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-For backward compatibility the following variables are also set:
+The following variables are provided for backward compatibility:
+
+``SDL_TTF_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``SDL_ttf_VERSION``, which has the same value.
+
+  The human-readable string containing the version of SDL_ttf found.
+
+``SDL_TTF_FOUND``
+  .. deprecated:: 4.2
+    Use ``SDL_ttf_FOUND``, which has the same value.
 
 ``SDLTTF_FOUND``
   .. deprecated:: 2.8.10
@@ -53,17 +81,6 @@
   .. deprecated:: 2.8.10
     Replaced with ``SDL_TTF_LIBRARIES``, which has the same value.
 
-Hints
-^^^^^
-
-This module accepts the following variables:
-
-``SDLDIR``
-  Environment variable that can be set to help locate an SDL library installed
-  in a custom location.  It should point to the installation destination that
-  was used when configuring, building, and installing SDL library:
-  ``./configure --prefix=$SDLDIR``.
-
 Examples
 ^^^^^^^^
 
@@ -149,7 +166,8 @@
   string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_TTF_VERSION_MAJOR "${SDL_TTF_VERSION_MAJOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_TTF_VERSION_MINOR "${SDL_TTF_VERSION_MINOR_LINE}")
   string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_TTF_VERSION_PATCH "${SDL_TTF_VERSION_PATCH_LINE}")
-  set(SDL_TTF_VERSION_STRING ${SDL_TTF_VERSION_MAJOR}.${SDL_TTF_VERSION_MINOR}.${SDL_TTF_VERSION_PATCH})
+  set(SDL_ttf_VERSION ${SDL_TTF_VERSION_MAJOR}.${SDL_TTF_VERSION_MINOR}.${SDL_TTF_VERSION_PATCH})
+  set(SDL_TTF_VERSION_STRING "${SDL_ttf_VERSION}")
   unset(SDL_TTF_VERSION_MAJOR_LINE)
   unset(SDL_TTF_VERSION_MINOR_LINE)
   unset(SDL_TTF_VERSION_PATCH_LINE)
@@ -165,7 +183,7 @@
 
 find_package_handle_standard_args(SDL_ttf
                                   REQUIRED_VARS SDL_TTF_LIBRARIES SDL_TTF_INCLUDE_DIRS
-                                  VERSION_VAR SDL_TTF_VERSION_STRING)
+                                  VERSION_VAR SDL_ttf_VERSION)
 
 # for backward compatibility
 set(SDLTTF_LIBRARY ${SDL_TTF_LIBRARIES})
diff --git a/Modules/FindSQLite3.cmake b/Modules/FindSQLite3.cmake
index 914b84a..ea859e6 100644
--- a/Modules/FindSQLite3.cmake
+++ b/Modules/FindSQLite3.cmake
@@ -7,9 +7,14 @@
 
 .. versionadded:: 3.14
 
-Finds the SQLite 3 library.  SQLite is a small, fast, self-contained,
-high-reliability, and full-featured SQL database engine written in C, intended
-for embedding in applications.
+Finds the SQLite 3 library:
+
+.. code-block:: cmake
+
+  find_package(SQLite3 [<version>] [...])
+
+SQLite is a small, fast, self-contained, high-reliability, and full-featured
+SQL database engine written in C, intended for embedding in applications.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -23,17 +28,21 @@
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module sets the following variables:
+This module defines the following variables:
+
+``SQLite3_FOUND``
+  Boolean indicating whether the (requested version of) SQLite library was
+  found.
+
+``SQLite3_VERSION``
+  The version of SQLite library found.
 
 ``SQLite3_INCLUDE_DIRS``
-  Include directories containing the ``sqlite3.h`` and related headers needed
-  to use SQLite.
+  Include directories containing the ``<sqlite3.h>`` and related headers
+  needed to use SQLite.
+
 ``SQLite3_LIBRARIES``
   Libraries needed to link against to use SQLite.
-``SQLite3_VERSION``
-  Version of the SQLite library found.
-``SQLite3_FOUND``
-  Boolean indicating whether the SQLite library is found.
 
 Examples
 ^^^^^^^^
@@ -50,7 +59,7 @@
 cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n>
 
 find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
+if(PkgConfig_FOUND)
   pkg_check_modules(PC_SQLite3 QUIET sqlite3)
 endif()
 
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
index 57303e5..ea6677c 100644
--- a/Modules/FindSWIG.cmake
+++ b/Modules/FindSWIG.cmake
@@ -5,41 +5,69 @@
 FindSWIG
 --------
 
-Find the Simplified Wrapper and Interface Generator (SWIG_) executable.
+Finds the installed Simplified Wrapper and Interface Generator (SWIG_)
+executable and determines its version:
 
-This module finds an installed SWIG and determines its version.
+.. code-block:: cmake
 
-.. versionadded:: 3.18
-  If a ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to the
-  :command:`find_package` command, it will also determine supported target
-  languages.
+  find_package(SWIG [<version>] [COMPONENTS <langs>...] [...])
 
 .. versionadded:: 3.19
-  When a version is requested, it can be specified as a simple value or as a
-  range. For a detailed description of version range usage and capabilities,
-  refer to the :command:`find_package` command.
+  Support for specifying version range when calling the :command:`find_package`
+  command.  When a version is requested, it can be specified as a single
+  value as before, and now also a version range can be used.  For a detailed
+  description of version range usage and capabilities, refer to the
+  :command:`find_package` command.
 
-The module defines the following variables:
+Components
+^^^^^^^^^^
+
+.. versionadded:: 3.18
+
+This module supports optional components to specify target languages.
+
+If a ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to the
+:command:`find_package` command, it will also determine supported target
+languages.
+
+.. code-block:: cmake
+
+  find_package(SWIG [COMPONENTS <langs>...] [OPTIONAL_COMPONENTS <langs>...])
+
+Any ``COMPONENTS`` given to ``find_package()`` should be the names of
+supported target languages as provided to the ``LANGUAGE`` argument of
+:command:`swig_add_library`, such as ``python`` or ``perl5``.  Language
+names *must* be lowercase.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
 
 ``SWIG_FOUND``
-  Whether SWIG and any required components were found on the system.
-``SWIG_EXECUTABLE``
-  Path to the SWIG executable.
-``SWIG_DIR``
-  Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
+  Boolean indicating whether (the requested version of) SWIG and any required
+  components were found on the system.
 ``SWIG_VERSION``
   SWIG executable version (result of ``swig -version``).
 ``SWIG_<lang>_FOUND``
   If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
   target language ``<lang>`` (lowercase) will be set to TRUE.
+``SWIG_DIR``
+  Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
 
-Any ``COMPONENTS`` given to ``find_package`` should be the names of supported
-target languages as provided to the LANGUAGE argument of ``swig_add_library``,
-such as ``python`` or ``perl5``. Language names *must* be lowercase.
+Cache Variables
+^^^^^^^^^^^^^^^
 
-All information is collected from the ``SWIG_EXECUTABLE``, so the version
-to be found can be changed from the command line by means of setting
-``SWIG_EXECUTABLE``.
+The following cache variables may also be set:
+
+``SWIG_EXECUTABLE``
+  The path to the SWIG executable.
+
+  This executable is used to retrieve all information for this module. It can
+  be also manually set to change the version to be found from the command line.
+
+Examples
+^^^^^^^^
 
 Example usage requiring SWIG 4.0 or higher and Python language support, with
 optional Fortran support:
@@ -54,8 +82,23 @@
      endif()
    endif()
 
-.. _SWIG: https://swig.org
+This module is commonly used in conjunction with the :module:`UseSWIG` module:
 
+.. code-block:: cmake
+
+  find_package(SWIG COMPONENTS python)
+  if(SWIG_FOUND)
+    include(UseSWIG)
+
+    swig_add_library(mymod LANGUAGE python SOURCES mymod.i)
+  endif()
+
+See Also
+^^^^^^^^
+
+* The :module:`UseSWIG` module to use SWIG in CMake.
+
+.. _SWIG: https://swig.org
 #]=======================================================================]
 
 include(FindPackageHandleStandardArgs)
diff --git a/Modules/FindSelfPackers.cmake b/Modules/FindSelfPackers.cmake
index dd50ba4..d5355a5 100644
--- a/Modules/FindSelfPackers.cmake
+++ b/Modules/FindSelfPackers.cmake
@@ -5,16 +5,30 @@
 FindSelfPackers
 ---------------
 
-Finds `UPX <https://upx.github.io/>`_, the Ultimate Packer for eXecutables.
+Finds `UPX <https://upx.github.io/>`_, the Ultimate Packer for eXecutables:
+
+.. code-block:: cmake
+
+  find_package(SelfPackers [...])
 
 This module searches for executable packers-tools that compress executables or
 shared libraries into on-the-fly, self-extracting versions.  It currently
 supports ``UPX``.
 
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``SelfPackers_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether packer tools were found.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be set:
+The following cache variables may also be set:
 
 ``SELF_PACKER_FOR_EXECUTABLE``
   Path to the executable packer for compressing executables.
@@ -81,3 +95,9 @@
   SELF_PACKER_FOR_EXECUTABLE_FLAGS
   SELF_PACKER_FOR_SHARED_LIB_FLAGS
 )
+
+if(SELF_PACKER_FOR_EXECUTABLE AND SELF_PACKER_FOR_SHARED_LIB)
+  set(SelfPackers_FOUND TRUE)
+else()
+  set(SelfPackers_FOUND FALSE)
+endif()
diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake
index ea96e7b..f405e45 100644
--- a/Modules/FindSquish.cmake
+++ b/Modules/FindSquish.cmake
@@ -5,9 +5,15 @@
 FindSquish
 ----------
 
-Finds Squish, a cross-platform automated GUI testing framework for applications
-built on various GUI technologies.  Squish supports testing of both native and
-cross-platform toolkits, such as Qt, Java, and Tk.
+Finds Squish, a cross-platform automated GUI testing framework for
+applications built on various GUI technologies:
+
+.. code-block:: cmake
+
+  find_package(Squish [<version>] [...])
+
+Squish supports testing of both native and cross-platform toolkits, such as
+Qt, Java, and Tk.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -15,30 +21,23 @@
 This module defines the following variables:
 
 ``Squish_FOUND``
-  Boolean indicating whether the (requested version of) Squish is found.  For
-  backward compatibility, the ``SQUISH_FOUND`` variable is also set to the same
-  value.
+  .. versionadded:: 3.3
 
-``SQUISH_VERSION``
+  Boolean indicating whether (the requested version of) Squish was found.
+
+``Squish_VERSION``
+  .. versionadded:: 4.2
+
   The full version of the Squish found.
 
-``SQUISH_VERSION_MAJOR``
-  The major version of the Squish found.
-
-``SQUISH_VERSION_MINOR``
-  The minor version of the Squish found.
-
-``SQUISH_VERSION_PATCH``
-  The patch version of the Squish found.
-
 ``SQUISH_INSTALL_DIR_FOUND``
-  Boolean indicating whether the Squish installation directory is found.
+  Boolean indicating whether the Squish installation directory was found.
 
 ``SQUISH_SERVER_EXECUTABLE_FOUND``
-  Boolean indicating whether the Squish server executable is found.
+  Boolean indicating whether the Squish server executable was found.
 
 ``SQUISH_CLIENT_EXECUTABLE_FOUND``
-  Boolean indicating whether the Squish client executable is found.
+  Boolean indicating whether the Squish client executable was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -162,6 +161,41 @@
     A string of one or more (semicolon-separated list) test wrappers needed by
     the test case.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``SQUISH_FOUND``
+  .. deprecated:: 4.2
+    Use ``Squish_FOUND``, which has the same value.
+
+  Boolean indicating whether (the requested version of) Squish was found.
+
+``SQUISH_VERSION``
+  .. deprecated:: 4.2
+    Superseded by the ``Squish_VERSION``.
+
+  The full version of the Squish found.
+
+``SQUISH_VERSION_MAJOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Squish_VERSION``.
+
+  The major version of the Squish found.
+
+``SQUISH_VERSION_MINOR``
+  .. deprecated:: 4.2
+    Superseded by the ``Squish_VERSION``.
+
+  The minor version of the Squish found.
+
+``SQUISH_VERSION_PATCH``
+  .. deprecated:: 4.2
+    Superseded by the ``Squish_VERSION``.
+
+  The patch version of the Squish found.
+
 Examples
 ^^^^^^^^
 
@@ -254,10 +288,11 @@
 endif()
 
 
-set(SQUISH_VERSION)
-set(SQUISH_VERSION_MAJOR)
-set(SQUISH_VERSION_MINOR)
-set(SQUISH_VERSION_PATCH)
+unset(Squish_VERSION)
+unset(SQUISH_VERSION)
+unset(SQUISH_VERSION_MAJOR)
+unset(SQUISH_VERSION_MINOR)
+unset(SQUISH_VERSION_PATCH)
 
 # record if executables are set
 if(SQUISH_CLIENT_EXECUTABLE)
@@ -269,7 +304,8 @@
     set(SQUISH_VERSION_MAJOR "${CMAKE_MATCH_1}")
     set(SQUISH_VERSION_MINOR "${CMAKE_MATCH_2}")
     set(SQUISH_VERSION_PATCH "${CMAKE_MATCH_3}")
-    set(SQUISH_VERSION "${SQUISH_VERSION_MAJOR}.${SQUISH_VERSION_MINOR}.${SQUISH_VERSION_PATCH}" )
+    set(Squish_VERSION "${SQUISH_VERSION_MAJOR}.${SQUISH_VERSION_MINOR}.${SQUISH_VERSION_PATCH}" )
+    set(SQUISH_VERSION "${Squish_VERSION}")
   endif()
 else()
   set(SQUISH_CLIENT_EXECUTABLE_FOUND 0)
@@ -284,7 +320,7 @@
 # record if Squish was found
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Squish  REQUIRED_VARS  SQUISH_INSTALL_DIR SQUISH_CLIENT_EXECUTABLE SQUISH_SERVER_EXECUTABLE
-                                          VERSION_VAR  SQUISH_VERSION )
+                                          VERSION_VAR Squish_VERSION)
 
 
 set(_SQUISH_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}")
diff --git a/Modules/FindSubversion.cmake b/Modules/FindSubversion.cmake
index ae17656..e102b18 100644
--- a/Modules/FindSubversion.cmake
+++ b/Modules/FindSubversion.cmake
@@ -18,11 +18,12 @@
 This module defines the following variables:
 
 ``Subversion_FOUND``
-  Boolean indicating whether (the requested version of) Subversion command-line
-  client is found.  For backward compatibility, the ``SUBVERSION_FOUND``
-  variable is also set to the same value.
+  Boolean indicating whether the (requested version of) Subversion
+  command-line client was found.
 
-``Subversion_VERSION_SVN``
+``Subversion_VERSION``
+  .. versionadded:: 4.2
+
   Version of the ``svn`` command-line client found.
 
 Cache Variables
@@ -93,6 +94,24 @@
     Last log of the base revision of a Subversion working copy located at
     ``<dir>``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``SUBVERSION_FOUND``
+  .. deprecated:: 4.2
+    Use ``Subversion_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) Subversion
+  command-line client was found.
+
+``Subversion_VERSION_SVN``
+  .. deprecated:: 4.2
+    Use the ``Subversion_VERSION``.
+
+  Version of the ``svn`` command-line client found.
+
 Examples
 ^^^^^^^^
 
@@ -166,6 +185,12 @@
     endif()
   endif()
 
+  if(DEFINED Subversion_VERSION_SVN)
+    set(Subversion_VERSION "${Subversion_VERSION_SVN}")
+  else()
+    unset(Subversion_VERSION)
+  endif()
+
   macro(Subversion_WC_INFO dir prefix)
 
     cmake_parse_arguments(
@@ -229,7 +254,7 @@
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE
-                                             VERSION_VAR Subversion_VERSION_SVN )
+                                             VERSION_VAR Subversion_VERSION)
 
 # for compatibility
 set(Subversion_SVN_FOUND ${Subversion_FOUND})
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index 5ed3791..d5931f3 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -5,7 +5,11 @@
 FindTCL
 -------
 
-Finds the Tcl (Tool Command Language), dynamic programming language.
+Finds the Tcl (Tool Command Language), dynamic programming language:
+
+.. code-block:: cmake
+
+  find_package(TCL [...])
 
 This module locates a Tcl installation, including its include directories and
 libraries, and determines the appropriate Tcl library name for linking.  As part
@@ -18,11 +22,11 @@
 This module defines the following variables:
 
 ``TCL_FOUND``
-  Boolean indicating whether the Tcl is found.
+  Boolean indicating whether Tcl was found.
 ``TK_FOUND``
-  Boolean indicating whether the Tk is found.
+  Boolean indicating whether Tk was found.
 ``TCLTK_FOUND``
-  Boolean indicating whether both Tcl and Tk are found.
+  Boolean indicating whether both Tcl and Tk were found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -44,14 +48,12 @@
 ``TK_WISH``
   The path to the ``wish`` windowing shell command-line executable.
 
-
 Other Libraries
 ^^^^^^^^^^^^^^^
 
 The Tcl Stub Library can be found using the separate :module:`FindTclStub`
 module.
 
-
 Examples
 ^^^^^^^^
 
@@ -77,8 +79,8 @@
 include(${CMAKE_CURRENT_LIST_DIR}/FindTclsh.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/FindWish.cmake)
 
-if(TCLSH_VERSION_STRING)
-  set(TCL_TCLSH_VERSION "${TCLSH_VERSION_STRING}")
+if(Tclsh_VERSION)
+  set(TCL_TCLSH_VERSION "${Tclsh_VERSION}")
 else()
   get_filename_component(TCL_TCLSH_PATH "${TCL_TCLSH}" PATH)
   get_filename_component(TCL_TCLSH_PATH_PARENT "${TCL_TCLSH_PATH}" PATH)
diff --git a/Modules/FindTIFF.cmake b/Modules/FindTIFF.cmake
index c756b93..c1fa789 100644
--- a/Modules/FindTIFF.cmake
+++ b/Modules/FindTIFF.cmake
@@ -5,14 +5,25 @@
 FindTIFF
 --------
 
-Finds the `TIFF library <https://libtiff.gitlab.io/libtiff/>`_ (``libtiff``).
+Finds the `TIFF library <https://libtiff.gitlab.io/libtiff/>`_ (``libtiff``):
+
+.. code-block:: cmake
+
+  find_package(TIFF [<version>] [COMPONENTS <components>...] [...])
+
 This module also takes into account the upstream TIFF library's exported CMake
 package configuration, if available.
 
 Components
 ^^^^^^^^^^
 
-This module supports the following components:
+This module supports optional components which can be specified with:
+
+.. code-block:: cmake
+
+  find_package(TIFF [COMPONENTS <components>...])
+
+Supported components include:
 
 ``CXX``
   .. versionadded:: 3.19
@@ -20,12 +31,6 @@
   Optional component that ensures that the C++ wrapper library (``libtiffxx``)
   is found.
 
-Components can be specified using the standard syntax:
-
-.. code-block:: cmake
-
-  find_package(TIFF [COMPONENTS <components>...])
-
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
@@ -51,10 +56,12 @@
 This module defines the following variables:
 
 ``TIFF_FOUND``
-  Boolean indicating whether the TIFF is found.
+  Boolean indicating whether (the requested version of) TIFF is found.
 
-``TIFF_VERSION_STRING``
-  The version of the TIFF library found.
+``TIFF_VERSION``
+  .. versionadded:: 4.2
+
+  The version of TIFF library found.
 
 ``TIFF_INCLUDE_DIRS``
   The directory containing the TIFF headers.
@@ -90,6 +97,17 @@
 
   The path to the TIFFXX library for debug configurations.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``TIFF_VERSION_STRING``
+  .. deprecated:: 4.2
+    Superseded by the ``TIFF_VERSION``.
+
+  The version of TIFF library found.
+
 Examples
 ^^^^^^^^
 
@@ -244,7 +262,8 @@
       endif ()
     endif ()
   endif ()
-  set(TIFF_VERSION_STRING "${Tiff_VERSION}")
+  set(TIFF_VERSION "${Tiff_VERSION}")
+  set(TIFF_VERSION_STRING "${TIFF_VERSION}")
   foreach (_TIFF_component IN LISTS TIFF_FIND_COMPONENTS)
     set(TIFF_${_TIFF_component}_FOUND "${Tiff_${_TIFF_component}_FOUND}")
   endforeach ()
@@ -254,7 +273,7 @@
   find_package_handle_standard_args(TIFF
                                     HANDLE_COMPONENTS
                                     REQUIRED_VARS Tiff_DIR
-                                    VERSION_VAR TIFF_VERSION_STRING)
+                                    VERSION_VAR TIFF_VERSION)
 
   cmake_policy(POP)
   return ()
@@ -280,7 +299,8 @@
          REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
 
     string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*"
-           "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
+           "\\1" TIFF_VERSION "${tiff_version_str}")
+    set(TIFF_VERSION_STRING "${TIFF_VERSION}")
     unset(tiff_version_str)
 endif()
 
@@ -316,7 +336,7 @@
 find_package_handle_standard_args(TIFF
                                   HANDLE_COMPONENTS
                                   REQUIRED_VARS TIFF_LIBRARY TIFF_INCLUDE_DIR
-                                  VERSION_VAR TIFF_VERSION_STRING)
+                                  VERSION_VAR TIFF_VERSION)
 
 if(TIFF_FOUND)
   set(TIFF_LIBRARIES ${TIFF_LIBRARY})
diff --git a/Modules/FindTclStub.cmake b/Modules/FindTclStub.cmake
index ac0b2a6..cf57b9e 100644
--- a/Modules/FindTclStub.cmake
+++ b/Modules/FindTclStub.cmake
@@ -6,7 +6,11 @@
 -----------
 
 Finds the Tcl Stub Library, which is used for building version-independent Tcl
-extensions.
+extensions:
+
+.. code-block:: cmake
+
+  find_package(TclStub [...])
 
 Tcl (Tool Command Language) is a dynamic programming language, and the Tcl Stub
 Library provides a mechanism to allow Tcl extensions to be compiled in a way
@@ -18,6 +22,16 @@
 :module:`FindTCL` module to locate Tcl installation and then attempts to find
 the stub libraries corresponding to the located Tcl version.
 
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``TclStub_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether the Tcl Stub Library was found.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
@@ -150,3 +164,9 @@
   TCL_STUB_LIBRARY
   TK_STUB_LIBRARY
   )
+
+if(TCL_STUB_LIBRARY AND TK_STUB_LIBRARY AND TTK_STUB_LIBRARY)
+  set(TclStub_FOUND TRUE)
+else()
+  set(TclStub_FOUND FALSE)
+endif()
diff --git a/Modules/FindTclsh.cmake b/Modules/FindTclsh.cmake
index 81c666a..81a2cbf 100644
--- a/Modules/FindTclsh.cmake
+++ b/Modules/FindTclsh.cmake
@@ -6,7 +6,11 @@
 ---------
 
 Finds the Tcl shell command-line executable (``tclsh``), which includes the Tcl
-(Tool Command Language) interpreter.
+(Tool Command Language) interpreter:
+
+.. code-block:: cmake
+
+  find_package(Tclsh [<version>] [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
@@ -14,9 +18,15 @@
 This module defines the following variables:
 
 ``Tclsh_FOUND``
-  Boolean indicating whether the ``tclsh`` executable (and the requested
-  version, if specified) is found.  For backward compatibility, the
-  ``TCLSH_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the (requested version of) ``tclsh`` executable
+  was found.
+
+``Tclsh_VERSION``
+  .. versionadded:: 4.2
+
+  The version of ``tclsh`` found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -26,14 +36,37 @@
 ``TCL_TCLSH``
   The path to the ``tclsh`` executable.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``TCLSH_FOUND``
+  .. deprecated:: 4.2
+    Use ``Tclsh_FOUND``, which has the same value.
+
+  Boolean indicating whether the (requested version of) ``tclsh`` executable
+  was found.
+
+``TCLSH_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``Tclsh_VERSION``, which has the same value.
+
+  The version of ``tclsh`` found.
+
 Examples
 ^^^^^^^^
 
-Finding the ``tclsh`` command-line executable:
+In the following example, this module is used to find the ``tclsh``
+command-line executable, which is then executed in a process to evaluate
+TCL code from the script file located in the project source directory:
 
 .. code-block:: cmake
 
   find_package(Tclsh)
+  if(Tclsh_FOUND)
+    execute_process(COMMAND ${TCL_TCLSH} example-script.tcl)
+  endif()
 
 See Also
 ^^^^^^^^
@@ -104,9 +137,10 @@
 if(TCL_TCLSH)
   execute_process(COMMAND "${CMAKE_COMMAND}" -E echo puts "\$tcl_version"
                   COMMAND "${TCL_TCLSH}"
-                  OUTPUT_VARIABLE TCLSH_VERSION_STRING
+                  OUTPUT_VARIABLE Tclsh_VERSION
                   ERROR_QUIET
                   OUTPUT_STRIP_TRAILING_WHITESPACE)
+  set(TCLSH_VERSION_STRING "${Tclsh_VERSION}")
 endif()
 
 include(FindPackageHandleStandardArgs)
@@ -120,7 +154,7 @@
 endif ()
 find_package_handle_standard_args(Tclsh
                                   REQUIRED_VARS TCL_TCLSH
-                                  VERSION_VAR TCLSH_VERSION_STRING)
+                                  VERSION_VAR Tclsh_VERSION)
 unset(FPHSA_NAME_MISMATCHED)
 
 mark_as_advanced(TCL_TCLSH)
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index 26bd7d3..f3cf823 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -5,27 +5,77 @@
 FindThreads
 -----------
 
-This module determines the thread library of the system.
+Finds and determines the thread library of the system for multithreading
+support:
+
+.. code-block:: cmake
+
+  find_package(Threads [...])
+
+Multithreading enables concurrent execution within a single program,
+typically by creating multiple threads of execution.  Most commonly, this
+is done using libraries such as POSIX Threads (``pthreads``) on Unix-like
+systems or Windows threads on Windows.
+
+This module abstracts the platform-specific differences and detects how to
+enable thread support - whether it requires linking to a specific library,
+adding compiler flags (like ``-pthread``), or both.  On some platforms,
+threading is also implicitly available in default libraries without the
+need to use additional flags or libraries.
+
+This module is suitable for use in both C and C++ projects (and occasionally
+other compiled languages) that rely on system-level threading APIs.
+
+Using this module ensures that project builds correctly across different
+platforms by handling the detection and setup of thread support in a
+portable way.
+
+C and C++ Language Standards
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The C11 standard introduced a minimal cross-platform thread API via
+``<threads.h>`` header file, and C++11 added ``<thread>`` header to the
+standard library, offering high-level multithreading support.  These standard
+headers allow writing portable threaded code at the language level, without
+directly using platform-specific APIs like ``pthreads`` or Windows threads.
+
+However, even with standard C11 or C++11 threads support available, there
+may still be a need for platform-specific compiler or linker flags (e.g.,
+``-pthread`` on Unix-like systems) for some applications.  This is where
+FindThreads remains relevant - it ensures these flags and any required
+libraries are correctly set up, even if not explicitly using system APIs.
+
+In short:
+
+* Use ``<thread>`` (C++11 and later) or ``<threads.h>`` (C11) in source code
+  for portability and simpler syntax.
+
+* Use ``find_package(Threads)`` in CMake project when application needs the
+  traditional threading support and to ensure code compiles and links
+  correctly across different platforms.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.1
-
-This module defines the following :prop_tgt:`IMPORTED` target:
+This module provides the following :ref:`Imported Targets`:
 
 ``Threads::Threads``
-  The thread library, if found.
+  .. versionadded:: 3.1
+
+  Target encapsulating the usage requirements to enable threading through
+  flags or a threading library, if found.  This target is available if
+  threads are detected as supported.
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-The following variables are set:
+This module defines the following variables:
 
 ``Threads_FOUND``
-  If a supported thread library was found.
+  Boolean indicating whether Threads is supported, either through a separate
+  library or a standard library.
 ``CMAKE_THREAD_LIBS_INIT``
-  The thread library to use. This may be empty if the thread functions
+  The thread library to use.  This may be empty if the thread functions
   are provided by the system libraries and no special flags are needed
   to use them.
 ``CMAKE_USE_WIN32_THREADS_INIT``
@@ -38,17 +88,30 @@
 Variables Affecting Behavior
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. variable:: THREADS_PREFER_PTHREAD_FLAG
+This module accepts the following variables before calling
+``find_package(Threads)``:
 
+``THREADS_PREFER_PTHREAD_FLAG``
   .. versionadded:: 3.1
 
-  If the use of the -pthread compiler and linker flag is preferred then
-  the caller can set this variable to TRUE. The compiler flag can only be
-  used with the imported target. Use of both the imported target as well
-  as this switch is highly recommended for new code.
+  If the use of the ``-pthread`` compiler and linker flag is preferred then
+  the caller can set this variable to boolean true.  The compiler flag can
+  only be used with the imported target.  Use of both the imported target
+  as well as this switch is highly recommended for new code.
 
   This variable has no effect if the system libraries provide the
   thread functions, i.e. when ``CMAKE_THREAD_LIBS_INIT`` will be empty.
+
+Examples
+^^^^^^^^
+
+Finding Threads and linking the imported target to a project target:
+
+.. code-block:: cmake
+
+  set(THREADS_PREFER_PTHREAD_FLAG TRUE)
+  find_package(Threads)
+  target_link_libraries(example PRIVATE Threads::Threads)
 #]=======================================================================]
 
 include (CheckLibraryExists)
@@ -225,7 +288,7 @@
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(Threads DEFAULT_MSG Threads_FOUND)
 
-if(THREADS_FOUND AND NOT TARGET Threads::Threads)
+if(Threads_FOUND AND NOT TARGET Threads::Threads)
   add_library(Threads::Threads INTERFACE IMPORTED)
 
   if(THREADS_HAVE_PTHREAD_ARG)
diff --git a/Modules/FindUnixCommands.cmake b/Modules/FindUnixCommands.cmake
index 12f1169..add0327 100644
--- a/Modules/FindUnixCommands.cmake
+++ b/Modules/FindUnixCommands.cmake
@@ -9,11 +9,45 @@
 
   Use :option:`${CMAKE_COMMAND} -E <cmake -E>` subcommands instead.
 
-Find Unix commands, including the ones from Cygwin
+Finds Unix commands ``bash``, ``cp``, ``gzip``, ``mv``, ``rm``, and
+``tar``, including the ones from Cygwin or MSYS:
 
-This module looks for the Unix commands ``bash``, ``cp``, ``gzip``,
-``mv``, ``rm``, and ``tar`` and stores the result in the variables
-``BASH``, ``CP``, ``GZIP``, ``MV``, ``RM``, and ``TAR``.
+.. code-block:: cmake
+
+  find_package(UnixCommands [...])
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``UnixCommands_FOUND``
+  .. versionadded:: 3.3
+
+  Boolean indicating whether Unix commands were found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``BASH``
+  The path to the ``bash`` command-line executable.
+
+``CP``
+  The path to the ``cp`` command-line executable.
+
+``GZIP``
+  The path to the ``gzip`` command-line executable.
+
+``MV``
+  The path to the ``mv`` command-line executable.
+
+``RM``
+  The path to the ``rm`` command-line executable.
+
+``TAR``
+  The path to the ``tar`` command-line executable.
 #]=======================================================================]
 
 include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake)
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index e10051d..4bbcb27 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -8,8 +8,13 @@
 .. versionadded:: 3.7
 
 Finds Vulkan, a low-overhead, cross-platform 3D graphics and computing API,
-along with related development tools typically provided by the Vulkan SDK.  This
-includes commonly used utilities such as shader compilers and SPIR-V tools
+along with related development tools typically provided by the Vulkan SDK:
+
+.. code-block:: cmake
+
+  find_package(Vulkan [<version>] [COMPONENTS <components>...] [...])
+
+Vulkan includes commonly used utilities such as shader compilers and SPIR-V tools
 (e.g., DXC, ``glslc``, ``glslang``, etc.) that support Vulkan-based development
 workflows.
 
@@ -155,7 +160,7 @@
 
 ``Vulkan_FOUND``
   Boolean indicating whether (the requested version of) Vulkan and all required
-  components are found.
+  components were found.
 
 ``Vulkan_VERSION``
   .. versionadded:: 3.23
diff --git a/Modules/FindWget.cmake b/Modules/FindWget.cmake
index ef63d1e..73715f2 100644
--- a/Modules/FindWget.cmake
+++ b/Modules/FindWget.cmake
@@ -6,15 +6,21 @@
 --------
 
 This module finds the ``wget`` command-line tool for retrieving content from web
-servers.
+servers:
+
+.. code-block:: cmake
+
+  find_package(Wget [...])
 
 Result Variables
 ^^^^^^^^^^^^^^^^
 
-This module defines the following local variables:
+This module defines the following variables:
 
 ``Wget_FOUND``
-  True if ``wget`` has been found.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether ``wget`` was found.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -24,6 +30,17 @@
 ``WGET_EXECUTABLE``
   The full path to the ``wget`` tool.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``WGET_FOUND``
+  .. deprecated:: 4.2
+    Use ``Wget_FOUND``, which has the same value.
+
+  Boolean indicating whether ``wget`` was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindWish.cmake b/Modules/FindWish.cmake
index 00b1201..7e9038f 100644
--- a/Modules/FindWish.cmake
+++ b/Modules/FindWish.cmake
@@ -5,7 +5,11 @@
 FindWish
 --------
 
-Finds ``wish``, a simple windowing shell command-line executable.
+Finds ``wish``, a simple windowing shell command-line executable:
+
+.. code-block:: cmake
+
+  find_package(Wish [...])
 
 This module is commonly used in conjunction with finding a TCL installation (see
 the :module:`FindTCL` module).  It helps determine where the TCL include paths
@@ -14,10 +18,20 @@
 If the :variable:`UNIX` variable is defined, the module will prioritize looking
 for the Cygwin version of ``wish`` executable.
 
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``Wish_FOUND``
+  .. versionadded:: 4.2
+
+  Boolean indicating whether the ``wish`` executable was found.
+
 Cache Variables
 ^^^^^^^^^^^^^^^
 
-The following cache variables may be set:
+The following cache variables may also be set:
 
 ``TK_WISH``
   The path to the ``wish`` executable.
@@ -96,3 +110,9 @@
   )
 
 mark_as_advanced(TK_WISH)
+
+if(TK_WISH)
+  set(Wish_FOUND TRUE)
+else()
+  set(Wish_FOUND FALSE)
+endif()
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index b2f23bd..93aa932 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -5,15 +5,28 @@
 FindX11
 -------
 
-Find X11 installation
+Finds the X11 installation on Unix-like systems:
 
-Try to find X11 on UNIX systems. The following values are defined
+.. code-block:: cmake
 
-::
+  find_package(X11 [COMPONENTS <components>...] [...])
 
-  X11_FOUND        - True if X11 is available
-  X11_INCLUDE_DIR  - include directories to use X11
-  X11_LIBRARIES    - link against these to use X11
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``X11_FOUND``
+  Boolean indicating whether X11 was found.
+
+``X11_<component>_FOUND``
+  Boolean indicating whether the ``<component>`` was found.
+
+``X11_INCLUDE_DIR``
+  Include directories needed to use X11.
+
+``X11_LIBRARIES``
+  Libraries needed to link against to use X11.
 
 and also the following more fine grained variables and targets:
 
diff --git a/Modules/FindXCTest.cmake b/Modules/FindXCTest.cmake
index 696718b..7b4cc41 100644
--- a/Modules/FindXCTest.cmake
+++ b/Modules/FindXCTest.cmake
@@ -7,7 +7,11 @@
 
 .. versionadded:: 3.3
 
-Finds the XCTest framework for writing unit tests in Xcode projects.
+Finds the XCTest framework for writing unit tests in Xcode projects:
+
+.. code-block:: cmake
+
+  find_package(XCTest [...])
 
 .. note::
 
@@ -26,7 +30,7 @@
 This module defines the following variables:
 
 ``XCTest_FOUND``
-  Boolean indicating whether the XCTest framework and executable are found.
+  Boolean indicating whether the XCTest framework and executable were found.
 
 ``XCTest_INCLUDE_DIRS``
   Include directories containing the XCTest framework headers needed to use
diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake
index 949f755..bce4c83 100644
--- a/Modules/FindXMLRPC.cmake
+++ b/Modules/FindXMLRPC.cmake
@@ -5,9 +5,15 @@
 FindXMLRPC
 ----------
 
-Finds the native XML-RPC library for C and C++.  XML-RPC is a standard network
-protocol that enables remote procedure calls (RPC) between systems.  It encodes
-requests and responses in XML and uses HTTP as the transport mechanism.
+Finds the native XML-RPC library for C and C++:
+
+.. code-block:: cmake
+
+  find_package(XMLRPC [...] [COMPONENTS <components>...] [...])
+
+XML-RPC is a standard network protocol that enables remote procedure calls
+(RPC) between systems.  It encodes requests and responses in XML and uses
+HTTP as the transport mechanism.
 
 Components
 ^^^^^^^^^^
@@ -21,7 +27,7 @@
 utility can be used.
 
 In CMake, these features can be specified as components with the
-``find_package()`` command:
+:command:`find_package` command:
 
 .. code-block:: cmake
 
@@ -50,29 +56,46 @@
 ``openssl``
   OpenSSL convenience functions.
 
+If no components are specified, this module searches for XML-RPC library and
+its include directories without additional features.
+
 Result Variables
 ^^^^^^^^^^^^^^^^
 
 This module defines the following variables:
 
+``XMLRPC_FOUND``
+  Boolean indicating whether the XML-RPC library and all its requested
+  components were found.
 ``XMLRPC_INCLUDE_DIRS``
   Include directories containing ``xmlrpc.h`` and other headers needed to use
   the XML-RPC library.
 ``XMLRPC_LIBRARIES``
   List of libraries needed for linking to XML-RPC library and its requested
   features.
-``XMLRPC_FOUND``
-  Boolean indicating whether the XML-RPC library and all its requested
-  components are found.
 
 Examples
 ^^^^^^^^
 
-Finding XML-RPC library and its ``client`` feature to use in the project:
+Finding XML-RPC library and its ``client`` feature, and conditionally
+creating an interface :ref:`imported target <Imported Targets>` that
+encapsulates its usage requirements for linking to a project target:
 
 .. code-block:: cmake
 
   find_package(XMLRPC REQUIRED COMPONENTS client)
+
+  if(XMLRPC_FOUND AND NOT TARGET XMLRPC::XMLRPC)
+    add_library(XMLRPC::XMLRPC INTERFACE IMPORTED)
+    set_target_properties(
+      XMLRPC::XMLRPC
+      PROPERTIES
+        INTERFACE_INCLUDE_DIRECTORIES "${XMLRPC_INCLUDE_DIRS}"
+        INTERFACE_LINK_LIBRARIES "${XMLRPC_LIBRARIES}"
+    )
+  endif()
+
+  target_link_libraries(example PRIVATE XMLRPC::XMLRPC)
 #]=======================================================================]
 
 # First find the config script from which to obtain other values.
diff --git a/Modules/FindXalanC.cmake b/Modules/FindXalanC.cmake
index 26d859b..88f2a36 100644
--- a/Modules/FindXalanC.cmake
+++ b/Modules/FindXalanC.cmake
@@ -7,7 +7,11 @@
 
 .. versionadded:: 3.5
 
-Finds the Apache Xalan-C++ XSL transform processor headers and libraries.
+Finds the Apache Xalan-C++ XSL transform processor headers and libraries:
+
+.. code-block:: cmake
+
+  find_package(XalaxC [<version>] [...])
 
 .. note::
 
@@ -29,7 +33,7 @@
 This module defines the following variables:
 
 ``XalanC_FOUND``
-  Boolean indicating whether the Xalan-C++ is found.
+  Boolean indicating whether (the requested version of) Xalan-C++ was found.
 ``XalanC_VERSION``
   The version of the found Xalan-C++ library.
 ``XalanC_INCLUDE_DIRS``
diff --git a/Modules/FindXercesC.cmake b/Modules/FindXercesC.cmake
index c172d28..bc69670 100644
--- a/Modules/FindXercesC.cmake
+++ b/Modules/FindXercesC.cmake
@@ -7,12 +7,16 @@
 
 .. versionadded:: 3.1
 
-Finds the Apache Xerces-C++ validating XML parser headers and libraries.
+Finds the Apache Xerces-C++ validating XML parser headers and libraries:
+
+.. code-block:: cmake
+
+  find_package(XercesC [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-This module defines the following :ref:`Imported Targets`:
+This module provides the following :ref:`Imported Targets`:
 
 ``XercesC::XercesC``
   .. versionadded:: 3.5
@@ -26,7 +30,7 @@
 This module defines the following variables:
 
 ``XercesC_FOUND``
-  Boolean indicating whether the Xerces-C++ is found.
+  Boolean indicating whether (the requested version of) Xerces-C++ was found.
 ``XercesC_VERSION``
   The version of the found Xerces-C++ library.
 ``XercesC_INCLUDE_DIRS``
diff --git a/Modules/FindZLIB.cmake b/Modules/FindZLIB.cmake
index fd7d41d..91cdb78 100644
--- a/Modules/FindZLIB.cmake
+++ b/Modules/FindZLIB.cmake
@@ -5,7 +5,11 @@
 FindZLIB
 --------
 
-Finds the native zlib data compression library.
+Finds the native zlib data compression library:
+
+.. code-block:: cmake
+
+  find_package(ZLIB [<version>] [...])
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
@@ -23,6 +27,14 @@
 
 This module defines the following variables:
 
+``ZLIB_FOUND``
+  Boolean indicating whether (the requested version of) zlib was found.
+
+``ZLIB_VERSION``
+  .. versionadded:: 3.26
+
+  The version of zlib found.
+
 ``ZLIB_INCLUDE_DIRS``
   Include directories containing ``zlib.h`` and other headers needed to use
   zlib.
@@ -33,58 +45,6 @@
   .. versionchanged:: 3.4
     Debug and Release library variants can be now found separately.
 
-``ZLIB_FOUND``
-  True if zlib is found.
-
-``ZLIB_VERSION``
-  .. versionadded:: 3.26
-
-  The version of zlib found.
-
-Legacy Variables
-^^^^^^^^^^^^^^^^
-
-The following variables are provided for backward compatibility:
-
-``ZLIB_VERSION_MAJOR``
-  The major version of zlib.
-
-  .. versionchanged:: 3.26
-    Superseded by ``ZLIB_VERSION``.
-
-``ZLIB_VERSION_MINOR``
-  The minor version of zlib.
-
-  .. versionchanged:: 3.26
-    Superseded by ``ZLIB_VERSION``.
-
-``ZLIB_VERSION_PATCH``
-  The patch version of zlib.
-
-  .. versionchanged:: 3.26
-    Superseded by ``ZLIB_VERSION``.
-
-``ZLIB_VERSION_TWEAK``
-  The tweak version of zlib.
-
-  .. versionchanged:: 3.26
-    Superseded by ``ZLIB_VERSION``.
-
-``ZLIB_VERSION_STRING``
-  The version of zlib found (x.y.z).
-
-  .. versionchanged:: 3.26
-    Superseded by ``ZLIB_VERSION``.
-
-``ZLIB_MAJOR_VERSION``
-  The major version of zlib.  Superseded by ``ZLIB_VERSION_MAJOR``.
-
-``ZLIB_MINOR_VERSION``
-  The minor version of zlib.  Superseded by ``ZLIB_VERSION_MINOR``.
-
-``ZLIB_PATCH_VERSION``
-  The patch version of zlib.  Superseded by ``ZLIB_VERSION_PATCH``.
-
 Hints
 ^^^^^
 
@@ -100,6 +60,59 @@
   Set this variable to ``ON`` before calling ``find_package(ZLIB)`` to look for
   static libraries.  Default is ``OFF``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``ZLIB_VERSION_MAJOR``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The major version of zlib.
+
+``ZLIB_VERSION_MINOR``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The minor version of zlib.
+
+``ZLIB_VERSION_PATCH``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The patch version of zlib.
+
+``ZLIB_VERSION_TWEAK``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The tweak version of zlib.
+
+``ZLIB_VERSION_STRING``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The version of zlib found (x.y.z).
+
+``ZLIB_MAJOR_VERSION``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The major version of zlib.
+
+``ZLIB_MINOR_VERSION``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The minor version of zlib.
+
+``ZLIB_PATCH_VERSION``
+  .. deprecated:: 3.26
+    Superseded by ``ZLIB_VERSION``.
+
+  The patch version of zlib.
+
 Examples
 ^^^^^^^^
 
@@ -140,8 +153,8 @@
 list(APPEND _ZLIB_SEARCHES _ZLIB_SEARCH_NORMAL)
 
 if(ZLIB_USE_STATIC_LIBS)
-  set(ZLIB_NAMES zlibstatic zlibstat zlib z)
-  set(ZLIB_NAMES_DEBUG zlibstaticd zlibstatd zlibd zd)
+  set(ZLIB_NAMES zs zlibstatic zlibstat zlib z)
+  set(ZLIB_NAMES_DEBUG zsd 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)
diff --git a/Modules/Findosg.cmake b/Modules/Findosg.cmake
index dfcb0cd..5418a92 100644
--- a/Modules/Findosg.cmake
+++ b/Modules/Findosg.cmake
@@ -44,8 +44,9 @@
 This module defines the following variables:
 
 ``osg_FOUND``
-  Boolean indicating whether osg library is found.  For backward
-  compatibility, the ``OSG_FOUND`` variable is also set to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the osg library was found.
 
 ``OSG_LIBRARIES``
   The libraries needed to link against to use osg library.
@@ -76,6 +77,17 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSG_FOUND``
+  .. deprecated:: 4.2
+    Use ``osg_FOUND``, which has the same value.
+
+  Boolean indicating whether the osg library was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgAnimation.cmake b/Modules/FindosgAnimation.cmake
index b2d506d..8cb7729 100644
--- a/Modules/FindosgAnimation.cmake
+++ b/Modules/FindosgAnimation.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgAnimation_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgAnimation library of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGANIMATION_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGANIMATION_LIBRARIES``
   The libraries needed to link against to use osgAnimation.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGANIMATION_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgAnimation_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgAnimation library of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgDB.cmake b/Modules/FindosgDB.cmake
index dadc27c..e5d96cc 100644
--- a/Modules/FindosgDB.cmake
+++ b/Modules/FindosgDB.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgDB_FOUND``
-  Boolean indicating whether the osgDB library of the OpenSceneGraph toolkit is
-  found.  For backward compatibility, the ``OSGDB_FOUND`` variable is also set
-  to the same value.
+  .. versionadded:: 3.3
+
+  Boolean indicating whether the osgDB library of the OpenSceneGraph toolkit
+  was found.
 
 ``OSGDB_LIBRARIES``
   The libraries needed to link against to use osgDB.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGDB_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgDB_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgDB library of the OpenSceneGraph toolkit
+  was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgFX.cmake b/Modules/FindosgFX.cmake
index 28a13cb..c229227 100644
--- a/Modules/FindosgFX.cmake
+++ b/Modules/FindosgFX.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgFX_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgFX NodeKit of the OpenSceneGraph toolkit
-  is found.  For backward compatibility, the ``OSGFX_FOUND`` variable is also
-  set to the same value.
+  was found.
 
 ``OSGFX_LIBRARIES``
   The libraries needed to link against to use osgFX.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGFX_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgFX_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgFX NodeKit of the OpenSceneGraph toolkit
+  was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgGA.cmake b/Modules/FindosgGA.cmake
index 3c5ceb6..7a3b7df 100644
--- a/Modules/FindosgGA.cmake
+++ b/Modules/FindosgGA.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgGA_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgGA library of the OpenSceneGraph toolkit
-  is found.  For backward compatibility, the ``OSGGA_FOUND`` variable is also
-  set to the same value.
+  was found.
 
 ``OSGGA_LIBRARIES``
   The libraries needed to link against to use osgGA.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGGA_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgGA_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgGA library of the OpenSceneGraph toolkit
+  was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgIntrospection.cmake b/Modules/FindosgIntrospection.cmake
index 2b87a95..887ba14 100644
--- a/Modules/FindosgIntrospection.cmake
+++ b/Modules/FindosgIntrospection.cmake
@@ -52,9 +52,10 @@
 This module defines the following variables:
 
 ``osgIntrospection_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgIntrospection library of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGINTROSPECTION_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGINTROSPECTION_LIBRARIES``
   The libraries needed to link against to use osgIntrospection.
@@ -85,6 +86,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGINTROSPECTION_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgIntrospection_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgIntrospection library of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgManipulator.cmake b/Modules/FindosgManipulator.cmake
index 34fc23a..275dcd9 100644
--- a/Modules/FindosgManipulator.cmake
+++ b/Modules/FindosgManipulator.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgManipulator_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgManipulator NodeKit of the
-  OpenSceneGraph toolkit is found.  For backward compatibility, the
-  ``OSGMANIPULATOR_FOUND`` variable is also set to the same value.
+  OpenSceneGraph toolkit was found.
 
 ``OSGMANIPULATOR_LIBRARIES``
   The libraries needed to link against to use osgManipulator.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGMANIPULATOR_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgManipulator_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgManipulator NodeKit of the
+  OpenSceneGraph toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgParticle.cmake b/Modules/FindosgParticle.cmake
index 637a893..01c6427 100644
--- a/Modules/FindosgParticle.cmake
+++ b/Modules/FindosgParticle.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgParticle_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgParticle NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGPARTICLE_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGPARTICLE_LIBRARIES``
   The libraries needed to link against to use the osgParticle NodeKit
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGPARTICLE_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgParticle_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgParticle NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgPresentation.cmake b/Modules/FindosgPresentation.cmake
index 4a74de5..87858e2 100644
--- a/Modules/FindosgPresentation.cmake
+++ b/Modules/FindosgPresentation.cmake
@@ -48,9 +48,10 @@
 This module defines the following variables:
 
 ``osgPresentation_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgPresentation NodeKit of the
-  OpenSceneGraph toolkit is found.  For backward compatibility, the
-  ``OSGPRESENTATION_FOUND`` variable is also set to the same value.
+  OpenSceneGraph toolkit was found.
 
 ``OSGPRESENTATION_LIBRARIES``
   The libraries needed to link against to use osgPresentation.
@@ -81,6 +82,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGPRESENTATION_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgPresentation_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgPresentation NodeKit of the
+  OpenSceneGraph toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgProducer.cmake b/Modules/FindosgProducer.cmake
index 69f86d2..241ffb7 100644
--- a/Modules/FindosgProducer.cmake
+++ b/Modules/FindosgProducer.cmake
@@ -54,9 +54,10 @@
 This module defines the following variables:
 
 ``osgProducer_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgProducer library of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGPRODUCER_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGPRODUCER_LIBRARIES``
   The libraries needed to link against to use osgProducer.
@@ -87,6 +88,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGPRODUCER_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgProducer_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgProducer library of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgQt.cmake b/Modules/FindosgQt.cmake
index 3fd817d..c701baa 100644
--- a/Modules/FindosgQt.cmake
+++ b/Modules/FindosgQt.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgQt_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgQt library of the OpenSceneGraph toolkit
-  is found.  For backward compatibility, the ``OSGQT_FOUND`` variable is also
-  set to the same value.
+  was found.
 
 ``OSGQT_LIBRARIES``
   The libraries needed to link against to use osgQt.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGQT_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgQt_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgQt library of the OpenSceneGraph toolkit
+  was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgShadow.cmake b/Modules/FindosgShadow.cmake
index d2f2ea7..9939832 100644
--- a/Modules/FindosgShadow.cmake
+++ b/Modules/FindosgShadow.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgShadow_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgShadow NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGSHADOW_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGSHADOW_LIBRARIES``
   The libraries needed to link against to use osgShadow.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGSHADOW_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgShadow_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgShadow NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgSim.cmake b/Modules/FindosgSim.cmake
index d981d7d..ab9342b 100644
--- a/Modules/FindosgSim.cmake
+++ b/Modules/FindosgSim.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgSim_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgSim NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGSIM_FOUND`` variable
-  is also set to the same value.
+  toolkit was found.
 
 ``OSGSIM_LIBRARIES``
   The libraries needed to link against to use osgSim.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGSIM_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgSim_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgSim NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgTerrain.cmake b/Modules/FindosgTerrain.cmake
index ed0d858..ab418b5 100644
--- a/Modules/FindosgTerrain.cmake
+++ b/Modules/FindosgTerrain.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgTerrain_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgTerrain NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGTERRAIN_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGTERRAIN_LIBRARIES``
   The libraries needed to link against to use osgTerrain.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGTERRAIN_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgTerrain_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgTerrain NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgText.cmake b/Modules/FindosgText.cmake
index 67f532a..52da20d 100644
--- a/Modules/FindosgText.cmake
+++ b/Modules/FindosgText.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgText_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgText NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGTEXT_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGTEXT_LIBRARIES``
   The libraries needed to link against to use osgText.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGTEXT_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgText_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgText NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgUtil.cmake b/Modules/FindosgUtil.cmake
index 2b6bc23..f302d56 100644
--- a/Modules/FindosgUtil.cmake
+++ b/Modules/FindosgUtil.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgUtil_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgUtil library of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGUTIL_FOUND`` variable
-  is also set to the same value.
+  toolkit was found.
 
 ``OSGUTIL_LIBRARIES``
   The libraries needed to link against to use osgUtil.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGUTIL_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgUtil_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgUtil library of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgViewer.cmake b/Modules/FindosgViewer.cmake
index bb4e676..ec16fc8 100644
--- a/Modules/FindosgViewer.cmake
+++ b/Modules/FindosgViewer.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgViewer_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgViewer library of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGVIEWER_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGVIEWER_LIBRARIES``
   The libraries needed to link against to use osgViewer.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGVIEWER_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgViewer_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgViewer library of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgVolume.cmake b/Modules/FindosgVolume.cmake
index 0e447e9..15c6728 100644
--- a/Modules/FindosgVolume.cmake
+++ b/Modules/FindosgVolume.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgVolume_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgVolume NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGVOLUME_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGVOLUME_LIBRARIES``
   The libraries needed to link against to use osgVolume.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGVOLUME_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgVolume_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgVolume NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindosgWidget.cmake b/Modules/FindosgWidget.cmake
index cd5da96..cec8ff8 100644
--- a/Modules/FindosgWidget.cmake
+++ b/Modules/FindosgWidget.cmake
@@ -47,9 +47,10 @@
 This module defines the following variables:
 
 ``osgWidget_FOUND``
+  .. versionadded:: 3.3
+
   Boolean indicating whether the osgWidget NodeKit of the OpenSceneGraph
-  toolkit is found.  For backward compatibility, the ``OSGWIDGET_FOUND``
-  variable is also set to the same value.
+  toolkit was found.
 
 ``OSGWIDGET_LIBRARIES``
   The libraries needed to link against to use osgWidget.
@@ -80,6 +81,18 @@
   location.  It should point to the OpenSceneGraph installation prefix used when
   it was configured, built, and installed: ``./configure --prefix=$OSGDIR``.
 
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``OSGWIDGET_FOUND``
+  .. deprecated:: 4.2
+    Use ``osgWidget_FOUND``, which has the same value.
+
+  Boolean indicating whether the osgWidget NodeKit of the OpenSceneGraph
+  toolkit was found.
+
 Examples
 ^^^^^^^^
 
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake
index fa2ad7b..dbbfb3c 100644
--- a/Modules/FindwxWidgets.cmake
+++ b/Modules/FindwxWidgets.cmake
@@ -5,133 +5,279 @@
 FindwxWidgets
 -------------
 
-Find a wxWidgets (a.k.a., wxWindows) installation.
+Finds a wxWidgets installation and provides usage requirements for usage in
+projects:
 
-This module finds if wxWidgets is installed and selects a default
-configuration to use.  wxWidgets is a modular library.  To specify the
-modules that you will use, you need to name them as components to the
-package:
+.. code-block:: cmake
 
-find_package(wxWidgets COMPONENTS core base ... OPTIONAL_COMPONENTS net ...)
+  find_package(wxWidgets [<version>] [COMPONENTS <components>...] [...])
+
+wxWidgets (formerly known as wxWindows) is a widget toolkit and tools
+library for creating graphical user interfaces (GUIs) for cross-platform
+applications.
 
 .. versionadded:: 3.4
-  Support for :command:`find_package` version argument; ``webview`` component.
+  Support for :command:`find_package` version argument.
 
 .. versionadded:: 3.14
   ``OPTIONAL_COMPONENTS`` support.
 
-There are two search branches: a windows style and a unix style.  For
-windows, the following variables are searched for and set to defaults
-in case of multiple choices.  Change them if the defaults are not
-desired (i.e., these are the only variables you should change to
-select a configuration):
+Components
+^^^^^^^^^^
 
-::
-
-  wxWidgets_ROOT_DIR      - Base wxWidgets directory
-                            (e.g., C:/wxWidgets-3.2.0).
-  wxWidgets_LIB_DIR       - Path to wxWidgets libraries
-                            (e.g., C:/wxWidgets-3.2.0/lib/vc_x64_lib).
-  wxWidgets_CONFIGURATION - Configuration to use
-                            (e.g., msw, mswd, mswu, mswunivud, etc.)
-  wxWidgets_EXCLUDE_COMMON_LIBRARIES
-                          - Set to TRUE to exclude linking of
-                            commonly required libs (e.g., png tiff
-                            jpeg zlib regex expat scintilla lexilla).
-
-
-
-For unix style it uses the wx-config utility.  You can select between
-debug/release, unicode/ansi, universal/non-universal, and
-static/shared in the QtDialog or ccmake interfaces by turning ON/OFF
-the following variables:
-
-::
-
-  wxWidgets_USE_DEBUG
-  wxWidgets_USE_UNICODE
-  wxWidgets_USE_UNIVERSAL
-  wxWidgets_USE_STATIC
-
-There is also a wxWidgets_CONFIG_OPTIONS variable for all other
-options that need to be passed to the wx-config utility.  For example,
-to use the base toolkit found in the /usr/local path, set the variable
-(before calling the FIND_PACKAGE command) as such:
+wxWidgets is a modular library.  This module supports components to specify
+the modules to use.  Components can be specified with the
+:command:`find_package` command:
 
 .. code-block:: cmake
 
-  set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr)
+  find_package(
+    wxWidgets
+    [COMPONENTS <components>...]
+    [OPTIONAL_COMPONENTS <components>...]
+  )
 
+Supported components include:
 
+``base``
+  Finds the library that provides mandatory classes that any wxWidgets code
+  depends on.  This component is always required for applications
+  implementing wxWidgets.
 
-The following are set after the configuration is done for both windows
-and unix style:
+``core``
+  Finds the library that provides basic GUI classes such as GDI classes or
+  controls.
 
-::
+``gl``
+  Finds the OpenGL support.
 
-  wxWidgets_FOUND            - Set to TRUE if wxWidgets was found.
-  wxWidgets_INCLUDE_DIRS     - Include directories for WIN32
-                               i.e., where to find "wx/wx.h" and
-                               "wx/setup.h"; possibly empty for unices.
-  wxWidgets_LIBRARIES        - Path to the wxWidgets libraries.
-  wxWidgets_LIBRARY_DIRS     - compile time link dirs, useful for
-                               rpath on UNIX. Typically an empty string
-                               in WIN32 environment.
-  wxWidgets_DEFINITIONS      - Contains defines required to compile/link
-                               against WX, e.g. WXUSINGDLL
-  wxWidgets_DEFINITIONS_DEBUG- Contains defines required to compile/link
-                               against WX debug builds, e.g. __WXDEBUG__
-  wxWidgets_CXX_FLAGS        - Include dirs and compiler flags for
-                               unices, empty on WIN32. Essentially
-                               "`wx-config --cxxflags`".
-  wxWidgets_USE_FILE         - Convenience include file.
+``mono``
+  Finds the wxWidgets monolithic library.
 
-.. versionadded:: 3.11
-  The following environment variables can be used as hints: ``WX_CONFIG``,
-  ``WXRC_CMD``.
+``aui``
+  Finds the Advanced User Interface docking library.
 
+``net``
+  Finds the library that provides network access.
 
-Sample usage:
+``webview``
+  .. versionadded:: 3.4
 
-.. code-block:: cmake
+  Finds the library that provides rendering of web documents
+  (HTML/CSS/JavaScript).
 
-   # Note that for MinGW users the order of libs is important!
-   find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
-   if(wxWidgets_FOUND)
-     include(${wxWidgets_USE_FILE})
-     # and for each of your dependent executable/library targets:
-     target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
-   endif()
+For a full list of supported wxWidgets components, refer to the upstream
+documentation.
 
-
-
-If wxWidgets is required (i.e., not an optional part):
-
-.. code-block:: cmake
-
-   find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net)
-   include(${wxWidgets_USE_FILE})
-   # and for each of your dependent executable/library targets:
-   target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES})
+If no components are specified, this module by default searches for ``core``
+and ``base`` components.
 
 Imported Targets
 ^^^^^^^^^^^^^^^^
 
-.. versionadded:: 3.27
-
-This module defines the following :prop_tgt:`IMPORTED` targets:
+This module provides the following :ref:`Imported Targets`:
 
 ``wxWidgets::wxWidgets``
-  An interface library providing usage requirements for the found components.
-#]=======================================================================]
+  .. versionadded:: 3.27
 
-#
-# FIXME: check this and provide a correct sample usage...
-#        Remember to connect back to the upper text.
-# Sample usage with monolithic wx build:
-#
-#   find_package(wxWidgets COMPONENTS mono)
-#   ...
+  An interface imported target encapsulating the wxWidgets usage requirements
+  for the found components, available if wxWidgets is found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``wxWidgets_FOUND``
+  Boolean indicating whether (the requested version of) wxWidgets and all
+  its requested components were found.
+
+``wxWidgets_VERSION``
+  .. versionadded:: 4.2
+
+  The version of the wxWidgets found.
+
+``wxWidgets_INCLUDE_DIRS``
+  Include directories for WIN32, i.e., where to find ``<wx/wx.h>`` and
+  ``<wx/setup.h>``; possibly empty for Unix-like systems.
+
+``wxWidgets_LIBRARIES``
+  Path to the wxWidgets libraries.
+
+``wxWidgets_LIBRARY_DIRS``
+  Compile time link dirs, useful for setting ``rpath`` on Unix-like systems.
+  Typically an empty string in WIN32 environment.
+
+``wxWidgets_DEFINITIONS``
+  Contains compile definitions required to compile/link against WX, e.g.
+  ``WXUSINGDLL``.
+
+``wxWidgets_DEFINITIONS_DEBUG``
+  Contains compile definitions required to compile/link against WX debug builds,
+  e.g. ``__WXDEBUG__``.
+
+``wxWidgets_CXX_FLAGS``
+  Include directories and compiler flags for Unix-like systems, empty on
+  Windows. Essentially the output of ``wx-config --cxxflags``.
+
+Hints
+^^^^^
+
+This module accepts the following variables before calling
+``find_package(wxWidgets)``:
+
+``WX_CONFIG``
+  .. versionadded:: 3.11
+
+  Environment variable to manually specify the name of the wxWidgets library
+  configuration provider executable that will be searched besides the default
+  name ``wx-config``.
+
+``WXRC_CMD``
+  .. versionadded:: 3.11
+
+  Environment variable to manually specify the name of the wxWidgets resource
+  file compiler executable that will be searched besides the default name
+  ``wxrc``.
+
+There are two search branches: a Windows style and a Unix style.  For
+Windows, the following variables are searched for and set to defaults
+in case of multiple choices.  Change them if the defaults are not
+desired (i.e., these are the only variables that should be changed to
+select a configuration):
+
+``wxWidgets_ROOT_DIR``
+  Base wxWidgets directory (e.g., ``C:/wxWidgets-3.2.0``).
+
+``wxWidgets_LIB_DIR``
+  Path to wxWidgets libraries (e.g., ``C:/wxWidgets-3.2.0/lib/vc_x64_lib``).
+
+``wxWidgets_CONFIGURATION``
+  Configuration to use (e.g., msw, mswd, mswu, mswunivud, etc.)
+
+``wxWidgets_EXCLUDE_COMMON_LIBRARIES``
+  Set to TRUE to exclude linking of commonly required libs (e.g., png, tiff,
+  jpeg, zlib, webp, regex, expat, scintilla, lexilla, etc.).
+
+For Unix style this module uses the ``wx-config`` utility.  Selecting
+between debug/release, unicode/ansi, universal/non-universal, and
+static/shared is possible in the QtDialog or ccmake interfaces by turning
+ON/OFF the following variables:
+
+``wxWidgets_USE_DEBUG``
+  If enabled, the wxWidgets debug build will be searched.
+
+``wxWidgets_USE_UNICODE``
+  If enabled, the wxWidgets unicode build will be searched.
+
+``wxWidgets_USE_UNIVERSAL``
+  If enabled, the wxWidgets universal build will be searched.
+
+``wxWidgets_USE_STATIC``
+  If enabled, static wxWidgets libraries will be linked.
+
+``wxWidgets_CONFIG_OPTIONS``
+  This variable can be used for all other options that need to be passed to
+  the wx-config utility.  For example, to use the base toolkit found on the
+  system at ``/usr`` install prefix, set the variable (before calling the
+  :command:`find_package` command) as such:
+
+  .. code-block:: cmake
+
+    set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr)
+
+Deprecated Variables
+^^^^^^^^^^^^^^^^^^^^
+
+The following variables are provided for backward compatibility:
+
+``wxWidgets_VERSION_STRING``
+  .. deprecated:: 4.2
+    Use ``wxWidgets_VERSION``, which has the same value.
+
+  .. versionadded:: 3.4
+
+  The version of the wxWidgets found.
+
+``wxWidgets_USE_FILE``
+  .. deprecated:: 4.2
+    Instead of using this variable, include the :module:`UsewxWidgets`
+    module directly:
+
+    .. code-block:: cmake
+
+      include(UsewxWidgets)
+
+  The path to the :module:`UsewxWidgets` module for using wxWidgets in the
+  current directory.  For example:
+
+  .. code-block:: cmake
+
+    find_package(wxWidgets)
+    if(wxWidgets_FOUND)
+      include(${wxWidgets_USE_FILE})
+    endif()
+
+Examples
+^^^^^^^^
+
+Example: Finding wxWidgets
+""""""""""""""""""""""""""
+
+Finding wxWidgets and making it required (if wxWidgets is not found,
+processing stops with an error message):
+
+.. code-block:: cmake
+
+   find_package(wxWidgets REQUIRED)
+
+Example: Using Imported Target
+""""""""""""""""""""""""""""""
+
+Finding wxWidgets and using imported target in a project:
+
+.. code-block:: cmake
+
+  find_package(wxWidgets)
+  target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
+
+Example: Using Components
+"""""""""""""""""""""""""
+
+Finding wxWidgets and specifying components:
+
+.. code-block:: cmake
+
+  find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
+  target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
+
+Example: Monolithic wxWidgets Build
+"""""""""""""""""""""""""""""""""""
+
+Sample usage with monolithic wxWidgets build:
+
+.. code-block:: cmake
+
+  find_package(wxWidgets COMPONENTS mono)
+  target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
+
+Example: Using Variables
+""""""""""""""""""""""""
+
+Finding and using wxWidgets in CMake versions prior to 3.27, when the
+imported target wasn't yet available:
+
+.. code-block:: cmake
+
+  # Note that for MinGW users the order of libs is important.
+  find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net)
+
+  if(wxWidgets_FOUND)
+    include(UsewxWidgets)
+    # and for each of the project dependent executable/library targets:
+    target_link_libraries(example ${wxWidgets_LIBRARIES})
+  endif()
+#]=======================================================================]
 
 # NOTES
 #
@@ -209,16 +355,13 @@
 # Add the convenience use file if available.
 #
 # Get dir of this file which may reside in:
-# - CMAKE_MAKE_ROOT/Modules on CMake installation
-# - CMAKE_MODULE_PATH if user prefers his own specialized version
-set(wxWidgets_USE_FILE "")
-get_filename_component(
-  wxWidgets_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_FILE} PATH)
+# - CMAKE_ROOT/Modules on CMake installation
+# - CMAKE_MODULE_PATH if the user prefers their own specialized version
+set(wxWidgets_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_DIR}")
 # Prefer an existing customized version, but the user might override
 # the FindwxWidgets module and not the UsewxWidgets one.
 if(EXISTS "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
-  set(wxWidgets_USE_FILE
-    "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
+  set(wxWidgets_USE_FILE "${wxWidgets_CURRENT_LIST_DIR}/UsewxWidgets.cmake")
 else()
   set(wxWidgets_USE_FILE UsewxWidgets)
 endif()
@@ -247,12 +390,12 @@
   string(REGEX REPLACE "^(.*\n)?#define +wxSUBRELEASE_NUMBER +([0-9]+).*"
     "\\2" wxWidgets_VERSION_TWEAK "${_wx_version_h}" )
 
-  set(wxWidgets_VERSION_STRING
-    "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}" )
+  set(wxWidgets_VERSION
+    "${wxWidgets_VERSION_MAJOR}.${wxWidgets_VERSION_MINOR}.${wxWidgets_VERSION_PATCH}")
   if(${wxWidgets_VERSION_TWEAK} GREATER 0)
-    string(APPEND wxWidgets_VERSION_STRING ".${wxWidgets_VERSION_TWEAK}")
+    string(APPEND wxWidgets_VERSION ".${wxWidgets_VERSION_TWEAK}")
   endif()
-  dbg_msg("wxWidgets_VERSION_STRING:    ${wxWidgets_VERSION_STRING}")
+  set(wxWidgets_VERSION_STRING "${wxWidgets_VERSION}")
 endmacro()
 
 #=====================================================================
@@ -269,7 +412,8 @@
 #=====================================================================
 if(wxWidgets_FIND_STYLE STREQUAL "win32")
   # Useful common wx libs needed by almost all components.
-  set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib regex expat)
+  set(wxWidgets_WEBP_LIBRARIES webp webpdemux sharpyuv)
+  set(wxWidgets_COMMON_LIBRARIES png tiff jpeg zlib ${wxWidgets_WEBP_LIBRARIES} regex expat)
 
   # Libraries needed by stc component
   set(wxWidgets_STC_LIBRARIES scintilla lexilla)
@@ -464,7 +608,30 @@
       list(APPEND wxWidgets_LIBRARIES imm32)
     endif()
 
-    list(APPEND wxWidgets_LIBRARIES gdiplus msimg32 winmm comctl32 uuid oleacc uxtheme rpcrt4 shlwapi version wsock32)
+    list(APPEND wxWidgets_LIBRARIES
+      kernel32
+      user32
+      gdi32
+      gdiplus
+      msimg32
+      comdlg32
+      winspool
+      winmm
+      shell32
+      shlwapi
+      comctl32
+      ole32
+      oleaut32
+      uuid
+      rpcrt4
+      advapi32
+      version
+      ws2_32
+      wininet
+      oleacc
+      uxtheme
+      wsock32
+    )
   endmacro()
 
   #-------------------------------------------------------------------
@@ -999,7 +1166,6 @@
 DBG_MSG("wxWidgets_LIBRARY_DIRS    : ${wxWidgets_LIBRARY_DIRS}")
 DBG_MSG("wxWidgets_LIBRARIES       : ${wxWidgets_LIBRARIES}")
 DBG_MSG("wxWidgets_CXX_FLAGS       : ${wxWidgets_CXX_FLAGS}")
-DBG_MSG("wxWidgets_USE_FILE        : ${wxWidgets_USE_FILE}")
 
 #=====================================================================
 #=====================================================================
@@ -1014,7 +1180,7 @@
 
 find_package_handle_standard_args(wxWidgets
   REQUIRED_VARS wxWidgets_LIBRARIES wxWidgets_INCLUDE_DIRS
-  VERSION_VAR   wxWidgets_VERSION_STRING
+  VERSION_VAR wxWidgets_VERSION
   ${wxWidgets_HANDLE_COMPONENTS}
   )
 unset(wxWidgets_HANDLE_COMPONENTS)
diff --git a/Modules/FindwxWindows.cmake b/Modules/FindwxWindows.cmake
index 88af70c..90cb0b7 100644
--- a/Modules/FindwxWindows.cmake
+++ b/Modules/FindwxWindows.cmake
@@ -11,7 +11,11 @@
 
 Finds the wxWidgets (formerly known as wxWindows) installation and determines
 the locations of its include directories and libraries, as well as the name of
-the library.
+the library:
+
+.. code-block:: cmake
+
+  find_package(wxWindows [...])
 
 wxWidgets 2.6.x is supported for monolithic builds, such as those compiled in
 the ``wx/build/msw`` directory using:
@@ -26,7 +30,7 @@
 This module defines the following variables:
 
 ``WXWINDOWS_FOUND``
-  Boolean indicating whether the wxWidgets is found.
+  Boolean indicating whether the wxWidgets was found.
 ``WXWINDOWS_LIBRARIES``
   Libraries needed to link against to use wxWidgets.  This includes paths to
   the wxWidgets libraries and any additional linker flags, typically derived
@@ -57,7 +61,7 @@
 Deprecated Variables
 ^^^^^^^^^^^^^^^^^^^^
 
-These variables are provided for backward compatibility:
+The following variables are provided for backward compatibility:
 
 ``CMAKE_WX_CAN_COMPILE``
   .. deprecated:: 1.8
@@ -78,7 +82,7 @@
 Examples
 ^^^^^^^^
 
-Example: Finding wxWidgets in earlier CMake versions
+Example: Finding wxWidgets in Earlier CMake Versions
 """"""""""""""""""""""""""""""""""""""""""""""""""""
 
 In earlier versions of CMake, wxWidgets (wxWindows) could be found using:
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index 70ad3c7..d559ab7 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -5,25 +5,39 @@
 FortranCInterface
 -----------------
 
-Fortran/C Interface Detection
+This module provides variables and commands to detect Fortran/C Interface.
 
-This module automatically detects the API by which C and Fortran
-languages interact.
+Load this module in a CMake project with:
 
-Module Variables
-^^^^^^^^^^^^^^^^
+.. code-block:: cmake
 
-Variables that indicate if the mangling is found:
+  include(FortranCInterface)
+
+This module automatically detects the API by which C and Fortran languages
+interact.
+
+Variables
+^^^^^^^^^
+
+Result Variables
+""""""""""""""""
+
+Including this module defines the following variables that indicate if the
+mangling is found:
 
 ``FortranCInterface_GLOBAL_FOUND``
-  Global subroutines and functions.
+  Boolean indicating whether global subroutines and functions are available.
 
 ``FortranCInterface_MODULE_FOUND``
-  Module subroutines and functions (declared by "MODULE PROCEDURE").
+  Boolean indicating whether module subroutines and functions (declared by
+  ``MODULE PROCEDURE``) are available.
+
+Input Variables
+"""""""""""""""
 
 This module also provides the following variables to specify
 the detected mangling, though a typical use case does not need
-to reference them and can use the `Module Functions`_ below.
+to reference them and can use the `Commands`_ below.
 
 ``FortranCInterface_GLOBAL_PREFIX``
   Prefix for a global symbol without an underscore.
@@ -99,29 +113,48 @@
     The module name appears *after* the symbol name, i.e.,
     ``<PREFIX><symbol><MIDDLE><module><SUFFIX>``.
 
-Module Functions
-^^^^^^^^^^^^^^^^
+Variables For Additional Manglings
+""""""""""""""""""""""""""""""""""
+
+This module is aware of possible ``GLOBAL`` and ``MODULE`` manglings for
+many Fortran compilers, but it also provides an interface to specify
+new possible manglings.  The following variables can be set before including
+this module to specify additional manglings:
+
+``FortranCInterface_GLOBAL_SYMBOLS``
+
+``FortranCInterface_MODULE_SYMBOLS``
+
+before including this module to specify manglings of the symbols
+``MySub``, ``My_Sub``, ``MyModule:MySub``, and ``My_Module:My_Sub``.
+
+Commands
+^^^^^^^^
+
+This module provides the following commands:
 
 .. command:: FortranCInterface_HEADER
 
-  The ``FortranCInterface_HEADER`` function is provided to generate a
-  C header file containing macros to mangle symbol names:
+  Generates a C header file containing macros to mangle symbol names:
 
   .. code-block:: cmake
 
-    FortranCInterface_HEADER(<file>
-                             [MACRO_NAMESPACE <macro-ns>]
-                             [SYMBOL_NAMESPACE <ns>]
-                             [SYMBOLS [<module>:]<function> ...])
+    FortranCInterface_HEADER(
+      <file>
+      [MACRO_NAMESPACE <macro-ns>]
+      [SYMBOL_NAMESPACE <ns>]
+      [SYMBOLS [<module>:]<function> ...]
+    )
 
-  It generates in ``<file>`` definitions of the following macros:
+  This command generates a ``<file>`` with definitions of the following
+  macros:
 
   .. code-block:: c
 
-     #define FortranCInterface_GLOBAL (name,NAME) ...
-     #define FortranCInterface_GLOBAL_(name,NAME) ...
-     #define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
-     #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
+    #define FortranCInterface_GLOBAL (name,NAME) ...
+    #define FortranCInterface_GLOBAL_(name,NAME) ...
+    #define FortranCInterface_MODULE (mod,name, MOD,NAME) ...
+    #define FortranCInterface_MODULE_(mod,name, MOD,NAME) ...
 
   These macros mangle four categories of Fortran symbols, respectively:
 
@@ -139,6 +172,10 @@
     Replace the default ``FortranCInterface_`` prefix with a given
     namespace ``<macro-ns>``.
 
+  ``SYMBOL_NAMESPACE``
+    Prefix all preprocessor definitions generated by the ``SYMBOLS``
+    option with a given namespace ``<ns>``.
+
   ``SYMBOLS``
     List symbols to mangle automatically with C preprocessor definitions::
 
@@ -148,77 +185,71 @@
     If the mangling for some symbol is not known then no preprocessor
     definition is created, and a warning is displayed.
 
-  ``SYMBOL_NAMESPACE``
-    Prefix all preprocessor definitions generated by the ``SYMBOLS``
-    option with a given namespace ``<ns>``.
-
 .. command:: FortranCInterface_VERIFY
 
-  The ``FortranCInterface_VERIFY`` function is provided to verify
-  that the Fortran and C/C++ compilers work together:
+  Verifies that the Fortran and C/C++ compilers work together:
 
   .. code-block:: cmake
 
     FortranCInterface_VERIFY([CXX] [QUIET])
 
-  It tests whether a simple test executable using Fortran and C (and C++
-  when the CXX option is given) compiles and links successfully.  The
-  result is stored in the cache entry ``FortranCInterface_VERIFIED_C``
+  This command tests whether a simple test executable using Fortran and C
+  (and C++ when the ``CXX`` option is given) compiles and links successfully.
+  The result is stored in the cache entry ``FortranCInterface_VERIFIED_C``
   (or ``FortranCInterface_VERIFIED_CXX`` if ``CXX`` is given) as a boolean.
-  If the check fails and ``QUIET`` is not given the function terminates with a
+  If the check fails and ``QUIET`` is not given the command terminates with a
   fatal error message describing the problem.  The purpose of this check
   is to stop a build early for incompatible compiler combinations.  The
   test is built in the ``Release`` configuration.
 
-Example Usage
-^^^^^^^^^^^^^
+Examples
+^^^^^^^^
+
+Examples: Basic Usage
+"""""""""""""""""""""
+
+The following example creates a ``FC.h`` header that defines mangling macros
+``FC_GLOBAL()``, ``FC_GLOBAL_()``, ``FC_MODULE()``, and ``FC_MODULE_()``:
 
 .. code-block:: cmake
 
-   include(FortranCInterface)
-   FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
+  include(FortranCInterface)
+  FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
 
-This creates a "FC.h" header that defines mangling macros ``FC_GLOBAL()``,
-``FC_GLOBAL_()``, ``FC_MODULE()``, and ``FC_MODULE_()``.
+The next example creates a ``FCMangle.h`` header that defines the same
+``FC_*()`` mangling macros as the previous example plus preprocessor symbols
+``FC_mysub`` and ``FC_mymod_my_sub``:
 
 .. code-block:: cmake
 
-   include(FortranCInterface)
-   FortranCInterface_HEADER(FCMangle.h
-                            MACRO_NAMESPACE "FC_"
-                            SYMBOL_NAMESPACE "FC_"
-                            SYMBOLS mysub mymod:my_sub)
+  include(FortranCInterface)
+  FortranCInterface_HEADER(
+    FCMangle.h
+    MACRO_NAMESPACE "FC_"
+    SYMBOL_NAMESPACE "FC_"
+    SYMBOLS mysub mymod:my_sub
+  )
 
-This creates a "FCMangle.h" header that defines the same ``FC_*()``
-mangling macros as the previous example plus preprocessor symbols
-``FC_mysub`` and ``FC_mymod_my_sub``.
+Example: Additional Manglings
+"""""""""""""""""""""""""""""
 
-Additional Manglings
-^^^^^^^^^^^^^^^^^^^^
-
-FortranCInterface is aware of possible ``GLOBAL`` and ``MODULE`` manglings
-for many Fortran compilers, but it also provides an interface to specify
-new possible manglings.  Set the variables::
-
-   FortranCInterface_GLOBAL_SYMBOLS
-   FortranCInterface_MODULE_SYMBOLS
-
-before including FortranCInterface to specify manglings of the symbols
+The following example shows how to specify manglings of the symbols
 ``MySub``, ``My_Sub``, ``MyModule:MySub``, and ``My_Module:My_Sub``.
-For example, the code:
+The following code tells this module to try given ``GLOBAL`` and ``MODULE``
+manglings.  (The carets point at raw symbol names for clarity in this
+example but are not needed.)
 
 .. code-block:: cmake
 
-   set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
-     #                                  ^^^^^  ^^^^^^   ^^^^^
-   set(FortranCInterface_MODULE_SYMBOLS
-       __mymodule_MOD_mysub __my_module_MOD_my_sub)
-     #   ^^^^^^^^     ^^^^^   ^^^^^^^^^     ^^^^^^
-   include(FortranCInterface)
+  set(FortranCInterface_GLOBAL_SYMBOLS mysub_ my_sub__ MYSUB_)
+    #                                  ^^^^^  ^^^^^^   ^^^^^
+  set(FortranCInterface_MODULE_SYMBOLS
+      __mymodule_MOD_mysub __my_module_MOD_my_sub)
+    #   ^^^^^^^^     ^^^^^   ^^^^^^^^^     ^^^^^^
 
-tells FortranCInterface to try given ``GLOBAL`` and ``MODULE`` manglings.
-(The carets point at raw symbol names for clarity in this example but
-are not needed.)
+  include(FortranCInterface)
+
+  # ...
 #]=======================================================================]
 
 #-----------------------------------------------------------------------------
diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake
index 5467651..52bbe80 100644
--- a/Modules/GenerateExportHeader.cmake
+++ b/Modules/GenerateExportHeader.cmake
@@ -8,7 +8,7 @@
 This module provides commands for generating a header file containing
 preprocessor macro definitions to control C/C++ symbol visibility.
 
-Load this module in CMake project with:
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake
index f1f5db7..952e66c 100644
--- a/Modules/GetPrerequisites.cmake
+++ b/Modules/GetPrerequisites.cmake
@@ -9,12 +9,19 @@
 
   Use :command:`file(GET_RUNTIME_DEPENDENCIES)` instead.
 
-This module provides functions to analyze and list the dependencies
-(prerequisites) of executable or shared library files.  These functions list the
-shared libraries (``.dll``, ``.dylib``, or ``.so`` files) required by an
+This module provides commands to analyze and list the dependencies
+(prerequisites) of executable or shared library files.  These commands list
+the shared libraries (``.dll``, ``.dylib``, or ``.so`` files) required by an
 executable or shared library.
 
-It determines dependencies using the following platform-specific tools:
+Load this module in CMake with:
+
+.. code-block:: cmake
+
+  include(GetPrerequisites)
+
+This module determines dependencies using the following platform-specific
+tools:
 
 * ``dumpbin`` (Windows)
 * ``objdump`` (MinGW on Windows)
@@ -25,7 +32,10 @@
   The tool specified by the :variable:`CMAKE_OBJDUMP` variable will be used, if
   set.
 
-The following functions are provided by this module:
+Commands
+^^^^^^^^
+
+This module provides the following commands:
 
 * :command:`get_prerequisites`
 * :command:`list_prerequisites`
@@ -40,20 +50,18 @@
   (projects can override it with ``gp_resolved_file_type_override()``)
 * :command:`gp_file_type`
 
-Functions
-^^^^^^^^^
-
 .. command:: get_prerequisites
 
+  Gets the list of shared library files required by specified target:
+
   .. code-block:: cmake
 
     get_prerequisites(<target> <prerequisites-var> <exclude-system> <recurse>
                       <exepath> <dirs> [<rpaths>])
 
-  Gets the list of shared library files required by ``<target>``.  The list
-  in the variable named ``<prerequisites-var>`` should be empty on first
-  entry to this function.  On exit, ``<prerequisites-var>`` will contain the
-  list of required shared library files.
+  The list in the variable named ``<prerequisites-var>`` should be empty on
+  first entry to this command.  On exit, ``<prerequisites-var>`` will contain
+  the list of required shared library files.
 
   The arguments are:
 
@@ -80,16 +88,16 @@
 
   .. versionadded:: 3.14
     The variable ``GET_PREREQUISITES_VERBOSE`` can be set to true before calling
-    this function to enable verbose output.
+    this command to enable verbose output.
 
 .. command:: list_prerequisites
 
+  Prints a message listing the prerequisites of the specified target:
+
   .. code-block:: cmake
 
     list_prerequisites(<target> [<recurse> [<exclude-system> [<verbose>]]])
 
-  Prints a message listing the prerequisites of ``<target>``.
-
   The arguments are:
 
   ``<target>``
@@ -107,15 +115,15 @@
 
 .. command:: list_prerequisites_by_glob
 
+  Prints the prerequisites of shared library and executable files matching a
+  globbing pattern:
+
   .. code-block:: cmake
 
     list_prerequisites_by_glob(<GLOB|GLOB_RECURSE>
                                <glob-exp>
                                [<optional-args>...])
 
-  Prints the prerequisites of shared library and executable files matching a
-  globbing pattern.
-
   The arguments are:
 
   ``GLOB`` or ``GLOB_RECURSE``
@@ -131,44 +139,56 @@
 
 .. command:: gp_append_unique
 
+  Appends the value to the list only if it is not already in the list:
+
   .. code-block:: cmake
 
     gp_append_unique(<list-var> <value>)
 
-  Appends ``<value>`` to the list variable ``<list-var>`` only if the value is
-  not already in the list.
+  The arguments are:
+
+  ``<value>``
+    The value to be appended to the list.
+  ``<list-var>``
+    The list variable name that will have the value appended only if it is
+    not already in the list.
 
 .. command:: is_file_executable
 
+  Checks if given file is a binary executable:
+
   .. code-block:: cmake
 
     is_file_executable(<file> <result-var>)
 
-  Sets ``<result-var>`` to 1 if ``<file>`` is a binary executable; otherwise
-  sets it to 0.
+  This command sets the ``<result-var>`` to 1 if ``<file>`` is a binary
+  executable; otherwise it sets it to 0.
 
 .. command:: gp_item_default_embedded_path
 
+  Determines the reference path for the specified item:
+
   .. code-block:: cmake
 
     gp_item_default_embedded_path(<item> <default-embedded-path-var>)
 
-  Determines the reference path for ``<item>`` when it is embedded inside a
-  bundle and stores it to a variable ``<default-embedded-path-var>``.
+  This command determines the reference path for ``<item>`` when it is
+  embedded inside a bundle and stores it to a variable
+  ``<default-embedded-path-var>``.
 
-  Projects can override this function by defining a custom
-  ``gp_item_default_embedded_path_override()`` function.
+  Projects can override this command by defining a custom
+  ``gp_item_default_embedded_path_override()`` command.
 
 .. command:: gp_resolve_item
 
+  Resolves a given item into an existing full path file and stores it to a
+  variable:
+
   .. code-block:: cmake
 
     gp_resolve_item(<context> <item> <exepath> <dirs> <resolved-item-var>
                     [<rpaths>])
 
-  Resolves a given ``<item>`` into an existing full path file and stores it to a
-  ``<resolved-item-var>`` variable.
-
   The arguments are:
 
   ``<context>``
@@ -187,18 +207,21 @@
   ``<rpaths>``
     See the argument description in :command:`get_prerequisites`.
 
-  Projects can override this function by defining a custom
-  ``gp_resolve_item_override()`` function.
+  Projects can override this command by defining a custom
+  ``gp_resolve_item_override()`` command.
 
 .. command:: gp_resolved_file_type
 
+  Determines the type of a given file:
+
   .. code-block:: cmake
 
     gp_resolved_file_type(<original-file> <file> <exepath> <dirs> <type-var>
                           [<rpaths>])
 
-  Determines the type of ``<file>`` with respect to ``<original-file>``. The
-  resulting type of prerequisite is stored in the ``<type-var>`` variable.
+  This command determines the type of ``<file>`` with respect to the
+  ``<original-file>``.  The resulting type of prerequisite is stored in the
+  ``<type-var>`` variable.
 
   Use ``<exepath>`` and ``<dirs>`` if necessary to resolve non-absolute
   ``<file>`` values -- but only for non-embedded items.
@@ -213,17 +236,20 @@
   * ``embedded``
   * ``other``
 
-  Projects can override this function by defining a custom
-  ``gp_resolved_file_type_override()`` function.
+  Projects can override this command by defining a custom
+  ``gp_resolved_file_type_override()`` command.
 
 .. command:: gp_file_type
 
+  Determines the type of a given file:
+
   .. code-block:: cmake
 
     gp_file_type(<original-file> <file> <type-var>)
 
-  Determines the type of ``<file>`` with respect to ``<original-file>``. The
-  resulting type of prerequisite is stored in the ``<type-var>`` variable.
+  This command determines the type of ``<file>`` with respect to the
+  ``<original-file>``.  The resulting type of prerequisite is stored in the
+  ``<type-var>`` variable.
 
   The ``<type-var>`` variable will be set to one of the following values:
 
@@ -235,6 +261,9 @@
 Examples
 ^^^^^^^^
 
+Example: Basic Usage
+""""""""""""""""""""
+
 Printing all dependencies of a shared library, including system libraries, with
 verbose output:
 
@@ -242,6 +271,25 @@
 
   include(GetPrerequisites)
   list_prerequisites("path/to/libfoo.dylib" 1 0 1)
+
+Example: Upgrading Code
+"""""""""""""""""""""""
+
+For example:
+
+.. code-block:: cmake
+
+  include(GetPrerequisites)
+  # ...
+  gp_append_unique(keys "${key}")
+
+the ``gp_append_unique()`` can be in new code replaced with:
+
+.. code-block:: cmake
+
+  if(NOT key IN_LIST keys)
+    list(APPEND keys "${key}")
+  endif()
 #]=======================================================================]
 
 function(gp_append_unique list_var value)
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index ebf0ba0..2fded3f 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -7,9 +7,16 @@
 
 .. versionadded:: 3.9
 
-This module defines functions to help use the Google Test infrastructure.  Two
-mechanisms for adding tests are provided. :command:`gtest_add_tests` has been
-around for some time, originally via ``find_package(GTest)``.
+This module provides commands to help use the Google Test infrastructure.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(GoogleTest)
+
+Two mechanisms for adding tests are provided. :command:`gtest_add_tests` has
+been around for some time, originally via ``find_package(GTest)``.
 :command:`gtest_discover_tests` was introduced in CMake 3.10.
 
 The (older) :command:`gtest_add_tests` scans source files to identify tests.
@@ -636,11 +643,21 @@
     PARENT_SCOPE # undocumented, do not use outside of CMake
   )
   if(NOT cmp0178 STREQUAL "NEW")
-    # Preserve old behavior where empty list items are silently discarded
+    # Preserve old behavior where empty list items are silently discarded.
+    # Before CMP0178 was added, we used the old cmake_parse_arguments() form
+    # rather than cmake_parse_arguments(PARSE_ARGV). The latter escapes
+    # embedded semicolons if a value is quoted and there are semicolons
+    # within the quoted value. We can't just unescape them to get the old
+    # value, we have to reparse the arguments with the old form.
+    cmake_parse_arguments(old_arg
+      "${options}" "${oneValueArgs}" "${multiValueArgs}"
+      ${ARGN}
+    )
+    set(new_arg_EXTRA_ARGS "${arg_EXTRA_ARGS}")
+    set(arg_EXTRA_ARGS "${old_arg_EXTRA_ARGS}")
+
     set(test_executor_orig "${test_executor}")
     set(test_executor ${test_executor})
-    set(arg_EXTRA_ARGS_orig "${arg_EXTRA_ARGS}")
-    set(arg_EXTRA_ARGS ${arg_EXTRA_ARGS})
     if(NOT cmp0178 STREQUAL "OLD")
       if(NOT "${test_executor}" STREQUAL "${test_executor_orig}")
         cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
@@ -652,7 +669,9 @@
           "${cmp0178_warning}"
         )
       endif()
-      if(NOT "${arg_EXTRA_ARGS}" STREQUAL "${arg_EXTRA_ARGS_orig}")
+      # Unescape semicolons from the PARSE_ARGV form's value before comparing
+      string(REPLACE [[\;]] ";" new_arg_EXTRA_ARGS "${new_arg_EXTRA_ARGS}")
+      if(NOT "${old_arg_EXTRA_ARGS}" STREQUAL "${new_arg_EXTRA_ARGS}")
         cmake_policy(GET_WARNING CMP0178 cmp0178_warning)
         message(AUTHOR_WARNING
           "The EXTRA_ARGS value contains one or more empty values. "
@@ -737,24 +756,18 @@
     )
 
     if(GENERATOR_IS_MULTI_CONFIG)
-      foreach(_config ${CMAKE_CONFIGURATION_TYPES})
-        file(GENERATE
-          OUTPUT "${ctest_file_base}_include-${_config}.cmake"
-          CONTENT "${ctest_include_content}"
-          CONDITION $<CONFIG:${_config}>
-        )
-      endforeach()
+      file(GENERATE
+        OUTPUT "${ctest_file_base}_include-$<CONFIG>.cmake"
+        CONTENT "${ctest_include_content}"
+      )
       file(WRITE "${ctest_include_file}"
         "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")"
       )
     else()
       file(GENERATE
-        OUTPUT "${ctest_file_base}_include.cmake"
+        OUTPUT "${ctest_include_file}"
         CONTENT "${ctest_include_content}"
       )
-      file(WRITE "${ctest_include_file}"
-        "include(\"${ctest_file_base}_include.cmake\")"
-      )
     endif()
 
   else()
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 3af16f8..940cea0 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -43,12 +43,246 @@
   endif()
 endfunction()
 
+macro(write_test_to_file)
+  # Store the gtest test name before messing with these strings
+  set(gtest_name ${current_test_suite}.${current_test_name})
+
+  set(pretty_test_suite ${current_test_suite})
+  set(pretty_test_name ${current_test_name})
+
+  # Handle disabled tests
+  set(maybe_DISABLED "")
+  if(pretty_test_suite MATCHES "^DISABLED_" OR pretty_test_name MATCHES "^DISABLED_")
+    set(maybe_DISABLED DISABLED YES)
+    string(REGEX REPLACE "^DISABLED_" "" pretty_test_suite "${pretty_test_suite}")
+    string(REGEX REPLACE "^DISABLED_" "" pretty_test_name "${pretty_test_name}")
+  endif()
+
+  if (NOT current_test_value_param STREQUAL "" AND NOT arg_NO_PRETTY_VALUES)
+    # Remove value param name, if any, from test name
+    string(REGEX REPLACE "^(.+)/.+$" "\\1" pretty_test_name "${pretty_test_name}")
+    set(pretty_test_name "${pretty_test_name}/${current_test_value_param}")
+  endif()
+
+  if(NOT current_test_type_param STREQUAL "")
+    # Parse type param name from suite name
+    if(pretty_test_suite MATCHES "^(.+)/(.+)$")
+      set(pretty_test_suite "${CMAKE_MATCH_1}")
+      set(current_type_param_name "${CMAKE_MATCH_2}")
+    else()
+      set(current_type_param_name "")
+    endif()
+    if (NOT arg_NO_PRETTY_TYPES)
+      string(APPEND pretty_test_name  "<${current_test_type_param}>")
+    elseif(NOT current_type_param_name STREQUAL "")
+        string(APPEND pretty_test_name "<${current_type_param_name}>")
+    endif()
+  endif()
+
+  set(test_name_template "@prefix@@pretty_test_suite@.@pretty_test_name@@suffix@")
+  string(CONFIGURE "${test_name_template}" testname)
+
+  if(NOT "${arg_TEST_XML_OUTPUT_DIR}" STREQUAL "")
+    set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${arg_TEST_XML_OUTPUT_DIR}/${prefix}${gtest_name}${suffix}.xml")
+  else()
+    set(TEST_XML_OUTPUT_PARAM "")
+  endif()
+
+  # unescape []
+  if(open_sb)
+    string(REPLACE "${open_sb}" "[" testname "${testname}")
+  endif()
+  if(close_sb)
+    string(REPLACE "${close_sb}" "]" testname "${testname}")
+  endif()
+  set(guarded_testname "${open_guard}${testname}${close_guard}")
+  # Add to script. Do not use add_command() here because it messes up the
+  # handling of empty values when forwarding arguments, and we need to
+  # preserve those carefully for arg_TEST_EXECUTOR and arg_EXTRA_ARGS.
+  string(APPEND script "add_test(${guarded_testname} ${launcherArgs}")
+  foreach(arg IN ITEMS
+    "${arg_TEST_EXECUTABLE}"
+    "--gtest_filter=${gtest_name}"
+    "--gtest_also_run_disabled_tests"
+    ${TEST_XML_OUTPUT_PARAM}
+  )
+
+    if(arg MATCHES "[^-./:a-zA-Z0-9_]")
+      string(APPEND script " [==[${arg}]==]")
+    else()
+      string(APPEND script " ${arg}")
+    endif()
+  endforeach()
+
+  if(arg_TEST_EXTRA_ARGS)
+    list(JOIN arg_TEST_EXTRA_ARGS "]==] [==[" extra_args)
+    string(APPEND script " [==[${extra_args}]==]")
+  endif()
+  string(APPEND script ")\n")
+
+  set(maybe_LOCATION "")
+  if(NOT current_test_file STREQUAL "" AND NOT current_test_line STREQUAL "")
+    set(maybe_LOCATION DEF_SOURCE_LINE "${current_test_file}:${current_test_line}")
+  endif()
+
+  add_command(set_tests_properties
+    "${guarded_testname}"
+    PROPERTIES
+      ${maybe_DISABLED}
+      ${maybe_LOCATION}
+      WORKING_DIRECTORY "${arg_TEST_WORKING_DIR}"
+      SKIP_REGULAR_EXPRESSION "\\[  SKIPPED \\]"
+      ${arg_TEST_PROPERTIES}
+  )
+
+  # possibly unbalanced square brackets render lists invalid so skip such
+  # tests in ${arg_TEST_LIST}
+  if(NOT "${testname}" MATCHES [=[(\[|\])]=])
+    # escape ;
+    string(REPLACE [[;]] [[\\;]] testname "${testname}")
+    list(APPEND tests_buffer "${testname}")
+    list(LENGTH tests_buffer tests_buffer_length)
+    if(tests_buffer_length GREATER "250")
+      # Chunk updates to the final "tests" variable, keeping the
+      # "tests_buffer" variable that we append each test to relatively
+      # small. This mitigates worsening performance impacts for the
+      # corner case of having many thousands of tests.
+      list(APPEND tests "${tests_buffer}")
+      set(tests_buffer "")
+    endif()
+  endif()
+
+  # If we've built up a sizable script so far, write it out as a chunk now
+  # so we don't accumulate a massive string to write at the end
+  string(LENGTH "${script}" script_len)
+  if(${script_len} GREATER "50000")
+    file(APPEND "${arg_CTEST_FILE}" "${script}")
+    set(script "")
+  endif()
+endmacro()
+
+macro(parse_tests_from_output)
+  generate_testname_guards("${output}" open_guard close_guard)
+  escape_square_brackets("${output}" "[" "__osb" open_sb output)
+  escape_square_brackets("${output}" "]" "__csb" close_sb output)
+
+  # Preserve semicolon in test-parameters
+  string(REPLACE [[;]] [[\;]] output "${output}")
+  string(REPLACE "\n" ";" output "${output}")
+
+  # Command line output doesn't contain information about the file and line number of the tests
+  set(current_test_file "")
+  set(current_test_line "")
+
+  # Parse output
+  foreach(line ${output})
+    # Skip header
+    if(line MATCHES "gtest_main\\.cc")
+      continue()
+    endif()
+
+    if(line STREQUAL "")
+      continue()
+    endif()
+
+    # Do we have a module name or a test name?
+    if(NOT line MATCHES "^  ")
+      set(current_test_type_param "")
+
+      # Module; remove trailing '.' to get just the name...
+      string(REGEX REPLACE "\\.( *#.*)?$" "" current_test_suite "${line}")
+      if(line MATCHES "# *TypeParam = (.*)$")
+        set(current_test_type_param "${CMAKE_MATCH_1}")
+      endif()
+    else()
+      string(STRIP "${line}" test)
+      string(REGEX REPLACE " ( *#.*)?$" "" current_test_name "${test}")
+
+      set(current_test_value_param "")
+      if(line MATCHES "# *GetParam\\(\\) = (.*)$")
+        set(current_test_value_param "${CMAKE_MATCH_1}")
+      endif()
+
+      write_test_to_file()
+    endif()
+  endforeach()
+endmacro()
+
+macro(get_json_member_with_default json_variable member_name out_variable)
+  string(JSON ${out_variable}
+    ERROR_VARIABLE error_param
+    GET "${${json_variable}}" "${member_name}"
+  )
+  if(error_param)
+    # Member not present
+    set(${out_variable} "")
+  endif()
+endmacro()
+
+macro(parse_tests_from_json json_file)
+  if(NOT EXISTS "${json_file}")
+    message(FATAL_ERROR "Missing expected JSON file with test list: ${json_file}")
+  endif()
+
+  file(READ "${json_file}" test_json)
+  string(JSON test_suites_json GET "${test_json}" "testsuites")
+
+  # Return if there are no testsuites
+  string(JSON len_test_suites LENGTH "${test_suites_json}")
+  if(len_test_suites GREATER 0)
+    set(open_sb)
+    set(close_sb)
+
+    math(EXPR upper_limit_test_suite_range "${len_test_suites} - 1")
+
+    foreach(index_test_suite RANGE ${upper_limit_test_suite_range})
+      string(JSON test_suite_json GET "${test_suites_json}" ${index_test_suite})
+
+      # "suite" is expected to be set in write_test_to_file(). When parsing the
+      # plain text output, "suite" is expected to be the original suite name
+      # before accounting for pretty names. This may be used to construct the
+      # name of XML output results files.
+      string(JSON current_test_suite GET "${test_suite_json}" "name")
+      string(JSON tests_json GET "${test_suite_json}" "testsuite")
+
+      # Skip test suites without tests
+      string(JSON len_tests LENGTH "${tests_json}")
+      if(len_tests LESS_EQUAL 0)
+        continue()
+      endif()
+
+      math(EXPR upper_limit_test_range "${len_tests} - 1")
+      foreach(index_test RANGE ${upper_limit_test_range})
+        string(JSON test_json GET "${tests_json}" ${index_test})
+
+        string(JSON len_test_parameters LENGTH "${test_json}")
+        if(len_test_parameters LESS_EQUAL 0)
+          continue()
+        endif()
+
+        get_json_member_with_default(test_json "name" current_test_name)
+        get_json_member_with_default(test_json "file" current_test_file)
+        get_json_member_with_default(test_json "line" current_test_line)
+        get_json_member_with_default(test_json "value_param" current_test_value_param)
+        get_json_member_with_default(test_json "type_param" current_test_type_param)
+
+        generate_testname_guards(
+          "${current_test_suite}${current_test_name}${current_test_value_param}${current_test_type_param}"
+          open_guard close_guard
+        )
+        write_test_to_file()
+      endforeach()
+    endforeach()
+  endif()
+endmacro()
+
 function(gtest_discover_tests_impl)
 
   set(options "")
   set(oneValueArgs
     NO_PRETTY_TYPES   # These two take a value, unlike gtest_discover_tests()
     NO_PRETTY_VALUES  #
+    TEST_TARGET
     TEST_EXECUTABLE
     TEST_WORKING_DIR
     TEST_PREFIX
@@ -74,19 +308,15 @@
   set(prefix "${arg_TEST_PREFIX}")
   set(suffix "${arg_TEST_SUFFIX}")
   set(script)
-  set(suite)
   set(tests)
   set(tests_buffer "")
 
   # If a file at ${arg_CTEST_FILE} already exists, we overwrite it.
-  # For performance reasons, we write to this file in chunks, and this variable
-  # is updated to APPEND after the first write.
-  set(file_write_mode WRITE)
+  file(REMOVE "${arg_CTEST_FILE}")
 
+  set(filter)
   if(arg_TEST_FILTER)
     set(filter "--gtest_filter=${arg_TEST_FILTER}")
-  else()
-    set(filter)
   endif()
 
   # CMP0178 has already been handled in gtest_discover_tests(), so we only need
@@ -113,15 +343,35 @@
     set(discovery_extra_args "[==[${discovery_extra_args}]==]")
   endif()
 
+  # Avoid a potential race condition for the POST_BUILD case when multiple
+  # calls are made to gtest_discover_tests() for different targets but the same
+  # working directory. For PRE_TEST, we're always executing serially during the
+  # ctest setup phase, so there is no race condition there, but POST_BUILD can
+  # lead to this code path being run in parallel. Use a hash to avoid potential
+  # problems with very long target names.
+  string(SHA256 target_hash "${arg_TEST_TARGET}")
+  string(SUBSTRING "${target_hash}" 0 10 target_hash)
+  set(json_file
+    "${arg_TEST_WORKING_DIR}/cmake_test_discovery_${target_hash}.json"
+  )
+
+  # Remove json file to make sure we don't pick up an outdated one
+  file(REMOVE "${json_file}")
+
   cmake_language(EVAL CODE
     "execute_process(
-      COMMAND ${launcherArgs} [==[${arg_TEST_EXECUTABLE}]==] --gtest_list_tests ${filter} ${discovery_extra_args}
+      COMMAND ${launcherArgs} [==[${arg_TEST_EXECUTABLE}]==]
+        --gtest_list_tests
+        [==[--gtest_output=json:${json_file}]==]
+        ${filter}
+        ${discovery_extra_args}
       WORKING_DIRECTORY [==[${arg_TEST_WORKING_DIR}]==]
       TIMEOUT ${arg_TEST_DISCOVERY_TIMEOUT}
       OUTPUT_VARIABLE output
       RESULT_VARIABLE result
     )"
   )
+
   if(NOT ${result} EQUAL 0)
     string(REPLACE "\n" "\n    " output "${output}")
     if(arg_TEST_EXECUTOR)
@@ -139,124 +389,21 @@
     )
   endif()
 
-  generate_testname_guards("${output}" open_guard close_guard)
-  escape_square_brackets("${output}" "[" "__osb" open_sb output)
-  escape_square_brackets("${output}" "]" "__csb" close_sb output)
-  # Preserve semicolon in test-parameters
-  string(REPLACE [[;]] [[\;]] output "${output}")
-  string(REPLACE "\n" ";" output "${output}")
+  if(EXISTS "${json_file}")
+    parse_tests_from_json("${json_file}")
+  else()
+    # gtest < 1.8.1, and all gtest compiled with GTEST_HAS_FILE_SYSTEM=0, don't
+    # recognize the --gtest_output=json option, and issue a warning or error on
+    # stdout about it being unrecognized, but still return an exit code 0 for
+    # success. All versions report the test list on stdout whether
+    # --gtest_output=json is recognized or not.
 
-  # Parse output
-  foreach(line ${output})
-    # Skip header
-    if(NOT line MATCHES "gtest_main\\.cc")
-      # Do we have a module name or a test name?
-      if(NOT line MATCHES "^  ")
-        # Module; remove trailing '.' to get just the name...
-        string(REGEX REPLACE "\\.( *#.*)?$" "" suite "${line}")
-        if(line MATCHES "#")
-          string(REGEX REPLACE "/[0-9].*" "" pretty_suite "${line}")
-          if(NOT arg_NO_PRETTY_TYPES)
-            string(REGEX REPLACE ".*/[0-9]+[ .#]+TypeParam = (.*)" "\\1" type_parameter "${line}")
-          else()
-            string(REGEX REPLACE ".*/([0-9]+)[ .#]+TypeParam = .*" "\\1" type_parameter "${line}")
-          endif()
-          set(test_name_template "@prefix@@pretty_suite@.@pretty_test@<@type_parameter@>@suffix@")
-        else()
-          set(pretty_suite "${suite}")
-          set(test_name_template "@prefix@@pretty_suite@.@pretty_test@@suffix@")
-        endif()
-        string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
-      else()
-        string(STRIP "${line}" test)
-        if(test MATCHES "#" AND NOT arg_NO_PRETTY_VALUES)
-          string(REGEX REPLACE "/[0-9]+[ #]+GetParam\\(\\) = " "/" pretty_test "${test}")
-        else()
-          string(REGEX REPLACE " +#.*" "" pretty_test "${test}")
-        endif()
-        string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
-        string(REGEX REPLACE " +#.*" "" test "${test}")
-        if(NOT "${arg_TEST_XML_OUTPUT_DIR}" STREQUAL "")
-          set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${arg_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
-        else()
-          unset(TEST_XML_OUTPUT_PARAM)
-        endif()
-
-        string(CONFIGURE "${test_name_template}" testname)
-        # unescape []
-        if(open_sb)
-          string(REPLACE "${open_sb}" "[" testname "${testname}")
-        endif()
-        if(close_sb)
-          string(REPLACE "${close_sb}" "]" testname "${testname}")
-        endif()
-        set(guarded_testname "${open_guard}${testname}${close_guard}")
-
-        # Add to script. Do not use add_command() here because it messes up the
-        # handling of empty values when forwarding arguments, and we need to
-        # preserve those carefully for arg_TEST_EXECUTOR and arg_EXTRA_ARGS.
-        string(APPEND script "add_test(${guarded_testname} ${launcherArgs}")
-        foreach(arg IN ITEMS
-          "${arg_TEST_EXECUTABLE}"
-          "--gtest_filter=${suite}.${test}"
-          "--gtest_also_run_disabled_tests"
-          ${TEST_XML_OUTPUT_PARAM}
-          )
-          if(arg MATCHES "[^-./:a-zA-Z0-9_]")
-            string(APPEND script " [==[${arg}]==]")
-          else()
-            string(APPEND script " ${arg}")
-          endif()
-        endforeach()
-        if(arg_TEST_EXTRA_ARGS)
-          list(JOIN arg_TEST_EXTRA_ARGS "]==] [==[" extra_args)
-          string(APPEND script " [==[${extra_args}]==]")
-        endif()
-        string(APPEND script ")\n")
-
-        set(maybe_disabled "")
-        if(suite MATCHES "^DISABLED_" OR test MATCHES "^DISABLED_")
-          set(maybe_disabled DISABLED TRUE)
-        endif()
-
-        add_command(set_tests_properties
-          "${guarded_testname}"
-          PROPERTIES
-          ${maybe_disabled}
-          WORKING_DIRECTORY "${arg_TEST_WORKING_DIR}"
-          SKIP_REGULAR_EXPRESSION "\\[  SKIPPED \\]"
-          ${arg_TEST_PROPERTIES}
-        )
-
-        # possibly unbalanced square brackets render lists invalid so skip such
-        # tests in ${arg_TEST_LIST}
-        if(NOT "${testname}" MATCHES [=[(\[|\])]=])
-          # escape ;
-          string(REPLACE [[;]] [[\\;]] testname "${testname}")
-          list(APPEND tests_buffer "${testname}")
-          list(LENGTH tests_buffer tests_buffer_length)
-          if(tests_buffer_length GREATER "250")
-            # Chunk updates to the final "tests" variable, keeping the
-            # "tests_buffer" variable that we append each test to relatively
-            # small. This mitigates worsening performance impacts for the
-            # corner case of having many thousands of tests.
-            list(APPEND tests "${tests_buffer}")
-            set(tests_buffer "")
-          endif()
-        endif()
-      endif()
-
-      # If we've built up a sizable script so far, write it out as a chunk now
-      # so we don't accumulate a massive string to write at the end
-      string(LENGTH "${script}" script_len)
-      if(${script_len} GREATER "50000")
-        file(${file_write_mode} "${arg_CTEST_FILE}" "${script}")
-        set(file_write_mode APPEND)
-        set(script "")
-      endif()
-
-    endif()
-  endforeach()
+    # NOTE: Because we are calling a macro, we don't want to pass "output" as
+    # an argument because it messes up the contents passed through due to the
+    # different escaping, etc. that gets applied. We rely on it picking up the
+    # "output" variable we have already set here.
+    parse_tests_from_output()
+  endif()
 
   if(NOT tests_buffer STREQUAL "")
     list(APPEND tests "${tests_buffer}")
@@ -267,14 +414,14 @@
   add_command(set "" ${arg_TEST_LIST} "${tests}")
 
   # Write remaining content to the CTest script
-  file(${file_write_mode} "${arg_CTEST_FILE}" "${script}")
-
+  file(APPEND "${arg_CTEST_FILE}" "${script}")
 endfunction()
 
 if(CMAKE_SCRIPT_MODE_FILE)
   gtest_discover_tests_impl(
     NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
     NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
+    TEST_TARGET ${TEST_TARGET}
     TEST_EXECUTABLE ${TEST_EXECUTABLE}
     TEST_EXECUTOR "${TEST_EXECUTOR}"
     TEST_WORKING_DIR ${TEST_WORKING_DIR}
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 4d7aff3..8f1543b 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -5,9 +5,17 @@
 InstallRequiredSystemLibraries
 ------------------------------
 
-Include this module to search for compiler-provided system runtime
-libraries and add install rules for them.  Some optional variables
-may be set prior to including the module to adjust behavior:
+This module searches for compiler-provided system runtime libraries and adds
+installation rules for them.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(InstallRequiredSystemLibraries)
+
+Some optional variables may be set prior to including this module to adjust
+behavior:
 
 ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS``
   Specify additional runtime libraries that may not be detected.
@@ -239,8 +247,12 @@
   set(_MSVC_IDE_VERSION "")
   if(MSVC_VERSION GREATER_EQUAL 2000)
     message(WARNING "MSVC ${MSVC_VERSION} not yet supported.")
-  elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 144)
+  elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 146)
     message(WARNING "MSVC toolset v${MSVC_TOOLSET_VERSION} not yet supported.")
+  elseif(MSVC_TOOLSET_VERSION EQUAL 145)
+    set(MSVC_REDIST_NAME VC145)
+    set(_MSVC_DLL_VERSION 140)
+    set(_MSVC_IDE_VERSION 18)
   elseif(MSVC_TOOLSET_VERSION EQUAL 143)
     set(MSVC_REDIST_NAME VC143)
     set(_MSVC_DLL_VERSION 140)
@@ -285,7 +297,7 @@
     if(NOT vs VERSION_LESS 15)
       set(_vs_redist_paths "")
       # The toolset and its redistributables may come with any VS version 15 or newer.
-      set(_MSVC_IDE_VERSIONS 17 16 15)
+      set(_MSVC_IDE_VERSIONS 18 17 16 15)
       foreach(_vs_ver ${_MSVC_IDE_VERSIONS})
         set(_vs_glob_redist_paths "")
         cmake_host_system_information(RESULT _vs_dir QUERY VS_${_vs_ver}_DIR) # undocumented query
diff --git a/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake b/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake
index 57dd7e3..3f4d15a 100644
--- a/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake
+++ b/Modules/Internal/CMakeCUDAArchitecturesValidate.cmake
@@ -5,6 +5,11 @@
   if(DEFINED CMAKE_${lang}_ARCHITECTURES)
     if(CMAKE_${lang}_ARCHITECTURES STREQUAL "")
       message(FATAL_ERROR "CMAKE_${lang}_ARCHITECTURES must be non-empty if set.")
+    elseif(CMAKE_${lang}_ARCHITECTURES MATCHES [["]])
+      message(FATAL_ERROR
+        "CMAKE_${lang}_ARCHITECTURES contains literal quotes:\n"
+        "  ${CMAKE_${lang}_ARCHITECTURES}\n"
+      )
     elseif(CMAKE_${lang}_ARCHITECTURES AND NOT CMAKE_${lang}_ARCHITECTURES MATCHES "^([0-9]+(a|f)?(-real|-virtual)?(;[0-9]+(a|f)?(-real|-virtual)?|;)*|all|all-major|native)$")
       message(FATAL_ERROR
         "CMAKE_${lang}_ARCHITECTURES:\n"
diff --git a/Modules/Internal/CMakeDetermineLinkerId.cmake b/Modules/Internal/CMakeDetermineLinkerId.cmake
index 2b17036..df2ddbe 100644
--- a/Modules/Internal/CMakeDetermineLinkerId.cmake
+++ b/Modules/Internal/CMakeDetermineLinkerId.cmake
@@ -29,7 +29,9 @@
                     OUTPUT_VARIABLE linker_desc
                     ERROR_VARIABLE linker_desc
                     OUTPUT_STRIP_TRAILING_WHITESPACE
-                    ERROR_STRIP_TRAILING_WHITESPACE)
+                    ERROR_STRIP_TRAILING_WHITESPACE
+                    COMMAND_ERROR_IS_FATAL NONE
+    )
 
     string(JOIN "\" \"" flags_string ${flags})
     string(REGEX REPLACE "\n\n.*" "" linker_desc_head "${linker_desc}")
diff --git a/Modules/Internal/CMakeParseCompilerArchitectureId.cmake b/Modules/Internal/CMakeParseCompilerArchitectureId.cmake
index 9200158..2f3b9b9 100644
--- a/Modules/Internal/CMakeParseCompilerArchitectureId.cmake
+++ b/Modules/Internal/CMakeParseCompilerArchitectureId.cmake
@@ -47,6 +47,8 @@
     set(ARCHITECTURE_ID "riscv64")
   elseif(_dumpmachine_triple MATCHES "^riscv32-")
     set(ARCHITECTURE_ID "riscv32")
+  elseif(_dumpmachine_triple MATCHES "^sunway-")
+    set(ARCHITECTURE_ID "sw_64")
   elseif(_dumpmachine_triple MATCHES "^s390x-")
     set(ARCHITECTURE_ID "s390x")
   elseif(_dumpmachine_triple MATCHES "^s390-")
@@ -67,6 +69,10 @@
     set(ARCHITECTURE_ID "ppcle")
   elseif(_dumpmachine_triple MATCHES "^(powerpc|ppc)-")
     set(ARCHITECTURE_ID "ppc")
+  elseif(_dumpmachine_triple MATCHES "^wasm64-")
+    set(ARCHITECTURE_ID "wasm64")
+  elseif(_dumpmachine_triple MATCHES "^wasm32-")
+    set(ARCHITECTURE_ID "wasm32")
   else()
     set(ARCHITECTURE_ID "")
   endif()
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index b733cfe..d0454e1 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -445,13 +445,13 @@
 endfunction()
 
 function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS)
-  list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN)
+  list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUNT)
   list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT)
 
   list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}")
   list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO)
 
-  if(SYMLINK_PATHS_COUTN)
+  if(SYMLINK_PATHS_COUNT)
     foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS)
       list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX)
 
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index c0b61e3..cba71bf 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -43,6 +43,7 @@
 @CPACK_NSIS_DEFINES@
 @CPACK_NSIS_MANIFEST_DPI_AWARE_CODE@
 @CPACK_NSIS_BRANDING_TEXT_CODE@
+@CPACK_NSIS_CRC_CHECK_CODE@
 
   !include Sections.nsh
 
diff --git a/Modules/Internal/CPack/WIX-v3/WIX.template.in b/Modules/Internal/CPack/WIX-v3/WIX.template.in
index 71ec5b2..b32c1ee 100644
--- a/Modules/Internal/CPack/WIX-v3/WIX.template.in
+++ b/Modules/Internal/CPack/WIX-v3/WIX.template.in
@@ -19,7 +19,9 @@
         <Package InstallerVersion="301" Compressed="yes" InstallScope="$(var.CPACK_WIX_INSTALL_SCOPE)"/>
         <?endif?>
 
+        <?ifndef CPACK_WIX_CAB_PER_COMPONENT?>
         <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+        <?endif?>
 
         <MajorUpgrade
             Schedule="afterInstallInitialize"
diff --git a/Modules/Internal/CPack/WIX.template.in b/Modules/Internal/CPack/WIX.template.in
index 7cad186..839be36 100644
--- a/Modules/Internal/CPack/WIX.template.in
+++ b/Modules/Internal/CPack/WIX.template.in
@@ -19,7 +19,9 @@
         Compressed="yes"
         >
 
+        <?ifndef CPACK_WIX_CAB_PER_COMPONENT?>
         <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+        <?endif?>
 
         <MajorUpgrade
             Schedule="afterInstallInitialize"
diff --git a/Modules/Internal/CheckFlagCommonConfig.cmake b/Modules/Internal/CheckFlagCommonConfig.cmake
index 3403c1d..a5459d1 100644
--- a/Modules/Internal/CheckFlagCommonConfig.cmake
+++ b/Modules/Internal/CheckFlagCommonConfig.cmake
@@ -11,39 +11,53 @@
 macro(CMAKE_CHECK_FLAG_COMMON_INIT _FUNC _LANG _SRC _PATTERNS)
   if("${_LANG}" STREQUAL "C")
     set(${_SRC} "int main(void) { return 0; }")
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C"
-      FAIL_REGEX "-Werror=.* argument .* is not valid for C")
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for C"
+      FAIL_REGEX "-Werror=[^\n]* argument [^\n]* is not valid for C"
+    )
   elseif("${_LANG}" STREQUAL "CXX")
     set(${_SRC} "int main() { return 0; }")
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+"
-      FAIL_REGEX "-Werror=.* argument .* is not valid for C\\+\\+")
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for C\\+\\+"
+      FAIL_REGEX "-Werror=[^\n]* argument [^\n]* is not valid for C\\+\\+"
+    )
   elseif("${_LANG}" STREQUAL "CUDA")
     set(${_SRC} "__host__ int main() { return 0; }")
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU
-      FAIL_REGEX "argument unused during compilation: .*") # Clang
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for C\\+\\+" # Host GNU
+      FAIL_REGEX "argument unused during compilation: [^\n]*" # Clang
+    )
   elseif("${_LANG}" STREQUAL "Fortran")
     set(${_SRC} "       program test\n       stop\n       end program")
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran"
-      FAIL_REGEX "argument unused during compilation: .*") # LLVMFlang
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for Fortran"
+      FAIL_REGEX "argument unused during compilation: [^\n]*" # LLVMFlang
+    )
   elseif("${_LANG}" STREQUAL "HIP")
     set(${_SRC} "__host__ int main() { return 0; }")
-    set(${_PATTERNS} FAIL_REGEX "argument unused during compilation: .*") # Clang
+    set(${_PATTERNS}
+      FAIL_REGEX "argument unused during compilation: [^\n]*" # Clang
+    )
   elseif("${_LANG}" STREQUAL "OBJC")
     set(${_SRC} [=[
       #ifndef __OBJC__
       #  error "Not an Objective-C compiler"
       #endif
       int main(void) { return 0; }]=])
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU
-      FAIL_REGEX "argument unused during compilation: .*") # Clang
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for Objective-C" # GNU
+      FAIL_REGEX "argument unused during compilation: [^\n]*" # Clang
+    )
   elseif("${_LANG}" STREQUAL "OBJCXX")
     set(${_SRC} [=[
       #ifndef __OBJC__
       #  error "Not an Objective-C++ compiler"
       #endif
       int main(void) { return 0; }]=])
-    set(${_PATTERNS} FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU
-      FAIL_REGEX "argument unused during compilation: .*") # Clang
+    set(${_PATTERNS}
+      FAIL_REGEX "command[ -]line option [^\n]* is valid for [^\n]* but not for Objective-C\\+\\+" # GNU
+      FAIL_REGEX "argument unused during compilation: [^\n]*" # Clang
+    )
   elseif("${_LANG}" STREQUAL "ISPC")
     set(${_SRC} "float func(uniform int32, float a) { return a / 2.25; }")
   elseif("${_LANG}" STREQUAL "Swift")
diff --git a/Modules/Internal/CheckLinkerFlag.cmake b/Modules/Internal/CheckLinkerFlag.cmake
index 64fdff8..461c765 100644
--- a/Modules/Internal/CheckLinkerFlag.cmake
+++ b/Modules/Internal/CheckLinkerFlag.cmake
@@ -27,7 +27,7 @@
   foreach(flag IN LISTS _flag)
     string(REGEX REPLACE "([][+.*?()^$])" [[\\\1]] _flag_regex "${flag}")
     list(APPEND _common_patterns
-      FAIL_REGEX "warning: .*${_flag_regex}.* ignored"
+      FAIL_REGEX "warning: [^\n]*${_flag_regex}[^\n]* ignored"
       )
   endforeach()
 
diff --git a/Modules/Linker/GNU.cmake b/Modules/Linker/GNU.cmake
index 2ac5ea6..b56608e 100644
--- a/Modules/Linker/GNU.cmake
+++ b/Modules/Linker/GNU.cmake
@@ -35,7 +35,7 @@
 
     if (NOT DEFINED CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED)
       ## check if this feature is supported by the linker
-      if (CMAKE_${lang}_COMPILER_LINKER AND CMAKE_${lang}_COMPILER_LINKER_ID MATCHES "GNU|LLD")
+      if (CMAKE_${lang}_COMPILER_LINKER AND CMAKE_${lang}_COMPILER_LINKER_ID MATCHES "GNU|LLD|MOLD")
         execute_process(COMMAND "${CMAKE_${lang}_COMPILER_LINKER}" --help
                         OUTPUT_VARIABLE _linker_capabilities
                         ERROR_VARIABLE _linker_capabilities)
diff --git a/Modules/MacroAddFileDependencies.cmake b/Modules/MacroAddFileDependencies.cmake
index 9dee09d..0c65c46 100644
--- a/Modules/MacroAddFileDependencies.cmake
+++ b/Modules/MacroAddFileDependencies.cmake
@@ -6,24 +6,38 @@
 ------------------------
 
 .. deprecated:: 3.14
+  Do not use this module in new code.
+
+  Instead use the :command:`set_property` command to append to the
+  :prop_sf:`OBJECT_DEPENDS` source file property directly:
+
+  .. code-block:: cmake
+
+    set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
+
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
-  macro_add_file_dependencies(<source> <files>...)
+  include(MacroAddFileDependencies)
 
-Do not use this command in new code.  It is just a wrapper around:
+Commands
+^^^^^^^^
 
-.. code-block:: cmake
+This module provides the following command:
 
-  set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)
+.. command:: macro_add_file_dependencies
 
-Instead use the :command:`set_property` command to append to the
-:prop_sf:`OBJECT_DEPENDS` source file property directly.
+  Adds dependencies to a source file:
 
+  .. code-block:: cmake
+
+    macro_add_file_dependencies(<source> <files>...)
+
+  This command adds the given ``<files>`` to the dependencies of file
+  ``<source>``.
 #]=======================================================================]
 
-macro (MACRO_ADD_FILE_DEPENDENCIES _file)
-
+macro(MACRO_ADD_FILE_DEPENDENCIES _file)
   set_property(SOURCE "${_file}" APPEND PROPERTY OBJECT_DEPENDS "${ARGN}")
-
-endmacro ()
+endmacro()
diff --git a/Modules/Platform/AIX.cmake b/Modules/Platform/AIX.cmake
index dcc9837..a8561a0 100644
--- a/Modules/Platform/AIX.cmake
+++ b/Modules/Platform/AIX.cmake
@@ -3,7 +3,7 @@
 set(CMAKE_SHARED_LIBRARY_ARCHIVE_SUFFIX ".a")   # .a
 set(CMAKE_AIX_IMPORT_FILE_PREFIX "")
 set(CMAKE_AIX_IMPORT_FILE_SUFFIX ".imp")
-set(CMAKE_DL_LIBS "-lld")
+set(CMAKE_DL_LIBS "ld")
 
 # RPATH support on AIX is called libpath.  By default the runtime
 # libpath is paths specified by -L followed by /usr/lib and /lib.  In
diff --git a/Modules/Platform/AIX/ExportImportList b/Modules/Platform/AIX/ExportImportList
index 67c53eb..064024b 100755
--- a/Modules/Platform/AIX/ExportImportList
+++ b/Modules/Platform/AIX/ExportImportList
@@ -23,6 +23,7 @@
     -n) no_objects='1' ;;
     -c) shift; compiler="$1" ;;
     --) shift; break ;;
+    --target=*) ;;
     -*) die "$usage" ;;
     *)  break ;;
     esac
diff --git a/Modules/Platform/Android-Determine-C.cmake b/Modules/Platform/Android-Determine-C.cmake
index c7d1d15..1d93cd7 100644
--- a/Modules/Platform/Android-Determine-C.cmake
+++ b/Modules/Platform/Android-Determine-C.cmake
@@ -1,2 +1,5 @@
+if(CMAKE_C_COMPILER)
+  return()
+endif()
 include(Platform/Android/Determine-Compiler)
 __android_determine_compiler(C)
diff --git a/Modules/Platform/Android-Determine-CXX.cmake b/Modules/Platform/Android-Determine-CXX.cmake
index 3a3de88..e7d96be 100644
--- a/Modules/Platform/Android-Determine-CXX.cmake
+++ b/Modules/Platform/Android-Determine-CXX.cmake
@@ -1,2 +1,5 @@
+if(CMAKE_CXX_COMPILER)
+  return()
+endif()
 include(Platform/Android/Determine-Compiler)
 __android_determine_compiler(CXX)
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index b7981d9..bd0b301 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -53,7 +53,7 @@
     set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
     if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
       set(vcx_revision "2.0")
-    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
+    elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[5678]")
       set(vcx_revision "3.0")
     else()
       set(vcx_revision "")
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 0c0a206..d518ac9 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -183,7 +183,7 @@
     return() # Only apply to multi-arch
   endif()
 
-  if(NOT CMAKE_OSX_SYSROOT OR CMAKE_OSX_SYSROOT STREQUAL "macosx")
+  if(NOT CMAKE_OSX_SYSROOT OR CMAKE_OSX_SYSROOT MATCHES "(^|/)[Mm][Aa][Cc][Oo][Ss][Xx]")
     # macOS doesn't have a simulator sdk / sysroot, so there is no need to handle per-sdk arches.
     return()
   endif()
diff --git a/Modules/Platform/Emscripten-Clang-C.cmake b/Modules/Platform/Emscripten-Clang-C.cmake
new file mode 100644
index 0000000..1b6b2ab
--- /dev/null
+++ b/Modules/Platform/Emscripten-Clang-C.cmake
@@ -0,0 +1,3 @@
+include(Platform/Emscripten-Clang)
+
+__emscripten_clang(C)
diff --git a/Modules/Platform/Emscripten-Clang-CXX.cmake b/Modules/Platform/Emscripten-Clang-CXX.cmake
new file mode 100644
index 0000000..32b913e
--- /dev/null
+++ b/Modules/Platform/Emscripten-Clang-CXX.cmake
@@ -0,0 +1,3 @@
+include(Platform/Emscripten-Clang)
+
+__emscripten_clang(CXX)
diff --git a/Modules/Platform/Emscripten-Clang.cmake b/Modules/Platform/Emscripten-Clang.cmake
new file mode 100644
index 0000000..8d321f5
--- /dev/null
+++ b/Modules/Platform/Emscripten-Clang.cmake
@@ -0,0 +1,19 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+include_guard()
+
+macro(__emscripten_clang lang)
+  set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,")
+
+  # FIXME(#27240): We do not add -sMAIN_MODULE to CMAKE_${lang}_LINK_EXECUTABLE
+  # because it is not always needed, and can break things if added unnecessarily.
+  # We also do not add -sMAIN_MODULE to CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS
+  # to preserve legacy behavior in which projects added it as needed.
+  # In the future we may add both flags with suitable controls.
+  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "")
+
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+  set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
+endmacro()
diff --git a/Modules/Platform/Emscripten-Determine-C.cmake b/Modules/Platform/Emscripten-Determine-C.cmake
new file mode 100644
index 0000000..91e9235
--- /dev/null
+++ b/Modules/Platform/Emscripten-Determine-C.cmake
@@ -0,0 +1,3 @@
+if(NOT CMAKE_C_COMPILER_NAMES)
+  set(CMAKE_C_COMPILER_NAMES emcc)
+endif()
diff --git a/Modules/Platform/Emscripten-Determine-CXX.cmake b/Modules/Platform/Emscripten-Determine-CXX.cmake
new file mode 100644
index 0000000..9374d57
--- /dev/null
+++ b/Modules/Platform/Emscripten-Determine-CXX.cmake
@@ -0,0 +1,3 @@
+if(NOT CMAKE_CXX_COMPILER_NAMES)
+  set(CMAKE_CXX_COMPILER_NAMES em++)
+endif()
diff --git a/Modules/Platform/Emscripten-Initialize.cmake b/Modules/Platform/Emscripten-Initialize.cmake
new file mode 100644
index 0000000..3117e05
--- /dev/null
+++ b/Modules/Platform/Emscripten-Initialize.cmake
@@ -0,0 +1,2 @@
+set(EMSCRIPTEN 1)
+set(UNIX 1)
diff --git a/Modules/Platform/Emscripten.cmake b/Modules/Platform/Emscripten.cmake
new file mode 100644
index 0000000..2db51a4
--- /dev/null
+++ b/Modules/Platform/Emscripten.cmake
@@ -0,0 +1,21 @@
+# Emscripten provides a combined toolchain file and platform module
+# that predates CMake upstream support.  As a toolchain file it sets
+# CMAKE_SYSTEM_VERSION to 1 and points CMAKE_MODULE_PATH to itself.
+# Include it here to preserve its role as a platform module.
+if(CMAKE_SYSTEM_VERSION EQUAL 1 AND CMAKE_MODULE_PATH)
+  find_file(_EMSCRIPTEN_PLATFORM_MODULE NAMES "Platform/Emscripten.cmake"
+    NO_CACHE NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH PATHS ${CMAKE_MODULE_PATH})
+  if(_EMSCRIPTEN_PLATFORM_MODULE)
+    include("${_EMSCRIPTEN_PLATFORM_MODULE}")
+    unset(_EMSCRIPTEN_PLATFORM_MODULE)
+    return()
+  endif()
+  unset(_EMSCRIPTEN_PLATFORM_MODULE)
+endif()
+
+set(CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH ON)
+
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".wasm")
+set(CMAKE_EXECUTABLE_SUFFIX ".js")
+
+set(CMAKE_DL_LIBS "")
diff --git a/Modules/Platform/FreeBSD-Clang-ASM.cmake b/Modules/Platform/FreeBSD-Clang-ASM.cmake
new file mode 100644
index 0000000..d9557d6
--- /dev/null
+++ b/Modules/Platform/FreeBSD-Clang-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/FreeBSD-GNU-ASM)
diff --git a/Modules/Platform/FreeBSD-Clang-C.cmake b/Modules/Platform/FreeBSD-Clang-C.cmake
new file mode 100644
index 0000000..bf7349b
--- /dev/null
+++ b/Modules/Platform/FreeBSD-Clang-C.cmake
@@ -0,0 +1 @@
+include(Platform/FreeBSD-GNU-C)
diff --git a/Modules/Platform/FreeBSD-Clang-CXX.cmake b/Modules/Platform/FreeBSD-Clang-CXX.cmake
new file mode 100644
index 0000000..ceed6b6
--- /dev/null
+++ b/Modules/Platform/FreeBSD-Clang-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/FreeBSD-GNU-CXX)
diff --git a/Modules/Platform/FreeBSD-GNU-ASM.cmake b/Modules/Platform/FreeBSD-GNU-ASM.cmake
new file mode 100644
index 0000000..8da5100
--- /dev/null
+++ b/Modules/Platform/FreeBSD-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/FreeBSD-GNU)
+__freebsd_compiler_gnu(ASM)
diff --git a/Modules/Platform/FreeBSD-GNU-C.cmake b/Modules/Platform/FreeBSD-GNU-C.cmake
new file mode 100644
index 0000000..f19c60b
--- /dev/null
+++ b/Modules/Platform/FreeBSD-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/FreeBSD-GNU)
+__freebsd_compiler_gnu(C)
diff --git a/Modules/Platform/FreeBSD-GNU-CXX.cmake b/Modules/Platform/FreeBSD-GNU-CXX.cmake
new file mode 100644
index 0000000..9589dad
--- /dev/null
+++ b/Modules/Platform/FreeBSD-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/FreeBSD-GNU)
+__freebsd_compiler_gnu(CXX)
diff --git a/Modules/Platform/FreeBSD-GNU-Fortran.cmake b/Modules/Platform/FreeBSD-GNU-Fortran.cmake
new file mode 100644
index 0000000..d37a355
--- /dev/null
+++ b/Modules/Platform/FreeBSD-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/FreeBSD-GNU)
+__freebsd_compiler_gnu(Fortran)
diff --git a/Modules/Platform/FreeBSD-GNU.cmake b/Modules/Platform/FreeBSD-GNU.cmake
new file mode 100644
index 0000000..36ba126
--- /dev/null
+++ b/Modules/Platform/FreeBSD-GNU.cmake
@@ -0,0 +1,16 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+include_guard()
+
+macro(__freebsd_compiler_gnu lang)
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
+  set(CMAKE_${lang}_USING_LINKER_BFD "-fuse-ld=bfd")
+  set(CMAKE_${lang}_USING_LINKER_GOLD "-fuse-ld=gold")
+  if(NOT CMAKE_${lang}_COMPILER_ID STREQUAL "GNU"
+      OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1")
+    set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
+  endif()
+endmacro()
diff --git a/Modules/Platform/Linker/Emscripten-C.cmake b/Modules/Platform/Linker/Emscripten-C.cmake
new file mode 100644
index 0000000..481f950
--- /dev/null
+++ b/Modules/Platform/Linker/Emscripten-C.cmake
@@ -0,0 +1,5 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+# LLD is the default linker
+include(Platform/Linker/Emscripten-LLD-C)
diff --git a/Modules/Platform/Linker/Emscripten-CXX.cmake b/Modules/Platform/Linker/Emscripten-CXX.cmake
new file mode 100644
index 0000000..7d8203e
--- /dev/null
+++ b/Modules/Platform/Linker/Emscripten-CXX.cmake
@@ -0,0 +1,5 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+# LLD is the default linker
+include(Platform/Linker/Emscripten-LLD-CXX)
diff --git a/Modules/Platform/Linker/Emscripten-LLD-C.cmake b/Modules/Platform/Linker/Emscripten-LLD-C.cmake
new file mode 100644
index 0000000..448d7cc
--- /dev/null
+++ b/Modules/Platform/Linker/Emscripten-LLD-C.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+include(Platform/Linker/Emscripten-LLD)
+
+__emscripten_linker_lld(C)
diff --git a/Modules/Platform/Linker/Emscripten-LLD-CXX.cmake b/Modules/Platform/Linker/Emscripten-LLD-CXX.cmake
new file mode 100644
index 0000000..63d71b4
--- /dev/null
+++ b/Modules/Platform/Linker/Emscripten-LLD-CXX.cmake
@@ -0,0 +1,6 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+include(Platform/Linker/Emscripten-LLD)
+
+__emscripten_linker_lld(CXX)
diff --git a/Modules/Platform/Linker/Emscripten-LLD.cmake b/Modules/Platform/Linker/Emscripten-LLD.cmake
new file mode 100644
index 0000000..2073237
--- /dev/null
+++ b/Modules/Platform/Linker/Emscripten-LLD.cmake
@@ -0,0 +1,14 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+macro(__emscripten_linker_lld lang)
+  set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE "-Wl,--whole-archive" "<LINK_ITEM>" "-Wl,--no-whole-archive")
+  set(CMAKE_${lang}_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
+  set(CMAKE_${lang}_LINK_LIBRARY_WHOLE_ARCHIVE_ATTRIBUTES LIBRARY_TYPE=STATIC DEDUPLICATION=YES OVERRIDE=DEFAULT)
+
+  set(CMAKE_${lang}_PLATFORM_LINKER_ID LLD)
+  set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE DEDUPLICATION=ALL)
+endmacro()
diff --git a/Modules/Platform/Linker/GNU.cmake b/Modules/Platform/Linker/GNU.cmake
index 979aa98..3e665fa 100644
--- a/Modules/Platform/Linker/GNU.cmake
+++ b/Modules/Platform/Linker/GNU.cmake
@@ -21,7 +21,9 @@
     # launch linker to check if push_state/pop_state options are supported
     execute_process(COMMAND "${__linker}" --push-state --pop-state
                     OUTPUT_VARIABLE __linker_log
-                    ERROR_VARIABLE __linker_log)
+                    ERROR_VARIABLE __linker_log
+                    COMMAND_ERROR_IS_FATAL NONE
+    )
     if(__linker_log MATCHES "--push-state" OR __linker_log MATCHES "--pop-state")
       set(CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED FALSE)
     else()
diff --git a/Modules/Platform/MirBSD-GNU-ASM.cmake b/Modules/Platform/MirBSD-GNU-ASM.cmake
new file mode 100644
index 0000000..812fc96
--- /dev/null
+++ b/Modules/Platform/MirBSD-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/MirBSD-GNU)
+__mirbsd_compiler_gnu(ASM)
diff --git a/Modules/Platform/MirBSD-GNU-C.cmake b/Modules/Platform/MirBSD-GNU-C.cmake
new file mode 100644
index 0000000..c1c66d7
--- /dev/null
+++ b/Modules/Platform/MirBSD-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/MirBSD-GNU)
+__mirbsd_compiler_gnu(C)
diff --git a/Modules/Platform/MirBSD-GNU-CXX.cmake b/Modules/Platform/MirBSD-GNU-CXX.cmake
new file mode 100644
index 0000000..bf02157
--- /dev/null
+++ b/Modules/Platform/MirBSD-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/MirBSD-GNU)
+__mirbsd_compiler_gnu(CXX)
diff --git a/Modules/Platform/MirBSD-GNU-Fortran.cmake b/Modules/Platform/MirBSD-GNU-Fortran.cmake
new file mode 100644
index 0000000..52ba2cb
--- /dev/null
+++ b/Modules/Platform/MirBSD-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/MirBSD-GNU)
+__mirbsd_compiler_gnu(Fortran)
diff --git a/Modules/Platform/MirBSD-GNU.cmake b/Modules/Platform/MirBSD-GNU.cmake
new file mode 100644
index 0000000..9025c36
--- /dev/null
+++ b/Modules/Platform/MirBSD-GNU.cmake
@@ -0,0 +1,7 @@
+include_guard()
+
+include(Platform/OpenBSD-GNU)
+
+macro(__mirbsd_compiler_gnu lang)
+  __openbsd_compiler_gnu(${lang})
+endmacro()
diff --git a/Modules/Platform/NetBSD-Clang-ASM.cmake b/Modules/Platform/NetBSD-Clang-ASM.cmake
new file mode 100644
index 0000000..b7c7b2d
--- /dev/null
+++ b/Modules/Platform/NetBSD-Clang-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/NetBSD-GNU-ASM)
diff --git a/Modules/Platform/NetBSD-Clang-C.cmake b/Modules/Platform/NetBSD-Clang-C.cmake
new file mode 100644
index 0000000..86b6a01
--- /dev/null
+++ b/Modules/Platform/NetBSD-Clang-C.cmake
@@ -0,0 +1 @@
+include(Platform/NetBSD-GNU-C)
diff --git a/Modules/Platform/NetBSD-Clang-CXX.cmake b/Modules/Platform/NetBSD-Clang-CXX.cmake
new file mode 100644
index 0000000..b1a5d10
--- /dev/null
+++ b/Modules/Platform/NetBSD-Clang-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/NetBSD-GNU-CXX)
diff --git a/Modules/Platform/NetBSD-GNU-ASM.cmake b/Modules/Platform/NetBSD-GNU-ASM.cmake
new file mode 100644
index 0000000..6b7d012
--- /dev/null
+++ b/Modules/Platform/NetBSD-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/NetBSD-GNU)
+__netbsd_compiler_gnu(ASM)
diff --git a/Modules/Platform/NetBSD-GNU-C.cmake b/Modules/Platform/NetBSD-GNU-C.cmake
new file mode 100644
index 0000000..815644a
--- /dev/null
+++ b/Modules/Platform/NetBSD-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/NetBSD-GNU)
+__netbsd_compiler_gnu(C)
diff --git a/Modules/Platform/NetBSD-GNU-CXX.cmake b/Modules/Platform/NetBSD-GNU-CXX.cmake
new file mode 100644
index 0000000..55ad6b0
--- /dev/null
+++ b/Modules/Platform/NetBSD-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/NetBSD-GNU)
+__netbsd_compiler_gnu(CXX)
diff --git a/Modules/Platform/NetBSD-GNU-Fortran.cmake b/Modules/Platform/NetBSD-GNU-Fortran.cmake
new file mode 100644
index 0000000..eb85ecb
--- /dev/null
+++ b/Modules/Platform/NetBSD-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/NetBSD-GNU)
+__netbsd_compiler_gnu(Fortran)
diff --git a/Modules/Platform/NetBSD-GNU.cmake b/Modules/Platform/NetBSD-GNU.cmake
new file mode 100644
index 0000000..37abdeb
--- /dev/null
+++ b/Modules/Platform/NetBSD-GNU.cmake
@@ -0,0 +1,16 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file LICENSE.rst or https://cmake.org/licensing for details.
+
+include_guard()
+
+macro(__netbsd_compiler_gnu lang)
+  # linker selection
+  set(CMAKE_${lang}_USING_LINKER_SYSTEM "")
+  set(CMAKE_${lang}_USING_LINKER_LLD "-fuse-ld=lld")
+  set(CMAKE_${lang}_USING_LINKER_BFD "-fuse-ld=bfd")
+  set(CMAKE_${lang}_USING_LINKER_GOLD "-fuse-ld=gold")
+  if(NOT CMAKE_${lang}_COMPILER_ID STREQUAL "GNU"
+      OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1")
+    set(CMAKE_${lang}_USING_LINKER_MOLD "-fuse-ld=mold")
+  endif()
+endmacro()
diff --git a/Modules/Platform/OpenBSD-Clang-ASM.cmake b/Modules/Platform/OpenBSD-Clang-ASM.cmake
new file mode 100644
index 0000000..500eb68
--- /dev/null
+++ b/Modules/Platform/OpenBSD-Clang-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/OpenBSD-GNU-ASM)
diff --git a/Modules/Platform/OpenBSD-Clang-C.cmake b/Modules/Platform/OpenBSD-Clang-C.cmake
new file mode 100644
index 0000000..86e511a
--- /dev/null
+++ b/Modules/Platform/OpenBSD-Clang-C.cmake
@@ -0,0 +1 @@
+include(Platform/OpenBSD-GNU-C)
diff --git a/Modules/Platform/OpenBSD-Clang-CXX.cmake b/Modules/Platform/OpenBSD-Clang-CXX.cmake
new file mode 100644
index 0000000..3faf012
--- /dev/null
+++ b/Modules/Platform/OpenBSD-Clang-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/OpenBSD-GNU-CXX)
diff --git a/Modules/Platform/OpenBSD-GNU-ASM.cmake b/Modules/Platform/OpenBSD-GNU-ASM.cmake
new file mode 100644
index 0000000..f4eed41
--- /dev/null
+++ b/Modules/Platform/OpenBSD-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/OpenBSD-GNU)
+__openbsd_compiler_gnu(ASM)
diff --git a/Modules/Platform/OpenBSD-GNU-C.cmake b/Modules/Platform/OpenBSD-GNU-C.cmake
new file mode 100644
index 0000000..ab94c4c
--- /dev/null
+++ b/Modules/Platform/OpenBSD-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/OpenBSD-GNU)
+__openbsd_compiler_gnu(C)
diff --git a/Modules/Platform/OpenBSD-GNU-CXX.cmake b/Modules/Platform/OpenBSD-GNU-CXX.cmake
new file mode 100644
index 0000000..5829eb9
--- /dev/null
+++ b/Modules/Platform/OpenBSD-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/OpenBSD-GNU)
+__openbsd_compiler_gnu(CXX)
diff --git a/Modules/Platform/OpenBSD-GNU-Fortran.cmake b/Modules/Platform/OpenBSD-GNU-Fortran.cmake
new file mode 100644
index 0000000..57fe66c
--- /dev/null
+++ b/Modules/Platform/OpenBSD-GNU-Fortran.cmake
@@ -0,0 +1,2 @@
+include(Platform/OpenBSD-GNU)
+__openbsd_compiler_gnu(Fortran)
diff --git a/Modules/Platform/OpenBSD-GNU.cmake b/Modules/Platform/OpenBSD-GNU.cmake
new file mode 100644
index 0000000..be4b1b4
--- /dev/null
+++ b/Modules/Platform/OpenBSD-GNU.cmake
@@ -0,0 +1,7 @@
+include_guard()
+
+include(Platform/NetBSD-GNU)
+
+macro(__openbsd_compiler_gnu lang)
+  __netbsd_compiler_gnu(${lang})
+endmacro()
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 9ca8d6f..82e9d82 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -36,6 +36,8 @@
   set(CMAKE_${lang}_LINK_DEF_FILE_FLAG "-Xlinker /DEF:")
   set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINK_DEF_FILE_FLAG}")
 
+  set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "--sysroot=")
+
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
 
@@ -57,6 +59,7 @@
   set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+  set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
 
   # linker selection
   set(CMAKE_${lang}_USING_LINKER_DEFAULT "-fuse-ld=lld-link")
@@ -156,9 +159,15 @@
     endif()
     if(DEFINED CMAKE_RC_PREPROCESSOR)
       set(CMAKE_DEPFILE_FLAGS_RC "${clang_option_prefix}-MD ${clang_option_prefix}-MF ${clang_option_prefix}<DEP_FILE>")
-      # The <FLAGS> are passed to the preprocess and the resource compiler to pick
-      # up the eventual -D / -C options passed through the CMAKE_RC_FLAGS.
-      set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> ${extra_pp_flags} -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo <OBJECT> <OBJECT>.pp")
+      # llvm-rc runs preprocessor starting from LLVM-13, so we can run it directly instead of using "cmake_llvm_rc".
+      # See https://reviews.llvm.org/D100755 for more details.
+      if (CMAKE_GENERATOR MATCHES "FASTBuild")
+        set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo<OBJECT> <SOURCE>")
+      else()
+        # The <FLAGS> are passed to the preprocess and the resource compiler to pick
+        # up the eventual -D / -C options passed through the CMAKE_RC_FLAGS.
+        set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_COMMAND> -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> ${extra_pp_flags} -E -- <SOURCE> ++ <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> <FLAGS> /fo <OBJECT> <OBJECT>.pp")
+      endif()
       if(CMAKE_GENERATOR MATCHES "Ninja")
         set(CMAKE_NINJA_CMCLDEPS_RC 0)
         set(CMAKE_NINJA_DEP_TYPE_RC gcc)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 37d5cf1..962b57a 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -181,7 +181,7 @@
 
     # Query the VS Installer tool for locations of VS 2017 and above.
     set(_vs_installer_paths "")
-    foreach(vs RANGE 17 15 -1) # change the first number to the largest supported version
+    foreach(vs RANGE 18 15 -1) # change the first number to the largest supported version
       cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR)
       if(_vs_dir)
         list(APPEND _vs_installer_paths "${_vs_dir}/VC/Auxiliary/Build")
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index 48c7b49..cacddd4 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -61,7 +61,10 @@
     message(FATAL_ERROR "MSVC compiler version not detected properly: ${_compiler_version}")
   endif()
 
-  if(MSVC_VERSION GREATER_EQUAL 1930)
+  if(MSVC_VERSION GREATER_EQUAL 1950)
+    # VS 2026 or greater
+    set(MSVC_TOOLSET_VERSION 145)
+  elseif(MSVC_VERSION GREATER_EQUAL 1930)
     # VS 2022 or greater
     set(MSVC_TOOLSET_VERSION 143)
   elseif(MSVC_VERSION GREATER_EQUAL 1920)
@@ -388,15 +391,17 @@
 unset(__WINDOWS_MSVC_CMP0184)
 
 macro(__windows_compiler_msvc lang)
-  if(NOT MSVC_VERSION LESS 1400)
+  if(NOT MSVC_VERSION LESS 1400 AND NOT CMAKE_GENERATOR MATCHES "FASTBuild")
     # for 2005 make sure the manifest is put in the dll with mt
     set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --msvc-ver=${MSVC_VERSION} --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
     set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --msvc-ver=${MSVC_VERSION} --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
   endif()
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "")
   if(CMAKE_SYSTEM_NAME STREQUAL "WindowsKernelModeDriver")
+    set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "")
     set(_DLL_DRIVER "-driver")
   else()
+    set(CMAKE_${lang}_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
     set(_DLL_DRIVER "/dll")
   endif()
   set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
@@ -434,10 +439,11 @@
     # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets
     # paths starting with /U as macro undefines, so we need to put a -- before the
     # input file path to force it to be treated as a path.
-    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}")
-    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE}")
-    string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE}")
-
+    if(NOT CMAKE_GENERATOR MATCHES "FASTBuild")
+      string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_COMPILE_OBJECT "${CMAKE_${lang}_COMPILE_OBJECT}")
+      string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "${CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE}")
+      string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "${CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE}")
+    endif()
   elseif(MSVC_VERSION GREATER_EQUAL 1913)
     # At least MSVC toolet 14.13 from VS 2017 15.6
     set(CMAKE_PCH_PROLOGUE "#pragma system_header")
diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
index cc6b687..c8ed9fa 100644
--- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake
+++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
@@ -11,10 +11,17 @@
   string(APPEND __IMPLICIT_LINKS " \"${lib}\"")
 endforeach()
 
-set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
-set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
+set(_CMAKE_VS_LINK_DLL "")
+set(_CMAKE_VS_LINK_EXE "")
+# Use linker directly with FASTBuild
+if (NOT CMAKE_GENERATOR MATCHES "FASTBuild")
+  set(_CMAKE_VS_LINK_DLL "<CMAKE_COMMAND> -E vs_link_dll --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
+  set(_CMAKE_VS_LINK_EXE "<CMAKE_COMMAND> -E vs_link_exe --intdir=<OBJECT_DIR> --rc=<CMAKE_RC_COMPILER> --mt=<CMAKE_MT> --manifests <MANIFESTS> -- ")
+endif()
+
 set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
   "${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICIT_LINKS} ${CMAKE_END_TEMP_FILE}")
+set(CMAKE_CUDA_SHARED_LIBRARY_COMPILE_DEFINITIONS "_WINDLL")
 
 set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY})
 set(CMAKE_CUDA_CREATE_STATIC_LIBRARY  "<CMAKE_AR> ${CMAKE_CL_NOLOGO}${_PLATFORM_ARCHIVE_FLAGS} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake
index 8f44b97..af18b7e 100644
--- a/Modules/Qt4Macros.cmake
+++ b/Modules/Qt4Macros.cmake
@@ -125,9 +125,12 @@
     set(targetincludes)
     set(targetdefines)
   else()
-    set(CMAKE_CONFIGURABLE_FILE_CONTENT "${_moc_parameters}")
-    configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
-                   "${_moc_parameters_file}" @ONLY)
+    file(
+      CONFIGURE
+      OUTPUT "${_moc_parameters_file}"
+      CONTENT "${_moc_parameters}\n"
+      @ONLY
+    )
   endif()
 
   set(_moc_extra_parameters_file @${_moc_parameters_file})
diff --git a/Modules/SelectLibraryConfigurations.cmake b/Modules/SelectLibraryConfigurations.cmake
index e26c908..5fde66e 100644
--- a/Modules/SelectLibraryConfigurations.cmake
+++ b/Modules/SelectLibraryConfigurations.cmake
@@ -5,13 +5,15 @@
 SelectLibraryConfigurations
 ---------------------------
 
-This module is intended for use in :ref:`Find Modules` and provides a
-command to automatically set library variables when package is available
-with multiple :ref:`Build Configurations`.
+This module provides a command to automatically set library variables when
+package is available with multiple :ref:`Build Configurations`.  It is
+intended for use in :ref:`Find Modules` implementing
+:command:`find_package(<PackageName>)` calls.
 
-Load it in a CMake find module with:
+Load this module in a CMake find module with:
 
 .. code-block:: cmake
+  :caption: ``FindFoo.cmake``
 
   include(SelectLibraryConfigurations)
 
diff --git a/Modules/SquishTestScript.cmake b/Modules/SquishTestScript.cmake
index c4b45dc..9575084 100644
--- a/Modules/SquishTestScript.cmake
+++ b/Modules/SquishTestScript.cmake
@@ -4,7 +4,6 @@
 #[=======================================================================[.rst:
 SquishTestScript
 ----------------
-.. deprecated:: 3.0
 
 .. note::
 
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
index a64303d..4b31780 100644
--- a/Modules/TestBigEndian.cmake
+++ b/Modules/TestBigEndian.cmake
@@ -7,19 +7,74 @@
 
 .. deprecated:: 3.20
 
-  Supserseded by the :variable:`CMAKE_<LANG>_BYTE_ORDER` variable.
+  Superseded by the :variable:`CMAKE_<LANG>_BYTE_ORDER` variable.
 
-Check if the target architecture is big endian or little endian.
+This module provides a command to check the endianness (byte order) of the
+target architecture.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(TestBigEndian)
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
 
 .. command:: test_big_endian
 
+  Checks if the target architecture is big-endian or little-endian:
+
   .. code-block:: cmake
 
     test_big_endian(<var>)
 
-  Stores in variable ``<var>`` either 1 or 0 indicating whether the
-  target architecture is big or little endian.
+  This command stores in variable ``<var>`` either 1 or 0 indicating whether
+  the target architecture is big or little endian.
 
+  At least one of the supported languages must be enabled in
+  CMake project when using this command.
+
+  Supported languages are ``C``, ``CXX``.
+
+  .. versionchanged:: 3.20
+    This command is now mainly a wrapper around the
+    :variable:`CMAKE_<LANG>_BYTE_ORDER` where also ``OBJC``, ``OBJCXX``,
+    and ``CUDA`` languages are supported.
+
+Examples
+^^^^^^^^
+
+Example: Checking Endianness
+""""""""""""""""""""""""""""
+
+Checking endianness of the target architecture with this module and storing
+the result in a CMake variable ``WORDS_BIGENDIAN``:
+
+.. code-block:: cmake
+
+  include(TestBigEndian)
+  test_big_endian(WORDS_BIGENDIAN)
+
+Example: Checking Endianness in New Code
+""""""""""""""""""""""""""""""""""""""""
+
+As of CMake 3.20, this module should be replaced with the
+:variable:`CMAKE_<LANG>_BYTE_ORDER` variable.  For example, in a project,
+where ``C`` language is one of the enabled languages:
+
+.. code-block:: cmake
+
+  if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN")
+    set(WORDS_BIGENDIAN TRUE)
+  elseif(CMAKE_C_BYTE_ORDER STREQUAL "LITTLE_ENDIAN")
+    set(WORDS_BIGENDIAN FALSE)
+  else()
+    set(WORDS_BIGENDIAN FALSE)
+    message(WARNING "Endianness could not be determined.")
+  endif()
 #]=======================================================================]
 include_guard()
 
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake
index a39f8b3..69c7bc3 100644
--- a/Modules/TestCXXAcceptsFlag.cmake
+++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -12,11 +12,19 @@
   :module:`CheckCompilerFlag` module is also available for checking flags across
   multiple languages.
 
-This module provides a macro to test whether the C++ (CXX) compiler supports
+This module provides a command to test whether the C++ (CXX) compiler supports
 specific flags.
 
-Macros
-^^^^^^
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(TestCXXAcceptsFlag)
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
 
 .. command:: check_cxx_accepts_flag
 
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 9c8811b..9deb8d6 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -8,7 +8,7 @@
 This module defines variables and provides commands required to build an eCos
 application.
 
-Load this module in CMake project with:
+Load this module in a CMake project with:
 
 .. code-block:: cmake
 
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index b977d95..b79d8d2 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -9,6 +9,12 @@
 :module:`FindJava` has already been loaded.  See :module:`FindJava` for
 information on how to load Java into your CMake project.
 
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(UseJava)
+
 Synopsis
 ^^^^^^^^
 
@@ -877,10 +883,12 @@
             # Create the list of files to compile.
             set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
             string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
-            set(CMAKE_CONFIGURABLE_FILE_CONTENT "${_JAVA_COMPILE_STRING}")
-            configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
-              "${_JAVA_SOURCES_FILE}" @ONLY)
-            unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
+            file(
+              CONFIGURE
+              OUTPUT "${_JAVA_SOURCES_FILE}"
+              CONTENT "${_JAVA_COMPILE_STRING}\n"
+              @ONLY
+            )
             list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
         endif()
         if (_JAVA_COMPILE_FILELISTS)
diff --git a/Modules/UseJava/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in
index 4aa6560..68643c4 100644
--- a/Modules/UseJava/javaTargets.cmake.in
+++ b/Modules/UseJava/javaTargets.cmake.in
@@ -1,5 +1,5 @@
 cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.12...3.31)
+cmake_policy(VERSION 2.8.12...4.0)
 
 #----------------------------------------------------------------
 # Generated CMake Java target import file.
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake
index 2c34c26..21ee08b 100644
--- a/Modules/UsePkgConfig.cmake
+++ b/Modules/UsePkgConfig.cmake
@@ -10,7 +10,7 @@
   This module should no longer be used.  Instead, use the
   :module:`FindPkgConfig` module or the :command:`cmake_pkg_config` command.
 
-  This module provided a macro for finding external packages using
+  This module provided a command for finding external packages using
   ``pkg-config`` command-line utility.  It has been replaced by the more
   convenient ``FindPkgConfig`` module, which is commonly used in
   :ref:`Find Modules`.
@@ -18,10 +18,16 @@
   As of CMake 3.31, the built-in :command:`cmake_pkg_config` command provides
   even more features to extract package information.
 
-Macros
-^^^^^^
+Load this module in a CMake project with:
 
-This module defines the following macro:
+.. code-block:: cmake
+
+  include(UsePkgConfig)
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
 
 .. command:: pkgconfig
 
@@ -31,9 +37,10 @@
 
     pkgconfig(<package> <includedir> <libdir> <linkflags> <cflags>)
 
-  This macro invokes ``pkg-config`` command-line utility to retrieve the package
-  information into specified variables.  If ``pkg-config`` or the specified
-  package ``<package>`` is NOT found, the result variables remain empty.
+  This command invokes ``pkg-config`` command-line utility to retrieve the
+  package information into specified variables.  If ``pkg-config`` or the
+  specified package ``<package>`` is NOT found, the result variables remain
+  empty.
 
   The arguments are:
 
@@ -73,7 +80,7 @@
 .. code-block:: cmake
 
   find_package(PkgConfig QUIET)
-  if(PKG_CONFIG_FOUND)
+  if(PkgConfig_FOUND)
     pkg_check_modules(LIBART QUIET libart-2.0)
   endif()
 
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index cc023ee..a469c4f 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -5,13 +5,19 @@
 UseSWIG
 -------
 
-This file provides support for ``SWIG``. It is assumed that :module:`FindSWIG`
-module has already been loaded.
-
 .. only:: html
 
   .. contents::
 
+This module provides support for ``SWIG``. It is assumed that :module:`FindSWIG`
+module has already been loaded.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(UseSWIG)
+
 CMake Commands
 ^^^^^^^^^^^^^^
 
@@ -29,6 +35,7 @@
                      [TYPE <SHARED|MODULE|STATIC|USE_BUILD_SHARED_LIBS>]
                      LANGUAGE <language>
                      [NO_PROXY]
+                     [DEBUG_POSTFIX <postfix>]
                      [OUTPUT_DIR <directory>]
                      [OUTFILE_DIR <directory>]
                      SOURCES <file>...
@@ -94,6 +101,16 @@
 
     Prevent the generation of the wrapper layer (swig ``-noproxy`` option).
 
+  ``DEBUG_POSTFIX``
+    .. versionadded:: 4.2
+
+    Manage the :prop_tgt:`DEBUG_POSTFIX` target property. Currently, only
+    meaningful for the ``python`` language.
+
+    If the :prop_gbl:`DEBUG_CONFIGURATIONS` global property is defined, define
+    the :prop_tgt:`<CONFIG>_POSTFIX` target property for each debug
+    configuration.
+
   ``OUTPUT_DIR``
     .. versionadded:: 3.12
 
@@ -669,7 +686,7 @@
         NOT ("-interface" IN_LIST swig_source_file_flags OR "-interface" IN_LIST SWIG_MODULE_${name}_EXTRA_FLAGS))
       # This makes sure that the name used in the proxy code
       # matches the library name created by CMake
-      list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name}>")
+      list (APPEND SWIG_MODULE_${name}_EXTRA_FLAGS "-interface" "$<TARGET_FILE_PREFIX:${target_name}>$<TARGET_FILE_BASE_NAME:${target_name},POSTFIX:$<IF:$<AND:$<BOOL:${SWIG_DEBUG_POSTFIX}>,$<CONFIG:${SWIG_DEBUG_CONFIGS}>>,EXCLUDE,INCLUDE>>")
     endif()
   endif()
   list (APPEND swig_extra_flags ${SWIG_MODULE_${name}_EXTRA_FLAGS})
@@ -781,6 +798,7 @@
   set(options NO_PROXY)
   set(oneValueArgs LANGUAGE
                    TYPE
+                   DEBUG_POSTFIX
                    OUTPUT_DIR
                    OUTFILE_DIR)
   set(multiValueArgs SOURCES)
@@ -804,6 +822,18 @@
     unset(_SAM_TYPE)
   endif()
 
+  if(_SAM_DEBUG_POSTFIX)
+    get_property(SWIG_DEBUG_CONFIGS GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
+    if(NOT SWIG_DEBUG_CONFIGS)
+      set(SWIG_DEBUG_CONFIGS DEBUG)
+    endif()
+    string(TOUPPER "${SWIG_DEBUG_CONFIGS}" SWIG_DEBUG_CONFIGS)
+    set(SWIG_DEBUG_POSTFIX "${_SAM_DEBUG_POSTFIX}")
+  else()
+    unset(SWIG_DEBUG_CONFIGS)
+    unset(SWIG_DEBUG_POSTFIX)
+  endif()
+
   cmake_policy(GET CMP0078 target_name_policy)
   if (target_name_policy STREQUAL "NEW")
     set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
@@ -995,6 +1025,11 @@
     if(WIN32 AND NOT CYGWIN)
       set_target_properties(${target_name} PROPERTIES SUFFIX ".pyd")
     endif()
+    if(SWIG_DEBUG_POSTFIX)
+      foreach(config IN LISTS SWIG_DEBUG_CONFIGS)
+        set_target_properties(${target_name} PROPERTIES ${config}_POSTFIX "${SWIG_DEBUG_POSTFIX}")
+      endforeach()
+    endif()
   elseif (swig_lowercase_language STREQUAL "r")
     set_target_properties(${target_name} PROPERTIES PREFIX "")
   elseif (swig_lowercase_language STREQUAL "ruby")
@@ -1067,6 +1102,10 @@
 # Like TARGET_LINK_LIBRARIES but for swig modules
 #
 function(SWIG_LINK_LIBRARIES name)
+  cmake_policy(GET CMP0078 target_name_policy)
+  if (target_name_policy STREQUAL "NEW")
+    set (UseSWIG_TARGET_NAME_PREFERENCE STANDARD)
+  endif()
   if (UseSWIG_TARGET_NAME_PREFERENCE STREQUAL "STANDARD")
     message(DEPRECATION "SWIG_LINK_LIBRARIES is deprecated. Use TARGET_LINK_LIBRARIES instead.")
     target_link_libraries(${name} ${ARGN})
diff --git a/Modules/Use_wxWindows.cmake b/Modules/Use_wxWindows.cmake
index e3c1870..aca80d9 100644
--- a/Modules/Use_wxWindows.cmake
+++ b/Modules/Use_wxWindows.cmake
@@ -7,28 +7,54 @@
 
 .. deprecated:: 2.8.10
 
-  Use :module:`find_package(wxWidgets) <FindwxWidgets>` instead.
+  This module should no longer be used.  Use :module:`find_package(wxWidgets)
+  <FindwxWidgets>` instead.
 
-This convenience include finds if wxWindows library is installed and sets the
-appropriate libraries, include directories, flags, etc.
+This module serves as a convenience wrapper for finding the wxWidgets library
+(formerly known as wxWindows) and propagates its usage requirements, such as
+libraries, include directories, and compiler flags, into the current directory
+scope for use by targets.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(Use_wxWindows)
 
 Examples
 ^^^^^^^^
 
-Include ``Use_wxWindows`` module in project's ``CMakeLists.txt``:
+In earlier versions of CMake, wxWidgets (wxWindows) could be found and used in
+the current directory like this:
 
 .. code-block:: cmake
+  :caption: ``CMakeLists.txt``
 
-  # CMakeLists.txt
   include(Use_wxWindows)
 
-When the GL support is required, set ``WXWINDOWS_USE_GL`` *before* including
-this module:
+To request OpenGL support, the ``WXWINDOWS_USE_GL`` variable could be set before
+including this module:
 
 .. code-block:: cmake
+  :caption: ``CMakeLists.txt``
 
   set(WXWINDOWS_USE_GL ON)
   include(Use_wxWindows)
+
+  add_library(example example.cxx)
+
+Starting with CMake 3.0, wxWidgets can be found using the
+:module:`FindwxWidgets` module, which provides the wxWidgets usage requirements
+either using result variables or imported target as of CMake 3.27:
+
+.. code-block:: cmake
+  :caption: ``CMakeLists.txt``
+
+  find_package(wxWidgets)
+
+  add_library(example example.cxx)
+
+  target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
 #]=======================================================================]
 
 # Author: Jan Woetzel <jw -at- mip.informatik.uni-kiel.de> (07/2003)
diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake
index 3751025..c6f8557 100644
--- a/Modules/UsewxWidgets.cmake
+++ b/Modules/UsewxWidgets.cmake
@@ -5,42 +5,65 @@
 UsewxWidgets
 ------------
 
+This module serves as a convenience wrapper for using the wxWidgets
+library (formerly known as wxWindows) and propagates its usage requirements,
+such as library directories, include directories, and compiler flags, into
+the current directory scope for use by targets.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(UsewxWidgets)
+
 This module calls :command:`include_directories` and
-:command:`link_directories`, sets compile definitions for the current directory
-and appends some compile flags to use wxWidgets library after calling the
-:module:`find_package(wxWidgets) <FindwxWidgets>`.
+:command:`link_directories`, sets compile definitions for the current
+directory and appends some compile flags to use wxWidgets library after
+calling the :module:`find_package(wxWidgets) <FindwxWidgets>`.
 
 Examples
 ^^^^^^^^
 
-Include ``UsewxWidgets`` module in project's ``CMakeLists.txt``:
+Include this module in a project after finding wxWidgets to configure its
+usage requirements:
 
 .. code-block:: cmake
+  :caption: ``CMakeLists.txt``
 
   # Note that for MinGW users the order of libraries is important.
-  find_package(wxWidgets REQUIRED net gl core base)
+  find_package(wxWidgets COMPONENTS net gl core base)
 
-  # Above also sets the wxWidgets_USE_FILE variable that points to this module.
-  include(${wxWidgets_USE_FILE})
+  add_library(example example.cxx)
 
-  # Link wxWidgets libraries for each dependent executable/library target.
-  target_link_libraries(<ProjectTarget> ${wxWidgets_LIBRARIES})
+  if(wxWidgets_FOUND)
+    include(UsewxWidgets)
+
+    # Link wxWidgets libraries for each dependent executable/library target.
+    target_link_libraries(example PRIVATE ${wxWidgets_LIBRARIES})
+  endif()
 
 As of CMake 3.27, a better approach is to link only the
-:module:`wxWidgets::wxWidgets <FindwxWidgets>` ``IMPORTED`` target to specific
-targets that require it, rather than including this module. Imported targets
-provide better control of the package usage properties, such as include
-directories and compile flags, by applying them only to the targets they are
-linked to, avoiding unnecessary propagation to all targets in the current
-directory.
+:module:`wxWidgets::wxWidgets <FindwxWidgets>` imported target to specific
+targets that require it, rather than including this module.  Imported
+targets provide better control of the package usage properties, such as
+include directories and compile flags, by applying them only to the targets
+they are linked to, avoiding unnecessary propagation to all targets in the
+current directory.
 
 .. code-block:: cmake
+  :caption: ``CMakeLists.txt``
 
-  # CMakeLists.txt
-  find_package(wxWidgets)
+  find_package(wxWidgets COMPONENTS net gl core base)
+
+  add_library(example example.cxx)
 
   # Link the imported target for each dependent executable/library target.
-  target_link_libraries(<ProjectTarget> wxWidgets::wxWidgets)
+  target_link_libraries(example PRIVATE wxWidgets::wxWidgets)
+
+See Also
+^^^^^^^^
+
+* The :module:`FindwxWidgets` module to find wxWidgets.
 #]=======================================================================]
 
 # Author: Jan Woetzel <jw -at- mip.informatik.uni-kiel.de>
diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake
index 954875e..d752b01 100644
--- a/Modules/WriteCompilerDetectionHeader.cmake
+++ b/Modules/WriteCompilerDetectionHeader.cmake
@@ -11,7 +11,20 @@
 
 .. versionadded:: 3.1
 
-This module provides the function ``write_compiler_detection_header()``.
+This module provides a command to generate header with preprocessor macros.
+
+Load this module in a CMake project with:
+
+.. code-block:: cmake
+
+  include(WriteCompilerDetectionHeader)
+
+Commands
+^^^^^^^^
+
+This module provides the following command:
+
+.. command:: write_compiler_detection_header
 
 This function can be used to generate a file suitable for preprocessor
 inclusion which contains macros to be used in source code:
@@ -818,14 +831,13 @@
     foreach(compiler ${_WCD_COMPILERS})
       foreach(_lang ${_langs})
         if(compiler_file_content_${compiler}_${_lang})
-          set(CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_}")
-          string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "${compiler_file_content_${compiler}_${_lang}}")
-
           set(compile_file_name "${_WCD_OUTPUT_DIR}${prefix_arg}_COMPILER_INFO_${compiler}_${_lang}.h")
           set(full_path "${main_file_dir}/${compile_file_name}")
           list(APPEND ${_WCD_OUTPUT_FILES_VAR} ${full_path})
-          configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
-            "${full_path}"
+          file(
+            CONFIGURE
+            OUTPUT "${full_path}"
+            CONTENT "${compiler_file_content_}${compiler_file_content_${compiler}_${_lang}}\n"
             @ONLY
           )
         endif()
@@ -839,9 +851,5 @@
   endif()
   string(APPEND file_content "\n#endif")
 
-  set(CMAKE_CONFIGURABLE_FILE_CONTENT ${file_content})
-  configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
-    "${file_arg}"
-    @ONLY
-  )
+  file(CONFIGURE OUTPUT "${file_arg}" CONTENT "${file_content}\n" @ONLY)
 endfunction()
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index c54da44..44f87db 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -148,8 +148,6 @@
   cmComputeTargetDepends.cxx
   cmConfigureLog.h
   cmConfigureLog.cxx
-  cmConstStack.h
-  cmConstStack.tcc
   cmCPackPropertiesGenerator.h
   cmCPackPropertiesGenerator.cxx
   cmCryptoHash.cxx
@@ -405,6 +403,8 @@
   cmMSVC60LinkLineComputer.h
   cmOSXBundleGenerator.cxx
   cmOSXBundleGenerator.h
+  cmObjectLocation.cxx
+  cmObjectLocation.h
   cmOutputConverter.cxx
   cmOutputConverter.h
   cmNewLineStyle.h
@@ -460,6 +460,8 @@
   cmSourceFileLocationKind.h
   cmSourceGroup.cxx
   cmSourceGroup.h
+  cmStack.h
+  cmStack.tcc
   cmStandardLevel.h
   cmStandardLevelResolver.cxx
   cmStandardLevelResolver.h
@@ -719,6 +721,9 @@
   cmSiteNameCommand.h
   cmSourceGroupCommand.cxx
   cmSourceGroupCommand.h
+  cmSPDXSerializer.cxx
+  cmSPDXSerializer.h
+  cmSPDXTypes.def
   cmString.cxx
   cmString.hxx
   cmStringReplaceHelper.cxx
@@ -779,9 +784,21 @@
   cmNinjaLinkLineComputer.h
   cmNinjaLinkLineDeviceComputer.cxx
   cmNinjaLinkLineDeviceComputer.h
+  # FASTBuild support
+  cmGlobalFastbuildGenerator.cxx
+  cmGlobalFastbuildGenerator.h
+  cmLocalFastbuildGenerator.cxx
+  cmLocalFastbuildGenerator.h
+  cmFastbuildTargetGenerator.cxx
+  cmFastbuildTargetGenerator.h
+  cmFastbuildLinkLineComputer.cxx
+  cmFastbuildNormalTargetGenerator.cxx
+  cmFastbuildNormalTargetGenerator.h
+  cmFastbuildUtilityTargetGenerator.cxx
+  cmFastbuildUtilityTargetGenerator.h
 
-  cm_get_date.h
-  cm_get_date.c
+  cm_parse_date.h
+  cm_parse_date.c
   cm_utf8.h
   cm_utf8.c
   cm_codecvt.hxx
@@ -920,8 +937,6 @@
         cmGlobalNMakeMakefileGenerator.h
         cmGlobalJOMMakefileGenerator.cxx
         cmGlobalJOMMakefileGenerator.h
-        cmGlobalVisualStudio71Generator.cxx
-        cmGlobalVisualStudio71Generator.h
         cmGlobalVisualStudio7Generator.cxx
         cmGlobalVisualStudio7Generator.h
         cmGlobalVisualStudio8Generator.cxx
@@ -960,11 +975,18 @@
         cmVisualStudioWCEPlatformParser.cxx
         cmVSSetupHelper.cxx
         cmVSSetupHelper.h
+        cmVSSolution.cxx
+        cmVSSolution.h
+        cmVSVersion.h
       )
 
     # Add a manifest file to executables on Windows to allow for
     # GetVersion to work properly on Windows 8 and above.
-    target_sources(ManifestLib INTERFACE cmake.version.manifest)
+    if(MSVC)
+      target_sources(ManifestLib INTERFACE cmake.version.manifest)
+    else()
+      target_sources(ManifestLib INTERFACE cmake.version.manifest.rc)
+    endif()
   endif()
 endif()
 
@@ -1176,7 +1198,9 @@
   CPack/cmCPackArchiveGenerator.cxx
   CPack/cmCPackComponentGroup.cxx
   CPack/cmCPackDebGenerator.cxx
+  CPack/cmCPackDebGenerator.h
   CPack/cmCPackExternalGenerator.cxx
+  CPack/cmCPackExternalGenerator.h
   CPack/cmCPackGeneratorFactory.cxx
   CPack/cmCPackGenerator.cxx
   CPack/cmCPackLog.cxx
@@ -1241,6 +1265,15 @@
   endif()
 endif()
 
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+  target_sources(
+    CPackLib
+    PRIVATE
+      CPack/cmCPackAppImageGenerator.cxx
+      CPack/cmCPackAppImageGenerator.h
+    )
+endif()
+
 if(CYGWIN)
   target_sources(
     CPackLib
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 1995c14..b6d95b9 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 4)
-set(CMake_VERSION_MINOR 1)
-set(CMake_VERSION_PATCH 5)
+set(CMake_VERSION_MINOR 2)
+set(CMake_VERSION_PATCH 2)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index ce542c7..8b955aa 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -430,6 +430,7 @@
   CopyDefinition(includeFile, "CPACK_WIX_PROGRAM_MENU_FOLDER");
   CopyDefinition(includeFile, "CPACK_WIX_UI_REF");
   CopyDefinition(includeFile, "CPACK_WIX_INSTALL_SCOPE");
+  CopyDefinition(includeFile, "CPACK_WIX_CAB_PER_COMPONENT");
 }
 
 void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
@@ -492,6 +493,22 @@
                                 cmWIXSourceWriter::INCLUDE_ELEMENT_ROOT);
   InjectXmlNamespaces(includeFile);
 
+  bool perComponentCab = GetOption("CPACK_WIX_CAB_PER_COMPONENT").IsOn();
+
+  if (perComponentCab) {
+    std::size_t cabCount = std::max<std::size_t>(1, this->Components.size());
+
+    for (std::size_t i = 0; i < cabCount; ++i) {
+      std::string diskId = std::to_string(i + 1);
+
+      includeFile.BeginElement("Media");
+      includeFile.AddAttribute("Id", diskId);
+      includeFile.AddAttribute("Cabinet", "media" + diskId + ".cab");
+      includeFile.AddAttribute("EmbedCab", "yes");
+      includeFile.EndElement("Media");
+    }
+  }
+
   this->Patch->ApplyFragment("#PRODUCT", includeFile);
 }
 
@@ -617,11 +634,17 @@
   if (Components.empty()) {
     AddComponentsToFeature(toplevel, "ProductFeature", directoryDefinitions,
                            fileDefinitions, featureDefinitions,
-                           globalShortcuts);
+                           globalShortcuts, 0);
 
     globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
   } else {
+    bool perComponentCab = GetOption("CPACK_WIX_CAB_PER_COMPONENT").IsOn();
+
+    std::size_t componentDiskId = 0;
+
     for (auto const& i : this->Components) {
+      ++componentDiskId;
+
       cmCPackComponent const& component = i.second;
 
       std::string componentPath = cmStrCat(toplevel, '/', component.Name);
@@ -631,7 +654,8 @@
       cmWIXShortcuts featureShortcuts;
       AddComponentsToFeature(componentPath, componentFeatureId,
                              directoryDefinitions, fileDefinitions,
-                             featureDefinitions, featureShortcuts);
+                             featureDefinitions, featureShortcuts,
+                             perComponentCab ? componentDiskId : 0);
 
       featureShortcuts.AddShortcutTypes(emittedShortcutTypes);
 
@@ -779,7 +803,8 @@
   std::string const& rootPath, std::string const& featureId,
   cmWIXDirectoriesSourceWriter& directoryDefinitions,
   cmWIXFilesSourceWriter& fileDefinitions,
-  cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts)
+  cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts,
+  int diskId)
 {
   featureDefinitions.BeginElement("FeatureRef");
   featureDefinitions.AddAttribute("Id", featureId);
@@ -807,7 +832,7 @@
   AddDirectoryAndFileDefinitions(
     rootPath, "INSTALL_ROOT", directoryDefinitions, fileDefinitions,
     featureDefinitions, cpackPackageExecutablesList,
-    cpackPackageDesktopLinksList, shortcuts);
+    cpackPackageDesktopLinksList, shortcuts, diskId);
 
   featureDefinitions.EndElement("FeatureRef");
 
@@ -995,7 +1020,7 @@
   cmWIXFeaturesSourceWriter& featureDefinitions,
   std::vector<std::string> const& packageExecutables,
   std::vector<std::string> const& desktopExecutables,
-  cmWIXShortcuts& shortcuts)
+  cmWIXShortcuts& shortcuts, int diskId)
 {
   cmsys::Directory dir;
   dir.Load(topdir.c_str());
@@ -1015,6 +1040,10 @@
 
   if (emptyDirectory) {
     createDirectory = true;
+
+    if (directoryId == "INSTALL_ROOT") {
+      return;
+    }
   }
 
   if (directoryInstalledFile) {
@@ -1054,9 +1083,10 @@
       directoryDefinitions.AddAttribute("Name", fileName);
       this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
 
-      AddDirectoryAndFileDefinitions(
-        fullPath, subDirectoryId, directoryDefinitions, fileDefinitions,
-        featureDefinitions, packageExecutables, desktopExecutables, shortcuts);
+      AddDirectoryAndFileDefinitions(fullPath, subDirectoryId,
+                                     directoryDefinitions, fileDefinitions,
+                                     featureDefinitions, packageExecutables,
+                                     desktopExecutables, shortcuts, diskId);
 
       directoryDefinitions.EndElement("Directory");
     } else {
@@ -1068,7 +1098,7 @@
       }
 
       std::string componentId = fileDefinitions.EmitComponentFile(
-        directoryId, id, fullPath, *(this->Patch), installedFile);
+        directoryId, id, fullPath, *(this->Patch), installedFile, diskId);
 
       featureDefinitions.EmitComponentRef(componentId);
 
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index 49f20a7..bfad0d4 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -86,7 +86,8 @@
     std::string const& rootPath, std::string const& featureId,
     cmWIXDirectoriesSourceWriter& directoryDefinitions,
     cmWIXFilesSourceWriter& fileDefinitions,
-    cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts);
+    cmWIXFeaturesSourceWriter& featureDefinitions, cmWIXShortcuts& shortcuts,
+    int diskId);
 
   bool CreateShortcuts(std::string const& cpackComponentName,
                        std::string const& featureId,
@@ -122,7 +123,7 @@
     cmWIXFeaturesSourceWriter& featureDefinitions,
     std::vector<std::string> const& packageExecutables,
     std::vector<std::string> const& desktopExecutables,
-    cmWIXShortcuts& shortcuts);
+    cmWIXShortcuts& shortcuts, int diskId);
 
   bool RequireOption(std::string const& name, std::string& value) const;
 
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index d5a9f0f..550e029 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -15,6 +15,10 @@
 #include "cmUuid.h"
 #include "cmWIXAccessControlList.h"
 
+#ifdef _WIN32
+#  include "cmsys/Encoding.hxx"
+#endif
+
 cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(unsigned long wixVersion,
                                                cmCPackLog* logger,
                                                std::string const& filename,
@@ -118,7 +122,7 @@
 std::string cmWIXFilesSourceWriter::EmitComponentFile(
   std::string const& directoryId, std::string const& id,
   std::string const& filePath, cmWIXPatch& patch,
-  cmInstalledFile const* installedFile)
+  cmInstalledFile const* installedFile, int diskId)
 {
   std::string componentId = std::string("CM_C") + id;
   std::string fileId = std::string("CM_F") + id;
@@ -132,6 +136,10 @@
   AddAttribute("Id", componentId);
   AddAttribute("Guid", guid);
 
+  if (diskId) {
+    AddAttribute("DiskId", std::to_string(diskId));
+  }
+
   if (installedFile) {
     if (installedFile->GetPropertyAsBool("CPACK_NEVER_OVERWRITE")) {
       AddAttribute("NeverOverwrite", "yes");
@@ -144,7 +152,18 @@
   patch.ApplyFragment(componentId, *this);
   BeginElement("File");
   AddAttribute("Id", fileId);
-  AddAttribute("Source", CMakeToWixPath(filePath));
+
+  std::string sourcePath = CMakeToWixPath(filePath);
+#ifdef _WIN32
+  // WiX cannot handle long paths natively, but since v4,
+  // it supports long paths via UNC prefixes.
+  if (this->WixVersion >= 4) {
+    sourcePath = cmsys::Encoding::ToNarrow(
+      cmsys::Encoding::ToWindowsExtendedPath(sourcePath));
+  }
+#endif
+  AddAttribute("Source", sourcePath);
+
   AddAttribute("KeyPath", "yes");
 
   mode_t fileMode = 0;
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
index 997c674..fff7c4f 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -35,5 +35,6 @@
   std::string EmitComponentFile(std::string const& directoryId,
                                 std::string const& id,
                                 std::string const& filePath, cmWIXPatch& patch,
-                                cmInstalledFile const* installedFile);
+                                cmInstalledFile const* installedFile,
+                                int diskId);
 };
diff --git a/Source/CPack/cmCPackAppImageGenerator.cxx b/Source/CPack/cmCPackAppImageGenerator.cxx
new file mode 100644
index 0000000..c6d4d8a
--- /dev/null
+++ b/Source/CPack/cmCPackAppImageGenerator.cxx
@@ -0,0 +1,470 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmCPackAppImageGenerator.h"
+
+#include <algorithm>
+#include <cctype>
+#include <cstddef>
+#include <utility>
+#include <vector>
+
+#include <fcntl.h>
+
+#include <sys/types.h>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmCPackLog.h"
+#include "cmELF.h"
+#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmValue.h"
+
+cmCPackAppImageGenerator::cmCPackAppImageGenerator() = default;
+
+cmCPackAppImageGenerator::~cmCPackAppImageGenerator() = default;
+
+int cmCPackAppImageGenerator::InitializeInternal()
+{
+  this->SetOptionIfNotSet("CPACK_APPIMAGE_TOOL_EXECUTABLE", "appimagetool");
+  this->AppimagetoolPath = cmSystemTools::FindProgram(
+    *this->GetOption("CPACK_APPIMAGE_TOOL_EXECUTABLE"));
+
+  if (this->AppimagetoolPath.empty()) {
+    cmCPackLogger(
+      cmCPackLog::LOG_ERROR,
+      "Cannot find AppImageTool: '"
+        << *this->GetOption("CPACK_APPIMAGE_TOOL_EXECUTABLE")
+        << "' check if it's installed, is executable, or is in your PATH"
+        << std::endl);
+
+    return 0;
+  }
+
+  this->SetOptionIfNotSet("CPACK_APPIMAGE_PATCHELF_EXECUTABLE", "patchelf");
+  this->PatchElfPath = cmSystemTools::FindProgram(
+    *this->GetOption("CPACK_APPIMAGE_PATCHELF_EXECUTABLE"));
+
+  if (this->PatchElfPath.empty()) {
+    cmCPackLogger(
+      cmCPackLog::LOG_ERROR,
+      "Cannot find patchelf: '"
+        << *this->GetOption("CPACK_APPIMAGE_PATCHELF_EXECUTABLE")
+        << "' check if it's installed, is executable, or is in your PATH"
+        << std::endl);
+
+    return 0;
+  }
+
+  return Superclass::InitializeInternal();
+}
+
+int cmCPackAppImageGenerator::PackageFiles()
+{
+  cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                "AppDir: \"" << this->toplevel << "\"" << std::endl);
+
+  // Desktop file must be in the toplevel dir
+  auto const desktopFile = FindDesktopFile();
+  if (!desktopFile) {
+    cmCPackLogger(cmCPackLog::LOG_WARNING,
+                  "A desktop file is required to build an AppImage, make sure "
+                  "it's listed for install()."
+                    << std::endl);
+    return 0;
+  }
+
+  {
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                  "Found Desktop file: \"" << desktopFile.value() << "\""
+                                           << std::endl);
+    std::string desktopSymLink = this->toplevel + "/" +
+      cmSystemTools::GetFilenameName(desktopFile.value());
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                  "Desktop file destination: \"" << desktopSymLink << "\""
+                                                 << std::endl);
+    auto status = cmSystemTools::CreateSymlink(
+      cmSystemTools::RelativePath(toplevel, *desktopFile), desktopSymLink);
+    if (status.IsSuccess()) {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                    "Desktop symbolic link created successfully."
+                      << std::endl);
+    } else {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error creating symbolic link." << status.GetString()
+                                                    << std::endl);
+      return 0;
+    }
+  }
+
+  auto const desktopEntry = ParseDesktopFile(*desktopFile);
+
+  {
+    // Prepare Icon file
+    auto const iconValue = desktopEntry.find("Icon");
+    if (iconValue == desktopEntry.end()) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "An Icon key is required to build an AppImage, make sure "
+                    "the desktop file has a reference to one."
+                      << std::endl);
+      return 0;
+    }
+
+    auto icon = this->GetOption("CPACK_PACKAGE_ICON");
+    if (!icon) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "CPACK_PACKAGE_ICON is required to build an AppImage."
+                      << std::endl);
+      return 0;
+    }
+
+    if (!cmSystemTools::StringStartsWith(*icon, iconValue->second.c_str())) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "CPACK_PACKAGE_ICON must match the file name referenced "
+                    "in the desktop file."
+                      << std::endl);
+      return 0;
+    }
+
+    auto const iconFile = FindFile(icon);
+    if (!iconFile) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Could not find the Icon referenced in the desktop file: "
+                      << *icon << std::endl);
+      return 0;
+    }
+
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                  "Icon file: \"" << *iconFile << "\"" << std::endl);
+    std::string iconSymLink =
+      this->toplevel + "/" + cmSystemTools::GetFilenameName(*iconFile);
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                  "Icon link destination: \"" << iconSymLink << "\""
+                                              << std::endl);
+    auto status = cmSystemTools::CreateSymlink(
+      cmSystemTools::RelativePath(toplevel, *iconFile), iconSymLink);
+    if (status.IsSuccess()) {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                    "Icon symbolic link created successfully." << std::endl);
+    } else {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error creating symbolic link." << status.GetString()
+                                                    << std::endl);
+      return 0;
+    }
+  }
+
+  std::string application;
+  {
+    // Prepare executable file
+    auto const execValue = desktopEntry.find("Exec");
+    if (execValue == desktopEntry.end() || execValue->second.empty()) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "An Exec key is required to build an AppImage, make sure "
+                    "the desktop file has a reference to one."
+                      << std::endl);
+      return 0;
+    }
+
+    auto const execName =
+      cmSystemTools::SplitString(execValue->second, ' ').front();
+    auto const mainExecutable = FindFile(execName);
+
+    if (!mainExecutable) {
+      cmCPackLogger(
+        cmCPackLog::LOG_ERROR,
+        "Could not find the Executable referenced in the desktop file: "
+          << execName << std::endl);
+      return 0;
+    }
+    application = cmSystemTools::RelativePath(toplevel, *mainExecutable);
+  }
+
+  std::string const appRunFile = this->toplevel + "/AppRun";
+  if (cmSystemTools::PathExists(appRunFile)) {
+    // User provided an AppRun file
+    cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                  cmStrCat("Found AppRun file: \"", appRunFile, '"')
+                    << std::endl);
+  } else {
+    // Generate a default AppRun script that will run our application
+    cmCPackLogger(
+      cmCPackLog::LOG_OUTPUT,
+      cmStrCat("No AppRun found, generating a default one that will run: \"",
+               application, '"')
+        << std::endl);
+    cmGeneratedFileStream appRun(appRunFile);
+    appRun << R"sh(#! /usr/bin/env bash
+
+  # autogenerated by CPack
+
+  # make sure errors in sourced scripts will cause this script to stop
+  set -e
+
+  this_dir="$(readlink -f "$(dirname "$0")")"
+  )sh" << std::endl;
+    appRun << R"sh(exec "$this_dir"/)sh" << application << R"sh( "$@")sh"
+           << std::endl;
+  }
+
+  mode_t permissions;
+  {
+    auto status = cmSystemTools::GetPermissions(appRunFile, permissions);
+    if (!status.IsSuccess()) {
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Error getting AppRun permission: " << status.GetString()
+                                                        << std::endl);
+      return 0;
+    }
+  }
+
+  auto status =
+    cmSystemTools::SetPermissions(appRunFile, permissions | S_IXUSR);
+  if (!status.IsSuccess()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error changing AppRun permission: " << status.GetString()
+                                                       << std::endl);
+    return 0;
+  }
+
+  // Set RPATH to "$ORIGIN/../lib"
+  if (!ChangeRPath()) {
+    return 0;
+  }
+
+  // Run appimagetool
+  std::vector<std::string> command{
+    this->AppimagetoolPath,
+    this->toplevel,
+  };
+  command.emplace_back("../" + *this->GetOption("CPACK_PACKAGE_FILE_NAME") +
+                       this->GetOutputExtension());
+
+  auto addOptionFlag = [&command, this](std::string const& op,
+                                        std::string commandFlag) {
+    auto opt = this->GetOption(op);
+    if (opt) {
+      command.emplace_back(commandFlag);
+    }
+  };
+
+  auto addOption = [&command, this](std::string const& op,
+                                    std::string commandFlag) {
+    auto opt = this->GetOption(op);
+    if (opt) {
+      command.emplace_back(commandFlag);
+      command.emplace_back(*opt);
+    }
+  };
+
+  auto addOptions = [&command, this](std::string const& op,
+                                     std::string commandFlag) {
+    auto opt = this->GetOption(op);
+    if (opt) {
+      auto const options = cmSystemTools::SplitString(*opt, ';');
+      for (auto const& mkOpt : options) {
+        command.emplace_back(commandFlag);
+        command.emplace_back(mkOpt);
+      }
+    }
+  };
+
+  addOption("CPACK_APPIMAGE_UPDATE_INFORMATION", "--updateinformation");
+
+  addOptionFlag("CPACK_APPIMAGE_GUESS_UPDATE_INFORMATION", "--guess");
+
+  addOption("CPACK_APPIMAGE_COMPRESSOR", "--comp");
+
+  addOptions("CPACK_APPIMAGE_MKSQUASHFS_OPTIONS", "--mksquashfs-opt");
+
+  addOptionFlag("CPACK_APPIMAGE_NO_APPSTREAM", "--no-appstream");
+
+  addOption("CPACK_APPIMAGE_EXCLUDE_FILE", "--exclude-file");
+
+  addOption("CPACK_APPIMAGE_RUNTIME_FILE", "--runtime-file");
+
+  addOptionFlag("CPACK_APPIMAGE_SIGN", "--sign");
+
+  addOption("CPACK_APPIMAGE_SIGN_KEY", "--sign-key");
+
+  cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+                "Running AppImageTool: "
+                  << cmSystemTools::PrintSingleCommand(command) << std::endl);
+  int retVal = 1;
+  bool resS = cmSystemTools::RunSingleCommand(
+    command, nullptr, nullptr, &retVal, this->toplevel.c_str(),
+    cmSystemTools::OutputOption::OUTPUT_PASSTHROUGH);
+  if (!resS || retVal) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Problem running appimagetool: " << this->AppimagetoolPath
+                                                   << std::endl);
+    return 0;
+  }
+
+  return 1;
+}
+
+cm::optional<std::string> cmCPackAppImageGenerator::FindFile(
+  std::string const& filename) const
+{
+  for (std::string const& file : this->files) {
+    if (cmSystemTools::GetFilenameName(file) == filename) {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG, "Found file:" << file << std::endl);
+      return file;
+    }
+  }
+  return cm::nullopt;
+}
+
+cm::optional<std::string> cmCPackAppImageGenerator::FindDesktopFile() const
+{
+  cmValue desktopFileOpt = GetOption("CPACK_APPIMAGE_DESKTOP_FILE");
+  if (desktopFileOpt) {
+    return FindFile(*desktopFileOpt);
+  }
+
+  for (std::string const& file : this->files) {
+    if (cmSystemTools::StringEndsWith(file, ".desktop")) {
+      cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                    "Found desktop file:" << file << std::endl);
+      return file;
+    }
+  }
+
+  return cm::nullopt;
+}
+
+namespace {
+// Trim leading and trailing whitespace from a string
+std::string trim(std::string const& str)
+{
+  auto start = std::find_if_not(
+    str.begin(), str.end(), [](unsigned char c) { return std::isspace(c); });
+  auto end = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c) {
+               return std::isspace(c);
+             }).base();
+  return (start < end) ? std::string(start, end) : std::string();
+}
+} // namespace
+
+std::unordered_map<std::string, std::string>
+cmCPackAppImageGenerator::ParseDesktopFile(std::string const& filePath) const
+{
+  std::unordered_map<std::string, std::string> ret;
+
+  cmsys::ifstream file(filePath);
+  if (!file.is_open()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Failed to open desktop file:" << filePath << std::endl);
+    return ret;
+  }
+
+  bool inDesktopEntry = false;
+  std::string line;
+  while (std::getline(file, line)) {
+    line = trim(line);
+
+    if (line.empty() || line[0] == '#') {
+      // Skip empty lines or comments
+      continue;
+    }
+
+    if (line.front() == '[' && line.back() == ']') {
+      // We only care for [Desktop Entry] section
+      inDesktopEntry = (line == "[Desktop Entry]");
+      continue;
+    }
+
+    if (inDesktopEntry) {
+      size_t delimiter_pos = line.find('=');
+      if (delimiter_pos == std::string::npos) {
+        cmCPackLogger(cmCPackLog::LOG_WARNING,
+                      "Invalid desktop file line format: " << line
+                                                           << std::endl);
+        continue;
+      }
+
+      std::string key = trim(line.substr(0, delimiter_pos));
+      std::string value = trim(line.substr(delimiter_pos + 1));
+      if (!key.empty()) {
+        ret.emplace(key, value);
+      }
+    }
+  }
+
+  return ret;
+}
+
+bool cmCPackAppImageGenerator::ChangeRPath()
+{
+  // AppImages are mounted in random locations so we need RPATH to resolve to
+  // that location
+  std::string const newRPath = "$ORIGIN/../lib";
+
+  for (std::string const& file : this->files) {
+    cmELF elf(file.c_str());
+
+    auto const type = elf.GetFileType();
+    switch (type) {
+      case cmELF::FileType::FileTypeExecutable:
+      case cmELF::FileType::FileTypeSharedLibrary: {
+        std::string oldRPath;
+        auto const* rpath = elf.GetRPath();
+        if (rpath) {
+          oldRPath = rpath->Value;
+        } else {
+          auto const* runpath = elf.GetRunPath();
+          if (runpath) {
+            oldRPath = runpath->Value;
+          } else {
+            oldRPath = "";
+          }
+        }
+
+        if (cmSystemTools::StringStartsWith(oldRPath, "$ORIGIN")) {
+          // Skip libraries with ORIGIN RPATH set
+          continue;
+        }
+
+        if (!PatchElfSetRPath(file, newRPath)) {
+          return false;
+        }
+
+        break;
+      }
+      default:
+        cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                      "ELF <" << file << "> type: " << type << std::endl);
+        break;
+    }
+  }
+
+  return true;
+}
+
+bool cmCPackAppImageGenerator::PatchElfSetRPath(std::string const& file,
+                                                std::string const& rpath) const
+{
+  cmCPackLogger(cmCPackLog::LOG_DEBUG,
+                "Changing RPATH: " << file << " to: " << rpath << std::endl);
+  int retVal = 1;
+  bool resS = cmSystemTools::RunSingleCommand(
+    {
+      this->PatchElfPath,
+      "--set-rpath",
+      rpath,
+      file,
+    },
+    nullptr, nullptr, &retVal, nullptr,
+    cmSystemTools::OutputOption::OUTPUT_NONE);
+  if (!resS || retVal) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Problem running patchelf to change RPATH: " << file
+                                                               << std::endl);
+    return false;
+  }
+
+  return true;
+}
diff --git a/Source/CPack/cmCPackAppImageGenerator.h b/Source/CPack/cmCPackAppImageGenerator.h
new file mode 100644
index 0000000..2e1a84b
--- /dev/null
+++ b/Source/CPack/cmCPackAppImageGenerator.h
@@ -0,0 +1,68 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+#include <cm/optional>
+
+#include "cmCPackGenerator.h"
+
+/** \class cmCPackAppImageGenerator
+ * \brief A generator for creating AppImages with CPack
+ */
+class cmCPackAppImageGenerator : public cmCPackGenerator
+{
+public:
+  cmCPackTypeMacro(cmCPackAppImageGenerator, cmCPackGenerator);
+
+  char const* GetOutputExtension() override { return ".AppImage"; }
+
+  cmCPackAppImageGenerator();
+  ~cmCPackAppImageGenerator() override;
+
+protected:
+  /**
+   * @brief Initializes the CPack engine with our defaults
+   */
+  int InitializeInternal() override;
+
+  /**
+   * @brief AppImages are for single applications
+   */
+  bool SupportsComponentInstallation() const override { return false; }
+
+  /**
+   * Main Packaging step
+   */
+  int PackageFiles() override;
+
+private:
+  /**
+   * @brief Finds the first installed file by it's name
+   */
+  cm::optional<std::string> FindFile(std::string const& filename) const;
+
+  /**
+   * @brief AppImage format requires a desktop file
+   */
+  cm::optional<std::string> FindDesktopFile() const;
+
+  /**
+   * @brief Parses a desktop file [Desktop Entry]
+   */
+  std::unordered_map<std::string, std::string> ParseDesktopFile(
+    std::string const& filePath) const;
+
+  /**
+   * @brief changes the RPATH so that AppImage can find it's libraries
+   */
+  bool ChangeRPath();
+
+  bool PatchElfSetRPath(std::string const& file,
+                        std::string const& rpath) const;
+
+  std::string AppimagetoolPath;
+  std::string PatchElfPath;
+};
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index d0d84db..1571bd1 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -312,7 +312,8 @@
 
 bool DebGenerator::generateControlTar(std::string const& md5Filename) const
 {
-  std::string filename_control_tar = this->WorkDir + "/control.tar.gz";
+  std::string filename_control_tar =
+    this->WorkDir + "/control.tar" + this->CompressionSuffix;
 
   cmGeneratedFileStream fileStream_control_tar;
   fileStream_control_tar.Open(filename_control_tar, false, true);
@@ -322,8 +323,7 @@
                     << filename_control_tar << "\" for writing" << std::endl);
     return false;
   }
-  cmArchiveWrite control_tar(fileStream_control_tar,
-                             cmArchiveWrite::CompressGZip,
+  cmArchiveWrite control_tar(fileStream_control_tar, this->TarCompressionType,
                              this->DebianArchiveType);
   if (!control_tar.Open()) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -484,7 +484,8 @@
   deb.SetUNAMEAndGNAME("root", "root");
 
   if (!deb.Add(tlDir + "debian-binary", tlDir.length()) ||
-      !deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
+      !deb.Add(tlDir + "control.tar" + this->CompressionSuffix,
+               tlDir.length()) ||
       !deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
                   "Error creating debian package:\n"
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 05489d0..f0c3439 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -76,6 +76,14 @@
   paths.emplace_back("/Applications/Xcode.app/Contents/Developer/Tools");
   paths.emplace_back("/Developer/Tools");
 
+  std::string const sync_path = cmSystemTools::FindProgram("sync");
+  if (sync_path.empty()) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Cannot locate sync command" << std::endl);
+    return 0;
+  }
+  this->SetOptionIfNotSet("CPACK_COMMAND_SYNC", sync_path);
+
   std::string const hdiutil_path = cmSystemTools::FindProgram("hdiutil");
   if (hdiutil_path.empty()) {
     cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -415,6 +423,16 @@
   std::string temp_image =
     cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg");
 
+  // Finish filesystem operations before writing disk image.
+  std::string sync_command = this->GetOption("CPACK_COMMAND_SYNC");
+  std::string sync_error;
+  if (!this->RunCommand(sync_command, &sync_error)) {
+    cmCPackLogger(cmCPackLog::LOG_ERROR,
+                  "Error running sync command." << std::endl
+                                                << sync_error << std::endl);
+    return 0;
+  }
+
   std::string create_error;
   auto temp_image_command =
     cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
diff --git a/Source/CPack/cmCPackExternalGenerator.h b/Source/CPack/cmCPackExternalGenerator.h
index 2055831..78f8011 100644
--- a/Source/CPack/cmCPackExternalGenerator.h
+++ b/Source/CPack/cmCPackExternalGenerator.h
@@ -9,7 +9,6 @@
 
 #include "cmCPackGenerator.h"
 
-class cmGlobalGenerator;
 namespace Json {
 class Value;
 }
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index e30a343..efe15c2 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -3,6 +3,7 @@
 #include "cmCPackGenerator.h"
 
 #include <algorithm>
+#include <iterator>
 #include <memory>
 #include <utility>
 
@@ -174,14 +175,42 @@
     return 0;
   }
 
-  // Check algorithm for calculating the checksum of the package.
-  cmValue algoSignature = this->GetOption("CPACK_PACKAGE_CHECKSUM");
-  if (algoSignature) {
-    if (!cmCryptoHash::New(*algoSignature)) {
-      cmCPackLogger(cmCPackLog::LOG_ERROR,
-                    "Cannot recognize algorithm: " << algoSignature
-                                                   << std::endl);
-      return 0;
+  // Check algorithms for calculating the checksum of the package.
+  cmValue algoSignatures = this->GetOption("CPACK_PACKAGE_CHECKSUM");
+  if (cmNonempty(algoSignatures)) {
+    cmList algoList{ algoSignatures };
+    // Workout unique algorithms and duplicates for diagnostic purposes
+    algoList.sort();
+    // Store a copy since std::unique modifies the sequence
+    cmList const sortedAlgoList = algoList;
+    auto const newEnd = std::unique(algoList.begin(), algoList.end());
+
+    if (newEnd != algoList.end()) {
+      cmList duplicatesAlgoList;
+
+      std::set_difference(sortedAlgoList.begin(), sortedAlgoList.end(),
+                          algoList.begin(), newEnd,
+                          std::back_inserter(duplicatesAlgoList));
+      // Make sure to output duplicates a single time even if these appear more
+      // than two times. Exploit the already sorted sequence to determine the
+      // unique elements.
+      duplicatesAlgoList.erase(
+        std::unique(duplicatesAlgoList.begin(), duplicatesAlgoList.end()),
+        duplicatesAlgoList.end());
+
+      cmCPackLogger(cmCPackLog::LOG_WARNING,
+                    "Algorithm specified multiple times: "
+                      << duplicatesAlgoList.join(", ") << std::endl);
+    }
+
+    algoList.erase(newEnd, algoList.end());
+
+    for (std::string const& algo : algoList) {
+      if (!cmCryptoHash::New(algo)) {
+        cmCPackLogger(cmCPackLog::LOG_ERROR,
+                      "Cannot recognize algorithm: " << algo << std::endl);
+        return 0;
+      }
     }
   }
 
@@ -1200,8 +1229,22 @@
   }
 
   /* Prepare checksum algorithm*/
-  cmValue algo = this->GetOption("CPACK_PACKAGE_CHECKSUM");
-  std::unique_ptr<cmCryptoHash> crypto = cmCryptoHash::New(*algo);
+  cmValue algoSignatures = this->GetOption("CPACK_PACKAGE_CHECKSUM");
+  std::vector<std::unique_ptr<cmCryptoHash>> crypto;
+
+  if (cmNonempty(algoSignatures)) {
+    cmList algoList{ algoSignatures };
+    // Keep unique algorithms since generating the same checksum multiple times
+    // is not meaningful.
+    algoList.remove_duplicates();
+    crypto.reserve(algoList.size());
+
+    for (std::string const& algo : algoList) {
+      if (std::unique_ptr<cmCryptoHash> hash = cmCryptoHash::New(algo)) {
+        crypto.push_back(std::move(hash));
+      }
+    }
+  }
 
   /*
    * Copy the generated packages to final destination
@@ -1218,9 +1261,9 @@
     if (!this->CopyPackageFile(pkgFileName, filename)) {
       return 0;
     }
-    /* Generate checksum file */
-    if (crypto) {
-      if (!this->GenerateChecksumFile(*crypto, filename)) {
+    /* Generate checksum files */
+    for (std::unique_ptr<cmCryptoHash> const& hash : crypto) {
+      if (!this->GenerateChecksumFile(*hash, filename)) {
         return 0;
       }
     }
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index daf9fa6..c46710c 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -39,6 +39,10 @@
 #  include "WiX/cmCPackWIXGenerator.h"
 #endif
 
+#ifdef __linux__
+#  include "cmCPackAppImageGenerator.h"
+#endif
+
 cmCPackGeneratorFactory::cmCPackGeneratorFactory()
 {
   if (cmCPackArchiveGenerator::CanGenerate()) {
@@ -132,6 +136,12 @@
                             cmCPackFreeBSDGenerator::CreateGenerator);
   }
 #endif
+#ifdef __linux__
+  if (cmCPackAppImageGenerator::CanGenerate()) {
+    this->RegisterGenerator("AppImage", "AppImage packages",
+                            cmCPackAppImageGenerator::CreateGenerator);
+  }
+#endif
 }
 
 std::unique_ptr<cmCPackGenerator> cmCPackGeneratorFactory::NewGenerator(
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 31f0737..85f1786 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -236,6 +236,10 @@
     this->SetOptionIfNotSet("CPACK_NSIS_BRANDING_TEXT_CODE", brandingTextCode);
   }
 
+  if (cmValue v = this->GetOptionIfSet("CPACK_NSIS_CRC_CHECK")) {
+    this->SetOption("CPACK_NSIS_CRC_CHECK_CODE", "CRCCheck " + *v);
+  }
+
   if (!this->IsSet("CPACK_NSIS_IGNORE_LICENSE_PAGE")) {
     cmValue v = this->GetOption("CPACK_RESOURCE_FILE_LICENSE");
     std::string licenseFile = cmSystemTools::ConvertToWindowsOutputPath(*v);
diff --git a/Source/CTest/cmCTestBuildAndTest.cxx b/Source/CTest/cmCTestBuildAndTest.cxx
index 2e9d434..def87dc 100644
--- a/Source/CTest/cmCTestBuildAndTest.cxx
+++ b/Source/CTest/cmCTestBuildAndTest.cxx
@@ -57,7 +57,8 @@
   }
   if (!this->BuildMakeProgram.empty() &&
       (this->BuildGenerator.find("Make") != std::string::npos ||
-       this->BuildGenerator.find("Ninja") != std::string::npos)) {
+       this->BuildGenerator.find("Ninja") != std::string::npos ||
+       this->BuildGenerator.find("FASTBuild") != std::string::npos)) {
     args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram);
   }
 
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index 805da0f..b83f5db 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -4,15 +4,10 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <memory>
 #include <string>
-#include <vector>
 
 #include "cmCTestHandlerCommand.h"
 
-class cmExecutionStatus;
-class cmCTestGenericHandler;
-
 class cmCTestBuildCommand : public cmCTestHandlerCommand
 {
 public:
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index f0e7dab..046ae3d 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -4,7 +4,6 @@
 
 #include <cstdlib>
 #include <memory>
-#include <ratio>
 #include <set>
 #include <utility>
 
@@ -626,48 +625,38 @@
       xml.StartElement("Target");
       xml.Attribute("name", target_name);
 
-      // Check if we have a link snippet for this target.
-      cmsys::Directory target_dir;
-      if (!target_dir.Load(targets_dir.GetFilePath(i))) {
-        cmSystemTools::Error(
-          cmStrCat("Error loading directory ", targets_dir.GetFilePath(i)));
-      }
-      Json::Value link_item;
-      for (unsigned int j = 0; j < target_dir.GetNumberOfFiles(); j++) {
-        std::string fname = target_dir.GetFile(j);
-        if (fname.rfind("link-", 0) == 0) {
-          std::string fpath = target_dir.GetFilePath(j);
-          cmJSONState parseState = cmJSONState(fpath, &link_item);
-          if (!parseState.errors.empty()) {
-            cmSystemTools::Error(parseState.GetErrorMessage(true));
-            break;
-          }
-
-          if (!link_item.isObject()) {
-            std::string error_msg =
-              cmStrCat("Expected snippet ", fpath, " to contain an object");
-            cmSystemTools::Error(error_msg);
-            break;
-          }
+      // Load latest CMake content file
+      Json::Value target_data;
+      std::string cmake_content_file =
+        cmStrCat(CTest->GetInstrumentation().GetDataDir(), "/content/",
+                 this->CTest->GetInstrumentation().GetFileByTimestamp(
+                   cmInstrumentation::LatestOrOldest::Latest, "content"));
+      if (!cmake_content_file.empty() &&
+          cmSystemTools::FileExists(cmake_content_file)) {
+        Json::Value cmake_content;
+        cmJSONState parseState =
+          cmJSONState(cmake_content_file, &cmake_content);
+        if (!parseState.errors.empty()) {
+          cmSystemTools::Error(parseState.GetErrorMessage(true));
           break;
         }
-      }
-
-      // If so, parse targetType and targetLabels (optional) from it.
-      if (link_item.isMember("targetType")) {
-        target_type = link_item["targetType"].asString();
-      }
-
-      xml.Attribute("type", target_type);
-
-      if (link_item.isMember("targetLabels") &&
-          !link_item["targetLabels"].empty()) {
-        xml.StartElement("Labels");
-        for (auto const& json_label_item : link_item["targetLabels"]) {
-          xml.Element("Label", json_label_item.asString());
+        if (cmake_content.isMember("targets")) {
+          target_data = cmake_content["targets"];
         }
-        xml.EndElement(); // Labels
       }
+      // Extract targetType and targetLabels
+      if (target_data.isObject() && target_data.isMember(target_name)) {
+        target_type = target_data[target_name]["type"].asString();
+        if (!target_data[target_name]["labels"].empty()) {
+          xml.StartElement("Labels");
+          for (auto const& json_label_item :
+               target_data[target_name]["labels"]) {
+            xml.Element("Label", json_label_item.asString());
+          }
+          xml.EndElement(); // Labels
+        }
+      }
+      xml.Attribute("type", target_type);
 
       // Write instrumendation data for this target.
       std::string target_subdir = cmStrCat("build/targets/", target_name);
diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h
index 8baec69..2b8feec 100644
--- a/Source/CTest/cmCTestBuildHandler.h
+++ b/Source/CTest/cmCTestBuildHandler.h
@@ -17,7 +17,6 @@
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
 
-class cmMakefile;
 class cmStringReplaceHelper;
 class cmXMLWriter;
 class cmCTest;
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index 5e3001e..6caa56b 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -5,7 +5,6 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmCTestHandlerCommand.h"
 
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 5df1c0e..95b64eb 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -4,7 +4,6 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <memory>
 #include <string>
 #include <vector>
 
@@ -13,9 +12,6 @@
 #include "cmArgumentParserTypes.h" // IWYU pragma: keep
 #include "cmCTestHandlerCommand.h"
 
-class cmExecutionStatus;
-class cmCTestGenericHandler;
-
 class cmCTestCoverageCommand : public cmCTestHandlerCommand
 {
 public:
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 1a0451d..5eb201f 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -9,9 +9,7 @@
 #include <iomanip>
 #include <iterator>
 #include <memory>
-#include <ratio>
 #include <sstream>
-#include <type_traits>
 #include <utility>
 
 #include <cmext/algorithm>
@@ -36,8 +34,6 @@
 #include "cmWorkingDirectory.h"
 #include "cmXMLWriter.h"
 
-class cmMakefile;
-
 #define SAFEDIV(x, y) (((y) != 0) ? ((x) / (y)) : (0))
 
 cmCTestCoverageHandler::cmCTestCoverageHandler(cmCTest* ctest)
diff --git a/Source/CTest/cmCTestCoverageHandler.h b/Source/CTest/cmCTestCoverageHandler.h
index e8232f8..b278161 100644
--- a/Source/CTest/cmCTestCoverageHandler.h
+++ b/Source/CTest/cmCTestCoverageHandler.h
@@ -15,7 +15,6 @@
 #include "cmCTestGenericHandler.h"
 
 class cmGeneratedFileStream;
-class cmMakefile;
 class cmXMLWriter;
 class cmCTest;
 
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index a929b39..1e65450 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -4,16 +4,20 @@
 
 #include <cstdio>
 #include <cstring>
+#include <functional>
 #include <iostream>
 #include <map>
 #include <memory>
 #include <utility>
 
+#include <cm/optional>
+
 #include <cm3p/uv.h>
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
+#include "cmCMakePath.h"
 #include "cmCTestLaunchReporter.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstrumentation.h"
@@ -71,7 +75,8 @@
     DoingCurrentBuildDir,
     DoingCount,
     DoingFilterPrefix,
-    DoingConfig
+    DoingConfig,
+    DoingObjectDir
   };
   Doing doing = DoingNone;
   int arg0 = 0;
@@ -103,6 +108,8 @@
       doing = DoingFilterPrefix;
     } else if (strcmp(arg, "--config") == 0) {
       doing = DoingConfig;
+    } else if (strcmp(arg, "--object-dir") == 0) {
+      doing = DoingObjectDir;
     } else if (doing == DoingOutput) {
       this->Reporter.OptionOutput = arg;
       doing = DoingNone;
@@ -142,9 +149,28 @@
     } else if (doing == DoingConfig) {
       this->Reporter.OptionConfig = arg;
       doing = DoingNone;
+    } else if (doing == DoingObjectDir) {
+      this->Reporter.OptionObjectDir = arg;
+      doing = DoingNone;
     }
   }
 
+  // Older builds do not pass `--object-dir`, so construct a default if the
+  // components are available.
+  if (this->Reporter.OptionObjectDir.empty() &&
+      !this->Reporter.OptionCurrentBuildDir.empty() &&
+      !this->Reporter.OptionTargetName.empty()) {
+    this->Reporter.OptionObjectDir =
+      cmStrCat(this->Reporter.OptionCurrentBuildDir, "/CMakeFiles/",
+               this->Reporter.OptionTargetName, ".dir");
+  }
+  if (!this->Reporter.OptionObjectDir.empty() &&
+      !cmCMakePath(this->Reporter.OptionObjectDir).IsAbsolute() &&
+      !this->Reporter.OptionBuildDir.empty()) {
+    this->Reporter.OptionObjectDir = cmStrCat(
+      this->Reporter.OptionBuildDir, '/', this->Reporter.OptionObjectDir);
+  }
+
   // Extract the real command line.
   if (arg0) {
     for (int i = 0; i < argc - arg0; ++i) {
@@ -283,7 +309,7 @@
     this->Reporter.OptionCommandType, this->RealArgV,
     [this]() -> int {
       this->RunChild();
-      return 0;
+      return this->Reporter.ExitCode;
     },
     options, arrayOptions);
 
diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx
index 2e1d2bb..a768e27 100644
--- a/Source/CTest/cmCTestLaunchReporter.cxx
+++ b/Source/CTest/cmCTestLaunchReporter.cxx
@@ -78,13 +78,12 @@
 
 void cmCTestLaunchReporter::LoadLabels()
 {
-  if (this->OptionCurrentBuildDir.empty() || this->OptionTargetName.empty()) {
+  if (this->OptionObjectDir.empty()) {
     return;
   }
 
   // Labels are listed in per-target files.
-  std::string fname = cmStrCat(this->OptionCurrentBuildDir, "/CMakeFiles/",
-                               this->OptionTargetName, ".dir/Labels.txt");
+  std::string fname = cmStrCat(this->OptionObjectDir, "/Labels.txt");
 
   // We are interested in per-target labels for this source file.
   std::string source = this->OptionSource;
diff --git a/Source/CTest/cmCTestLaunchReporter.h b/Source/CTest/cmCTestLaunchReporter.h
index cc32ced..65b3e3a 100644
--- a/Source/CTest/cmCTestLaunchReporter.h
+++ b/Source/CTest/cmCTestLaunchReporter.h
@@ -8,10 +8,12 @@
 #include <string>
 #include <vector>
 
-#include "cmsys/RegularExpression.hxx"
-
 #include "cmUVProcessChain.h"
 
+namespace cmsys {
+class RegularExpression;
+}
+
 class cmXMLElement;
 
 /** \class cmCTestLaunchReporter
@@ -43,6 +45,7 @@
   std::string OptionCommandType;
   std::string OptionRole;
   std::string OptionConfig;
+  std::string OptionObjectDir;
 
   // The real command line appearing after launcher arguments.
   std::string CWD;
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index b0ea52f..c0a8395 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -4,16 +4,10 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <memory>
 #include <string>
-#include <vector>
 
 #include "cmCTestTestCommand.h"
 
-class cmExecutionStatus;
-class cmCTestGenericHandler;
-class cmCTestTestHandler;
-
 class cmCTestMemCheckCommand : public cmCTestTestCommand
 {
 public:
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index c95cc3f..95f73cb 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -7,7 +7,6 @@
 #include <cstring>
 #include <iostream>
 #include <iterator>
-#include <ratio>
 #include <sstream>
 #include <utility>
 
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index 5f381c2..9bc32fd 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -9,8 +9,6 @@
 
 #include "cmCTestTestHandler.h"
 
-class cmMakefile;
-class cmXMLWriter;
 class cmCTest;
 
 /** \class cmCTestMemCheckHandler
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 1c4f2a5..71a3ab4 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -8,6 +8,7 @@
 #include <cmath>
 #include <cstddef> // IWYU pragma: keep
 #include <cstdlib>
+#include <functional>
 #include <iomanip>
 #include <iostream>
 #include <list>
@@ -34,7 +35,6 @@
 #include "cmCTestBinPacker.h"
 #include "cmCTestRunTest.h"
 #include "cmCTestTestHandler.h"
-#include "cmDuration.h"
 #include "cmJSONState.h"
 #include "cmListFileCache.h"
 #include "cmRange.h"
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.cxx b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
index 343a74e..1b0271f 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.cxx
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.cxx
@@ -2,6 +2,8 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmCTestReadCustomFilesCommand.h"
 
+#include <vector>
+
 #include "cmCTest.h"
 #include "cmExecutionStatus.h"
 
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index 8b1b357..165dd26 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -5,12 +5,9 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmCTestCommand.h"
 
-class cmExecutionStatus;
-
 class cmCTestReadCustomFilesCommand : public cmCTestCommand
 {
 public:
diff --git a/Source/CTest/cmCTestResourceAllocator.cxx b/Source/CTest/cmCTestResourceAllocator.cxx
index a7ae7bc..8aa2152 100644
--- a/Source/CTest/cmCTestResourceAllocator.cxx
+++ b/Source/CTest/cmCTestResourceAllocator.cxx
@@ -72,15 +72,3 @@
   resIt->second.Locked -= slots;
   return true;
 }
-
-bool cmCTestResourceAllocator::Resource::operator==(
-  Resource const& other) const
-{
-  return this->Total == other.Total && this->Locked == other.Locked;
-}
-
-bool cmCTestResourceAllocator::Resource::operator!=(
-  Resource const& other) const
-{
-  return !(*this == other);
-}
diff --git a/Source/CTest/cmCTestResourceAllocator.h b/Source/CTest/cmCTestResourceAllocator.h
index fcb5ef6..cf83c57 100644
--- a/Source/CTest/cmCTestResourceAllocator.h
+++ b/Source/CTest/cmCTestResourceAllocator.h
@@ -17,8 +17,15 @@
 
     unsigned int Free() const { return this->Total - this->Locked; }
 
-    bool operator==(Resource const& other) const;
-    bool operator!=(Resource const& other) const;
+    friend bool operator==(Resource left, Resource right)
+    {
+      return left.Total == right.Total && left.Locked == right.Locked;
+    }
+
+    friend bool operator!=(Resource left, Resource right)
+    {
+      return !(left == right);
+    }
   };
 
   void InitializeFromResourceSpec(cmCTestResourceSpec const& spec);
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index e415310..d1b1ab7 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -2,6 +2,8 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmCTestRunScriptCommand.h"
 
+#include <vector>
+
 #include "cmCTestScriptHandler.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 5b189e5..830b6bf 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -5,12 +5,9 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmCTestCommand.h"
 
-class cmExecutionStatus;
-
 /** \class cmCTestRunScript
  * \brief Run a ctest script
  */
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 24ee6eb..de8651c 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -813,9 +813,7 @@
   if (stop_time != std::chrono::system_clock::time_point()) {
     cmDuration timeUntilStop =
       (stop_time - std::chrono::system_clock::now()) % std::chrono::hours(24);
-    if (timeUntilStop < timeRemaining) {
-      timeRemaining = timeUntilStop;
-    }
+    this->TestProcess->SetStopTimeout(timeUntilStop);
   }
 
   // Enforce remaining time even over explicit TIMEOUT=0.
@@ -824,7 +822,16 @@
   }
   if (!timeout || timeRemaining < *timeout) {
     timeout = timeRemaining;
-    this->TestProcess->SetTimeoutReason(cmProcess::TimeoutReason::StopTime);
+  }
+
+  // Inform the test process of its normal timeout
+  if (timeout) {
+    this->TestProcess->SetTimeout(*timeout);
+  }
+
+  // Ask the test process which timeout is in effect.
+  if (auto ctimeout = this->TestProcess->GetComputedTimeout()) {
+    timeout = ctimeout->Duration;
   }
 
   if (timeout) {
diff --git a/Source/CTest/cmCTestSVN.h b/Source/CTest/cmCTestSVN.h
index 9b4ea6a..7507cac 100644
--- a/Source/CTest/cmCTestSVN.h
+++ b/Source/CTest/cmCTestSVN.h
@@ -13,7 +13,6 @@
 
 class cmCTest;
 class cmMakefile;
-class cmXMLWriter;
 
 /** \class cmCTestSVN
  * \brief Interaction with subversion command-line tool
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index ca66f18..bed2bb7 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -4,8 +4,8 @@
 
 #include <chrono>
 #include <cstdlib>
+#include <functional>
 #include <map>
-#include <ratio>
 #include <sstream>
 #include <utility>
 
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index f939512..e46b4bf 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -4,6 +4,7 @@
 
 #include <cstddef>
 #include <sstream>
+#include <vector>
 
 #include "cmCTest.h"
 #include "cmCTestVC.h"
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 0b5a337..acac563 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -6,7 +6,6 @@
 
 #include <iosfwd>
 #include <string>
-#include <vector>
 
 #include "cmCTestCommand.h"
 
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index f688976..689f193 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -4,7 +4,6 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <memory>
 #include <string>
 #include <vector>
 
@@ -13,9 +12,6 @@
 #include "cmArgumentParserTypes.h"
 #include "cmCTestHandlerCommand.h"
 
-class cmExecutionStatus;
-class cmCTestGenericHandler;
-
 class cmCTestSubmitCommand : public cmCTestHandlerCommand
 {
 public:
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 200ba03..49b71b6 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -9,8 +9,10 @@
 
 #include <cm/iomanip>
 #include <cm/optional>
+#include <cm/string>
 #include <cm/string_view>
 #include <cmext/algorithm>
+#include <cmext/string_view>
 
 #include <cm3p/curl/curl.h>
 #include <cm3p/json/reader.h>
@@ -226,6 +228,11 @@
       std::string remote_file =
         remoteprefix + cmSystemTools::GetFilenameName(file);
 
+      // Erase non-filename and non-space whitespace characters.
+      cm::erase_if(remote_file, [](char c) {
+        return cm::contains("\\:*?\"<>|\n\r\t\f\v"_s, c);
+      });
+
       *this->LogFile << "\tUpload file: " << local_file << " to "
                      << remote_file << std::endl;
 
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 090d42d..125d5a5 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -7,7 +7,6 @@
 #include <memory>
 #include <string>
 #include <type_traits>
-#include <vector>
 
 #include <cm/optional>
 #include <cmext/string_view>
@@ -17,7 +16,6 @@
 #include "cmCTestHandlerCommand.h"
 
 class cmExecutionStatus;
-class cmCTestGenericHandler;
 class cmCTestTestHandler;
 
 class cmCTestTestCommand : public cmCTestHandlerCommand
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index a39cb7b..d0045d1 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -530,7 +530,7 @@
 
 void cmCTestTestHandler::LogTestSummary(std::vector<std::string> const& passed,
                                         std::vector<std::string> const& failed,
-                                        cmDuration const& durationInSecs)
+                                        cmDuration durationInSecs)
 {
   std::size_t total = passed.size() + failed.size();
 
@@ -2073,7 +2073,7 @@
             xml.Attribute("encoding", "base64");
             std::ostringstream ostr;
             for (size_t cc = 0; cc < rlen; cc++) {
-              ostr << encoded_buffer[cc];
+              ostr << static_cast<char>(encoded_buffer[cc]);
               if (cc % 60 == 0 && cc) {
                 ostr << std::endl;
               }
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 9388425..e57bc10 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -25,7 +25,6 @@
 #include "cmDuration.h"
 #include "cmListFileCache.h"
 
-class cmMakefile;
 class cmXMLWriter;
 
 struct cmCTestTestOptions
@@ -242,7 +241,7 @@
   bool ProcessOptions();
   void LogTestSummary(std::vector<std::string> const& passed,
                       std::vector<std::string> const& failed,
-                      cmDuration const& durationInSecs);
+                      cmDuration durationInSecs);
   void LogDisabledTests(std::vector<cmCTestTestResult> const& disabledTests);
   void LogFailedTests(std::vector<std::string> const& failed,
                       SetOfTests const& resultsSet);
diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx
index 71d92c4..925941b 100644
--- a/Source/CTest/cmCTestUpdateCommand.cxx
+++ b/Source/CTest/cmCTestUpdateCommand.cxx
@@ -5,7 +5,6 @@
 #include <chrono>
 #include <sstream>
 #include <string>
-#include <vector>
 
 #include <cm/memory>
 #include <cmext/string_view>
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index 93316de..7bc2e01 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -5,7 +5,6 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmCTestHandlerCommand.h"
 
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 31ed960..9bf81f8 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -158,9 +158,10 @@
 
 void cmProcess::StartTimer()
 {
-  if (this->Timeout) {
-    auto msec =
-      std::chrono::duration_cast<std::chrono::milliseconds>(*this->Timeout);
+  if (auto ctimeout = this->GetComputedTimeout()) {
+    this->TimeoutReason_ = ctimeout->Reason;
+    auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(
+      ctimeout->Duration);
     this->Timer.start(&cmProcess::OnTimeoutCB,
                       static_cast<uint64_t>(msec.count()), 0,
                       cm::uv_update_time::no);
@@ -374,6 +375,24 @@
   return this->ProcessState;
 }
 
+cm::optional<cmProcess::ComputedTimeout> cmProcess::GetComputedTimeout() const
+{
+  if (this->StopTimeout && this->Timeout) {
+    if (*this->StopTimeout < *this->Timeout) {
+      return ComputedTimeout{ TimeoutReason::StopTime, *this->StopTimeout };
+    }
+    return ComputedTimeout{ TimeoutReason::Normal, *this->Timeout };
+  }
+  if (this->StopTimeout) {
+    return ComputedTimeout{ TimeoutReason::StopTime, *this->StopTimeout };
+  }
+  if (this->Timeout) {
+    return ComputedTimeout{ TimeoutReason::Normal, *this->Timeout };
+  }
+
+  return cm::nullopt;
+}
+
 void cmProcess::ChangeTimeout(cmDuration t)
 {
   this->Timeout = t;
@@ -537,7 +556,7 @@
     case STATUS_NO_MEMORY:
     default:
       char buf[1024];
-      char const* fmt = "Exit code 0x%" KWIML_INT_PRIx64 "\n";
+      char const* fmt = "Exit code 0x%" KWIML_INT_PRIx64;
       snprintf(buf, sizeof(buf), fmt, this->ExitValue);
       exception_str.assign(buf);
   }
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 33b781c..a4704b4 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -16,6 +16,8 @@
 
 #include <cm3p/uv.h>
 
+#include <sys/types.h>
+
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
 #include "cmUVHandlePtr.h"
@@ -35,6 +37,7 @@
   void SetCommand(std::string const& command);
   void SetCommandArguments(std::vector<std::string> const& arg);
   void SetWorkingDirectory(std::string const& dir);
+  void SetStopTimeout(cmDuration t) { this->StopTimeout = t; }
   void SetTimeout(cmDuration t) { this->Timeout = t; }
   void ChangeTimeout(cmDuration t);
   void ResetStartTime();
@@ -46,8 +49,13 @@
     Normal,
     StopTime,
   };
-  void SetTimeoutReason(TimeoutReason r) { this->TimeoutReason_ = r; }
   TimeoutReason GetTimeoutReason() const { return this->TimeoutReason_; }
+  struct ComputedTimeout
+  {
+    TimeoutReason Reason;
+    cmDuration Duration;
+  };
+  cm::optional<ComputedTimeout> GetComputedTimeout() const;
 
   enum class State
   {
@@ -102,6 +110,7 @@
   Termination GetTerminationStyle() const { return this->TerminationStyle; }
 
 private:
+  cm::optional<cmDuration> StopTimeout;
   cm::optional<cmDuration> Timeout;
   TimeoutReason TimeoutReason_ = TimeoutReason::Normal;
   std::chrono::steady_clock::time_point StartTime;
diff --git a/Source/CTest/cmUVJobServerClient.cxx b/Source/CTest/cmUVJobServerClient.cxx
index 6ea5452..19fed2c 100644
--- a/Source/CTest/cmUVJobServerClient.cxx
+++ b/Source/CTest/cmUVJobServerClient.cxx
@@ -12,6 +12,8 @@
 
 #  include <fcntl.h>
 #  include <unistd.h>
+
+#  include <sys/types.h>
 #endif
 
 #include <cm/memory>
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
index b074068..ed62602 100644
--- a/Source/Checks/Curses/CMakeLists.txt
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.13...3.31 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...4.0 FATAL_ERROR)
 project(CheckCurses C)
 
 set(CURSES_NEED_NCURSES TRUE)
diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h
index d9fa96f..a6eccc0 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.h
+++ b/Source/CursesDialog/cmCursesBoolWidget.h
@@ -7,8 +7,6 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesWidget.h"
 
-class cmCursesMainForm;
-
 class cmCursesBoolWidget : public cmCursesWidget
 {
 public:
diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h
index b3c6f8f..001625a 100644
--- a/Source/CursesDialog/cmCursesDummyWidget.h
+++ b/Source/CursesDialog/cmCursesDummyWidget.h
@@ -7,8 +7,6 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesWidget.h"
 
-class cmCursesMainForm;
-
 class cmCursesDummyWidget : public cmCursesWidget
 {
 public:
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
index 0a957c9..b432dce 100644
--- a/Source/CursesDialog/cmCursesLabelWidget.h
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -9,8 +9,6 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesWidget.h"
 
-class cmCursesMainForm;
-
 class cmCursesLabelWidget : public cmCursesWidget
 {
 public:
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index d7695b7..5c70aae 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -11,12 +11,12 @@
 
 #include <cm/optional>
 
-#include "cmCursesCacheEntryComposite.h"
 #include "cmCursesForm.h"
 #include "cmCursesStandardIncludes.h"
 #include "cmStateTypes.h"
 
 class cmake;
+class cmCursesCacheEntryComposite;
 class cmCursesLongMessageForm;
 
 /** \class cmCursesMainForm
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.h b/Source/CursesDialog/cmCursesOptionsWidget.h
index 80ba37f..d12eafe 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.h
+++ b/Source/CursesDialog/cmCursesOptionsWidget.h
@@ -10,8 +10,6 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesWidget.h"
 
-class cmCursesMainForm;
-
 class cmCursesOptionsWidget : public cmCursesWidget
 {
 public:
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
index 7aa4545..c4348a2 100644
--- a/Source/CursesDialog/cmCursesPathWidget.h
+++ b/Source/CursesDialog/cmCursesPathWidget.h
@@ -9,8 +9,6 @@
 #include "cmCursesStandardIncludes.h"
 #include "cmCursesStringWidget.h"
 
-class cmCursesMainForm;
-
 class cmCursesPathWidget : public cmCursesStringWidget
 {
 public:
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 08fd0a9..63d8a4f 100644
--- a/Source/LexerParser/cmListFileLexer.c
+++ b/Source/LexerParser/cmListFileLexer.c
@@ -576,16 +576,16 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[79] =
+static const flex_int16_t yy_accept[77] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    4,    4,
        25,   13,   22,    1,   16,    3,   13,    5,    6,    7,
-       15,   23,   23,   17,   19,   20,   21,   24,   10,   11,
-        8,   12,    9,    4,   13,    0,   13,    0,   22,    0,
-        0,    7,   13,    0,   13,    0,    2,    0,   13,   17,
-        0,   18,   10,    8,    4,    0,   14,    0,    0,    0,
-        0,   14,    0,    0,   14,    0,    0,    0,    2,   14,
-        0,    0,    0,    0,    0,    0,    0,    0
+       15,   23,   17,   19,   20,   21,   10,   11,    8,   12,
+        9,    4,   13,    0,   13,    0,   22,    0,    0,    7,
+       13,    0,   13,    0,    2,    0,   13,   17,    0,   18,
+       10,    8,    4,    0,   14,    0,    0,    0,    0,   14,
+        0,    0,   14,    0,    0,    0,    2,   14,    0,    0,
+        0,    0,    0,    0,    0,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -620,118 +620,104 @@
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[17] =
+static const YY_CHAR yy_meta[16] =
     {   0,
         1,    1,    2,    3,    4,    3,    1,    3,    5,    6,
-        1,    6,    1,    1,    7,    2
+        1,    6,    1,    1,    7
     } ;
 
-static const flex_int16_t yy_base[97] =
+static const flex_int16_t yy_base[95] =
     {   0,
-        0,    0,   14,   28,   42,   56,   70,   84,   18,   19,
-       68,  100,   16,  298,  298,   54,   58,  298,  298,   13,
-      115,    0,  298,   51,  298,  298,   21,  298,    0,  298,
-       53,  298,  298,    0,    0,  126,   55,    0,   25,   25,
-       53,    0,    0,  136,   53,    0,   57,    0,    0,   42,
-       50,  298,    0,   43,    0,  146,  160,   45,  172,   43,
-       26,    0,   42,  177,    0,   42,  188,   40,  298,   40,
-        0,   38,   37,   34,   32,   31,   23,  298,  197,  204,
-      211,  218,  225,  232,  239,  245,  252,  259,  262,  268,
-      275,  278,  280,  286,  289,  291
+        0,    0,   13,   25,   14,   16,   17,   18,   90,   88,
+       88,   39,   20,  237,  237,   74,   78,  237,  237,   13,
+       54,    0,   71,  237,  237,   31,    0,  237,   73,  237,
+      237,    0,    0,   65,   75,    0,   33,   30,   72,    0,
+        0,   75,   70,    0,   74,    0,    0,   62,   70,  237,
+        0,   63,    0,   85,   99,   65,  111,   62,   34,    0,
+       54,  116,    0,   54,  127,   51,  237,   50,    0,   48,
+       47,   39,   33,   29,   17,  237,  136,  143,  150,  157,
+      164,  171,  178,  184,  191,  198,  201,  207,  214,  217,
+      219,  225,  228,  230
 
     } ;
 
-static const flex_int16_t yy_def[97] =
+static const flex_int16_t yy_def[95] =
     {   0,
-       78,    1,   79,   79,   80,   80,   81,   81,   82,   82,
-       78,   78,   78,   78,   78,   78,   12,   78,   78,   12,
-       78,   83,   78,   84,   78,   78,   84,   78,   85,   78,
-       78,   78,   78,   86,   12,   87,   12,   88,   78,   78,
-       89,   20,   12,   90,   12,   21,   78,   91,   12,   84,
-       84,   78,   85,   78,   86,   87,   78,   56,   87,   92,
-       78,   57,   89,   90,   57,   64,   90,   93,   78,   57,
-       94,   95,   92,   96,   93,   95,   96,    0,   78,   78,
-       78,   78,   78,   78,   78,   78,   78,   78,   78,   78,
-       78,   78,   78,   78,   78,   78
+       76,    1,   77,   77,   78,   78,   79,   79,   80,   80,
+       76,   76,   76,   76,   76,   76,   12,   76,   76,   12,
+       76,   81,   82,   76,   76,   82,   83,   76,   76,   76,
+       76,   84,   12,   85,   12,   86,   76,   76,   87,   20,
+       12,   88,   12,   21,   76,   89,   12,   82,   82,   76,
+       83,   76,   84,   85,   76,   54,   85,   90,   76,   55,
+       87,   88,   55,   62,   88,   91,   76,   55,   92,   93,
+       90,   94,   91,   93,   94,    0,   76,   76,   76,   76,
+       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
+       76,   76,   76,   76
 
     } ;
 
-static const flex_int16_t yy_nxt[315] =
+static const flex_int16_t yy_nxt[253] =
     {   0,
        12,   13,   14,   13,   15,   16,   17,   18,   19,   12,
-       12,   20,   21,   22,   12,   23,   25,   39,   26,   39,
-       14,   14,   42,   52,   42,   50,   39,   27,   39,   28,
-       25,   64,   26,   28,   28,   61,   61,   47,   47,   56,
-       65,   27,   64,   28,   30,   57,   56,   60,   65,   74,
-       62,   57,   72,   54,   50,   51,   31,   28,   30,   69,
-       68,   62,   60,   54,   51,   41,   40,   78,   78,   78,
-       31,   28,   30,   78,   78,   78,   78,   78,   78,   78,
-       78,   78,   78,   78,   33,   28,   30,   78,   78,   78,
-       78,   78,   78,   78,   78,   78,   78,   78,   33,   28,
+       12,   20,   21,   22,   12,   24,   28,   25,   28,   28,
+       28,   37,   40,   37,   40,   62,   26,   24,   29,   25,
+       29,   31,   31,   50,   37,   48,   37,   54,   26,   33,
+       59,   63,   45,   34,   59,   35,   45,   62,   33,   33,
+       33,   33,   36,   33,   41,   55,   54,   58,   42,   63,
+       43,   72,   60,   41,   44,   41,   45,   46,   41,   55,
+       55,   56,   70,   52,   48,   49,   67,   66,   57,   63,
+       60,   64,   58,   52,   49,   39,   38,   76,   65,   55,
+       14,   56,   14,   76,   76,   76,   76,   76,   57,   55,
 
-       35,   78,   78,   78,   36,   78,   37,   78,   78,   35,
-       35,   35,   35,   38,   35,   43,   78,   78,   78,   44,
-       78,   45,   78,   78,   43,   46,   43,   47,   48,   43,
-       57,   78,   58,   78,   78,   78,   78,   78,   78,   59,
-       65,   78,   66,   78,   78,   78,   78,   78,   78,   67,
-       57,   78,   58,   78,   78,   78,   78,   78,   78,   59,
-       57,   78,   78,   78,   36,   78,   70,   78,   78,   57,
-       57,   57,   57,   71,   57,   56,   78,   56,   78,   56,
-       56,   65,   78,   66,   78,   78,   78,   78,   78,   78,
-       67,   64,   78,   64,   78,   64,   64,   24,   24,   24,
+       76,   76,   76,   34,   76,   68,   76,   76,   55,   55,
+       55,   55,   69,   55,   54,   76,   54,   76,   54,   54,
+       63,   76,   64,   76,   76,   76,   76,   76,   76,   65,
+       62,   76,   62,   76,   62,   62,   23,   23,   23,   23,
+       23,   23,   23,   27,   27,   27,   27,   27,   27,   27,
+       30,   30,   30,   30,   30,   30,   30,   32,   32,   32,
+       32,   32,   32,   32,   47,   76,   47,   47,   47,   47,
+       47,   48,   76,   48,   76,   48,   48,   48,   51,   76,
+       51,   51,   51,   51,   53,   76,   53,   53,   53,   53,
+       53,   54,   76,   76,   54,   76,   54,   54,   33,   76,
 
-       24,   24,   24,   24,   29,   29,   29,   29,   29,   29,
-       29,   32,   32,   32,   32,   32,   32,   32,   34,   34,
-       34,   34,   34,   34,   34,   49,   78,   49,   49,   49,
-       49,   49,   50,   78,   50,   78,   50,   50,   50,   53,
-       78,   53,   53,   53,   53,   55,   78,   55,   55,   55,
-       55,   55,   56,   78,   78,   56,   78,   56,   56,   35,
-       78,   35,   35,   35,   35,   35,   63,   63,   64,   78,
-       78,   64,   78,   64,   64,   43,   78,   43,   43,   43,
-       43,   43,   73,   73,   75,   75,   57,   78,   57,   57,
-       57,   57,   57,   76,   76,   77,   77,   11,   78,   78,
-
-       78,   78,   78,   78,   78,   78,   78,   78,   78,   78,
-       78,   78,   78,   78
+       33,   33,   33,   33,   33,   61,   61,   62,   76,   76,
+       62,   76,   62,   62,   41,   76,   41,   41,   41,   41,
+       41,   71,   71,   73,   73,   55,   76,   55,   55,   55,
+       55,   55,   74,   74,   75,   75,   11,   76,   76,   76,
+       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
+       76,   76
     } ;
 
-static const flex_int16_t yy_chk[315] =
+static const flex_int16_t yy_chk[253] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    3,   13,    3,   13,
-        9,   10,   20,   27,   20,   27,   39,    3,   39,    3,
-        4,   77,    4,    9,   10,   40,   61,   40,   61,   76,
-       75,    4,   74,    4,    5,   73,   72,   70,   68,   66,
-       63,   60,   58,   54,   51,   50,    5,    5,    6,   47,
-       45,   41,   37,   31,   24,   17,   16,   11,    0,    0,
-        6,    6,    7,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    7,    7,    8,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    8,    8,
+        1,    1,    1,    1,    1,    3,    5,    3,    6,    7,
+        8,   13,   20,   13,   20,   75,    3,    4,    5,    4,
+        6,    7,    8,   26,   37,   26,   37,   74,    4,   12,
+       38,   73,   38,   12,   59,   12,   59,   72,   12,   12,
+       12,   12,   12,   12,   21,   71,   70,   68,   21,   66,
+       21,   64,   61,   21,   21,   21,   21,   21,   21,   34,
+       58,   34,   56,   52,   49,   48,   45,   43,   34,   42,
+       39,   42,   35,   29,   23,   17,   16,   11,   42,   54,
+       10,   54,    9,    0,    0,    0,    0,    0,   54,   55,
 
-       12,    0,    0,    0,   12,    0,   12,    0,    0,   12,
-       12,   12,   12,   12,   12,   21,    0,    0,    0,   21,
-        0,   21,    0,    0,   21,   21,   21,   21,   21,   21,
-       36,    0,   36,    0,    0,    0,    0,    0,    0,   36,
-       44,    0,   44,    0,    0,    0,    0,    0,    0,   44,
-       56,    0,   56,    0,    0,    0,    0,    0,    0,   56,
-       57,    0,    0,    0,   57,    0,   57,    0,    0,   57,
-       57,   57,   57,   57,   57,   59,    0,   59,    0,   59,
-       59,   64,    0,   64,    0,    0,    0,    0,    0,    0,
-       64,   67,    0,   67,    0,   67,   67,   79,   79,   79,
+        0,    0,    0,   55,    0,   55,    0,    0,   55,   55,
+       55,   55,   55,   55,   57,    0,   57,    0,   57,   57,
+       62,    0,   62,    0,    0,    0,    0,    0,    0,   62,
+       65,    0,   65,    0,   65,   65,   77,   77,   77,   77,
+       77,   77,   77,   78,   78,   78,   78,   78,   78,   78,
+       79,   79,   79,   79,   79,   79,   79,   80,   80,   80,
+       80,   80,   80,   80,   81,    0,   81,   81,   81,   81,
+       81,   82,    0,   82,    0,   82,   82,   82,   83,    0,
+       83,   83,   83,   83,   84,    0,   84,   84,   84,   84,
+       84,   85,    0,    0,   85,    0,   85,   85,   86,    0,
 
-       79,   79,   79,   79,   80,   80,   80,   80,   80,   80,
-       80,   81,   81,   81,   81,   81,   81,   81,   82,   82,
-       82,   82,   82,   82,   82,   83,    0,   83,   83,   83,
-       83,   83,   84,    0,   84,    0,   84,   84,   84,   85,
-        0,   85,   85,   85,   85,   86,    0,   86,   86,   86,
-       86,   86,   87,    0,    0,   87,    0,   87,   87,   88,
-        0,   88,   88,   88,   88,   88,   89,   89,   90,    0,
-        0,   90,    0,   90,   90,   91,    0,   91,   91,   91,
-       91,   91,   92,   92,   93,   93,   94,    0,   94,   94,
-       94,   94,   94,   95,   95,   96,   96,   78,   78,   78,
-
-       78,   78,   78,   78,   78,   78,   78,   78,   78,   78,
-       78,   78,   78,   78
+       86,   86,   86,   86,   86,   87,   87,   88,    0,    0,
+       88,    0,   88,   88,   89,    0,   89,   89,   89,   89,
+       89,   90,   90,   91,   91,   92,    0,   92,   92,   92,
+       92,   92,   93,   93,   94,   94,   76,   76,   76,   76,
+       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,
+       76,   76
     } ;
 
 /* Table of booleans, true if rule could match eol. */
@@ -784,19 +770,22 @@
   int comment;
   int line;
   int column;
-  int size;
+  size_t size;
   FILE* file;
   size_t cr;
+  char read_buffer[4];
+  size_t read_size;
+  size_t read_position;
   char* string_buffer;
   char* string_position;
-  int string_left;
+  size_t string_left;
   yyscan_t scanner;
 };
 
 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
-                                    int length);
+                                    size_t length);
 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
-                                  int length);
+                                  size_t length);
 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
                                 size_t bufferSize);
 static void cmListFileLexerInit(cmListFileLexer* lexer);
@@ -1089,13 +1078,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 79 )
+				if ( yy_current_state >= 77 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 298 );
+		while ( yy_base[yy_current_state] != 237 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -1148,15 +1137,17 @@
 YY_RULE_SETUP
 {
   const char* bracket = yytext;
+  size_t length = yyleng;
   lexer->comment = yytext[0] == '#';
   if (lexer->comment) {
     lexer->token.type = cmListFileLexer_Token_CommentBracket;
     bracket += 1;
+    --length;
   } else {
     lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
   }
   cmListFileLexerSetToken(lexer, "", 0);
-  lexer->bracket = strchr(bracket+1, '[') - bracket;
+  lexer->bracket = (char*)memchr(bracket + 1, '[', length - 1) - bracket;
   if (yytext[yyleng-1] == '\n') {
     ++lexer->line;
     lexer->column = 1;
@@ -1176,6 +1167,9 @@
 case 4:
 YY_RULE_SETUP
 {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   lexer->column += yyleng;
 }
 	YY_BREAK
@@ -1223,7 +1217,6 @@
   lexer->column += yyleng;
   /* Erase the partial bracket from the token.  */
   lexer->token.length -= lexer->bracket;
-  lexer->token.text[lexer->token.length] = 0;
   BEGIN(INITIAL);
   return 1;
 }
@@ -1231,6 +1224,9 @@
 case 10:
 YY_RULE_SETUP
 {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -1248,6 +1244,9 @@
 case 12:
 YY_RULE_SETUP
 {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
   BEGIN(BRACKET);
@@ -1264,7 +1263,12 @@
 case 13:
 YY_RULE_SETUP
 {
-  lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    /* An unquoted argument that contains a null character. */
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  } else {
+    lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  }
   cmListFileLexerSetToken(lexer, yytext, yyleng);
   lexer->column += yyleng;
   return 1;
@@ -1300,6 +1304,9 @@
 case 17:
 YY_RULE_SETUP
 {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -1333,6 +1340,9 @@
 case 21:
 YY_RULE_SETUP
 {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -1661,7 +1671,7 @@
 
 	for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
 		{
-		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 16);
+		YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
 		if ( yy_accept[yy_current_state] )
 			{
 			yyg->yy_last_accepting_state = yy_current_state;
@@ -1670,7 +1680,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 79 )
+			if ( yy_current_state >= 77 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -1690,7 +1700,7 @@
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
 	char *yy_cp = yyg->yy_c_buf_p;
 
-	YY_CHAR yy_c = 16;
+	YY_CHAR yy_c = 1;
 	if ( yy_accept[yy_current_state] )
 		{
 		yyg->yy_last_accepting_state = yy_current_state;
@@ -1699,11 +1709,11 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 79 )
+		if ( yy_current_state >= 77 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 78);
+	yy_is_jam = (yy_current_state == 76);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -2553,7 +2563,7 @@
 
 /*--------------------------------------------------------------------------*/
 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
-                                    int length)
+                                    size_t length)
 {
   /* Set the token line and column number.  */
   lexer->token.line = lexer->line;
@@ -2562,7 +2572,7 @@
   /* Use the same buffer if possible.  */
   if (lexer->token.text) {
     if (text && length < lexer->size) {
-      strcpy(lexer->token.text, text);
+      memcpy(lexer->token.text, text, length);
       lexer->token.length = length;
       return;
     }
@@ -2572,10 +2582,11 @@
   }
 
   /* Need to extend the buffer.  */
-  if (text) {
-    lexer->token.text = strdup(text);
+  if (length > 0) {
+    lexer->token.text = (char*)malloc(length);
+    memcpy(lexer->token.text, text, length);
     lexer->token.length = length;
-    lexer->size = length + 1;
+    lexer->size = length;
   } else {
     lexer->token.length = 0;
   }
@@ -2583,15 +2594,15 @@
 
 /*--------------------------------------------------------------------------*/
 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
-                                  int length)
+                                  size_t length)
 {
   char* temp;
-  int newSize;
+  size_t newSize;
 
   /* If the appended text will fit in the buffer, do not reallocate.  */
-  newSize = lexer->token.length + length + 1;
+  newSize = lexer->token.length + length;
   if (lexer->token.text && newSize <= lexer->size) {
-    strcpy(lexer->token.text + lexer->token.length, text);
+    memcpy(lexer->token.text + lexer->token.length, text, length);
     lexer->token.length += length;
     return;
   }
@@ -2603,7 +2614,6 @@
     free(lexer->token.text);
   }
   memcpy(temp + lexer->token.length, text, length);
-  temp[lexer->token.length + length] = 0;
   lexer->token.text = temp;
   lexer->token.length += length;
   lexer->size = newSize;
@@ -2619,9 +2629,26 @@
          does not convert newlines on all platforms.  Move any
          trailing CR to the start of the buffer for the next read. */
       size_t cr = lexer->cr;
-      size_t n;
+      size_t n = 0;
       buffer[0] = '\r';
-      n = fread(buffer + cr, 1, bufferSize - cr, lexer->file);
+
+      size_t actualBufferSize = bufferSize - cr;
+      char* p = buffer + cr;
+      size_t readLeft = lexer->read_size - lexer->read_position;
+
+      /* Absorb the bytes that were read during BOM detection, if any. */
+      if (readLeft > 0) {
+        size_t actualReadSize =
+          actualBufferSize >= readLeft ? readLeft : actualBufferSize;
+        memcpy(p, lexer->read_buffer + lexer->read_position, actualReadSize);
+        lexer->read_position += actualReadSize;
+        p += actualReadSize;
+        n += actualReadSize;
+        actualBufferSize -= actualReadSize;
+      }
+
+      n += fread(p, 1, actualBufferSize, lexer->file);
+
       if (n) {
         char* o = buffer;
         const char* i = buffer;
@@ -2643,9 +2670,9 @@
       lexer->cr = cr;
       return n;
     } else if (lexer->string_left) {
-      int length = lexer->string_left;
-      if ((int)bufferSize < length) {
-        length = (int)bufferSize;
+      size_t length = lexer->string_left;
+      if (bufferSize < length) {
+        length = bufferSize;
       }
       memcpy(buffer, lexer->string_position, length);
       lexer->string_position += length;
@@ -2675,6 +2702,11 @@
       fclose(lexer->file);
       lexer->file = 0;
     }
+    if (lexer->read_size != 0) {
+      memset(lexer->read_buffer, 0, sizeof(lexer->read_buffer));
+      lexer->read_size = 0;
+      lexer->read_position = 0;
+    }
     if (lexer->string_buffer) {
       free(lexer->string_buffer);
       lexer->string_buffer = 0;
@@ -2705,36 +2737,66 @@
 }
 
 /*--------------------------------------------------------------------------*/
-static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f,
+                                                   unsigned char readBuffer[4],
+                                                   size_t* readSize)
 {
-  unsigned char b[2];
-  if (fread(b, 1, 2, f) == 2) {
+  /* Read the up to four bytes that might correspond to a BOM. In case these
+     bytes turn out not to represent a BOM, save them for later consumption in
+     order to avoid seeking the file (which might not be seekable, e.g., if
+     it's a pipe). */
+  unsigned char* b = readBuffer;
+
+  size_t n = fread(b, 1, 2, f);
+  *readSize = n; /* Initialize first and then accumulate */
+
+  if (n == 2) {
     if (b[0] == 0xEF && b[1] == 0xBB) {
-      if (fread(b, 1, 1, f) == 1 && b[0] == 0xBF) {
-        return cmListFileLexer_BOM_UTF8;
+      n = fread(b + 2, 1, 1, f);
+      *readSize += n;
+
+      if (n == 1) {
+        if (b[2] == 0xBF) {
+          *readSize = 0; /* We consumed the BOM: discard it */
+          return cmListFileLexer_BOM_UTF8;
+        }
       }
     } else if (b[0] == 0xFE && b[1] == 0xFF) {
+      *readSize = 0; /* We consumed the BOM: discard it */
       /* UTF-16 BE */
       return cmListFileLexer_BOM_UTF16BE;
     } else if (b[0] == 0 && b[1] == 0) {
-      if (fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF) {
-        return cmListFileLexer_BOM_UTF32BE;
+      n = fread(b + 2, 1, 2, f);
+      *readSize += n;
+
+      if (n == 2) {
+        if (b[2] == 0xFE && b[3] == 0xFF) {
+          *readSize = 0; /* We consumed the BOM: discard it */
+          return cmListFileLexer_BOM_UTF32BE;
+        }
       }
     } else if (b[0] == 0xFF && b[1] == 0xFE) {
-      fpos_t p;
-      fgetpos(f, &p);
-      if (fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0) {
+      n = fread(b + 2, 1, 2, f);
+      *readSize += n;
+
+      if (n == 2 && b[2] == 0 && b[3] == 0) {
+        *readSize = 0; /* We consumed the BOM: discard it */
         return cmListFileLexer_BOM_UTF32LE;
       }
-      if (fsetpos(f, &p) != 0) {
-        return cmListFileLexer_BOM_Broken;
+
+      /* In case we were able to subsequently read only a single byte out of two
+         (i.e., three in total), the file must be corrupt and the BOM cannot
+         represent a UTF-16-LE BOM since each code unit must consist of two
+         bytes. This avoids incorrectly detecting an incomplete UTF-32-LE BOM as
+         UTF-16-LE input. */
+      if (n % 2 == 0) {
+        *readSize = n; /* We consumed the read bytes as BOM only partially */
+        memmove(b, b + 2, n);
+        return cmListFileLexer_BOM_UTF16LE;
       }
-      return cmListFileLexer_BOM_UTF16LE;
     }
   }
-  if (fseek(f, 0, SEEK_SET) != 0) {
-    return cmListFileLexer_BOM_Broken;
-  }
+
   return cmListFileLexer_BOM_None;
 }
 
@@ -2754,7 +2816,13 @@
 #endif
     if (lexer->file) {
       if (bom) {
-        *bom = cmListFileLexer_ReadBOM(lexer->file);
+        *bom = cmListFileLexer_ReadBOM(
+          lexer->file, (unsigned char*)lexer->read_buffer, &lexer->read_size);
+        lexer->read_position = 0;
+      } else {
+        memset(lexer->read_buffer, 0, sizeof(lexer->read_buffer));
+        lexer->read_size = 0;
+        lexer->read_position = 0;
       }
     } else {
       result = 0;
@@ -2765,15 +2833,23 @@
 }
 
 /*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
+int cmListFileLexer_SetString(cmListFileLexer* lexer, char const* text,
+                              size_t length)
 {
   int result = 1;
   cmListFileLexerDestroy(lexer);
-  if (text) {
-    int length = (int)strlen(text);
-    lexer->string_buffer = (char*)malloc(length + 1);
+  /* text might be not NULL while length is 0. However, on some platforms
+     malloc(0) will return NULL. To avoid signaling an error to the caller in
+     such cases, ensure nonzero length. */
+  size_t read_size = lexer->read_size - lexer->read_position;
+  size_t string_size = read_size + length;
+  if (string_size > 0) {
+    lexer->string_buffer = (char*)malloc(string_size);
     if (lexer->string_buffer) {
-      strcpy(lexer->string_buffer, text);
+      memcpy(lexer->string_buffer, lexer->read_buffer + lexer->read_position,
+             read_size);
+      memcpy(lexer->string_buffer + read_size, text, length);
+      lexer->read_position += read_size;
       lexer->string_position = lexer->string_buffer;
       lexer->string_left = length;
     } else {
diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l
index 623a36b..18ef5be 100644
--- a/Source/LexerParser/cmListFileLexer.in.l
+++ b/Source/LexerParser/cmListFileLexer.in.l
@@ -36,19 +36,22 @@
   int comment;
   int line;
   int column;
-  int size;
+  size_t size;
   FILE* file;
   size_t cr;
+  char read_buffer[4];
+  size_t read_size;
+  size_t read_position;
   char* string_buffer;
   char* string_position;
-  int string_left;
+  size_t string_left;
   yyscan_t scanner;
 };
 
 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
-                                    int length);
+                                    size_t length);
 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
-                                  int length);
+                                  size_t length);
 static int cmListFileLexerInput(cmListFileLexer* lexer, char* buffer,
                                 size_t bufferSize);
 static void cmListFileLexerInit(cmListFileLexer* lexer);
@@ -74,7 +77,7 @@
 %x COMMENT
 
 MAKEVAR \$\([A-Za-z0-9_]*\)
-UNQUOTED ([^ \0\t\r\n\(\)#\\\"[=]|\\[^\0\n])
+UNQUOTED ([^ \t\r\n\(\)#\\\"[=]|\\[^\n])
 LEGACY {MAKEVAR}|{UNQUOTED}|\"({MAKEVAR}|{UNQUOTED}|[ \t[=])*\"
 
 %%
@@ -90,15 +93,17 @@
 
 #?\[=*\[\n? {
   const char* bracket = yytext;
+  size_t length = yyleng;
   lexer->comment = yytext[0] == '#';
   if (lexer->comment) {
     lexer->token.type = cmListFileLexer_Token_CommentBracket;
     bracket += 1;
+    --length;
   } else {
     lexer->token.type = cmListFileLexer_Token_ArgumentBracket;
   }
   cmListFileLexerSetToken(lexer, "", 0);
-  lexer->bracket = strchr(bracket+1, '[') - bracket;
+  lexer->bracket = (char*)memchr(bracket + 1, '[', length - 1) - bracket;
   if (yytext[yyleng-1] == '\n') {
     ++lexer->line;
     lexer->column = 1;
@@ -113,7 +118,10 @@
   BEGIN(COMMENT);
 }
 
-<COMMENT>[^\0\n]* {
+<COMMENT>[^\n]* {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   lexer->column += yyleng;
 }
 
@@ -151,12 +159,14 @@
   lexer->column += yyleng;
   /* Erase the partial bracket from the token.  */
   lexer->token.length -= lexer->bracket;
-  lexer->token.text[lexer->token.length] = 0;
   BEGIN(INITIAL);
   return 1;
 }
 
-<BRACKET>([^]\0\n])+ {
+<BRACKET>([^]\n])+ {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -168,7 +178,10 @@
   BEGIN(BRACKET);
 }
 
-<BRACKET,BRACKETEND>[^\0\n] {
+<BRACKET,BRACKETEND>[^\n] {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
   BEGIN(BRACKET);
@@ -181,7 +194,12 @@
 }
 
 ({UNQUOTED}|=|\[=*{UNQUOTED})({UNQUOTED}|[[=])* {
-  lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    /* An unquoted argument that contains a null character. */
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  } else {
+    lexer->token.type = cmListFileLexer_Token_ArgumentUnquoted;
+  }
   cmListFileLexerSetToken(lexer, yytext, yyleng);
   lexer->column += yyleng;
   return 1;
@@ -208,7 +226,10 @@
   BEGIN(STRING);
 }
 
-<STRING>([^\\\0\n\"]|\\[^\0\n])+ {
+<STRING>([^\\\n\"]|\\[^\n])+ {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -231,7 +252,10 @@
   return 1;
 }
 
-<STRING>[^\0\n] {
+<STRING>[^\n] {
+  if (memchr(yytext, '\0', yyleng) != NULL) {
+    lexer->token.type = cmListFileLexer_Token_BadCharacter;
+  }
   cmListFileLexerAppend(lexer, yytext, yyleng);
   lexer->column += yyleng;
 }
@@ -266,7 +290,7 @@
 
 /*--------------------------------------------------------------------------*/
 static void cmListFileLexerSetToken(cmListFileLexer* lexer, const char* text,
-                                    int length)
+                                    size_t length)
 {
   /* Set the token line and column number.  */
   lexer->token.line = lexer->line;
@@ -275,7 +299,7 @@
   /* Use the same buffer if possible.  */
   if (lexer->token.text) {
     if (text && length < lexer->size) {
-      strcpy(lexer->token.text, text);
+      memcpy(lexer->token.text, text, length);
       lexer->token.length = length;
       return;
     }
@@ -285,10 +309,11 @@
   }
 
   /* Need to extend the buffer.  */
-  if (text) {
-    lexer->token.text = strdup(text);
+  if (length > 0) {
+    lexer->token.text = (char*)malloc(length);
+    memcpy(lexer->token.text, text, length);
     lexer->token.length = length;
-    lexer->size = length + 1;
+    lexer->size = length;
   } else {
     lexer->token.length = 0;
   }
@@ -296,15 +321,15 @@
 
 /*--------------------------------------------------------------------------*/
 static void cmListFileLexerAppend(cmListFileLexer* lexer, const char* text,
-                                  int length)
+                                  size_t length)
 {
   char* temp;
-  int newSize;
+  size_t newSize;
 
   /* If the appended text will fit in the buffer, do not reallocate.  */
-  newSize = lexer->token.length + length + 1;
+  newSize = lexer->token.length + length;
   if (lexer->token.text && newSize <= lexer->size) {
-    strcpy(lexer->token.text + lexer->token.length, text);
+    memcpy(lexer->token.text + lexer->token.length, text, length);
     lexer->token.length += length;
     return;
   }
@@ -316,7 +341,6 @@
     free(lexer->token.text);
   }
   memcpy(temp + lexer->token.length, text, length);
-  temp[lexer->token.length + length] = 0;
   lexer->token.text = temp;
   lexer->token.length += length;
   lexer->size = newSize;
@@ -332,9 +356,26 @@
          does not convert newlines on all platforms.  Move any
          trailing CR to the start of the buffer for the next read. */
       size_t cr = lexer->cr;
-      size_t n;
+      size_t n = 0;
       buffer[0] = '\r';
-      n = fread(buffer + cr, 1, bufferSize - cr, lexer->file);
+
+      size_t actualBufferSize = bufferSize - cr;
+      char* p = buffer + cr;
+      size_t readLeft = lexer->read_size - lexer->read_position;
+
+      /* Absorb the bytes that were read during BOM detection, if any. */
+      if (readLeft > 0) {
+        size_t actualReadSize =
+          actualBufferSize >= readLeft ? readLeft : actualBufferSize;
+        memcpy(p, lexer->read_buffer + lexer->read_position, actualReadSize);
+        lexer->read_position += actualReadSize;
+        p += actualReadSize;
+        n += actualReadSize;
+        actualBufferSize -= actualReadSize;
+      }
+
+      n += fread(p, 1, actualBufferSize, lexer->file);
+
       if (n) {
         char* o = buffer;
         const char* i = buffer;
@@ -356,9 +397,9 @@
       lexer->cr = cr;
       return n;
     } else if (lexer->string_left) {
-      int length = lexer->string_left;
-      if ((int)bufferSize < length) {
-        length = (int)bufferSize;
+      size_t length = lexer->string_left;
+      if (bufferSize < length) {
+        length = bufferSize;
       }
       memcpy(buffer, lexer->string_position, length);
       lexer->string_position += length;
@@ -388,6 +429,11 @@
       fclose(lexer->file);
       lexer->file = 0;
     }
+    if (lexer->read_size != 0) {
+      memset(lexer->read_buffer, 0, sizeof(lexer->read_buffer));
+      lexer->read_size = 0;
+      lexer->read_position = 0;
+    }
     if (lexer->string_buffer) {
       free(lexer->string_buffer);
       lexer->string_buffer = 0;
@@ -418,36 +464,66 @@
 }
 
 /*--------------------------------------------------------------------------*/
-static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f)
+static cmListFileLexer_BOM cmListFileLexer_ReadBOM(FILE* f,
+                                                   unsigned char readBuffer[4],
+                                                   size_t* readSize)
 {
-  unsigned char b[2];
-  if (fread(b, 1, 2, f) == 2) {
+  /* Read the up to four bytes that might correspond to a BOM. In case these
+     bytes turn out not to represent a BOM, save them for later consumption in
+     order to avoid seeking the file (which might not be seekable, e.g., if
+     it's a pipe). */
+  unsigned char* b = readBuffer;
+
+  size_t n = fread(b, 1, 2, f);
+  *readSize = n; /* Initialize first and then accumulate */
+
+  if (n == 2) {
     if (b[0] == 0xEF && b[1] == 0xBB) {
-      if (fread(b, 1, 1, f) == 1 && b[0] == 0xBF) {
-        return cmListFileLexer_BOM_UTF8;
+      n = fread(b + 2, 1, 1, f);
+      *readSize += n;
+
+      if (n == 1) {
+        if (b[2] == 0xBF) {
+          *readSize = 0; /* We consumed the BOM: discard it */
+          return cmListFileLexer_BOM_UTF8;
+        }
       }
     } else if (b[0] == 0xFE && b[1] == 0xFF) {
+      *readSize = 0; /* We consumed the BOM: discard it */
       /* UTF-16 BE */
       return cmListFileLexer_BOM_UTF16BE;
     } else if (b[0] == 0 && b[1] == 0) {
-      if (fread(b, 1, 2, f) == 2 && b[0] == 0xFE && b[1] == 0xFF) {
-        return cmListFileLexer_BOM_UTF32BE;
+      n = fread(b + 2, 1, 2, f);
+      *readSize += n;
+
+      if (n == 2) {
+        if (b[2] == 0xFE && b[3] == 0xFF) {
+          *readSize = 0; /* We consumed the BOM: discard it */
+          return cmListFileLexer_BOM_UTF32BE;
+        }
       }
     } else if (b[0] == 0xFF && b[1] == 0xFE) {
-      fpos_t p;
-      fgetpos(f, &p);
-      if (fread(b, 1, 2, f) == 2 && b[0] == 0 && b[1] == 0) {
+      n = fread(b + 2, 1, 2, f);
+      *readSize += n;
+
+      if (n == 2 && b[2] == 0 && b[3] == 0) {
+        *readSize = 0; /* We consumed the BOM: discard it */
         return cmListFileLexer_BOM_UTF32LE;
       }
-      if (fsetpos(f, &p) != 0) {
-        return cmListFileLexer_BOM_Broken;
+
+      /* In case we were able to subsequently read only a single byte out of two
+         (i.e., three in total), the file must be corrupt and the BOM cannot
+         represent a UTF-16-LE BOM since each code unit must consist of two
+         bytes. This avoids incorrectly detecting an incomplete UTF-32-LE BOM as
+         UTF-16-LE input. */
+      if (n % 2 == 0) {
+        *readSize = n; /* We consumed the read bytes as BOM only partially */
+        memmove(b, b + 2, n);
+        return cmListFileLexer_BOM_UTF16LE;
       }
-      return cmListFileLexer_BOM_UTF16LE;
     }
   }
-  if (fseek(f, 0, SEEK_SET) != 0) {
-    return cmListFileLexer_BOM_Broken;
-  }
+
   return cmListFileLexer_BOM_None;
 }
 
@@ -467,7 +543,13 @@
 #endif
     if (lexer->file) {
       if (bom) {
-        *bom = cmListFileLexer_ReadBOM(lexer->file);
+        *bom = cmListFileLexer_ReadBOM(
+          lexer->file, (unsigned char*)lexer->read_buffer, &lexer->read_size);
+        lexer->read_position = 0;
+      } else {
+        memset(lexer->read_buffer, 0, sizeof(lexer->read_buffer));
+        lexer->read_size = 0;
+        lexer->read_position = 0;
       }
     } else {
       result = 0;
@@ -478,15 +560,23 @@
 }
 
 /*--------------------------------------------------------------------------*/
-int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
+int cmListFileLexer_SetString(cmListFileLexer* lexer, char const* text,
+                              size_t length)
 {
   int result = 1;
   cmListFileLexerDestroy(lexer);
-  if (text) {
-    int length = (int)strlen(text);
-    lexer->string_buffer = (char*)malloc(length + 1);
+  /* text might be not NULL while length is 0. However, on some platforms
+     malloc(0) will return NULL. To avoid signaling an error to the caller in
+     such cases, ensure nonzero length. */
+  size_t read_size = lexer->read_size - lexer->read_position;
+  size_t string_size = read_size + length;
+  if (string_size > 0) {
+    lexer->string_buffer = (char*)malloc(string_size);
     if (lexer->string_buffer) {
-      strcpy(lexer->string_buffer, text);
+      memcpy(lexer->string_buffer, lexer->read_buffer + lexer->read_position,
+             read_size);
+      memcpy(lexer->string_buffer + read_size, text, length);
+      lexer->read_position += read_size;
       lexer->string_position = lexer->string_buffer;
       lexer->string_left = length;
     } else {
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index 44cde84..d6879fd 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -286,6 +286,7 @@
   set(ENABLE_CAT_SHARED OFF)
   set(ENABLE_UNZIP OFF)
   set(ENABLE_UNZIP_SHARED OFF)
+  set(ENABLE_WIN32_XMLLITE OFF)
   set(ENABLE_XATTR OFF)
   set(ENABLE_ACL OFF)
   set(ENABLE_ICONV OFF)
diff --git a/Source/Modules/FindJsonCpp.cmake b/Source/Modules/FindJsonCpp.cmake
index beafeb3..8c58efb 100644
--- a/Source/Modules/FindJsonCpp.cmake
+++ b/Source/Modules/FindJsonCpp.cmake
@@ -19,12 +19,8 @@
 This module defines the following variables:
 
 ``JsonCpp_FOUND``
-  True if JsonCpp was found, false otherwise.
-``JsonCpp_INCLUDE_DIRS``
-  Include directories needed to include JsonCpp headers.
-``JsonCpp_LIBRARIES``
-  Libraries needed to link to JsonCpp.
-``JsonCpp_VERSION_STRING``
+  Boolean indicating whether (the requested version of) JsonCpp was found.
+``JsonCpp_VERSION``
   The version of JsonCpp found.
   May not be set for JsonCpp versions prior to 1.0.
 ``JsonCpp_VERSION_MAJOR``
@@ -33,6 +29,10 @@
   The minor version of JsonCpp.
 ``JsonCpp_VERSION_PATCH``
   The patch version of JsonCpp.
+``JsonCpp_INCLUDE_DIRS``
+  Include directories needed to include JsonCpp headers.
+``JsonCpp_LIBRARIES``
+  Libraries needed to link to JsonCpp.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
@@ -69,12 +69,12 @@
   set(_JsonCpp_H "")
 endif()
 if(_JsonCpp_H MATCHES "${_JsonCpp_H_REGEX}")
-  set(JsonCpp_VERSION_STRING "${CMAKE_MATCH_1}")
+  set(JsonCpp_VERSION "${CMAKE_MATCH_1}")
   set(JsonCpp_VERSION_MAJOR "${CMAKE_MATCH_2}")
   set(JsonCpp_VERSION_MINOR "${CMAKE_MATCH_3}")
   set(JsonCpp_VERSION_PATCH "${CMAKE_MATCH_4}")
 else()
-  set(JsonCpp_VERSION_STRING "")
+  set(JsonCpp_VERSION "")
   set(JsonCpp_VERSION_MAJOR "")
   set(JsonCpp_VERSION_MINOR "")
   set(JsonCpp_VERSION_PATCH "")
@@ -86,7 +86,7 @@
 include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
 find_package_handle_standard_args(JsonCpp
   REQUIRED_VARS JsonCpp_LIBRARY JsonCpp_INCLUDE_DIR
-  VERSION_VAR JsonCpp_VERSION_STRING
+  VERSION_VAR JsonCpp_VERSION
   )
 
 #-----------------------------------------------------------------------------
diff --git a/Source/Modules/FindLibRHash.cmake b/Source/Modules/FindLibRHash.cmake
index 7cd2006..6ed0385 100644
--- a/Source/Modules/FindLibRHash.cmake
+++ b/Source/Modules/FindLibRHash.cmake
@@ -19,7 +19,7 @@
 This module defines the following variables:
 
 ``LibRHash_FOUND``
-  True if LibRHash was found, false otherwise.
+  Boolean indicating whether LibRHash was found.
 ``LibRHash_INCLUDE_DIRS``
   Include directories needed to include LibRHash headers.
 ``LibRHash_LIBRARIES``
diff --git a/Source/Modules/FindLibUUID.cmake b/Source/Modules/FindLibUUID.cmake
index cc8168a..3fb5e14 100644
--- a/Source/Modules/FindLibUUID.cmake
+++ b/Source/Modules/FindLibUUID.cmake
@@ -19,7 +19,7 @@
 This module defines the following variables:
 
 ``LibUUID_FOUND``
-  True if LibUUID was found, false otherwise.
+  Boolean indicating whether LibUUID was found.
 ``LibUUID_INCLUDE_DIRS``
   Include directories needed to include LibUUID headers.
 ``LibUUID_LIBRARIES``
diff --git a/Source/Modules/FindLibUV.cmake b/Source/Modules/FindLibUV.cmake
index 049d31b..a866111 100644
--- a/Source/Modules/FindLibUV.cmake
+++ b/Source/Modules/FindLibUV.cmake
@@ -19,11 +19,7 @@
 This module defines the following variables:
 
 ``LibUV_FOUND``
-  True if libuv was found, false otherwise.
-``LibUV_INCLUDE_DIRS``
-  Include directories needed to include libuv headers.
-``LibUV_LIBRARIES``
-  Libraries needed to link to libuv.
+  Boolean indicating whether (the requested version of) libuv was found.
 ``LibUV_VERSION``
   The version of libuv found.
 ``LibUV_VERSION_MAJOR``
@@ -32,6 +28,10 @@
   The minor version of libuv.
 ``LibUV_VERSION_PATCH``
   The patch version of libuv.
+``LibUV_INCLUDE_DIRS``
+  Include directories needed to include libuv headers.
+``LibUV_LIBRARIES``
+  Libraries needed to link to libuv.
 
 Cache Variables
 ^^^^^^^^^^^^^^^
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index baf8fbd..62b6eb2 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -589,11 +589,12 @@
     preset.setToolset = !p.ToolsetStrategy ||
       p.ToolsetStrategy == cmCMakePresetsGraph::ArchToolsetStrategy::Set;
     preset.enabled = it.Expanded && it.Expanded->ConditionResult &&
-      std::find_if(this->AvailableGenerators.begin(),
-                   this->AvailableGenerators.end(),
-                   [&p](cmake::GeneratorInfo const& g) {
-                     return g.name == p.Generator;
-                   }) != this->AvailableGenerators.end();
+      ((p.OriginFile->Version >= 3 && p.Generator.empty()) ||
+       std::find_if(this->AvailableGenerators.begin(),
+                    this->AvailableGenerators.end(),
+                    [&p](cmake::GeneratorInfo const& g) {
+                      return g.name == p.Generator;
+                    }) != this->AvailableGenerators.end());
     presets.push_back(preset);
   }
   emit this->presetsChanged(presets);
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 842eb3b..1c9d0c6 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -33,6 +33,7 @@
   bool excludeFromAll = false;
   bool importTarget = false;
   bool importGlobal = false;
+  bool symbolicTarget = false;
 
   auto s = args.begin();
 
@@ -117,6 +118,9 @@
     } else if (*s == "EXCLUDE_FROM_ALL") {
       ++s;
       excludeFromAll = true;
+    } else if (*s == "SYMBOLIC") {
+      ++s;
+      symbolicTarget = true;
     } else if (*s == "IMPORTED") {
       ++s;
       importTarget = true;
@@ -223,9 +227,9 @@
   }
 
   /* ideally we should check whether for the linker language of the target
-    CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
-    STATIC. But at this point we know only the name of the target, but not
-    yet its linker language. */
+     CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
+     STATIC. But at this point we know only the name of the target, but not
+     yet its linker language. */
   if ((type == cmStateEnums::SHARED_LIBRARY ||
        type == cmStateEnums::MODULE_LIBRARY) &&
       !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
@@ -282,7 +286,8 @@
     }
 
     // Create the imported target.
-    mf.AddImportedTarget(libName, type, importGlobal);
+    cmTarget* target = mf.AddImportedTarget(libName, type, importGlobal);
+    target->SetSymbolic(symbolicTarget);
     return true;
   }
 
@@ -312,8 +317,15 @@
     }
   }
 
+  if (symbolicTarget && type != cmStateEnums::INTERFACE_LIBRARY) {
+    status.SetError(
+      "SYMBOLIC option may only be used with INTERFACE libraries");
+    return false;
+  }
+
   std::vector<std::string> srcs(s, args.end());
-  mf.AddLibrary(libName, type, srcs, excludeFromAll);
+  cmTarget* target = mf.AddLibrary(libName, type, srcs, excludeFromAll);
+  target->SetSymbolic(symbolicTarget);
 
   return true;
 }
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 321cddf..3a8c890 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -20,7 +20,7 @@
 #include "cmsys/Encoding.hxx"
 #include "cmsys/FStream.hxx"
 
-#include "cm_get_date.h"
+#include "cm_parse_date.h"
 
 #include "cmLocale.h"
 #include "cmStringAlgorithms.h"
@@ -345,7 +345,7 @@
   if (!this->MTime.empty()) {
     time_t now;
     time(&now);
-    time_t t = cm_get_date(now, this->MTime.c_str());
+    time_t t = cm_parse_date(now, this->MTime.c_str());
     if (t == -1) {
       this->Error = cmStrCat("unable to parse mtime '", this->MTime, '\'');
       return false;
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 104436b..765e9cb 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -14,11 +14,9 @@
 auto KeywordActionMap::Emplace(cm::string_view name, KeywordAction action)
   -> std::pair<iterator, bool>
 {
-  auto const it =
-    std::lower_bound(this->begin(), this->end(), name,
-                     [](value_type const& elem, cm::string_view const& k) {
-                       return elem.first < k;
-                     });
+  auto const it = std::lower_bound(
+    this->begin(), this->end(), name,
+    [](value_type const& elem, cm::string_view k) { return elem.first < k; });
   return (it != this->end() && it->first == name)
     ? std::make_pair(it, false)
     : std::make_pair(this->emplace(it, name, std::move(action)), true);
@@ -26,11 +24,9 @@
 
 auto KeywordActionMap::Find(cm::string_view name) const -> const_iterator
 {
-  auto const it =
-    std::lower_bound(this->begin(), this->end(), name,
-                     [](value_type const& elem, cm::string_view const& k) {
-                       return elem.first < k;
-                     });
+  auto const it = std::lower_bound(
+    this->begin(), this->end(), name,
+    [](value_type const& elem, cm::string_view k) { return elem.first < k; });
   return (it != this->end() && it->first == name) ? it : this->end();
 }
 
@@ -56,8 +52,8 @@
 void Instance::Bind(std::function<Continue(cm::string_view)> f,
                     ExpectAtLeast expect)
 {
-  this->KeywordValueFunc = std::move(f);
-  this->KeywordValuesExpected = expect.Count;
+  this->GetState().KeywordValueFunc = std::move(f);
+  this->GetState().KeywordValuesExpected = expect.Count;
 }
 
 void Instance::Bind(bool& val)
@@ -81,7 +77,7 @@
   this->Bind(
     [this, &val](cm::string_view arg) -> Continue {
       if (arg.empty() && this->ParseResults) {
-        this->ParseResults->AddKeywordError(this->Keyword,
+        this->ParseResults->AddKeywordError(this->GetState().Keyword,
                                             "  empty string not allowed\n");
       }
       val = std::string(arg);
@@ -132,48 +128,50 @@
     ExpectAtLeast{ 0 });
 }
 
-void Instance::Consume(std::size_t pos, cm::string_view arg)
+void Instance::Consume(cm::string_view arg)
 {
-  auto const it = this->Bindings.Keywords.Find(arg);
-  if (it != this->Bindings.Keywords.end()) {
+  ParserState& state = this->GetState();
+
+  auto const it = state.Bindings.Keywords.Find(arg);
+  if (it != state.Bindings.Keywords.end()) {
     this->FinishKeyword();
-    this->Keyword = it->first;
-    this->KeywordValuesSeen = 0;
-    this->DoneWithPositional = true;
-    if (this->Bindings.ParsedKeyword) {
-      this->Bindings.ParsedKeyword(*this, it->first);
+    state.Keyword = it->first;
+    state.KeywordValuesSeen = 0;
+    state.DoneWithPositional = true;
+    if (state.Bindings.ParsedKeyword) {
+      state.Bindings.ParsedKeyword(*this, it->first);
     }
     it->second(*this);
     return;
   }
 
-  if (!this->DoneWithPositional) {
-    auto const pit = this->Bindings.Positions.Find(pos);
-    if (pit != this->Bindings.Positions.end()) {
-      pit->second(*this, pos, arg);
+  if (!state.DoneWithPositional) {
+    auto const pit = state.Bindings.Positions.Find(state.Pos);
+    if (pit != state.Bindings.Positions.end()) {
+      pit->second(*this, state.Pos, arg);
       return;
     }
 
-    if (this->Bindings.TrailingArgs) {
-      this->Keyword = ""_s;
-      this->KeywordValuesSeen = 0;
-      this->DoneWithPositional = true;
-      this->Bindings.TrailingArgs(*this);
-      if (!this->KeywordValueFunc) {
+    if (state.Bindings.TrailingArgs) {
+      state.Keyword = ""_s;
+      state.KeywordValuesSeen = 0;
+      state.DoneWithPositional = true;
+      state.Bindings.TrailingArgs(*this);
+      if (!state.KeywordValueFunc) {
         return;
       }
     }
   }
 
-  if (this->KeywordValueFunc) {
-    switch (this->KeywordValueFunc(arg)) {
+  if (state.KeywordValueFunc) {
+    switch (state.KeywordValueFunc(arg)) {
       case Continue::Yes:
         break;
       case Continue::No:
-        this->KeywordValueFunc = nullptr;
+        state.KeywordValueFunc = nullptr;
         break;
     }
-    ++this->KeywordValuesSeen;
+    ++state.KeywordValuesSeen;
     return;
   }
 
@@ -184,16 +182,18 @@
 
 void Instance::FinishKeyword()
 {
-  if (!this->DoneWithPositional) {
+  ParserState const& state = this->GetState();
+  if (!state.DoneWithPositional) {
     return;
   }
-  if (this->KeywordValuesSeen < this->KeywordValuesExpected) {
+
+  if (state.KeywordValuesSeen < state.KeywordValuesExpected) {
     if (this->ParseResults) {
-      this->ParseResults->AddKeywordError(this->Keyword,
+      this->ParseResults->AddKeywordError(state.Keyword,
                                           "  missing required value\n");
     }
-    if (this->Bindings.KeywordMissingValue) {
-      this->Bindings.KeywordMissingValue(*this, this->Keyword);
+    if (state.Bindings.KeywordMissingValue) {
+      state.Bindings.KeywordMissingValue(*this, state.Keyword);
     }
   }
 }
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 223c3ce..2b37869 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -7,7 +7,6 @@
 #include <cassert>
 #include <cstddef>
 #include <functional>
-#include <iterator>
 #include <map>
 #include <string>
 #include <utility>
@@ -165,16 +164,49 @@
   }
 };
 
+class ParserState
+{
+public:
+  cm::string_view Keyword;
+  std::size_t Pos = 0;
+  std::size_t KeywordValuesSeen = 0;
+  std::size_t KeywordValuesExpected = 0;
+  std::function<Continue(cm::string_view)> KeywordValueFunc = nullptr;
+
+  ActionMap const& Bindings;
+  void* Result = nullptr;
+  bool DoneWithPositional = false;
+
+  ParserState(ActionMap const& bindings, void* result)
+    : Bindings(bindings)
+    , Result(result)
+  {
+  }
+};
+
 class Instance
 {
 public:
   Instance(ActionMap const& bindings, ParseResult* parseResult,
            std::vector<std::string>* unparsedArguments, void* result = nullptr)
-    : Bindings(bindings)
-    , ParseResults(parseResult)
+    : ParseResults(parseResult)
     , UnparsedArguments(unparsedArguments)
-    , Result(result)
   {
+    PushState(bindings, result);
+  }
+
+  ParserState& GetState() { return this->Stack.back(); }
+
+  void PushState(ActionMap const& bindings, void* result)
+  {
+    this->Stack.emplace_back(bindings, result);
+  }
+
+  void PopState()
+  {
+    if (!this->Stack.empty()) {
+      this->Stack.pop_back();
+    }
   }
 
   void Bind(std::function<Continue(cm::string_view)> f, ExpectAtLeast expect);
@@ -185,6 +217,7 @@
   void Bind(MaybeEmpty<std::vector<std::string>>& val);
   void Bind(NonEmpty<std::vector<std::string>>& val);
   void Bind(std::vector<std::vector<std::string>>& val);
+
   template <typename U>
   void Bind(NonEmpty<std::vector<std::pair<std::string, U>>>& val,
             U const& context)
@@ -217,27 +250,43 @@
   }
 
   template <typename Range>
-  void Parse(Range const& args, std::size_t pos = 0)
+  void Parse(Range& args, std::size_t const pos = 0)
   {
+    GetState().Pos = pos;
     for (cm::string_view arg : args) {
-      this->Consume(pos++, arg);
+      for (size_t j = 0; j < FindKeywordOwnerLevel(arg); ++j) {
+        this->PopState();
+      }
+
+      this->Consume(arg);
+      GetState().Pos++;
     }
+
     this->FinishKeyword();
+
+    while (this->Stack.size() > 1) {
+      this->FinishKeyword();
+      this->PopState();
+    }
+  }
+
+  std::size_t FindKeywordOwnerLevel(cm::string_view arg) const
+  {
+    for (std::size_t i = Stack.size(); i--;) {
+      if (this->Stack[i].Bindings.Keywords.Find(arg) !=
+          this->Stack[i].Bindings.Keywords.end()) {
+        return (this->Stack.size() - 1) - i;
+      }
+    }
+    return 0;
   }
 
 private:
-  ActionMap const& Bindings;
+  std::vector<ParserState> Stack;
   ParseResult* ParseResults = nullptr;
   std::vector<std::string>* UnparsedArguments = nullptr;
-  void* Result = nullptr;
 
-  cm::string_view Keyword;
-  std::size_t KeywordValuesSeen = 0;
-  std::size_t KeywordValuesExpected = 0;
-  std::function<Continue(cm::string_view)> KeywordValueFunc;
-  bool DoneWithPositional = false;
-
-  void Consume(std::size_t pos, cm::string_view arg);
+  void Consume(cm::string_view arg);
   void FinishKeyword();
 
   template <typename Result>
@@ -250,6 +299,8 @@
 class cmArgumentParser : private ArgumentParser::Base
 {
 public:
+  using Base::Bindings;
+
   // I *think* this function could be made `constexpr` when the code is
   // compiled as C++20.  This would allow building a parser at compile time.
   template <typename T, typename cT = cm::member_pointer_class_t<T>,
@@ -259,7 +310,7 @@
   cmArgumentParser& Bind(cm::static_string_view name, T member)
   {
     this->Base::Bind(name, [member](Instance& instance) {
-      instance.Bind(static_cast<Result*>(instance.Result)->*member);
+      instance.Bind(static_cast<Result*>(instance.GetState().Result)->*member);
     });
     return *this;
   }
@@ -269,7 +320,7 @@
                                     T Result::*member, U Result::*context)
   {
     this->Base::Bind(name, [member, context](Instance& instance) {
-      auto* result = static_cast<Result*>(instance.Result);
+      auto* result = static_cast<Result*>(instance.GetState().Result);
       instance.Bind(result->*member, result->*context);
     });
     return *this;
@@ -280,7 +331,7 @@
                          ExpectAtLeast expect = { 1 })
   {
     this->Base::Bind(name, [member, expect](Instance& instance) {
-      Result* result = static_cast<Result*>(instance.Result);
+      Result* result = static_cast<Result*>(instance.GetState().Result);
       instance.Bind(
         [result, member](cm::string_view arg) -> Continue {
           return (result->*member)(arg);
@@ -296,8 +347,8 @@
                          ExpectAtLeast expect = { 1 })
   {
     this->Base::Bind(name, [member, expect](Instance& instance) {
-      Result* result = static_cast<Result*>(instance.Result);
-      cm::string_view keyword = instance.Keyword;
+      Result* result = static_cast<Result*>(instance.GetState().Result);
+      cm::string_view keyword = instance.GetState().Keyword;
       instance.Bind(
         [result, member, keyword](cm::string_view arg) -> Continue {
           return (result->*member)(keyword, arg);
@@ -312,7 +363,7 @@
                          ExpectAtLeast expect = { 1 })
   {
     this->Base::Bind(name, [f, expect](Instance& instance) {
-      Result* result = static_cast<Result*>(instance.Result);
+      Result* result = static_cast<Result*>(instance.GetState().Result);
       instance.Bind(
         [result, &f](cm::string_view arg) -> Continue {
           return f(*result, arg);
@@ -328,8 +379,8 @@
     ExpectAtLeast expect = { 1 })
   {
     this->Base::Bind(name, [f, expect](Instance& instance) {
-      Result* result = static_cast<Result*>(instance.Result);
-      cm::string_view keyword = instance.Keyword;
+      Result* result = static_cast<Result*>(instance.GetState().Result);
+      cm::string_view keyword = instance.GetState().Keyword;
       instance.Bind(
         [result, keyword, &f](cm::string_view arg) -> Continue {
           return f(*result, keyword, arg);
@@ -345,7 +396,7 @@
     this->Base::Bind(
       position,
       [member](Instance& instance, std::size_t, cm::string_view arg) {
-        Result* result = static_cast<Result*>(instance.Result);
+        Result* result = static_cast<Result*>(instance.GetState().Result);
         result->*member = arg;
       });
     return *this;
@@ -356,7 +407,8 @@
   {
     this->Base::BindParsedKeyword(
       [member](Instance& instance, cm::string_view arg) {
-        (static_cast<Result*>(instance.Result)->*member).emplace_back(arg);
+        (static_cast<Result*>(instance.GetState().Result)->*member)
+          .emplace_back(arg);
       });
     return *this;
   }
@@ -368,11 +420,44 @@
   cmArgumentParser& BindTrailingArgs(T member)
   {
     this->Base::BindTrailingArgs([member](Instance& instance) {
-      instance.Bind(static_cast<Result*>(instance.Result)->*member);
+      instance.Bind(static_cast<Result*>(instance.GetState().Result)->*member);
     });
     return *this;
   }
 
+  template <typename T, typename U>
+  cmArgumentParser& BindSubParser(cm::static_string_view name,
+                                  cmArgumentParser<T>& parser,
+                                  cm::optional<T> U::*member)
+  {
+
+    this->Base::Bind(name, [name, parser, member](Instance& instance) {
+      auto* parentResult = static_cast<Result*>(instance.GetState().Result);
+      auto& childResult = parentResult->*member;
+      childResult.emplace(T());
+      instance.Bind(nullptr, ExpectAtLeast{ 0 });
+      instance.PushState(parser.Bindings, &(*childResult));
+      instance.Consume(name);
+    });
+
+    return *this;
+  }
+
+  template <typename T, typename U>
+  cmArgumentParser& BindSubParser(cm::static_string_view name,
+                                  cmArgumentParser<T>& parser, T U::*member)
+  {
+    this->Base::Bind(name, [name, parser, member](Instance& instance) {
+      auto* parentResult = static_cast<Result*>(instance.GetState().Result);
+      auto* childResult = &(parentResult->*member);
+      instance.Bind(nullptr, ExpectAtLeast{ 1 });
+      instance.PushState(parser.Bindings, childResult);
+      instance.Consume(name);
+    });
+
+    return *this;
+  }
+
   template <typename Range>
   bool Parse(Result& result, Range const& args,
              std::vector<std::string>* unparsedArguments,
@@ -405,6 +490,8 @@
 class cmArgumentParser<void> : private ArgumentParser::Base
 {
 public:
+  using Base::Bindings;
+
   template <typename T>
   cmArgumentParser& Bind(cm::static_string_view name, T& ref)
   {
@@ -429,7 +516,7 @@
     ExpectAtLeast expect = { 1 })
   {
     this->Base::Bind(name, [f, expect](Instance& instance) {
-      cm::string_view keyword = instance.Keyword;
+      cm::string_view keyword = instance.GetState().Keyword;
       instance.Bind(
         [keyword, &f](cm::string_view arg) -> Continue {
           return f(keyword, arg);
@@ -463,6 +550,32 @@
     return *this;
   }
 
+  template <typename T, typename U>
+  cmArgumentParser& BindSubParser(cm::static_string_view name,
+                                  cmArgumentParser<T>& parser,
+                                  cm::optional<U>& subResult)
+  {
+    this->Base::Bind(name, [name, parser, &subResult](Instance& instance) {
+      subResult.emplace(U());
+      instance.Bind(nullptr, ExpectAtLeast{ 0 });
+      instance.PushState(parser.Bindings, &(*subResult));
+      instance.Consume(name);
+    });
+    return *this;
+  }
+
+  template <typename T, typename U>
+  cmArgumentParser& BindSubParser(cm::static_string_view name,
+                                  cmArgumentParser<T>& parser, U& subResult)
+  {
+    this->Base::Bind(name, [name, parser, &subResult](Instance& instance) {
+      instance.Bind(nullptr, ExpectAtLeast{ 1 });
+      instance.PushState(parser.Bindings, &subResult);
+      instance.Consume(name);
+    });
+    return *this;
+  }
+
   template <typename Range>
   ParseResult Parse(Range const& args,
                     std::vector<std::string>* unparsedArguments,
diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
index 8c3dd49..82e956c 100644
--- a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.cxx
@@ -4,6 +4,7 @@
 #include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
 
 #include <sstream>
+#include <vector>
 
 #include <cmsys/RegularExpression.hxx>
 
diff --git a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
index 6719708..ebebbb6 100644
--- a/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
+++ b/Source/cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h
@@ -4,7 +4,6 @@
 #pragma once
 
 #include <string>
-#include <vector>
 
 #include "cmBinUtilsLinuxELFGetRuntimeDependenciesTool.h"
 
diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
index d2afe15..5fed9c9 100644
--- a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx
@@ -4,6 +4,7 @@
 #include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h"
 
 #include <sstream>
+#include <vector>
 
 #include <cmsys/RegularExpression.hxx>
 
diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
index faab98e..4cf70e2 100644
--- a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
+++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h
@@ -4,7 +4,6 @@
 #pragma once
 
 #include <string>
-#include <vector>
 
 #include "cmBinUtilsMacOSMachOGetRuntimeDependenciesTool.h"
 
diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
index 8e4a9aa..47ee8e8 100644
--- a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.cxx
@@ -4,6 +4,7 @@
 #include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
 
 #include <sstream>
+#include <vector>
 
 #include <cmsys/RegularExpression.hxx>
 
diff --git a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
index 552db10..4fcd454 100644
--- a/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
+++ b/Source/cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h
@@ -4,7 +4,6 @@
 #pragma once
 
 #include <string>
-#include <vector>
 
 #include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
 
diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
index 258e015..a83485c 100644
--- a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
+++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx
@@ -4,6 +4,7 @@
 #include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
 
 #include <sstream>
+#include <vector>
 
 #include <cmsys/RegularExpression.hxx>
 
diff --git a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
index 994235d..ef8e9d6 100644
--- a/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
+++ b/Source/cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h
@@ -4,7 +4,6 @@
 #pragma once
 
 #include <string>
-#include <vector>
 
 #include "cmBinUtilsWindowsPEGetRuntimeDependenciesTool.h"
 
diff --git a/Source/cmBlockCommand.cxx b/Source/cmBlockCommand.cxx
index 98d97a3..de31848 100644
--- a/Source/cmBlockCommand.cxx
+++ b/Source/cmBlockCommand.cxx
@@ -4,7 +4,6 @@
 #include "cmBlockCommand.h"
 
 #include <cstdint>
-#include <initializer_list>
 #include <utility>
 
 #include <cm/memory>
diff --git a/Source/cmBuildOptions.h b/Source/cmBuildOptions.h
index f84b576..a10b69f 100644
--- a/Source/cmBuildOptions.h
+++ b/Source/cmBuildOptions.h
@@ -35,8 +35,6 @@
     , ResolveMode(resolveMode)
   {
   }
-  explicit cmBuildOptions(cmBuildOptions const&) noexcept = default;
-  cmBuildOptions& operator=(cmBuildOptions const&) noexcept = default;
 
   bool Clean = false;
   bool Fast = false;
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 00b59c6..642cc91 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -303,7 +303,7 @@
     scripts = gl.GetFiles();
   }
 
-  // 2. User provided (append to the CMake prvided)
+  // 2. User provided (append to the CMake provided)
   cmList::append(
     scripts, makefile.GetDefinition("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS"));
 
@@ -498,7 +498,7 @@
                                           std::string const& key)
 {
   auto* const gg = status.GetMakefile().GetGlobalGenerator();
-  for (auto vs : { 15, 16, 17 }) {
+  for (auto vs : { 15, 16, 17, 18 }) {
     if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) {
       std::string value;
       // If generating for the VS nn IDE, use the same instance.
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index 4f2d52e..a093f8d 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -25,6 +25,7 @@
 #include "cmState.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
+#include "cmValue.h"
 #include "cmake.h"
 
 namespace {
@@ -542,5 +543,40 @@
                                                                   status);
   }
 
+  if (expArgs[expArg] == "TRACE") {
+    ++expArg; // Consume "TRACE".
+
+    if (!moreArgs()) {
+      return FatalError(status, "TRACE missing a boolean value");
+    }
+
+    bool const value = cmValue::IsOn(expArgs[expArg++]);
+    bool expand = false;
+
+    if (value && moreArgs()) {
+      expand = (expArgs[expArg] == "EXPAND");
+      if (!expand) {
+        return FatalError(
+          status,
+          cmStrCat("TRACE ON given an invalid argument ", expArgs[expArg]));
+      }
+      ++expArg;
+    }
+
+    if (moreArgs()) {
+      return FatalError(
+        status,
+        cmStrCat("TRACE O", value ? "N" : "FF", " given too many arguments"));
+    }
+
+    cmMakefile& makefile = status.GetMakefile();
+    if (value) {
+      makefile.GetCMakeInstance()->PushTraceCmd(expand);
+      return true;
+    }
+    return makefile.GetCMakeInstance()->PopTraceCmd() ||
+      FatalError(status, "TRACE OFF request without a corresponding TRACE ON");
+  }
+
   return FatalError(status, "called with unknown meta-operation");
 }
diff --git a/Source/cmCMakePath.h b/Source/cmCMakePath.h
index da92424..e681c81 100644
--- a/Source/cmCMakePath.h
+++ b/Source/cmCMakePath.h
@@ -664,12 +664,7 @@
 
   iterator() = default;
 
-  iterator(iterator const& other)
-    : Iterator(other.Iterator)
-    , Path(other.Path)
-    , PathElement(*this->Iterator)
-  {
-  }
+  iterator(iterator const& other) = default;
 
   ~iterator() = default;
 
@@ -678,7 +673,7 @@
     if (this != &other) {
       this->Iterator = other.Iterator;
       this->Path = other.Path;
-      this->PathElement = *this->Iterator;
+      this->PathElement = other.PathElement;
     }
 
     return *this;
@@ -691,7 +686,9 @@
   iterator& operator++()
   {
     ++this->Iterator;
-    this->PathElement = *this->Iterator;
+    if (this->Path && this->Iterator != this->Path->Path.end()) {
+      this->PathElement = *this->Iterator;
+    }
 
     return *this;
   }
@@ -706,7 +703,9 @@
   iterator& operator--()
   {
     --this->Iterator;
-    this->PathElement = *this->Iterator;
+    if (this->Path && this->Iterator != this->Path->Path.end()) {
+      this->PathElement = *this->Iterator;
+    }
 
     return *this;
   }
@@ -725,8 +724,10 @@
   iterator(cmCMakePath const* path, cm::filesystem::path::iterator const& it)
     : Iterator(it)
     , Path(path)
-    , PathElement(*this->Iterator)
   {
+    if (this->Path && this->Iterator != this->Path->Path.end()) {
+      this->PathElement = *this->Iterator;
+    }
   }
 
   cm::filesystem::path::iterator Iterator;
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index c112622..870315f 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -11,7 +11,6 @@
 #include <utility>
 
 #include <cm/memory>
-#include <cm/string_view>
 
 #include "cmsys/RegularExpression.hxx"
 
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index e76ba1d..4880186 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -1,7 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include <algorithm>
-#include <fstream>
+#include <cstddef>
 #include <functional>
 #include <map>
 #include <string>
diff --git a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
index e26c0c4..2fec3ae 100644
--- a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
@@ -1,6 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include <cstddef>
+#include <functional>
 #include <map>
 #include <memory>
 #include <string>
@@ -15,7 +16,7 @@
 #include "cmCMakePresetsGraph.h"
 #include "cmCMakePresetsGraphInternal.h"
 #include "cmJSONHelpers.h"
-class cmJSONState;
+#include "cmJSONState.h"
 
 namespace {
 using PackagePreset = cmCMakePresetsGraph::PackagePreset;
diff --git a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
index 22717f2..2d2669a 100644
--- a/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONTestPresets.cxx
@@ -1,6 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include <cstddef>
+#include <functional>
 #include <map>
 #include <memory>
 #include <string>
diff --git a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
index e428da4..d85d2e1 100644
--- a/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
+++ b/Source/cmCMakePresetsGraphReadJSONWorkflowPresets.cxx
@@ -1,6 +1,7 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include <cstddef>
+#include <functional>
 #include <string>
 #include <vector>
 
diff --git a/Source/cmCPackPropertiesGenerator.cxx b/Source/cmCPackPropertiesGenerator.cxx
index c1e662d..db33bba 100644
--- a/Source/cmCPackPropertiesGenerator.cxx
+++ b/Source/cmCPackPropertiesGenerator.cxx
@@ -1,7 +1,6 @@
 #include "cmCPackPropertiesGenerator.h"
 
 #include <map>
-#include <memory>
 #include <ostream>
 
 #include "cmGeneratorExpression.h"
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e7d34fd..e62743b 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -10,6 +10,7 @@
 #include <cstdlib>
 #include <cstring>
 #include <ctime>
+#include <functional>
 #include <initializer_list>
 #include <iostream>
 #include <map>
@@ -38,7 +39,7 @@
 #  include <unistd.h> // IWYU pragma: keep
 #endif
 
-#include "cm_get_date.h"
+#include "cm_parse_date.h"
 
 #include "cmCMakePresetsGraph.h"
 #include "cmCTestBuildAndTest.h"
@@ -76,6 +77,8 @@
 #  include <be/kernel/OS.h> /* disable_debugger() API. */
 #endif
 
+struct tm;
+
 struct cmCTest::Private
 {
   Private(cmCTest* ctest)
@@ -114,7 +117,6 @@
   bool UseHTTP10 = false;
   bool PrintLabels = false;
   bool Failover = false;
-  bool UseVerboseInstrumentation = false;
   cmJSONState parseState;
 
   bool FlushTestProgressLine = false;
@@ -215,7 +217,7 @@
   char buf[1024];
   std::snprintf(buf, sizeof(buf), "%d%02d%02d %s", lctime->tm_year + 1900,
                 lctime->tm_mon + 1, lctime->tm_mday, str.c_str());
-  time_t ntime = cm_get_date(tctime, buf);
+  time_t ntime = cm_parse_date(tctime, buf);
   cmCTestLog(this, DEBUG,
              "   Get the nightly start time: " << ntime << std::endl);
   tctime = time(nullptr);
@@ -320,10 +322,6 @@
     this->Impl->TestProgressOutput = !cmIsOff(envValue);
   }
   envValue.clear();
-  if (cmSystemTools::GetEnv("CTEST_USE_VERBOSE_INSTRUMENTATION", envValue)) {
-    this->Impl->UseVerboseInstrumentation = !cmIsOff(envValue);
-  }
-  envValue.clear();
 
   this->Impl->Parts[PartStart].SetName("Start");
   this->Impl->Parts[PartUpdate].SetName("Update");
@@ -729,8 +727,8 @@
   this->SetTimeLimit(mf.GetDefinition("CTEST_TIME_LIMIT"));
   this->SetCMakeVariables(mf);
   std::vector<cmListFileArgument> args{
-    cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0),
-    cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0),
+    cmListFileArgument("RETURN_VALUE"_s, cmListFileArgument::Unquoted, 0),
+    cmListFileArgument("return_value"_s, cmListFileArgument::Unquoted, 0),
   };
 
   if (this->Impl->Parts[PartStart]) {
@@ -848,12 +846,12 @@
     auto const func = cmListFileFunction(
       "ctest_submit", 0, 0,
       {
-        cmListFileArgument("RETRY_COUNT", cmListFileArgument::Unquoted, 0),
+        cmListFileArgument("RETRY_COUNT"_s, cmListFileArgument::Unquoted, 0),
         cmListFileArgument(count, cmListFileArgument::Quoted, 0),
-        cmListFileArgument("RETRY_DELAY", cmListFileArgument::Unquoted, 0),
+        cmListFileArgument("RETRY_DELAY"_s, cmListFileArgument::Unquoted, 0),
         cmListFileArgument(delay, cmListFileArgument::Quoted, 0),
-        cmListFileArgument("RETURN_VALUE", cmListFileArgument::Unquoted, 0),
-        cmListFileArgument("return_value", cmListFileArgument::Unquoted, 0),
+        cmListFileArgument("RETURN_VALUE"_s, cmListFileArgument::Unquoted, 0),
+        cmListFileArgument("return_value"_s, cmListFileArgument::Unquoted, 0),
       });
     auto status = cmExecutionStatus(mf);
     if (!mf.ExecuteCommand(func, status) ||
@@ -1013,32 +1011,7 @@
 
 std::string cmCTest::SafeBuildIdField(std::string const& value)
 {
-  std::string safevalue(value);
-
-  if (!safevalue.empty()) {
-    // Disallow non-filename and non-space whitespace characters.
-    // If they occur, replace them with ""
-    //
-    char const* disallowed = "\\:*?\"<>|\n\r\t\f\v";
-
-    if (safevalue.find_first_of(disallowed) != std::string::npos) {
-      std::string::size_type i = 0;
-      std::string::size_type n = strlen(disallowed);
-      char replace[2];
-      replace[1] = 0;
-
-      for (i = 0; i < n; ++i) {
-        replace[0] = disallowed[i];
-        cmSystemTools::ReplaceString(safevalue, replace, "");
-      }
-    }
-  }
-
-  if (safevalue.empty()) {
-    safevalue = "(empty)";
-  }
-
-  return safevalue;
+  return value.empty() ? "(empty)" : value;
 }
 
 void cmCTest::StartXML(cmXMLWriter& xml, cmake* cm, bool append)
@@ -2701,11 +2674,14 @@
 
   cmInstrumentation instrumentation(this->GetBinaryDir());
   auto processHandler = [&handler]() -> int {
-    return handler.ProcessHandler();
+    return handler.ProcessHandler() < 0 ? cmCTest::TEST_ERRORS : 0;
   };
-  int ret = instrumentation.InstrumentCommand("ctest", args, processHandler);
-  instrumentation.CollectTimingData(cmInstrumentationQuery::Hook::PostTest);
-  if (ret < 0) {
+  std::map<std::string, std::string> data;
+  data["showOnly"] = this->GetShowOnly() ? "1" : "0";
+  int ret =
+    instrumentation.InstrumentCommand("ctest", args, processHandler, data);
+  instrumentation.CollectTimingData(cmInstrumentationQuery::Hook::PostCTest);
+  if (ret == cmCTest::TEST_ERRORS) {
     cmCTestLog(this, ERROR_MESSAGE, "Errors while running CTest\n");
     if (!this->Impl->OutputTestOutputOnTestFailure) {
       std::string const lastTestLog =
@@ -2716,10 +2692,8 @@
                  "Use \"--rerun-failed --output-on-failure\" to re-run the "
                  "failed cases verbosely.\n");
     }
-    return cmCTest::TEST_ERRORS;
   }
-
-  return 0;
+  return ret;
 }
 
 int cmCTest::RunCMakeAndTest()
@@ -2773,7 +2747,7 @@
            lctime->tm_mon + 1, lctime->tm_mday, time_str.c_str(),
            tzone_offset);
 
-  time_t stop_time = cm_get_date(current_time, buf);
+  time_t stop_time = cm_parse_date(current_time, buf);
   if (stop_time == -1) {
     this->Impl->StopTime = std::chrono::system_clock::time_point();
     return;
@@ -3670,11 +3644,6 @@
   return *this->Impl->Instrumentation;
 }
 
-bool cmCTest::GetUseVerboseInstrumentation() const
-{
-  return this->Impl->UseVerboseInstrumentation;
-}
-
 void cmCTest::ConvertInstrumentationSnippetsToXML(cmXMLWriter& xml,
                                                   std::string const& subdir)
 {
@@ -3703,6 +3672,8 @@
 bool cmCTest::ConvertInstrumentationJSONFileToXML(std::string const& fpath,
                                                   cmXMLWriter& xml)
 {
+  bool verboseCommands = this->GetInstrumentation().HasOption(
+    cmInstrumentationQuery::Option::CDashVerbose);
   Json::Value root;
   this->Impl->parseState = cmJSONState(fpath, &root);
   if (!this->Impl->parseState.errors.empty()) {
@@ -3751,7 +3722,7 @@
       }
       // Truncate the full command line if verbose instrumentation
       // was not requested.
-      if (key == "command" && !this->GetUseVerboseInstrumentation()) {
+      if (key == "command" && !verboseCommands) {
         std::string command_str = root[key].asString();
         std::string truncated = command_str.substr(0, command_str.find(' '));
         if (command_str != truncated) {
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 6dfa0bc..46c88b7 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -436,7 +436,6 @@
   std::vector<std::string> GetCommandLineHttpHeaders() const;
 
   cmInstrumentation& GetInstrumentation();
-  bool GetUseVerboseInstrumentation() const;
 
 private:
   int GenerateNotesFile(cmake* cm, std::string const& files);
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 0b25313..498c1b5 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -3,7 +3,7 @@
 
 #include "cmCommands.h"
 
-#include <cm/memory>
+#include <string>
 
 #include "cmAddCompileDefinitionsCommand.h"
 #include "cmAddCustomCommandCommand.h"
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 3da4657..f5f46e6 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <sstream>
-#include <type_traits>
 #include <utility>
 
 #include <cm/string_view>
@@ -459,7 +458,8 @@
           this->GeneratorTarget->GetLocalGenerator()->EscapeForShell(
             cmStrCat(tidy, ";--extra-arg-before=--driver-mode=", driverMode,
                      exportFixes));
-      } else if (generatorName.find("Ninja") != std::string::npos) {
+      } else if (generatorName.find("Ninja") != std::string::npos ||
+                 generatorName.find("FASTBuild") != std::string::npos) {
         if (!clangTidyExportFixedDir.empty()) {
           this->GlobalCommonGenerator->AddClangTidyExportFixesFile(fixesFile);
           cmSystemTools::MakeDirectory(
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index a7a6432..d2da7ec 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -8,7 +8,6 @@
 #include <cstdio>
 #include <iterator>
 #include <sstream>
-#include <type_traits>
 #include <unordered_map>
 #include <utility>
 
@@ -772,7 +771,7 @@
 }
 
 std::pair<size_t, bool> cmComputeLinkDepends::AddLinkEntry(
-  cmLinkItem const& item, cm::optional<size_t> const& groupIndex)
+  cmLinkItem const& item, cm::optional<size_t> groupIndex)
 {
   // Allocate a spot for the item entry.
   auto lei = this->AllocateLinkEntry(item);
@@ -943,7 +942,7 @@
 }
 
 void cmComputeLinkDepends::AddVarLinkEntries(
-  cm::optional<size_t> const& depender_index, char const* value)
+  cm::optional<size_t> depender_index, char const* value)
 {
   // This is called to add the dependencies named by
   // <item>_LIB_DEPENDS.  The variable contains a semicolon-separated
@@ -1013,8 +1012,8 @@
 }
 
 template <typename T>
-void cmComputeLinkDepends::AddLinkEntries(
-  cm::optional<size_t> const& depender_index, std::vector<T> const& libs)
+void cmComputeLinkDepends::AddLinkEntries(cm::optional<size_t> depender_index,
+                                          std::vector<T> const& libs)
 {
   // Track inferred dependency sets implied by this list.
   std::map<size_t, DependSet> dependSets;
@@ -1298,7 +1297,7 @@
 }
 
 cmLinkItem cmComputeLinkDepends::ResolveLinkItem(
-  cm::optional<size_t> const& depender_index, std::string const& name)
+  cm::optional<size_t> depender_index, std::string const& name)
 {
   // Look for a target in the scope of the depender.
   cmGeneratorTarget const* from = this->Target;
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 3f9f6e2..f2162cf 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -105,16 +105,16 @@
   std::pair<std::map<cmLinkItem, size_t>::iterator, bool> AllocateLinkEntry(
     cmLinkItem const& item);
   std::pair<size_t, bool> AddLinkEntry(cmLinkItem const& item,
-                                       cm::optional<size_t> const& groupIndex);
+                                       cm::optional<size_t> groupIndex);
   void AddLinkObject(cmLinkItem const& item);
-  void AddVarLinkEntries(cm::optional<size_t> const& depender_index,
+  void AddVarLinkEntries(cm::optional<size_t> depender_index,
                          char const* value);
   void AddDirectLinkEntries();
   template <typename T>
-  void AddLinkEntries(cm::optional<size_t> const& depender_index,
+  void AddLinkEntries(cm::optional<size_t> depender_index,
                       std::vector<T> const& libs);
   void AddLinkObjects(std::vector<cmLinkItem> const& objs);
-  cmLinkItem ResolveLinkItem(cm::optional<size_t> const& depender_index,
+  cmLinkItem ResolveLinkItem(cm::optional<size_t> depender_index,
                              std::string const& name);
 
   // One entry for each unique item.
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 02a8a3e..986a314 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -221,7 +221,7 @@
 
       if (cmLinkImplementation const* impl = depender->GetLinkImplementation(
             it, cmGeneratorTarget::UseTo::Link)) {
-        for (cmLinkImplItem const& lib : impl->Libraries) {
+        for (cmLinkItem const& lib : impl->Libraries) {
           // Don't emit the same library twice for this target.
           if (emitted.insert(lib).second) {
             this->AddTargetDepend(depender_index, lib, true, false);
diff --git a/Source/cmConfigureLog.cxx b/Source/cmConfigureLog.cxx
index b486cc3..5f0c3c6 100644
--- a/Source/cmConfigureLog.cxx
+++ b/Source/cmConfigureLog.cxx
@@ -23,12 +23,12 @@
 #include "cmake.h"
 
 cmConfigureLog::cmConfigureLog(std::string logDir,
-                               std::vector<unsigned long> logVersions)
+                               std::vector<unsigned int> logVersions)
   : LogDir(std::move(logDir))
   , LogVersions(std::move(logVersions))
 {
   // Always emit events for the latest log version.
-  static unsigned long const LatestLogVersion = 1;
+  static unsigned int const LatestLogVersion = 1;
   if (!cm::contains(this->LogVersions, LatestLogVersion)) {
     this->LogVersions.emplace_back(LatestLogVersion);
   }
@@ -46,7 +46,7 @@
 }
 
 bool cmConfigureLog::IsAnyLogVersionEnabled(
-  std::vector<unsigned long> const& v) const
+  std::vector<unsigned int> const& v) const
 {
   // Both input lists are sorted.  Look for a matching element.
   auto i1 = v.cbegin();
diff --git a/Source/cmConfigureLog.h b/Source/cmConfigureLog.h
index 6c6c44f..db4b7af 100644
--- a/Source/cmConfigureLog.h
+++ b/Source/cmConfigureLog.h
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #pragma once
 
+#include <cstddef>
 #include <map>
 #include <memory>
 #include <string>
@@ -22,12 +23,12 @@
 public:
   /** Construct with the log directory and a sorted list of enabled log
       versions.  The latest log version will be enabled regardless.  */
-  cmConfigureLog(std::string logDir, std::vector<unsigned long> logVersions);
+  cmConfigureLog(std::string logDir, std::vector<unsigned int> logVersions);
   ~cmConfigureLog();
 
   /** Return true if at least one of the log versions in the given sorted
       list is enabled.  */
-  bool IsAnyLogVersionEnabled(std::vector<unsigned long> const& v) const;
+  bool IsAnyLogVersionEnabled(std::vector<unsigned int> const& v) const;
 
   void EnsureInit();
 
@@ -60,7 +61,7 @@
 
 private:
   std::string LogDir;
-  std::vector<unsigned long> LogVersions;
+  std::vector<unsigned int> LogVersions;
   cmsys::ofstream Stream;
   unsigned Indent = 0;
   bool Opened = false;
diff --git a/Source/cmConstStack.h b/Source/cmConstStack.h
deleted file mode 100644
index d6059e7..0000000
--- a/Source/cmConstStack.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <memory>
-
-/** Base class template for CRTP to represent a stack of constant values.
-    Provide value semantics, but use efficient reference-counting underneath
-    to avoid copies.  */
-template <typename T, typename Stack>
-class cmConstStack
-{
-  struct Entry;
-  std::shared_ptr<Entry const> TopEntry;
-
-public:
-  /** Default-construct an empty stack.  */
-  cmConstStack();
-
-  /** Get a stack with the given call context added to the top.  */
-  Stack Push(T value) const;
-
-  /** Get a stack with the top level removed.
-      May not be called until after a matching Push.  */
-  Stack Pop() const;
-
-  /** Get the value at the top of the stack.
-      This may be called only if Empty() would return false.  */
-  T const& Top() const;
-
-  /** Return true if this stack is empty.  */
-  bool Empty() const;
-
-protected:
-  cmConstStack(std::shared_ptr<Entry const> parent, T value);
-  cmConstStack(std::shared_ptr<Entry const> top);
-};
diff --git a/Source/cmConstStack.tcc b/Source/cmConstStack.tcc
deleted file mode 100644
index ee69c9c..0000000
--- a/Source/cmConstStack.tcc
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-
-#include <cassert>
-#include <memory>
-#include <utility>
-
-template <typename T, typename Stack>
-struct cmConstStack<T, Stack>::Entry
-{
-  Entry(std::shared_ptr<Entry const> parent, T value)
-    : Value(std::move(value))
-    , Parent(std::move(parent))
-  {
-  }
-
-  T Value;
-  std::shared_ptr<Entry const> Parent;
-};
-
-template <typename T, typename Stack>
-cmConstStack<T, Stack>::cmConstStack() = default;
-
-template <typename T, typename Stack>
-Stack cmConstStack<T, Stack>::Push(T value) const
-{
-  return Stack(this->TopEntry, std::move(value));
-}
-
-template <typename T, typename Stack>
-Stack cmConstStack<T, Stack>::Pop() const
-{
-  assert(this->TopEntry);
-  return Stack(this->TopEntry->Parent);
-}
-
-template <typename T, typename Stack>
-T const& cmConstStack<T, Stack>::Top() const
-{
-  assert(this->TopEntry);
-  return this->TopEntry->Value;
-}
-
-template <typename T, typename Stack>
-bool cmConstStack<T, Stack>::Empty() const
-{
-  return !this->TopEntry;
-}
-
-template <typename T, typename Stack>
-cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> parent,
-                                     T value)
-  : TopEntry(
-      std::make_shared<Entry const>(std::move(parent), std::move(value)))
-{
-}
-
-template <typename T, typename Stack>
-cmConstStack<T, Stack>::cmConstStack(std::shared_ptr<Entry const> top)
-  : TopEntry(std::move(top))
-{
-}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index eb8f616..c1d7054 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -5,6 +5,7 @@
 #include <array>
 #include <cstdio>
 #include <cstring>
+#include <functional>
 #include <set>
 #include <sstream>
 #include <utility>
@@ -236,7 +237,7 @@
 }
 
 Arguments cmCoreTryCompile::ParseArgs(
-  cmRange<std::vector<std::string>::const_iterator> const& args,
+  cmRange<std::vector<std::string>::const_iterator> args,
   cmArgumentParser<Arguments> const& parser,
   std::vector<std::string>& unparsedArguments)
 {
@@ -1095,6 +1096,7 @@
     vars.emplace("CMAKE_MSVC_RUNTIME_CHECKS"_s);
     vars.emplace("CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS"_s);
     vars.emplace("CMAKE_VS_USE_DEBUG_LIBRARIES"_s);
+    vars.emplace("CMAKE_CXX_STDLIB_MODULES_JSON"_s);
 
     if (cmValue varListStr = this->Makefile->GetDefinition(
           kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
@@ -1230,8 +1232,20 @@
 
     if ((res == 0) && arguments.CopyFileTo) {
       std::string const& copyFile = *arguments.CopyFileTo;
+      std::string outputFile = this->OutputFile;
+
+      // Emscripten `.js` executables have an adjacent `.wasm` file with the
+      // actual compiled binary.  Our COPY_FILE clients need the latter.
+      if (cmHasLiteralSuffix(outputFile, ".js")) {
+        std::string wasmOutput =
+          cmStrCat(outputFile.substr(0, outputFile.length() - 3), ".wasm");
+        if (cmSystemTools::FileExists(wasmOutput)) {
+          outputFile = std::move(wasmOutput);
+        }
+      }
+
       cmsys::SystemTools::CopyStatus status =
-        cmSystemTools::CopyFileAlways(this->OutputFile, copyFile);
+        cmSystemTools::CopyFileAlways(outputFile, copyFile);
       if (!status) {
         std::string err = status.GetString();
         switch (status.Path) {
@@ -1247,7 +1261,7 @@
         /* clang-format off */
         err = cmStrCat(
           "Cannot copy output executable\n"
-          "  '", this->OutputFile, "'\n"
+          "  '", outputFile, "'\n"
           "to destination specified by COPY_FILE:\n"
           "  '", copyFile, "'\n"
           "because:\n"
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 41d712f..3c36456 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -161,8 +161,7 @@
   std::string WriteSource(std::string const& name, std::string const& content,
                           char const* command) const;
 
-  Arguments ParseArgs(
-    cmRange<std::vector<std::string>::const_iterator> const& args,
-    cmArgumentParser<Arguments> const& parser,
-    std::vector<std::string>& unparsedArguments);
+  Arguments ParseArgs(cmRange<std::vector<std::string>::const_iterator> args,
+                      cmArgumentParser<Arguments> const& parser,
+                      std::vector<std::string>& unparsedArguments);
 };
diff --git a/Source/cmDebuggerAdapter.cxx b/Source/cmDebuggerAdapter.cxx
index 7dc6e7f..7cf9efe 100644
--- a/Source/cmDebuggerAdapter.cxx
+++ b/Source/cmDebuggerAdapter.cxx
@@ -164,8 +164,7 @@
     });
 
   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Threads
-  Session->registerHandler([this](dap::ThreadsRequest const& req) {
-    (void)req;
+  Session->registerHandler([this](dap::ThreadsRequest /*unused*/) {
     std::unique_lock<std::mutex> lock(Mutex);
     dap::ThreadsResponse response;
 
@@ -196,7 +195,7 @@
   });
 
   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Scopes
-  Session->registerHandler([this](dap::ScopesRequest const& request)
+  Session->registerHandler([this](dap::ScopesRequest request)
                              -> dap::ResponseOrError<dap::ScopesResponse> {
     std::unique_lock<std::mutex> lock(Mutex);
     return DefaultThread->GetScopesResponse(request.frameId,
@@ -210,8 +209,7 @@
   });
 
   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_Pause
-  Session->registerHandler([this](dap::PauseRequest const& req) {
-    (void)req;
+  Session->registerHandler([this](dap::PauseRequest /*unused*/) {
     PauseRequest.store(true);
     return dap::PauseResponse();
   });
@@ -286,8 +284,7 @@
   // The ConfigurationDone request is made by the client once all configuration
   // requests have been made.
   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ConfigurationDone
-  Session->registerHandler([this](dap::ConfigurationDoneRequest const& req) {
-    (void)req;
+  Session->registerHandler([this](dap::ConfigurationDoneRequest /*unused*/) {
     ConfigurationDoneEvent->Fire();
     return dap::ConfigurationDoneResponse();
   });
@@ -397,7 +394,7 @@
     dap::array<dap::integer> hitBreakpoints;
     hitBreakpoints.resize(hits.size());
     std::transform(hits.begin(), hits.end(), hitBreakpoints.begin(),
-                   [&](int64_t const& id) { return dap::integer(id); });
+                   [&](int64_t id) { return dap::integer(id); });
     stoppedEvent.reason = "breakpoint";
     stoppedEvent.hitBreakpointIds = hitBreakpoints;
   }
diff --git a/Source/cmDebuggerBreakpointManager.cxx b/Source/cmDebuggerBreakpointManager.cxx
index dfd131c..b33985b 100644
--- a/Source/cmDebuggerBreakpointManager.cxx
+++ b/Source/cmDebuggerBreakpointManager.cxx
@@ -33,7 +33,7 @@
   auto location =
     find_if(ListFileFunctionLines[sourcePath].begin(),
             ListFileFunctionLines[sourcePath].end(),
-            [=](cmDebuggerFunctionLocation const& loc) {
+            [=](cmDebuggerFunctionLocation loc) {
               return loc.StartLine <= line && loc.EndLine >= line;
             });
 
@@ -47,11 +47,10 @@
 int64_t cmDebuggerBreakpointManager::CalibrateBreakpointLine(
   std::string const& sourcePath, int64_t line)
 {
-  auto location = find_if(ListFileFunctionLines[sourcePath].begin(),
-                          ListFileFunctionLines[sourcePath].end(),
-                          [=](cmDebuggerFunctionLocation const& loc) {
-                            return loc.StartLine >= line;
-                          });
+  auto location = find_if(
+    ListFileFunctionLines[sourcePath].begin(),
+    ListFileFunctionLines[sourcePath].end(),
+    [=](cmDebuggerFunctionLocation loc) { return loc.StartLine >= line; });
 
   if (location != ListFileFunctionLines[sourcePath].end()) {
     return location->StartLine;
diff --git a/Source/cmDebuggerExceptionManager.cxx b/Source/cmDebuggerExceptionManager.cxx
index a2744e1..22a577a 100644
--- a/Source/cmDebuggerExceptionManager.cxx
+++ b/Source/cmDebuggerExceptionManager.cxx
@@ -25,8 +25,7 @@
     });
 
   // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo
-  DapSession->registerHandler([&](dap::ExceptionInfoRequest const& request) {
-    (void)request;
+  DapSession->registerHandler([&](dap::ExceptionInfoRequest /*unused*/) {
     return HandleExceptionInfoRequest();
   });
 
diff --git a/Source/cmDebuggerExceptionManager.h b/Source/cmDebuggerExceptionManager.h
index 2524b67..bec0f56 100644
--- a/Source/cmDebuggerExceptionManager.h
+++ b/Source/cmDebuggerExceptionManager.h
@@ -5,6 +5,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <cstddef>
+#include <functional>
 #include <mutex>
 #include <string>
 #include <unordered_map>
diff --git a/Source/cmDebuggerThreadManager.cxx b/Source/cmDebuggerThreadManager.cxx
index 951a101..ae699c2 100644
--- a/Source/cmDebuggerThreadManager.cxx
+++ b/Source/cmDebuggerThreadManager.cxx
@@ -5,6 +5,9 @@
 
 #include <algorithm>
 
+#include <cm/optional>
+
+#include <cm3p/cppdap/optional.h>
 #include <cm3p/cppdap/protocol.h>
 #include <cm3p/cppdap/types.h>
 
diff --git a/Source/cmDebuggerVariablesHelper.cxx b/Source/cmDebuggerVariablesHelper.cxx
index b8bc328..efe5c89 100644
--- a/Source/cmDebuggerVariablesHelper.cxx
+++ b/Source/cmDebuggerVariablesHelper.cxx
@@ -83,8 +83,7 @@
 
 std::shared_ptr<cmDebuggerVariables> cmDebuggerVariablesHelper::CreateIfAny(
   std::shared_ptr<cmDebuggerVariablesManager> const& variablesManager,
-  std::string const& name, bool supportsVariableType,
-  cmBTStringRange const& entries)
+  std::string const& name, bool supportsVariableType, cmBTStringRange entries)
 {
   if (entries.empty()) {
     return {};
diff --git a/Source/cmDebuggerVariablesHelper.h b/Source/cmDebuggerVariablesHelper.h
index e39a857..0e0fdb4 100644
--- a/Source/cmDebuggerVariablesHelper.h
+++ b/Source/cmDebuggerVariablesHelper.h
@@ -48,7 +48,7 @@
   static std::shared_ptr<cmDebuggerVariables> CreateIfAny(
     std::shared_ptr<cmDebuggerVariablesManager> const& variablesManager,
     std::string const& name, bool supportsVariableType,
-    cmBTStringRange const& entries);
+    cmBTStringRange entries);
 
   static std::shared_ptr<cmDebuggerVariables> CreateIfAny(
     std::shared_ptr<cmDebuggerVariablesManager> const& variablesManager,
diff --git a/Source/cmDebuggerVariablesManager.cxx b/Source/cmDebuggerVariablesManager.cxx
index 8a51805..442c9ec 100644
--- a/Source/cmDebuggerVariablesManager.cxx
+++ b/Source/cmDebuggerVariablesManager.cxx
@@ -4,6 +4,7 @@
 #include "cmDebuggerVariablesManager.h"
 
 #include <utility>
+#include <vector>
 
 #include <cm3p/cppdap/protocol.h>
 #include <cm3p/cppdap/types.h>
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index c3f6dce..974b7d1 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -96,9 +96,9 @@
 
       std::vector<std::string> depends;
       if (format == "custom"_s) {
-        auto deps = cmReadGccDepfile(
+        cm::optional<cmGccDepfileContent> deps = cmReadGccDepfile(
           depFile.c_str(), this->LocalGenerator->GetCurrentBinaryDirectory());
-        if (!deps) {
+        if (!deps || deps->empty()) {
           continue;
         }
 
@@ -130,10 +130,10 @@
             depends.emplace_back(std::move(line));
           }
         } else if (format == "gcc"_s) {
-          auto deps = cmReadGccDepfile(
+          cm::optional<cmGccDepfileContent> deps = cmReadGccDepfile(
             depFile.c_str(), this->LocalGenerator->GetCurrentBinaryDirectory(),
             GccDepfilePrependPaths::Deps);
-          if (!deps) {
+          if (!deps || deps->empty()) {
             continue;
           }
 
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index be63469..2b85d2b 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -6,7 +6,6 @@
 #include <cstdlib>
 #include <iostream>
 #include <map>
-#include <type_traits>
 #include <utility>
 
 #include "cmsys/FStream.hxx"
diff --git a/Source/cmDependsJava.cxx b/Source/cmDependsJava.cxx
index e85fcf5..15cf170 100644
--- a/Source/cmDependsJava.cxx
+++ b/Source/cmDependsJava.cxx
@@ -2,6 +2,8 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmDependsJava.h"
 
+#include <set>
+
 #include "cmSystemTools.h"
 
 cmDependsJava::cmDependsJava() = default;
diff --git a/Source/cmDependsJava.h b/Source/cmDependsJava.h
index 9b9710b..05b9efa 100644
--- a/Source/cmDependsJava.h
+++ b/Source/cmDependsJava.h
@@ -5,7 +5,6 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
-#include <set>
 #include <string>
 
 #include "cmDepends.h"
diff --git a/Source/cmDocumentationFormatter.cxx b/Source/cmDocumentationFormatter.cxx
index ea644d9..cd2645a 100644
--- a/Source/cmDocumentationFormatter.cxx
+++ b/Source/cmDocumentationFormatter.cxx
@@ -80,7 +80,7 @@
 }
 } // anonymous namespace
 
-std::string cmDocumentationFormatter::Format(std::string text) const
+std::string cmDocumentationFormatter::Format(cm::string_view text) const
 {
   // Exit early on empty text
   if (text.empty()) {
@@ -107,9 +107,8 @@
     ) // clang-format on
   {
     auto const isLastLine = end == std::string::npos;
-    auto const line = isLastLine
-      ? cm::string_view{ text.c_str() + start }
-      : cm::string_view{ text.c_str() + start, end - start };
+    auto const line =
+      isLastLine ? text.substr(start) : text.substr(start, end - start);
 
     if (!line.empty() && line.front() == ' ') {
       // Preformatted lines go as is w/ a leading padding
@@ -182,3 +181,9 @@
 
   this->TextIndent = savedIndent;
 }
+
+void cmDocumentationFormatter::PrintFormatted(std::ostream& os,
+                                              std::string const& text) const
+{
+  os << this->Format(text);
+}
diff --git a/Source/cmDocumentationFormatter.h b/Source/cmDocumentationFormatter.h
index 22b9c47..cbdb3ce 100644
--- a/Source/cmDocumentationFormatter.h
+++ b/Source/cmDocumentationFormatter.h
@@ -8,18 +8,17 @@
 #include <iosfwd>
 #include <string>
 
+#include <cm/string_view>
+
 class cmDocumentationSection;
 
 /** Print documentation in a simple text format. */
 class cmDocumentationFormatter
 {
 public:
-  std::string Format(std::string text) const;
+  std::string Format(cm::string_view text) const;
   void PrintSection(std::ostream& os, cmDocumentationSection const& section);
-  void PrintFormatted(std::ostream& os, std::string const& text) const
-  {
-    os << this->Format(text);
-  }
+  void PrintFormatted(std::ostream& os, std::string const& text) const;
   void SetIndent(std::size_t indent) { this->TextIndent = indent; }
 
   static constexpr std::size_t TEXT_WIDTH = 77u;
diff --git a/Source/cmDuration.cxx b/Source/cmDuration.cxx
index b017d0a..7981e77 100644
--- a/Source/cmDuration.cxx
+++ b/Source/cmDuration.cxx
@@ -4,7 +4,7 @@
 #include "cmDuration.h"
 
 template <typename T>
-T cmDurationTo(cmDuration const& duration)
+T cmDurationTo(cmDuration duration)
 {
   /* This works because the comparison operators for duration rely on
    * std::common_type.
@@ -23,5 +23,5 @@
     .count();
 }
 
-template int cmDurationTo<int>(cmDuration const&);
-template unsigned int cmDurationTo<unsigned int>(cmDuration const&);
+template int cmDurationTo<int>(cmDuration);
+template unsigned int cmDurationTo<unsigned int>(cmDuration);
diff --git a/Source/cmDuration.h b/Source/cmDuration.h
index c0268f9..378af9c 100644
--- a/Source/cmDuration.h
+++ b/Source/cmDuration.h
@@ -16,9 +16,9 @@
  * the permissible valid values for T.
  */
 template <typename T>
-T cmDurationTo(cmDuration const& duration);
+T cmDurationTo(cmDuration duration);
 
 #ifndef CMDURATION_CPP
-extern template int cmDurationTo<int>(cmDuration const&);
-extern template unsigned int cmDurationTo<unsigned int>(cmDuration const&);
+extern template int cmDurationTo<int>(cmDuration);
+extern template unsigned int cmDurationTo<unsigned int>(cmDuration);
 #endif
diff --git a/Source/cmEvaluatedTargetProperty.cxx b/Source/cmEvaluatedTargetProperty.cxx
index 7112a9b..f786985 100644
--- a/Source/cmEvaluatedTargetProperty.cxx
+++ b/Source/cmEvaluatedTargetProperty.cxx
@@ -14,8 +14,8 @@
 struct cmGeneratorExpressionDAGChecker;
 
 EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry(
-  cmLinkImplItem const& item, cmListFileBacktrace bt)
-  : LinkImplItem(item)
+  cmLinkItem const& item, cmListFileBacktrace bt)
+  : LinkItem(item)
   , Backtrace(std::move(bt))
 {
 }
@@ -25,7 +25,7 @@
   cmGeneratorExpressionDAGChecker* dagChecker,
   cmGeneratorTarget::TargetPropertyEntry& entry)
 {
-  EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
+  EvaluatedTargetPropertyEntry ee(entry.LinkItem, entry.GetBacktrace());
   cmExpandList(entry.Evaluate(context, thisTarget, dagChecker), ee.Values);
   if (entry.GetHadContextSensitiveCondition()) {
     ee.ContextDependent = true;
@@ -55,9 +55,9 @@
                        cmGeneratorExpressionDAGChecker* dagChecker,
                        EvaluatedTargetPropertyEntries& entries,
                        cmGeneratorTarget::UseTo usage,
-                       std::vector<cmLinkImplItem> const& libraries)
+                       std::vector<cmLinkItem> const& libraries)
 {
-  for (cmLinkImplItem const& lib : libraries) {
+  for (cmLinkItem const& lib : libraries) {
     if (lib.Target) {
       EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
       // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
diff --git a/Source/cmEvaluatedTargetProperty.h b/Source/cmEvaluatedTargetProperty.h
index 4ab4af4..1ffbec4 100644
--- a/Source/cmEvaluatedTargetProperty.h
+++ b/Source/cmEvaluatedTargetProperty.h
@@ -15,15 +15,14 @@
 }
 }
 
-class cmLinkImplItem;
+class cmLinkItem;
 struct cmGeneratorExpressionDAGChecker;
 
 // Represent a target property entry after evaluating generator expressions
 // and splitting up lists.
 struct EvaluatedTargetPropertyEntry
 {
-  EvaluatedTargetPropertyEntry(cmLinkImplItem const& item,
-                               cmListFileBacktrace bt);
+  EvaluatedTargetPropertyEntry(cmLinkItem const& item, cmListFileBacktrace bt);
 
   // Move-only.
   EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default;
@@ -33,7 +32,7 @@
   EvaluatedTargetPropertyEntry& operator=(
     EvaluatedTargetPropertyEntry const&) = delete;
 
-  cmLinkImplItem const& LinkImplItem;
+  cmLinkItem const& LinkItem;
   cmListFileBacktrace Backtrace;
   std::vector<std::string> Values;
   bool ContextDependent = false;
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index 2a018bc..b7aec46 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -65,7 +65,7 @@
     cmExperimental::TryCompileCondition::Never },
   // Instrumentation
   { "Instrumentation",
-    "a37d1069-1972-4901-b9c9-f194aaf2b6e0",
+    "ec7aa2dc-b87f-45a3-8022-fe01c5f59984",
     "CMAKE_EXPERIMENTAL_INSTRUMENTATION",
     "CMake's support for collecting instrumentation data is experimental. It "
     "is meant only for experimentation and feedback to CMake developers.",
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index c3cffc2..8650d49 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmExportBuildAndroidMKGenerator.h"
 
+#include <functional>
 #include <sstream>
 #include <vector>
 
diff --git a/Source/cmExportBuildAndroidMKGenerator.h b/Source/cmExportBuildAndroidMKGenerator.h
index 0624f2b..a754258 100644
--- a/Source/cmExportBuildAndroidMKGenerator.h
+++ b/Source/cmExportBuildAndroidMKGenerator.h
@@ -11,8 +11,6 @@
 #include "cmExportBuildFileGenerator.h"
 #include "cmStateTypes.h"
 
-class cmGeneratorTarget;
-
 /** \class cmExportBuildAndroidMKGenerator
  * \brief Generate a file exporting targets from a build tree.
  *
diff --git a/Source/cmExportBuildCMakeConfigGenerator.cxx b/Source/cmExportBuildCMakeConfigGenerator.cxx
index d317ffd..b163eae 100644
--- a/Source/cmExportBuildCMakeConfigGenerator.cxx
+++ b/Source/cmExportBuildCMakeConfigGenerator.cxx
@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <cstddef>
+#include <functional>
 #include <map>
 #include <memory>
 #include <set>
@@ -208,7 +209,6 @@
           cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
       } else {
         resultVector.emplace_back(cmStrCat('"', dest, '"'));
-        break;
       }
     }
   }
diff --git a/Source/cmExportBuildCMakeConfigGenerator.h b/Source/cmExportBuildCMakeConfigGenerator.h
index 7c089b5..c625032 100644
--- a/Source/cmExportBuildCMakeConfigGenerator.h
+++ b/Source/cmExportBuildCMakeConfigGenerator.h
@@ -10,10 +10,6 @@
 #include "cmExportBuildFileGenerator.h"
 #include "cmExportCMakeConfigGenerator.h"
 
-class cmFileSet;
-class cmGeneratorTarget;
-class cmTargetExport;
-
 /** \class cmExportBuildCMakeConfigGenerator
  * \brief Generate a file exporting targets from a build tree.
  *
diff --git a/Source/cmExportBuildPackageInfoGenerator.cxx b/Source/cmExportBuildPackageInfoGenerator.cxx
index 980bb29..a8546c0 100644
--- a/Source/cmExportBuildPackageInfoGenerator.cxx
+++ b/Source/cmExportBuildPackageInfoGenerator.cxx
@@ -3,6 +3,8 @@
 #include "cmExportBuildPackageInfoGenerator.h"
 
 #include <cassert>
+#include <functional>
+#include <map>
 #include <utility>
 #include <vector>
 
@@ -10,7 +12,9 @@
 
 #include <cm3p/json/value.h>
 
+#include "cmAlgorithms.h"
 #include "cmGeneratorExpression.h"
+#include "cmList.h"
 #include "cmPackageInfoArguments.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -68,6 +72,14 @@
       }
     }
 
+    // De-duplicate include directories prior to generation.
+    auto it = properties.find("INTERFACE_INCLUDE_DIRECTORIES");
+    if (it != properties.end()) {
+      auto list = cmList{ it->second };
+      list = cmList{ list.begin(), cmRemoveDuplicates(list) };
+      properties["INTERFACE_INCLUDE_DIRECTORIES"] = list.to_string();
+    }
+
     // Set configuration-agnostic properties for component.
     this->GenerateInterfaceProperties(*component, target, properties);
   }
diff --git a/Source/cmExportCMakeConfigGenerator.cxx b/Source/cmExportCMakeConfigGenerator.cxx
index ce9610a..47ea974 100644
--- a/Source/cmExportCMakeConfigGenerator.cxx
+++ b/Source/cmExportCMakeConfigGenerator.cxx
@@ -26,7 +26,7 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmValue.h"
-#include "cmVersion.h"
+#include "cmVersionMacros.h"
 
 struct cmLinkInterface;
 
@@ -173,7 +173,7 @@
   // Isolate the file policy level.
   // Support CMake versions as far back as the
   // RequiredCMakeVersion{Major,Minor,Patch}, but also support using NEW
-  // policy settings for up to CMake 3.31 (this upper limit may be reviewed
+  // policy settings for up to CMake 4.0 (this upper limit may be reviewed
   // and increased from time to time). This reduces the opportunity for CMake
   // warnings when an older export file is later used with newer CMake
   // versions.
@@ -182,7 +182,7 @@
         "cmake_policy(VERSION "
      << this->RequiredCMakeVersionMajor << '.'
      << this->RequiredCMakeVersionMinor << '.'
-     << this->RequiredCMakeVersionPatch << "...3.31)\n";
+     << this->RequiredCMakeVersionPatch << "...4.0)\n";
   /* clang-format on */
 }
 
@@ -292,7 +292,18 @@
       os << "add_library(" << targetName << " OBJECT IMPORTED)\n";
       break;
     case cmStateEnums::INTERFACE_LIBRARY:
-      os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
+      if (target->IsSymbolic()) {
+        os << "if(CMAKE_VERSION VERSION_GREATER_EQUAL \"4.2.0\")\n"
+              "  add_library("
+           << targetName << " INTERFACE SYMBOLIC IMPORTED)\n"
+           << "elseif(CMAKE_VERSION VERSION_GREATER_EQUAL 3.2.0)\n"
+           << "  add_library(" << targetName << " INTERFACE IMPORTED)\n"
+           << "  set_target_properties(" << targetName
+           << " PROPERTIES SYMBOLIC TRUE)\n"
+           << "endif()\n";
+      } else {
+        os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
+      }
       break;
     default: // should never happen
       break;
@@ -451,16 +462,27 @@
       return lhs.second.FindPackageIndex < rhs.second.FindPackageIndex;
     });
 
+  // Unwinding is only valid in a find_package() context
+  os << "if(DEFINED CMAKE_FIND_PACKAGE_NAME)\n"
+     << "  set(_cmake_unwind_arg UNWIND_INCLUDE)\n"
+     << "endif()\n\n";
+
   for (auto const& it : packageDependenciesSorted) {
     if (it.second.Enabled == cmExportSet::PackageDependencyExportEnabled::On) {
-      os << "find_dependency(" << it.first;
+      os << "__find_dependency_no_return(" << it.first;
       for (auto const& arg : it.second.ExtraArguments) {
         os << ' ' << cmOutputConverter::EscapeForCMake(arg);
       }
-      os << ")\n";
+      os << " ${_cmake_unwind_arg})\n";
+      os << "if(NOT " << it.first << "_FOUND)\n"
+         << "  unset(_cmake_unwind_arg)\n"
+         << "  cmake_policy(POP)\n"
+         << "  return()\n"
+         << "endif()\n\n";
     }
   }
-  os << "\n\n";
+
+  os << "unset(_cmake_unwind_arg)\n\n\n";
 }
 
 void cmExportCMakeConfigGenerator::GenerateMissingTargetsCheckCode(
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 42590f3..b4f7343 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -32,6 +32,7 @@
 #include "cmRange.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
+#include "cmSubcommandTable.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmValue.h"
@@ -45,73 +46,34 @@
 #  include <windows.h>
 #endif
 
-static bool HandlePackage(std::vector<std::string> const& args,
-                          cmExecutionStatus& status);
-
 static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
                                  char const* content, char const* hash);
 
-bool cmExportCommand(std::vector<std::string> const& args,
-                     cmExecutionStatus& status)
+static bool HandleTargetsMode(std::vector<std::string> const& args,
+                              cmExecutionStatus& status)
 {
-  if (args.size() < 2) {
-    status.SetError("called with too few arguments");
-    return false;
-  }
-
-  if (args[0] == "PACKAGE") {
-    return HandlePackage(args, status);
-  }
-
-  struct Arguments : cmPackageInfoArguments
+  struct Arguments
   {
     cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Targets;
     ArgumentParser::NonEmpty<std::string> ExportSetName;
     ArgumentParser::NonEmpty<std::string> Namespace;
     ArgumentParser::NonEmpty<std::string> Filename;
-    ArgumentParser::NonEmpty<std::string> AndroidMKFile;
     ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
+    ArgumentParser::NonEmpty<std::string> AndroidMKFile;
+
     bool Append = false;
     bool ExportOld = false;
-
-    std::vector<std::vector<std::string>> PackageDependencyArgs;
-    bool ExportPackageDependencies = false;
-
-    std::vector<std::vector<std::string>> TargetArgs;
   };
 
   auto parser =
     cmArgumentParser<Arguments>{}
       .Bind("NAMESPACE"_s, &Arguments::Namespace)
       .Bind("FILE"_s, &Arguments::Filename)
-      .Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory);
-
-  if (args[0] == "EXPORT") {
-    parser.Bind("EXPORT"_s, &Arguments::ExportSetName);
-    if (cmExperimental::HasSupportEnabled(
-          status.GetMakefile(),
-          cmExperimental::Feature::ExportPackageDependencies)) {
-      parser.Bind("EXPORT_PACKAGE_DEPENDENCIES"_s,
-                  &Arguments::ExportPackageDependencies);
-    }
-    if (cmExperimental::HasSupportEnabled(
-          status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) {
-      cmPackageInfoArguments::Bind(parser);
-    }
-  } else if (args[0] == "SETUP") {
-    parser.Bind("SETUP"_s, &Arguments::ExportSetName);
-    if (cmExperimental::HasSupportEnabled(
-          status.GetMakefile(),
-          cmExperimental::Feature::ExportPackageDependencies)) {
-      parser.Bind("PACKAGE_DEPENDENCY"_s, &Arguments::PackageDependencyArgs);
-    }
-    parser.Bind("TARGET"_s, &Arguments::TargetArgs);
-  } else {
-    parser.Bind("TARGETS"_s, &Arguments::Targets);
-    parser.Bind("ANDROID_MK"_s, &Arguments::AndroidMKFile);
-    parser.Bind("APPEND"_s, &Arguments::Append);
-    parser.Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, &Arguments::ExportOld);
-  }
+      .Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory)
+      .Bind("TARGETS"_s, &Arguments::Targets)
+      .Bind("APPEND"_s, &Arguments::Append)
+      .Bind("ANDROID_MK"_s, &Arguments::AndroidMKFile)
+      .Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, &Arguments::ExportOld);
 
   std::vector<std::string> unknownArgs;
   Arguments arguments = parser.Parse(args, &unknownArgs);
@@ -121,127 +83,13 @@
     return false;
   }
 
-  if (args[0] == "SETUP") {
-    cmMakefile& mf = status.GetMakefile();
-    cmGlobalGenerator* gg = mf.GetGlobalGenerator();
-
-    cmExportSetMap& setMap = gg->GetExportSets();
-    auto& exportSet = setMap[arguments.ExportSetName];
-
-    struct PackageDependencyArguments
-    {
-      std::string Enabled;
-      ArgumentParser::MaybeEmpty<std::vector<std::string>> ExtraArgs;
-    };
-
-    auto packageDependencyParser =
-      cmArgumentParser<PackageDependencyArguments>{}
-        .Bind("ENABLED"_s, &PackageDependencyArguments::Enabled)
-        .Bind("EXTRA_ARGS"_s, &PackageDependencyArguments::ExtraArgs);
-
-    for (auto const& packageDependencyArgs : arguments.PackageDependencyArgs) {
-      if (packageDependencyArgs.empty()) {
-        continue;
-      }
-
-      PackageDependencyArguments const packageDependencyArguments =
-        packageDependencyParser.Parse(
-          cmMakeRange(packageDependencyArgs).advance(1), &unknownArgs);
-
-      if (!unknownArgs.empty()) {
-        status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
-        return false;
-      }
-
-      auto& packageDependency =
-        exportSet.GetPackageDependencyForSetup(packageDependencyArgs.front());
-
-      if (!packageDependencyArguments.Enabled.empty()) {
-        if (packageDependencyArguments.Enabled == "AUTO") {
-          packageDependency.Enabled =
-            cmExportSet::PackageDependencyExportEnabled::Auto;
-        } else if (cmIsOff(packageDependencyArguments.Enabled)) {
-          packageDependency.Enabled =
-            cmExportSet::PackageDependencyExportEnabled::Off;
-        } else if (cmIsOn(packageDependencyArguments.Enabled)) {
-          packageDependency.Enabled =
-            cmExportSet::PackageDependencyExportEnabled::On;
-        } else {
-          status.SetError(
-            cmStrCat("Invalid enable setting for package dependency: \"",
-                     packageDependencyArguments.Enabled, '"'));
-          return false;
-        }
-      }
-
-      cm::append(packageDependency.ExtraArguments,
-                 packageDependencyArguments.ExtraArgs);
-    }
-
-    struct TargetArguments
-    {
-      std::string XcFrameworkLocation;
-    };
-
-    auto targetParser = cmArgumentParser<TargetArguments>{}.Bind(
-      "XCFRAMEWORK_LOCATION"_s, &TargetArguments::XcFrameworkLocation);
-
-    for (auto const& targetArgs : arguments.TargetArgs) {
-      if (targetArgs.empty()) {
-        continue;
-      }
-
-      TargetArguments const targetArguments =
-        targetParser.Parse(cmMakeRange(targetArgs).advance(1), &unknownArgs);
-
-      if (!unknownArgs.empty()) {
-        status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
-        return false;
-      }
-
-      exportSet.SetXcFrameworkLocation(targetArgs.front(),
-                                       targetArguments.XcFrameworkLocation);
-    }
-
-    return true;
-  }
-
-  if (arguments.PackageName.empty()) {
-    if (!arguments.Check(status, false)) {
-      return false;
-    }
-  } else {
-    if (!arguments.Filename.empty()) {
-      status.SetError("PACKAGE_INFO and FILE are mutually exclusive.");
-      return false;
-    }
-    if (!arguments.Namespace.empty()) {
-      status.SetError("PACKAGE_INFO and NAMESPACE are mutually exclusive.");
-      return false;
-    }
-    if (!arguments.Check(status) ||
-        !arguments.SetMetadataFromProject(status)) {
-      return false;
-    }
-  }
-
   std::string fname;
   bool android = false;
-  bool cps = false;
   if (!arguments.AndroidMKFile.empty()) {
     fname = arguments.AndroidMKFile;
     android = true;
   } else if (arguments.Filename.empty()) {
-    if (args[0] != "EXPORT") {
-      status.SetError("FILE <filename> option missing.");
-      return false;
-    }
-    if (arguments.PackageName.empty()) {
-      fname = arguments.ExportSetName + ".cmake";
-    } else {
-      fname = arguments.GetPackageFileName();
-      cps = true;
-    }
+    fname = arguments.ExportSetName + ".cmake";
   } else {
     // Make sure the file has a .cmake extension.
     if (cmSystemTools::GetFilenameLastExtension(arguments.Filename) !=
@@ -273,66 +121,43 @@
   }
 
   std::vector<cmExportBuildFileGenerator::TargetExport> targets;
-
   cmGlobalGenerator* gg = mf.GetGlobalGenerator();
 
-  cmExportSet* exportSet = nullptr;
-  if (args[0] == "EXPORT") {
-    cmExportSetMap& setMap = gg->GetExportSets();
-    auto const it = setMap.find(arguments.ExportSetName);
-    if (it == setMap.end()) {
+  for (std::string const& currentTarget : *arguments.Targets) {
+    if (mf.IsAlias(currentTarget)) {
       std::ostringstream e;
-      e << "Export set \"" << arguments.ExportSetName << "\" not found.";
+      e << "given ALIAS target \"" << currentTarget
+        << "\" which may not be exported.";
       status.SetError(e.str());
       return false;
     }
-    exportSet = &it->second;
-  } else if (arguments.Targets) {
-    for (std::string const& currentTarget : *arguments.Targets) {
-      if (mf.IsAlias(currentTarget)) {
-        std::ostringstream e;
-        e << "given ALIAS target \"" << currentTarget
-          << "\" which may not be exported.";
-        status.SetError(e.str());
-        return false;
-      }
 
-      if (cmTarget* target = gg->FindTarget(currentTarget)) {
-        if (target->GetType() == cmStateEnums::UTILITY) {
-          status.SetError("given custom target \"" + currentTarget +
-                          "\" which may not be exported.");
-          return false;
-        }
-      } else {
-        std::ostringstream e;
-        e << "given target \"" << currentTarget
-          << "\" which is not built by this project.";
-        status.SetError(e.str());
+    if (cmTarget* target = gg->FindTarget(currentTarget)) {
+      if (target->GetType() == cmStateEnums::UTILITY) {
+        status.SetError("given custom target \"" + currentTarget +
+                        "\" which may not be exported.");
         return false;
       }
-      targets.emplace_back(currentTarget, std::string{});
+    } else {
+      std::ostringstream e;
+      e << "given target \"" << currentTarget
+        << "\" which is not built by this project.";
+      status.SetError(e.str());
+      return false;
     }
-    if (arguments.Append) {
-      if (cmExportBuildFileGenerator* ebfg =
-            gg->GetExportedTargetsFile(fname)) {
-        ebfg->AppendTargets(targets);
-        return true;
-      }
+    targets.emplace_back(currentTarget, std::string{});
+  }
+  if (arguments.Append) {
+    if (cmExportBuildFileGenerator* ebfg = gg->GetExportedTargetsFile(fname)) {
+      ebfg->AppendTargets(targets);
+      return true;
     }
-  } else {
-    status.SetError("EXPORT or TARGETS specifier missing.");
-    return false;
   }
 
   // if cmExportBuildFileGenerator is already defined for the file
   // and APPEND is not specified, if CMP0103 is OLD ignore previous definition
   // else raise an error
   if (gg->GetExportedTargetsFile(fname)) {
-    if (cps) {
-      status.SetError(cmStrCat("command already specified for the file "_s,
-                               cmSystemTools::GetFilenameName(fname), '.'));
-      return false;
-    }
     switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
       case cmPolicies::WARN:
         mf.IssueMessage(
@@ -352,33 +177,173 @@
     }
   }
 
-  // Set up export file generation.
   std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
   if (android) {
     auto ebag = cm::make_unique<cmExportBuildAndroidMKGenerator>();
     ebag->SetNamespace(arguments.Namespace);
     ebag->SetAppendMode(arguments.Append);
     ebfg = std::move(ebag);
-  } else if (cps) {
-    auto ebpg = cm::make_unique<cmExportBuildPackageInfoGenerator>(arguments);
-    ebfg = std::move(ebpg);
   } else {
     auto ebcg = cm::make_unique<cmExportBuildCMakeConfigGenerator>();
     ebcg->SetNamespace(arguments.Namespace);
     ebcg->SetAppendMode(arguments.Append);
     ebcg->SetExportOld(arguments.ExportOld);
+    ebfg = std::move(ebcg);
+  }
+
+  ebfg->SetExportFile(fname.c_str());
+  ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
+  ebfg->SetTargets(targets);
+  std::vector<std::string> configurationTypes =
+    mf.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+  for (std::string const& ct : configurationTypes) {
+    ebfg->AddConfiguration(ct);
+  }
+  gg->AddBuildExportSet(ebfg.get());
+  mf.AddExportBuildFileGenerator(std::move(ebfg));
+
+  return true;
+}
+
+static bool HandleExportMode(std::vector<std::string> const& args,
+                             cmExecutionStatus& status)
+{
+  struct ExportArguments
+  {
+    ArgumentParser::NonEmpty<std::string> ExportSetName;
+    ArgumentParser::NonEmpty<std::string> Namespace;
+    ArgumentParser::NonEmpty<std::string> Filename;
+    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
+    cm::optional<cmPackageInfoArguments> PackageInfo;
+    bool ExportPackageDependencies = false;
+  };
+
+  auto parser =
+    cmArgumentParser<ExportArguments>{}
+      .Bind("EXPORT"_s, &ExportArguments::ExportSetName)
+      .Bind("NAMESPACE"_s, &ExportArguments::Namespace)
+      .Bind("FILE"_s, &ExportArguments::Filename)
+      .Bind("CXX_MODULES_DIRECTORY"_s, &ExportArguments::CxxModulesDirectory);
+
+  if (cmExperimental::HasSupportEnabled(
+        status.GetMakefile(),
+        cmExperimental::Feature::ExportPackageDependencies)) {
+    parser.Bind("EXPORT_PACKAGE_DEPENDENCIES"_s,
+                &ExportArguments::ExportPackageDependencies);
+  }
+
+  cmArgumentParser<cmPackageInfoArguments> packageInfoParser;
+  cmPackageInfoArguments::Bind(packageInfoParser);
+
+  if (cmExperimental::HasSupportEnabled(
+        status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) {
+    parser.BindSubParser("PACKAGE_INFO"_s, packageInfoParser,
+                         &ExportArguments::PackageInfo);
+  }
+
+  std::vector<std::string> unknownArgs;
+  ExportArguments arguments = parser.Parse(args, &unknownArgs);
+
+  cmMakefile& mf = status.GetMakefile();
+  cmGlobalGenerator* gg = mf.GetGlobalGenerator();
+
+  if (arguments.PackageInfo) {
+    if (arguments.PackageInfo->PackageName.empty()) {
+      // TODO: Fix our use of the parser to enforce this.
+      status.SetError("PACKAGE_INFO missing required value.");
+      return false;
+    }
+    if (!arguments.Filename.empty()) {
+      status.SetError("PACKAGE_INFO and FILE are mutually exclusive.");
+      return false;
+    }
+    if (!arguments.Namespace.empty()) {
+      status.SetError("PACKAGE_INFO and NAMESPACE are mutually exclusive.");
+      return false;
+    }
+    if (!arguments.PackageInfo->Check(status) ||
+        !arguments.PackageInfo->SetMetadataFromProject(status)) {
+      return false;
+    }
+  }
+
+  if (!unknownArgs.empty()) {
+    status.SetError("EXPORT given unknown argument: \"" + unknownArgs.front() +
+                    "\".");
+    return false;
+  }
+
+  std::string fname;
+  if (arguments.Filename.empty()) {
+    if (arguments.PackageInfo) {
+      fname = arguments.PackageInfo->GetPackageFileName();
+    } else {
+      fname = arguments.ExportSetName + ".cmake";
+    }
+  } else {
+    if (cmSystemTools::GetFilenameLastExtension(arguments.Filename) !=
+        ".cmake") {
+      std::ostringstream e;
+      e << "FILE option given filename \"" << arguments.Filename
+        << "\" which does not have an extension of \".cmake\".\n";
+      status.SetError(e.str());
+      return false;
+    }
+    fname = arguments.Filename;
+  }
+
+  if (cmSystemTools::FileIsFullPath(fname)) {
+    if (!mf.CanIWriteThisFile(fname)) {
+      std::ostringstream e;
+      e << "FILE option given filename \"" << fname
+        << "\" which is in the source tree.\n";
+      status.SetError(e.str());
+      return false;
+    }
+  } else {
+    // Interpret relative paths with respect to the current build dir.
+    std::string const& dir = mf.GetCurrentBinaryDirectory();
+    fname = dir + "/" + fname;
+  }
+
+  if (gg->GetExportedTargetsFile(fname)) {
+    if (arguments.PackageInfo) {
+      status.SetError(cmStrCat("command already specified for the file "_s,
+                               cmSystemTools::GetFilenameName(fname), '.'));
+      return false;
+    }
+  }
+
+  cmExportSet* exportSet = nullptr;
+  cmExportSetMap& setMap = gg->GetExportSets();
+  auto const it = setMap.find(arguments.ExportSetName);
+  if (it == setMap.end()) {
+    std::ostringstream e;
+    e << "Export set \"" << arguments.ExportSetName << "\" not found.";
+    status.SetError(e.str());
+    return false;
+  }
+  exportSet = &it->second;
+
+  // Set up export file generation.
+  std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
+  if (arguments.PackageInfo) {
+    auto ebpg = cm::make_unique<cmExportBuildPackageInfoGenerator>(
+      *arguments.PackageInfo);
+    ebfg = std::move(ebpg);
+  } else {
+    auto ebcg = cm::make_unique<cmExportBuildCMakeConfigGenerator>();
+    ebcg->SetNamespace(arguments.Namespace);
     ebcg->SetExportPackageDependencies(arguments.ExportPackageDependencies);
     ebfg = std::move(ebcg);
   }
+
   ebfg->SetExportFile(fname.c_str());
   ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
   if (exportSet) {
     ebfg->SetExportSet(exportSet);
-  } else {
-    ebfg->SetTargets(targets);
   }
-
-  // Compute the set of configurations exported.
   std::vector<std::string> configurationTypes =
     mf.GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
 
@@ -387,16 +352,123 @@
   }
   if (exportSet) {
     gg->AddBuildExportExportSet(ebfg.get());
-  } else {
-    gg->AddBuildExportSet(ebfg.get());
   }
-  mf.AddExportBuildFileGenerator(std::move(ebfg));
 
+  mf.AddExportBuildFileGenerator(std::move(ebfg));
   return true;
 }
 
-static bool HandlePackage(std::vector<std::string> const& args,
-                          cmExecutionStatus& status)
+static bool HandleSetupMode(std::vector<std::string> const& args,
+                            cmExecutionStatus& status)
+{
+  struct SetupArguments
+  {
+    ArgumentParser::NonEmpty<std::string> ExportSetName;
+    ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
+    std::vector<std::vector<std::string>> PackageDependencyArgs;
+    std::vector<std::vector<std::string>> TargetArgs;
+  };
+
+  auto parser = cmArgumentParser<SetupArguments>{};
+  parser.Bind("SETUP"_s, &SetupArguments::ExportSetName);
+  if (cmExperimental::HasSupportEnabled(
+        status.GetMakefile(),
+        cmExperimental::Feature::ExportPackageDependencies)) {
+    parser.Bind("PACKAGE_DEPENDENCY"_s,
+                &SetupArguments::PackageDependencyArgs);
+  }
+  parser.Bind("TARGET"_s, &SetupArguments::TargetArgs);
+
+  std::vector<std::string> unknownArgs;
+  SetupArguments arguments = parser.Parse(args, &unknownArgs);
+
+  if (!unknownArgs.empty()) {
+    status.SetError("SETUP given unknown argument: \"" + unknownArgs.front() +
+                    "\".");
+    return false;
+  }
+
+  cmMakefile& mf = status.GetMakefile();
+  cmGlobalGenerator* gg = mf.GetGlobalGenerator();
+
+  cmExportSetMap& setMap = gg->GetExportSets();
+  auto& exportSet = setMap[arguments.ExportSetName];
+
+  struct PackageDependencyArguments
+  {
+    std::string Enabled;
+    ArgumentParser::MaybeEmpty<std::vector<std::string>> ExtraArgs;
+  };
+
+  auto packageDependencyParser =
+    cmArgumentParser<PackageDependencyArguments>{}
+      .Bind("ENABLED"_s, &PackageDependencyArguments::Enabled)
+      .Bind("EXTRA_ARGS"_s, &PackageDependencyArguments::ExtraArgs);
+
+  for (auto const& packageDependencyArgs : arguments.PackageDependencyArgs) {
+    if (packageDependencyArgs.empty()) {
+      continue;
+    }
+    PackageDependencyArguments const packageDependencyArguments =
+      packageDependencyParser.Parse(
+        cmMakeRange(packageDependencyArgs).advance(1), &unknownArgs);
+
+    if (!unknownArgs.empty()) {
+      status.SetError("PACKAGE_DEPENDENCY given unknown argument: \"" +
+                      unknownArgs.front() + "\".");
+      return false;
+    }
+    auto& packageDependency =
+      exportSet.GetPackageDependencyForSetup(packageDependencyArgs.front());
+    if (!packageDependencyArguments.Enabled.empty()) {
+      if (packageDependencyArguments.Enabled == "AUTO") {
+        packageDependency.Enabled =
+          cmExportSet::PackageDependencyExportEnabled::Auto;
+      } else if (cmIsOff(packageDependencyArguments.Enabled)) {
+        packageDependency.Enabled =
+          cmExportSet::PackageDependencyExportEnabled::Off;
+      } else if (cmIsOn(packageDependencyArguments.Enabled)) {
+        packageDependency.Enabled =
+          cmExportSet::PackageDependencyExportEnabled::On;
+      } else {
+        status.SetError(
+          cmStrCat("Invalid enable setting for package dependency: \"",
+                   packageDependencyArguments.Enabled, '"'));
+        return false;
+      }
+    }
+    cm::append(packageDependency.ExtraArguments,
+               packageDependencyArguments.ExtraArgs);
+  }
+
+  struct TargetArguments
+  {
+    std::string XcFrameworkLocation;
+  };
+
+  auto targetParser = cmArgumentParser<TargetArguments>{}.Bind(
+    "XCFRAMEWORK_LOCATION"_s, &TargetArguments::XcFrameworkLocation);
+
+  for (auto const& targetArgs : arguments.TargetArgs) {
+    if (targetArgs.empty()) {
+      continue;
+    }
+    TargetArguments const targetArguments =
+      targetParser.Parse(cmMakeRange(targetArgs).advance(1), &unknownArgs);
+
+    if (!unknownArgs.empty()) {
+      status.SetError("TARGET given unknown argument: \"" +
+                      unknownArgs.front() + "\".");
+      return false;
+    }
+    exportSet.SetXcFrameworkLocation(targetArgs.front(),
+                                     targetArguments.XcFrameworkLocation);
+  }
+  return true;
+}
+
+static bool HandlePackageMode(std::vector<std::string> const& args,
+                              cmExecutionStatus& status)
 {
   // Parse PACKAGE mode arguments.
   enum Doing
@@ -545,3 +617,20 @@
   }
 }
 #endif
+
+bool cmExportCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status)
+{
+  if (args.empty()) {
+    return true;
+  }
+
+  static cmSubcommandTable const subcommand{
+    { "TARGETS"_s, HandleTargetsMode },
+    { "EXPORT"_s, HandleExportMode },
+    { "SETUP"_s, HandleSetupMode },
+    { "PACKAGE"_s, HandlePackageMode },
+  };
+
+  return subcommand(args[0], args, status);
+}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 477453d..fdf0dbd 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -215,7 +215,7 @@
   cmGeneratorExpression::Split(exportDirs, entries);
   exportDirs.clear();
   char const* sep = "";
-  cm::string_view const& prefixWithSlash = this->GetImportPrefixWithSlash();
+  cm::string_view const prefixWithSlash = this->GetImportPrefixWithSlash();
   for (std::string const& e : entries) {
     exportDirs += sep;
     sep = ";";
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index c32d82b..bae6b50 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -18,16 +18,6 @@
 class cmGeneratorTarget;
 class cmLocalGenerator;
 
-#define STRINGIFY_HELPER(X) #X
-#define STRINGIFY(X) STRINGIFY_HELPER(X)
-
-#define DEVEL_CMAKE_VERSION(major, minor)                                     \
-  (CMake_VERSION_ENCODE(major, minor, 0) >                                    \
-       CMake_VERSION_ENCODE(CMake_VERSION_MAJOR, CMake_VERSION_MINOR, 0)      \
-     ? STRINGIFY(CMake_VERSION_MAJOR) "." STRINGIFY(                          \
-         CMake_VERSION_MINOR) "." STRINGIFY(CMake_VERSION_PATCH)              \
-     : #major "." #minor ".0")
-
 /** \class cmExportFileGenerator
  * \brief Generate files exporting targets from a build or install tree.
  *
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 5ebde1f..15d4b41 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -3,6 +3,7 @@
 #include "cmExportInstallAndroidMKGenerator.h"
 
 #include <cstddef>
+#include <functional>
 #include <memory>
 #include <sstream>
 #include <vector>
diff --git a/Source/cmExportInstallCMakeConfigGenerator.cxx b/Source/cmExportInstallCMakeConfigGenerator.cxx
index a039be4..1eb3394 100644
--- a/Source/cmExportInstallCMakeConfigGenerator.cxx
+++ b/Source/cmExportInstallCMakeConfigGenerator.cxx
@@ -3,6 +3,7 @@
 #include "cmExportInstallCMakeConfigGenerator.h"
 
 #include <algorithm>
+#include <functional>
 #include <map>
 #include <memory>
 #include <set>
diff --git a/Source/cmExportInstallCMakeConfigGenerator.h b/Source/cmExportInstallCMakeConfigGenerator.h
index 4729c23..480384d 100644
--- a/Source/cmExportInstallCMakeConfigGenerator.h
+++ b/Source/cmExportInstallCMakeConfigGenerator.h
@@ -10,10 +10,7 @@
 #include "cmExportCMakeConfigGenerator.h"
 #include "cmExportInstallFileGenerator.h"
 
-class cmFileSet;
-class cmGeneratorTarget;
 class cmInstallExportGenerator;
-class cmTargetExport;
 
 /** \class cmExportInstallCMakeConfigGenerator
  * \brief Generate files exporting targets from an install tree.
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 2df3264..738fbb7 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -17,7 +17,6 @@
 #include "cmInstallExportGenerator.h"
 #include "cmStateTypes.h"
 
-class cmExportSet;
 class cmGeneratorTarget;
 class cmInstallTargetGenerator;
 class cmTargetExport;
@@ -75,7 +74,7 @@
 
   std::string GetInstallPrefix() const
   {
-    cm::string_view const& prefixWithSlash = this->GetImportPrefixWithSlash();
+    cm::string_view const prefixWithSlash = this->GetImportPrefixWithSlash();
     return std::string(prefixWithSlash.data(), prefixWithSlash.length() - 1);
   }
   virtual char GetConfigFileNameSeparator() const = 0;
diff --git a/Source/cmExportInstallPackageInfoGenerator.cxx b/Source/cmExportInstallPackageInfoGenerator.cxx
index 5a660c4..7fab8dc 100644
--- a/Source/cmExportInstallPackageInfoGenerator.cxx
+++ b/Source/cmExportInstallPackageInfoGenerator.cxx
@@ -2,19 +2,33 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmExportInstallPackageInfoGenerator.h"
 
+#include <functional>
+#include <map>
 #include <memory>
 #include <set>
+#include <sstream>
 #include <utility>
 #include <vector>
 
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
 #include <cm3p/json/value.h>
 
+#include "cmAlgorithms.h"
 #include "cmExportSet.h"
+#include "cmFileSet.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmInstallExportGenerator.h"
+#include "cmInstallFileSetGenerator.h"
+#include "cmList.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmOutputConverter.h"
 #include "cmPackageInfoArguments.h"
 #include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
@@ -67,7 +81,6 @@
   root["cps_path"] = packagePath;
 
   // Create all the imported targets.
-  bool requiresConfigFiles = false;
   for (cmTargetExport const* te : allTargets) {
     cmGeneratorTarget* gt = te->Target;
     cmStateEnums::TargetType targetType = this->GetExportTargetType(te);
@@ -86,11 +99,22 @@
       gt, cmGeneratorExpression::InstallInterface, properties);
 
     if (targetType != cmStateEnums::INTERFACE_LIBRARY) {
-      requiresConfigFiles = true;
+      this->RequiresConfigFiles = true;
+    }
+
+    // De-duplicate include directories prior to generation.
+    auto it = properties.find("INTERFACE_INCLUDE_DIRECTORIES");
+    if (it != properties.end()) {
+      auto list = cmList{ it->second };
+      list = cmList{ list.begin(), cmRemoveDuplicates(list) };
+      properties["INTERFACE_INCLUDE_DIRECTORIES"] = list.to_string();
     }
 
     // Set configuration-agnostic properties for component.
     this->GenerateInterfaceProperties(*component, gt, properties);
+    if (!this->GenerateFileSetProperties(*component, gt, te)) {
+      return false;
+    }
   }
 
   this->GeneratePackageRequires(root);
@@ -101,7 +125,7 @@
   bool result = true;
 
   // Generate an import file for each configuration.
-  if (requiresConfigFiles) {
+  if (this->RequiresConfigFiles) {
     for (std::string const& c : this->Configurations) {
       if (!this->GenerateImportFileConfig(c)) {
         result = false;
@@ -123,19 +147,19 @@
 
   for (auto const& te : this->GetExportSet()->GetTargetExports()) {
     // Collect import properties for this target.
-    if (this->GetExportTargetType(te.get()) ==
-        cmStateEnums::INTERFACE_LIBRARY) {
-      continue;
-    }
-
     ImportPropertyMap properties;
     std::set<std::string> importedLocations;
 
-    this->PopulateImportProperties(config, suffix, te.get(), properties,
-                                   importedLocations);
+    if (this->GetExportTargetType(te.get()) !=
+        cmStateEnums::INTERFACE_LIBRARY) {
+      this->PopulateImportProperties(config, suffix, te.get(), properties,
+                                     importedLocations);
+    }
 
     Json::Value component =
       this->GenerateInterfaceConfigProperties(suffix, properties);
+    this->GenerateFileSetProperties(component, te->Target, te.get(), config);
+
     if (!component.empty()) {
       components[te->Target->GetExportName()] = std::move(component);
     }
@@ -193,3 +217,82 @@
   // return IEGen->GetCxxModuleDirectory();
   return {};
 }
+
+cm::optional<std::string>
+cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
+  cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
+  cm::optional<std::string> const& config)
+{
+  cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
+  auto cge =
+    ge.Parse(te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
+
+  std::string const unescapedDest =
+    cge->Evaluate(gte->LocalGenerator, config.value_or(""), gte);
+  bool const isConfigDependent = cge->GetHadContextSensitiveCondition();
+
+  if (config && !isConfigDependent) {
+    return {};
+  }
+  if (!config && isConfigDependent) {
+    this->RequiresConfigFiles = true;
+    return {};
+  }
+
+  std::string const& type = fileSet->GetType();
+  if (config && (type == "CXX_MODULES"_s)) {
+    // C++ modules do not support interface file sets which are dependent
+    // upon the configuration.
+    cmMakefile* mf = gte->LocalGenerator->GetMakefile();
+    std::ostringstream e;
+    e << "The \"" << gte->GetName() << "\" target's interface file set \""
+      << fileSet->GetName() << "\" of type \"" << type
+      << "\" contains context-sensitive base file entries which is not "
+         "supported.";
+    mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    return {};
+  }
+
+  cm::optional<std::string> dest = cmOutputConverter::EscapeForCMake(
+    unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
+
+  if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
+    dest = cmStrCat("@prefix@/"_s, *dest);
+  }
+
+  return dest;
+}
+
+bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
+  Json::Value& component, cmGeneratorTarget* gte, cmTargetExport const* te,
+  cm::optional<std::string> config)
+{
+  std::set<std::string> seenIncludeDirectories;
+  for (auto const& name : gte->Target->GetAllInterfaceFileSets()) {
+    cmFileSet* fileSet = gte->Target->GetFileSet(name);
+
+    if (!fileSet) {
+      gte->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("File set \"", name,
+                 "\" is listed in interface file sets of ", gte->GetName(),
+                 " but has not been created"));
+      return false;
+    }
+
+    cm::optional<std::string> const& fileSetDirectory =
+      this->GetFileSetDirectory(gte, te, fileSet, config);
+
+    if (fileSet->GetType() == "HEADERS"_s) {
+      if (fileSetDirectory &&
+          !cm::contains(seenIncludeDirectories, *fileSetDirectory)) {
+        component["includes"].append(*fileSetDirectory);
+        seenIncludeDirectories.insert(*fileSetDirectory);
+      }
+    } else if (fileSet->GetType() == "CXX_MODULES"_s) {
+      /* TODO: Handle the CXX_MODULE directory */
+    }
+  }
+
+  return true;
+}
diff --git a/Source/cmExportInstallPackageInfoGenerator.h b/Source/cmExportInstallPackageInfoGenerator.h
index abdd015..0cb79c8 100644
--- a/Source/cmExportInstallPackageInfoGenerator.h
+++ b/Source/cmExportInstallPackageInfoGenerator.h
@@ -7,12 +7,20 @@
 #include <iosfwd>
 #include <string>
 
+#include <cm/optional>
+
 #include "cmExportInstallFileGenerator.h"
 #include "cmExportPackageInfoGenerator.h"
 
+class cmFileSet;
 class cmGeneratorTarget;
 class cmInstallExportGenerator;
 class cmPackageInfoArguments;
+class cmTargetExport;
+
+namespace Json {
+class Value;
+}
 
 /** \class cmExportInstallPackageInfoGenerator
  * \brief Generate files exporting targets from an install tree.
@@ -43,6 +51,8 @@
   std::string GetConfigImportFileGlob() const override;
 
 protected:
+  bool RequiresConfigFiles = false;
+
   std::string const& GetExportName() const override;
 
   // Implement virtual methods from the superclass.
@@ -60,4 +70,13 @@
 
   std::string GetCxxModulesDirectory() const override;
   // TODO: Generate C++ module info in a not-CMake-specific format.
+
+  cm::optional<std::string> GetFileSetDirectory(
+    cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
+    cm::optional<std::string> const& config = {});
+
+  bool GenerateFileSetProperties(Json::Value& component,
+                                 cmGeneratorTarget* gte,
+                                 cmTargetExport const* te,
+                                 cm::optional<std::string> config = {});
 };
diff --git a/Source/cmExportPackageInfoGenerator.cxx b/Source/cmExportPackageInfoGenerator.cxx
index a683025..d63b2d5 100644
--- a/Source/cmExportPackageInfoGenerator.cxx
+++ b/Source/cmExportPackageInfoGenerator.cxx
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include <cm/optional>
 #include <cm/string_view>
 #include <cmext/algorithm>
 #include <cmext/string_view>
@@ -27,7 +28,6 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
-#include "cmValue.h"
 
 static std::string const kCPS_VERSION_STR = "0.13.0";
 
@@ -39,6 +39,8 @@
   , PackageVersionSchema(std::move(arguments.VersionSchema))
   , PackageDescription(std::move(arguments.Description))
   , PackageWebsite(std::move(arguments.Website))
+  , PackageLicense(std::move(arguments.License))
+  , DefaultLicense(std::move(arguments.DefaultLicense))
   , DefaultTargets(std::move(arguments.DefaultTargets))
   , DefaultConfigurations(std::move(arguments.DefaultConfigs))
 {
@@ -127,7 +129,8 @@
 
   SetProperty(package, "description", this->PackageDescription);
   SetProperty(package, "website", this->PackageWebsite);
-  // TODO: license
+  SetProperty(package, "license", this->PackageLicense);
+  SetProperty(package, "default_license", this->DefaultLicense);
 
   return package;
 }
@@ -143,15 +146,25 @@
       auto data = Json::Value{ Json::objectValue };
 
       // Add required components.
-      if (!requirement.second.empty()) {
+      if (!requirement.second.Components.empty()) {
         auto components = Json::Value{ Json::arrayValue };
-        for (std::string const& component : requirement.second) {
+        for (std::string const& component : requirement.second.Components) {
           components.append(component);
         }
         data["components"] = components;
       }
 
-      // TODO: version, hint
+      // Add additional dependency information.
+      if (requirement.second.Directory) {
+        auto hints = Json::Value{ Json::arrayValue };
+        hints.append(*requirement.second.Directory);
+        data["hints"] = hints;
+      }
+
+      if (requirement.second.Version) {
+        data["version"] = *requirement.second.Version;
+      }
+
       requirements[requirement.first] = data;
     }
   }
@@ -168,6 +181,7 @@
 
   Json::Value& component = components[name];
   Json::Value& type = component["type"];
+
   switch (targetType) {
     case cmStateEnums::EXECUTABLE:
       type = "executable";
@@ -182,7 +196,7 @@
       type = "module";
       break;
     case cmStateEnums::INTERFACE_LIBRARY:
-      type = "interface";
+      type = target->IsSymbolic() ? "symbolic" : "interface";
       break;
     default:
       type = "unknown";
@@ -280,16 +294,24 @@
 
   if (linkedTarget->IsImported()) {
     // Target is imported from a found package.
-    auto pkgName = [linkedTarget]() -> std::string {
-      auto const& pkgStack = linkedTarget->Target->GetFindPackageStack();
+    using Package = cm::optional<std::pair<std::string, cmPackageInformation>>;
+    auto pkgInfo = [](cmTarget* t) -> Package {
+      cmFindPackageStack pkgStack = t->GetFindPackageStack();
       if (!pkgStack.Empty()) {
-        return pkgStack.Top().Name;
+        return std::make_pair(pkgStack.Top().Name, pkgStack.Top().PackageInfo);
       }
 
-      return linkedTarget->Target->GetProperty("EXPORT_FIND_PACKAGE_NAME");
-    }();
+      cmPackageInformation package;
+      std::string const pkgName =
+        t->GetSafeProperty("EXPORT_FIND_PACKAGE_NAME");
+      if (pkgName.empty()) {
+        return cm::nullopt;
+      }
 
-    if (pkgName.empty()) {
+      return std::make_pair(pkgName, package);
+    }(linkedTarget->Target);
+
+    if (!pkgInfo) {
       target->Makefile->IssueMessage(
         MessageType::FATAL_ERROR,
         cmStrCat("Target \"", target->GetName(),
@@ -298,6 +320,8 @@
       return false;
     }
 
+    std::string const& pkgName = pkgInfo->first;
+
     auto const& prefix = cmStrCat(pkgName, "::");
     if (!cmHasPrefix(linkedName, prefix)) {
       target->Makefile->IssueMessage(
@@ -312,8 +336,9 @@
 
     std::string component = linkedName.substr(prefix.length());
     this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component));
-    // TODO: Record package version, hint.
-    this->Requirements[pkgName].emplace(std::move(component));
+    cmPackageInformation& req =
+      this->Requirements.insert(std::move(*pkgInfo)).first->second;
+    req.Components.emplace(std::move(component));
     return true;
   }
 
@@ -337,7 +362,7 @@
       this->LinkTargets.emplace(linkedName, cmStrCat(':', component));
     } else {
       this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component));
-      this->Requirements[pkgName].emplace(std::move(component));
+      this->Requirements[pkgName].Components.emplace(std::move(component));
     }
     return true;
   }
diff --git a/Source/cmExportPackageInfoGenerator.h b/Source/cmExportPackageInfoGenerator.h
index fb7d79f..0614e27 100644
--- a/Source/cmExportPackageInfoGenerator.h
+++ b/Source/cmExportPackageInfoGenerator.h
@@ -6,13 +6,13 @@
 
 #include <iosfwd>
 #include <map>
-#include <set>
 #include <string>
 #include <vector>
 
 #include <cm/string_view>
 
 #include "cmExportFileGenerator.h"
+#include "cmFindPackageStack.h"
 #include "cmStateTypes.h"
 
 namespace Json {
@@ -110,9 +110,12 @@
   std::string const PackageVersionSchema;
   std::string const PackageDescription;
   std::string const PackageWebsite;
+  std::string const PackageLicense;
+  std::string const DefaultLicense;
+
   std::vector<std::string> DefaultTargets;
   std::vector<std::string> DefaultConfigurations;
 
   std::map<std::string, std::string> LinkTargets;
-  std::map<std::string, std::set<std::string>> Requirements;
+  std::map<std::string, cmPackageInformation> Requirements;
 };
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index 20c0714..456e6b9 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -6,7 +6,6 @@
 #include <utility>
 
 #include <cm/memory>
-#include <cm/string_view>
 
 #include "cmFileSet.h"
 #include "cmGenExContext.h"
@@ -24,8 +23,6 @@
 #include "cmTarget.h"
 #include "cmValue.h"
 
-class cmTargetExport;
-
 cmExportTryCompileFileGenerator::cmExportTryCompileFileGenerator(
   cmGlobalGenerator* gg, std::vector<std::string> const& targets,
   cmMakefile* mf, std::set<std::string> const& langs)
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 2637dfe..d9a8361 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -11,11 +11,9 @@
 
 #include "cmExportCMakeConfigGenerator.h"
 
-class cmFileSet;
 class cmGeneratorTarget;
 class cmGlobalGenerator;
 class cmMakefile;
-class cmTargetExport;
 
 class cmExportTryCompileFileGenerator : public cmExportCMakeConfigGenerator
 {
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index cabfe19..968145c 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -974,7 +974,8 @@
             std::string cleanArgs =
               cmStrCat("-E chdir \"", lgen->GetObjectOutputRoot(), "\" \"",
                        cmSystemTools::GetCMakeCommand(), "\" -P \"");
-            cleanArgs += lgen->GetTargetDirectory(target.get());
+            cleanArgs += lgen->GetTargetDirectory(
+              target.get(), cmStateEnums::IntermediateDirKind::ObjectFiles);
             cleanArgs += "/cmake_clean.cmake\"";
             cmExtraEclipseCDT4Generator::AppendTarget(
               xml, "Clean", cmSystemTools::GetCMakeCommand(), cleanArgs,
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 3f60956..269cf23 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -6,6 +6,7 @@
 #include <utility>
 
 #include <cm/memory>
+#include <cm/string_view>
 
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
diff --git a/Source/cmFastbuildLinkLineComputer.cxx b/Source/cmFastbuildLinkLineComputer.cxx
new file mode 100644
index 0000000..105d246
--- /dev/null
+++ b/Source/cmFastbuildLinkLineComputer.cxx
@@ -0,0 +1,22 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmFastbuildLinkLineComputer.h"
+
+#include "cmGlobalFastbuildGenerator.h"
+
+class cmOutputConverter;
+
+cmFastbuildLinkLineComputer::cmFastbuildLinkLineComputer(
+  cmOutputConverter* outputConverter, cmStateDirectory const& stateDir,
+  cmGlobalFastbuildGenerator const* gg)
+  : cmLinkLineComputer(outputConverter, stateDir)
+  , GG(gg)
+{
+}
+
+std::string cmFastbuildLinkLineComputer::ConvertToLinkReference(
+  std::string const& lib) const
+{
+  return this->GG->ConvertToFastbuildPath(lib);
+}
diff --git a/Source/cmFastbuildLinkLineComputer.h b/Source/cmFastbuildLinkLineComputer.h
new file mode 100644
index 0000000..597f8f5
--- /dev/null
+++ b/Source/cmFastbuildLinkLineComputer.h
@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+
+#include "cmLinkLineComputer.h"
+
+class cmGlobalFastbuildGenerator;
+class cmOutputConverter;
+class cmStateDirectory;
+
+class cmFastbuildLinkLineComputer : public cmLinkLineComputer
+{
+public:
+  cmFastbuildLinkLineComputer(cmOutputConverter* outputConverter,
+                              cmStateDirectory const& stateDir,
+                              cmGlobalFastbuildGenerator const* gg);
+
+  cmFastbuildLinkLineComputer(cmFastbuildLinkLineComputer const&) = delete;
+  cmFastbuildLinkLineComputer& operator=(cmFastbuildLinkLineComputer const&) =
+    delete;
+
+  std::string ConvertToLinkReference(std::string const& input) const override;
+
+private:
+  cmGlobalFastbuildGenerator const* GG;
+};
diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx
new file mode 100644
index 0000000..45b172e
--- /dev/null
+++ b/Source/cmFastbuildNormalTargetGenerator.cxx
@@ -0,0 +1,2345 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmFastbuildNormalTargetGenerator.h"
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <functional>
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+
+#include <cm/memory>
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmCommonTargetGenerator.h"
+#include "cmCryptoHash.h"
+#include "cmFastbuildTargetGenerator.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
+#include "cmGlobalFastbuildGenerator.h"
+#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
+#include "cmListFileCache.h"
+#include "cmLocalCommonGenerator.h"
+#include "cmLocalFastbuildGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmOSXBundleGenerator.h"
+#include "cmObjectLocation.h"
+#include "cmOutputConverter.h"
+#include "cmSourceFile.h"
+#include "cmState.h"
+#include "cmStateDirectory.h"
+#include "cmStateSnapshot.h"
+#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmTargetDepend.h"
+#include "cmValue.h"
+#include "cmake.h"
+
+namespace {
+
+std::string const COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
+std::string const COMPILE_OPTIONS("COMPILE_OPTIONS");
+std::string const COMPILE_FLAGS("COMPILE_FLAGS");
+std::string const CMAKE_LANGUAGE("CMAKE");
+std::string const INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
+
+std::string const CMAKE_UNITY_BUILD("CMAKE_UNITY_BUILD");
+std::string const CMAKE_UNITY_BUILD_BATCH_SIZE("CMAKE_UNITY_BUILD_BATCH_SIZE");
+std::string const UNITY_BUILD("UNITY_BUILD");
+std::string const UNITY_BUILD_BATCH_SIZE("UNITY_BUILD_BATCH_SIZE");
+std::string const SKIP_UNITY_BUILD_INCLUSION("SKIP_UNITY_BUILD_INCLUSION");
+std::string const UNITY_GROUP("UNITY_GROUP");
+
+#ifdef _WIN32
+char const kPATH_SLASH = '\\';
+#else
+char const kPATH_SLASH = '/';
+#endif
+
+} // anonymous namespace
+
+cmFastbuildNormalTargetGenerator::cmFastbuildNormalTargetGenerator(
+  cmGeneratorTarget* gt, std::string configParam)
+  : cmFastbuildTargetGenerator(gt, std::move(configParam))
+  , RulePlaceholderExpander(
+      this->LocalCommonGenerator->CreateRulePlaceholderExpander())
+  , ObjectOutDir(this->GetGlobalGenerator()->ConvertToFastbuildPath(
+      this->GeneratorTarget->GetObjectDirectory(Config)))
+  , Languages(GetLanguages())
+  , CompileObjectCmakeRules(GetCompileObjectCommand())
+  , CudaCompileMode(this->GetCudaCompileMode())
+{
+
+  LogMessage(cmStrCat("objectOutDir: ", ObjectOutDir));
+  this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(gt);
+  this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+
+  // Quotes to account for potential spaces.
+  RulePlaceholderExpander->SetTargetImpLib(
+    "\"" FASTBUILD_DOLLAR_TAG "TargetOutputImplib" FASTBUILD_DOLLAR_TAG "\"");
+  for (auto const& lang : Languages) {
+    TargetIncludesByLanguage[lang] = this->GetIncludes(lang, Config);
+    LogMessage("targetIncludes for lang " + lang + " = " +
+               TargetIncludesByLanguage[lang]);
+
+    for (auto const& arch : this->GetArches()) {
+      auto& flags = CompileFlagsByLangAndArch[std::make_pair(lang, arch)];
+      this->LocalCommonGenerator->GetTargetCompileFlags(
+        this->GeneratorTarget, Config, lang, flags, arch);
+      LogMessage(
+        cmStrCat("Lang: ", lang, ", arch: ", arch, ", flags: ", flags));
+    }
+  }
+}
+
+std::string cmFastbuildNormalTargetGenerator::DetectCompilerFlags(
+  cmSourceFile const& srcFile, std::string const& arch)
+{
+  std::string const language = srcFile.GetLanguage();
+  cmGeneratorExpressionInterpreter genexInterpreter(
+    this->GetLocalGenerator(), Config, this->GeneratorTarget, language);
+
+  std::vector<std::string> sourceIncludesVec;
+  if (cmValue cincludes = srcFile.GetProperty(INCLUDE_DIRECTORIES)) {
+    this->LocalGenerator->AppendIncludeDirectories(
+      sourceIncludesVec,
+      genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES), srcFile);
+  }
+  std::string sourceIncludesStr = this->LocalGenerator->GetIncludeFlags(
+    sourceIncludesVec, this->GeneratorTarget, language, Config, false);
+  LogMessage(cmStrCat("sourceIncludes = ", sourceIncludesStr));
+
+  std::string compileFlags =
+    CompileFlagsByLangAndArch[std::make_pair(language, arch)];
+  this->GeneratorTarget->AddExplicitLanguageFlags(compileFlags, srcFile);
+
+  if (cmValue const cflags = srcFile.GetProperty(COMPILE_FLAGS)) {
+    this->LocalGenerator->AppendFlags(
+      compileFlags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
+  }
+
+  if (cmValue const coptions = srcFile.GetProperty(COMPILE_OPTIONS)) {
+    this->LocalGenerator->AppendCompileOptions(
+      compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
+  }
+  // Source includes take precedence over target includes.
+  this->LocalGenerator->AppendFlags(compileFlags, sourceIncludesStr);
+  this->LocalGenerator->AppendFlags(compileFlags,
+                                    TargetIncludesByLanguage[language]);
+
+  if (language == "Fortran") {
+    this->AppendFortranFormatFlags(compileFlags, srcFile);
+    this->AppendFortranPreprocessFlags(compileFlags, srcFile);
+  }
+
+  LogMessage(cmStrCat("compileFlags = ", compileFlags));
+  return compileFlags;
+}
+
+void cmFastbuildNormalTargetGenerator::SplitLinkerFromArgs(
+  std::string const& command, std::string& outLinkerExecutable,
+  std::string& outLinkerArgs) const
+{
+#ifdef _WIN32
+  std::vector<std::string> args;
+  std::string tmp;
+  cmSystemTools::SplitProgramFromArgs(command, tmp, outLinkerArgs);
+  // cmLocalGenerator::GetStaticLibraryFlags seems to add empty quotes when
+  // appending "STATIC_LIBRARY_FLAGS_DEBUG"...
+  cmSystemTools::ReplaceString(outLinkerArgs, "\"\"", "");
+  cmSystemTools::ParseWindowsCommandLine(command.c_str(), args);
+  outLinkerExecutable = std::move(args[0]);
+#else
+  cmSystemTools::SplitProgramFromArgs(command, outLinkerExecutable,
+                                      outLinkerArgs);
+#endif
+}
+
+void cmFastbuildNormalTargetGenerator::GetLinkerExecutableAndArgs(
+  std::string const& command, std::string& outLinkerExecutable,
+  std::string& outLinkerArgs)
+{
+  if (command.empty()) {
+    return;
+  }
+
+  LogMessage("Link Command: " + command);
+
+  auto const& compilers = this->GetGlobalGenerator()->Compilers;
+  auto const linkerLauncherVarName = FASTBUILD_LINKER_LAUNCHER_PREFIX +
+    this->GeneratorTarget->GetLinkerLanguage(Config);
+  auto const iter = compilers.find(linkerLauncherVarName);
+  // Tested in "RunCMake.LinkerLauncher" test.
+  if (iter != compilers.end()) {
+    LogMessage("Linker launcher: " + iter->first);
+    outLinkerExecutable = iter->second.Executable;
+    outLinkerArgs = cmStrCat(iter->second.Args, " ", command);
+  } else {
+    SplitLinkerFromArgs(command, outLinkerExecutable, outLinkerArgs);
+  }
+  LogMessage("Linker Exe: " + outLinkerExecutable);
+  LogMessage("Linker args: " + outLinkerArgs);
+}
+
+bool cmFastbuildNormalTargetGenerator::DetectBaseLinkerCommand(
+  std::string& command, std::string const& arch,
+  cmGeneratorTarget::Names const& targetNames)
+{
+  std::string const linkLanguage =
+    this->GeneratorTarget->GetLinkerLanguage(Config);
+  if (linkLanguage.empty()) {
+    cmSystemTools::Error("CMake can not determine linker language for "
+                         "target: " +
+                         this->GeneratorTarget->GetName());
+    return false;
+  }
+  LogMessage("linkLanguage: " + linkLanguage);
+
+  std::string linkLibs;
+  std::string targetFlags;
+  std::string linkFlags;
+  std::string frameworkPath;
+  // Tested in "RunCMake.StandardLinkDirectories" test.
+  std::string linkPath;
+
+  std::unique_ptr<cmLinkLineComputer> const linkLineComputer =
+    this->GetGlobalGenerator()->CreateLinkLineComputer(
+      this->LocalGenerator,
+      this->GetLocalGenerator()->GetStateSnapshot().GetDirectory());
+
+  this->LocalCommonGenerator->GetTargetFlags(
+    linkLineComputer.get(), Config, linkLibs, targetFlags, linkFlags,
+    frameworkPath, linkPath, this->GeneratorTarget);
+
+  // cmLocalGenerator::GetStaticLibraryFlags seems to add empty quotes when
+  // appending "STATIC_LIBRARY_FLAGS_DEBUG"...
+  cmSystemTools::ReplaceString(linkFlags, "\"\"", "");
+  LogMessage("linkLibs: " + linkLibs);
+  LogMessage("targetFlags: " + targetFlags);
+  LogMessage("linkFlags: " + linkFlags);
+  LogMessage("frameworkPath: " + frameworkPath);
+  LogMessage("linkPath: " + linkPath);
+
+  LogMessage("MANIFESTS: " + this->GetManifests(Config));
+
+  cmComputeLinkInformation* linkInfo =
+    this->GeneratorTarget->GetLinkInformation(Config);
+  if (!linkInfo) {
+    return false;
+  }
+
+  // Tested in "RunCMake.RuntimePath" test.
+  std::string const rpath = linkLineComputer->ComputeRPath(*linkInfo);
+  LogMessage("RPath: " + rpath);
+
+  if (!linkFlags.empty()) {
+    linkFlags += " ";
+  }
+  linkFlags += cmJoin({ rpath, frameworkPath, linkPath }, " ");
+
+  cmStateEnums::TargetType const targetType = this->GeneratorTarget->GetType();
+  // Add OS X version flags, if any.
+  if (targetType == cmStateEnums::SHARED_LIBRARY ||
+      targetType == cmStateEnums::MODULE_LIBRARY) {
+    this->AppendOSXVerFlag(linkFlags, linkLanguage, "COMPATIBILITY", true);
+    this->AppendOSXVerFlag(linkFlags, linkLanguage, "CURRENT", false);
+  }
+  // Add Arch flags to link flags for binaries
+  if (targetType == cmStateEnums::SHARED_LIBRARY ||
+      targetType == cmStateEnums::MODULE_LIBRARY ||
+      targetType == cmStateEnums::EXECUTABLE) {
+    this->LocalCommonGenerator->AddArchitectureFlags(
+      linkFlags, this->GeneratorTarget, linkLanguage, Config, arch);
+    this->UseLWYU = this->GetLocalGenerator()->AppendLWYUFlags(
+      linkFlags, this->GetGeneratorTarget(), linkLanguage);
+  }
+
+  cmRulePlaceholderExpander::RuleVariables vars;
+  vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
+  vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
+  vars.Config = Config.c_str();
+  vars.Language = linkLanguage.c_str();
+  std::string const manifests =
+    cmJoin(this->GetManifestsAsFastbuildPath(), " ");
+  vars.Manifests = manifests.c_str();
+
+  std::string const stdLibString = this->Makefile->GetSafeDefinition(
+    cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES"));
+
+  LogMessage(cmStrCat("Target type: ", this->GeneratorTarget->GetType()));
+  if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
+      this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
+      this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
+    vars.Objects = FASTBUILD_1_0_INPUT_PLACEHOLDER;
+    vars.LinkLibraries = stdLibString.c_str();
+  } else {
+    vars.Objects = FASTBUILD_1_INPUT_PLACEHOLDER;
+  }
+
+  vars.ObjectDir = FASTBUILD_DOLLAR_TAG "TargetOutDir" FASTBUILD_DOLLAR_TAG;
+  vars.Target = FASTBUILD_2_INPUT_PLACEHOLDER;
+
+  std::string install_dir;
+  std::string target_so_name;
+  if (this->GeneratorTarget->HasSOName(Config)) {
+    vars.SONameFlag = this->Makefile->GetSONameFlag(
+      this->GeneratorTarget->GetLinkerLanguage(Config));
+    target_so_name =
+      cmGlobalFastbuildGenerator::QuoteIfHasSpaces(targetNames.SharedObject);
+    vars.TargetSOName = target_so_name.c_str();
+    // Tested in "RunCMake.RuntimePath / RunCMake.INSTALL_NAME_DIR"
+    // tests.
+    install_dir = this->LocalGenerator->ConvertToOutputFormat(
+      this->GeneratorTarget->GetInstallNameDirForBuildTree(Config),
+      cmOutputConverter::SHELL);
+    vars.TargetInstallNameDir = install_dir.c_str();
+  } else {
+    vars.TargetSOName = "";
+  }
+  vars.TargetPDB = FASTBUILD_DOLLAR_TAG "LinkerPDB" FASTBUILD_DOLLAR_TAG;
+
+  // Setup the target version.
+  std::string targetVersionMajor;
+  std::string targetVersionMinor;
+  {
+    std::ostringstream majorStream;
+    std::ostringstream minorStream;
+    int major;
+    int minor;
+    this->GeneratorTarget->GetTargetVersion(major, minor);
+    majorStream << major;
+    minorStream << minor;
+    targetVersionMajor = majorStream.str();
+    targetVersionMinor = minorStream.str();
+  }
+  vars.TargetVersionMajor = targetVersionMajor.c_str();
+  vars.TargetVersionMinor = targetVersionMinor.c_str();
+
+  vars.Defines =
+    FASTBUILD_DOLLAR_TAG "CompileDefineFlags" FASTBUILD_DOLLAR_TAG;
+  vars.Flags = targetFlags.c_str();
+  vars.LinkFlags = linkFlags.c_str();
+  vars.LanguageCompileFlags = "";
+  std::string const linker = this->GeneratorTarget->GetLinkerTool(Config);
+  vars.Linker = linker.c_str();
+  std::string const targetSupportPath = this->ConvertToFastbuildPath(
+    this->GetGeneratorTarget()->GetCMFSupportDirectory());
+  vars.TargetSupportDir = targetSupportPath.c_str();
+
+  LogMessage("linkFlags: " + linkFlags);
+  LogMessage("linker: " + linker);
+
+  std::string linkRule = GetLinkCommand();
+  ApplyLinkRuleLauncher(linkRule);
+  RulePlaceholderExpander->ExpandRuleVariables(
+    dynamic_cast<cmLocalFastbuildGenerator*>(this->LocalCommonGenerator),
+    linkRule, vars);
+
+  command = std::move(linkRule);
+  LogMessage(cmStrCat("Expanded link command: ", command));
+  return true;
+}
+
+void cmFastbuildNormalTargetGenerator::ApplyLinkRuleLauncher(
+  std::string& command)
+{
+  std::string const val = this->GetLocalGenerator()->GetRuleLauncher(
+    this->GetGeneratorTarget(), "RULE_LAUNCH_LINK", Config);
+  if (cmNonempty(val)) {
+    LogMessage("RULE_LAUNCH_LINK: " + val);
+    command = cmStrCat(val, " ", command);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::ApplyLWYUToLinkerCommand(
+  FastbuildLinkerNode& linkerNode)
+{
+  cmValue const lwyuCheck =
+    this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+  if (this->UseLWYU && lwyuCheck) {
+    LogMessage("UseLWYU=true");
+    std::string args = " -E __run_co_compile --lwyu=";
+    args += this->GetLocalGenerator()->EscapeForShell(*lwyuCheck);
+
+    args += cmStrCat(
+      " --source=",
+      this->ConvertToFastbuildPath(this->GetGeneratorTarget()->GetFullPath(
+        Config, cmStateEnums::RuntimeBinaryArtifact,
+        /*realname=*/true)));
+
+    LogMessage("LWUY args: " + args);
+    linkerNode.LinkerStampExe = cmSystemTools::GetCMakeCommand();
+    linkerNode.LinkerStampExeArgs = std::move(args);
+  }
+}
+
+std::string cmFastbuildNormalTargetGenerator::ComputeDefines(
+  cmSourceFile const& srcFile)
+{
+  std::string const language = srcFile.GetLanguage();
+  std::set<std::string> defines;
+  cmGeneratorExpressionInterpreter genexInterpreter(
+    this->GetLocalGenerator(), Config, this->GeneratorTarget, language);
+
+  if (auto compile_defs = srcFile.GetProperty(COMPILE_DEFINITIONS)) {
+    this->GetLocalGenerator()->AppendDefines(
+      defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
+  }
+
+  std::string defPropName = "COMPILE_DEFINITIONS_";
+  defPropName += cmSystemTools::UpperCase(Config);
+  if (auto config_compile_defs = srcFile.GetProperty(defPropName)) {
+    this->GetLocalGenerator()->AppendDefines(
+      defines,
+      genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
+  }
+
+  std::string definesString = this->GetDefines(language, Config);
+  LogMessage(cmStrCat("TARGET DEFINES = ", definesString));
+  this->GetLocalGenerator()->JoinDefines(defines, definesString, language);
+
+  LogMessage(cmStrCat("DEFINES = ", definesString));
+  return definesString;
+}
+
+void cmFastbuildNormalTargetGenerator::ComputePCH(
+  cmSourceFile const& srcFile, FastbuildObjectListNode& node,
+  std::set<std::string>& createdPCH)
+{
+  if (srcFile.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+    return;
+  }
+  // We have already computed PCH for this node.
+  if (!node.PCHOptions.empty() || !node.PCHInputFile.empty() ||
+      !node.PCHOutputFile.empty()) {
+    return;
+  }
+  std::string const language = srcFile.GetLanguage();
+  cmGeneratorExpressionInterpreter genexInterpreter(
+    this->GetLocalGenerator(), Config, this->GeneratorTarget, language);
+
+  //.cxx
+  std::string const pchSource =
+    this->GeneratorTarget->GetPchSource(Config, language);
+  //.hxx
+  std::string const pchHeader =
+    this->GeneratorTarget->GetPchHeader(Config, language);
+  //.pch
+  std::string const pchFile =
+    this->GeneratorTarget->GetPchFile(Config, language);
+
+  if (pchHeader.empty() || pchFile.empty()) {
+    return;
+  }
+  // In "RunCMake.GenEx-TARGET_PROPERTY" test we call set
+  // CMAKE_PCH_EXTENSION="", so pchHeader becomes same as pchFile...
+  if (pchHeader == pchFile) {
+    LogMessage("pchHeader == pchFile > skipping");
+    LogMessage("pchHeader: " + pchHeader);
+    LogMessage("pchFile: " + pchFile);
+    return;
+  }
+
+  node.PCHOutputFile =
+    this->GetGlobalGenerator()->ConvertToFastbuildPath(pchFile);
+  // Tell the ObjectList how to use PCH.
+  std::string const pchUseOption =
+    this->GeneratorTarget->GetPchUseCompileOptions(Config, language);
+  LogMessage(cmStrCat("pchUseOption: ", pchUseOption));
+
+  std::string origCompileOptions = node.CompilerOptions;
+  for (auto const& opt :
+       cmList{ genexInterpreter.Evaluate(pchUseOption, COMPILE_OPTIONS) }) {
+    node.CompilerOptions += " ";
+    node.CompilerOptions += opt;
+  }
+
+  if (!createdPCH.emplace(node.PCHOutputFile).second) {
+    LogMessage(node.PCHOutputFile + " is already created by this target");
+    return;
+  }
+
+  // Short circuit if the PCH has already been created by another target.
+  if (!this->GeneratorTarget->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM")
+         .empty()) {
+    LogMessage(cmStrCat("PCH: ", node.PCHOutputFile,
+                        " already created by another target"));
+    return;
+  }
+
+  node.PCHInputFile =
+    this->GetGlobalGenerator()->ConvertToFastbuildPath(pchSource);
+
+  std::string const pchCreateOptions =
+    this->GeneratorTarget->GetPchCreateCompileOptions(Config, language);
+  LogMessage(cmStrCat("pchCreateOptions: ", pchCreateOptions));
+  char const* sep = "";
+  for (auto const& opt : cmList{
+         genexInterpreter.Evaluate(pchCreateOptions, COMPILE_OPTIONS) }) {
+    node.PCHOptions += sep;
+    node.PCHOptions += opt;
+    sep = " ";
+  }
+
+  // Reuse compiler options for PCH options.
+  node.PCHOptions += origCompileOptions;
+  if (this->Makefile->GetSafeDefinition("CMAKE_" + language +
+                                        "_COMPILER_ID") == "MSVC") {
+    cmSystemTools::ReplaceString(node.PCHOptions,
+                                 FASTBUILD_2_INPUT_PLACEHOLDER,
+                                 FASTBUILD_3_INPUT_PLACEHOLDER);
+  }
+
+  LogMessage("PCH Source: " + pchSource);
+  LogMessage("node.PCHInputFile: " + node.PCHInputFile);
+  LogMessage("node.PCHOutputFile: " + node.PCHOutputFile);
+  LogMessage("node.PCHOptions: " + node.PCHOptions);
+  LogMessage("node.CompilerOptions: " + node.CompilerOptions);
+}
+
+void cmFastbuildNormalTargetGenerator::EnsureDirectoryExists(
+  std::string const& path) const
+{
+  if (cmSystemTools::FileIsFullPath(path.c_str())) {
+    cmSystemTools::MakeDirectory(path.c_str());
+  } else {
+    auto* gg = this->GetGlobalGenerator();
+    std::string fullPath = gg->GetCMakeInstance()->GetHomeOutputDirectory();
+    // Also ensures there is a trailing slash.
+    fullPath += path;
+    cmSystemTools::MakeDirectory(fullPath);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::EnsureParentDirectoryExists(
+  std::string const& path) const
+{
+  this->EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path));
+}
+
+std::vector<std::string>
+cmFastbuildNormalTargetGenerator::GetManifestsAsFastbuildPath() const
+{
+  std::vector<cmSourceFile const*> manifest_srcs;
+  this->GeneratorTarget->GetManifests(manifest_srcs, Config);
+  std::vector<std::string> manifests;
+  manifests.reserve(manifest_srcs.size());
+  for (auto& manifest_src : manifest_srcs) {
+    std::string str = this->ConvertToFastbuildPath(
+      cmSystemTools::ConvertToOutputPath(manifest_src->GetFullPath()));
+    LogMessage("Manifest: " + str);
+    manifests.emplace_back(std::move(str));
+  }
+
+  return manifests;
+}
+
+void cmFastbuildNormalTargetGenerator::GenerateModuleDefinitionInfo(
+  FastbuildTarget& target) const
+{
+  cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
+    GeneratorTarget->GetModuleDefinitionInfo(Config);
+  if (mdi && mdi->DefFileGenerated) {
+    FastbuildExecNode execNode;
+    execNode.Name = target.Name + "-def-files";
+    execNode.ExecExecutable = cmSystemTools::GetCMakeCommand();
+    execNode.ExecArguments =
+      cmStrCat("-E __create_def ", FASTBUILD_2_INPUT_PLACEHOLDER, " ",
+               FASTBUILD_1_INPUT_PLACEHOLDER);
+    std::string const obj_list_file = mdi->DefFile + ".objs";
+
+    auto const nm_executable = GetMakefile()->GetDefinition("CMAKE_NM");
+    if (!nm_executable.IsEmpty()) {
+      execNode.ExecArguments += " --nm=";
+      execNode.ExecArguments += ConvertToFastbuildPath(*nm_executable);
+    }
+    execNode.ExecOutput = ConvertToFastbuildPath(mdi->DefFile);
+    execNode.ExecInput.push_back(ConvertToFastbuildPath(obj_list_file));
+
+    // RunCMake.AutoExportDll
+    for (auto const& objList : target.ObjectListNodes) {
+      execNode.PreBuildDependencies.emplace(objList.Name);
+    }
+    // Tested in "RunCMake.AutoExportDll" / "ModuleDefinition" tests.
+    for (auto& linkerNode : target.LinkerNode) {
+      linkerNode.Libraries2.emplace_back(execNode.Name);
+    }
+
+    target.PreLinkExecNodes.Nodes.emplace_back(std::move(execNode));
+
+    // create a list of obj files for the -E __create_def to read
+    cmGeneratedFileStream fout(obj_list_file);
+    // Since we generate this file once during configuration, we should not
+    // remove it when "clean" is built.
+    // Tested in "RunCMake.AutoExportDll" / "ModuleDefinition" tests.
+    this->GetGlobalGenerator()->AllFilesToKeep.insert(obj_list_file);
+
+    if (mdi->WindowsExportAllSymbols) {
+      std::vector<cmSourceFile const*> objectSources;
+      GeneratorTarget->GetObjectSources(objectSources, Config);
+      std::map<cmSourceFile const*, cmObjectLocations> mapping;
+      for (cmSourceFile const* it : objectSources) {
+        mapping[it];
+      }
+      GeneratorTarget->LocalGenerator->ComputeObjectFilenames(mapping, Config,
+                                                              GeneratorTarget);
+
+      std::vector<std::string> objs;
+      for (cmSourceFile const* it : objectSources) {
+        auto const& v = mapping[it];
+        LogMessage("Obj source : " + v.LongLoc.GetPath());
+        std::string objFile = this->ConvertToFastbuildPath(
+          GeneratorTarget->GetObjectDirectory(Config) + v.LongLoc.GetPath());
+        objFile = cmSystemTools::ConvertToOutputPath(objFile);
+        LogMessage("objFile path: " + objFile);
+        objs.push_back(objFile);
+      }
+
+      std::vector<cmSourceFile const*> externalObjectSources;
+      GeneratorTarget->GetExternalObjects(externalObjectSources, Config);
+      for (cmSourceFile const* it : externalObjectSources) {
+        objs.push_back(cmSystemTools::ConvertToOutputPath(
+          this->ConvertToFastbuildPath(it->GetFullPath())));
+      }
+
+      for (std::string const& objFile : objs) {
+        if (cmHasLiteralSuffix(objFile, ".obj")) {
+          fout << objFile << "\n";
+        }
+      }
+    }
+    for (cmSourceFile const* src : mdi->Sources) {
+      fout << src->GetFullPath() << "\n";
+    }
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AddPrebuildDeps(
+  FastbuildTarget& target) const
+{
+  // All ObjectLists should wait for PRE_BUILD.
+  for (FastbuildObjectListNode& node : target.ObjectListNodes) {
+    if (!target.PreBuildExecNodes.Name.empty()) {
+      node.PreBuildDependencies.emplace(target.PreBuildExecNodes.Name);
+    }
+    if (!target.ExecNodes.Name.empty()) {
+      node.PreBuildDependencies.emplace(target.ExecNodes.Name);
+    }
+  }
+  for (auto& linkerNode : target.LinkerNode) {
+    // Wait for 'PRE_BUILD' custom commands.
+    if (!target.PreBuildExecNodes.Name.empty()) {
+      linkerNode.PreBuildDependencies.emplace(target.PreBuildExecNodes.Name);
+    }
+
+    // Wait for regular custom commands.
+    if (!target.ExecNodes.Name.empty()) {
+      linkerNode.PreBuildDependencies.emplace(target.ExecNodes.Name);
+    }
+    // All targets that we depend on must be prebuilt.
+    if (!target.DependenciesAlias.PreBuildDependencies.empty()) {
+      linkerNode.PreBuildDependencies.emplace(target.DependenciesAlias.Name);
+    }
+  }
+}
+
+std::set<std::string> cmFastbuildNormalTargetGenerator::GetLanguages()
+{
+  std::set<std::string> result;
+  this->GetGeneratorTarget()->GetLanguages(result, Config);
+  for (std::string const& lang : result) {
+    this->GetGlobalGenerator()->AddCompiler(lang, this->GetMakefile());
+  }
+  LogMessage("Languages: " + cmJoin(result, ", "));
+  return result;
+}
+
+std::unordered_map<std::string, std::string>
+cmFastbuildNormalTargetGenerator::GetCompileObjectCommand() const
+{
+  std::unordered_map<std::string, std::string> result;
+  result.reserve(Languages.size());
+  for (std::string const& lang : Languages) {
+    std::vector<std::string> commands;
+    std::string cmakeVar;
+    cmakeVar = "CMAKE_";
+    cmakeVar += lang;
+    cmakeVar += "_COMPILE_OBJECT";
+
+    std::string cmakeValue =
+      LocalCommonGenerator->GetMakefile()->GetSafeDefinition(cmakeVar);
+
+    LogMessage(cmakeVar.append(" = ").append(cmakeValue));
+
+    result[lang] = std::move(cmakeValue);
+  }
+  return result;
+}
+std::string cmFastbuildNormalTargetGenerator::GetCudaCompileMode() const
+{
+  if (Languages.find("CUDA") == Languages.end()) {
+    return {};
+  }
+  // TODO: unify it with makefile / ninja generators.
+  std::string cudaCompileMode;
+  if (this->GeneratorTarget->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION")) {
+    std::string const& rdcFlag =
+      this->Makefile->GetRequiredDefinition("_CMAKE_CUDA_RDC_FLAG");
+    cudaCompileMode = cmStrCat(cudaCompileMode, rdcFlag, ' ');
+  }
+  static std::array<cm::string_view, 4> const compileModes{
+    { "PTX"_s, "CUBIN"_s, "FATBIN"_s, "OPTIX"_s }
+  };
+  bool useNormalCompileMode = true;
+  for (cm::string_view mode : compileModes) {
+    auto propName = cmStrCat("CUDA_", mode, "_COMPILATION");
+    auto defName = cmStrCat("_CMAKE_CUDA_", mode, "_FLAG");
+    if (this->GeneratorTarget->GetPropertyAsBool(propName)) {
+      std::string const& flag = this->Makefile->GetRequiredDefinition(defName);
+      cudaCompileMode = cmStrCat(cudaCompileMode, flag);
+      useNormalCompileMode = false;
+      break;
+    }
+  }
+  if (useNormalCompileMode) {
+    std::string const& wholeFlag =
+      this->Makefile->GetRequiredDefinition("_CMAKE_CUDA_WHOLE_FLAG");
+    cudaCompileMode = cmStrCat(cudaCompileMode, wholeFlag);
+  }
+  return cudaCompileMode;
+}
+
+std::string cmFastbuildNormalTargetGenerator::GetLinkCommand() const
+{
+  std::string const& linkLanguage = GeneratorTarget->GetLinkerLanguage(Config);
+  std::string linkCmdVar =
+    GeneratorTarget->GetCreateRuleVariable(linkLanguage, Config);
+  std::string res = this->Makefile->GetSafeDefinition(linkCmdVar);
+  if (res.empty() &&
+      this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
+    linkCmdVar = linkCmdVar =
+      cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
+    res = this->Makefile->GetSafeDefinition(linkCmdVar);
+  }
+  LogMessage("Link rule: " + cmStrCat(linkCmdVar, " = ", res));
+  return res;
+}
+
+void cmFastbuildNormalTargetGenerator::AddCompilerLaunchersForLanguages()
+{
+  // General rule for all languages.
+  std::string const launchCompile = this->GetLocalGenerator()->GetRuleLauncher(
+    this->GetGeneratorTarget(), "RULE_LAUNCH_COMPILE", Config);
+  // See if we need to use a compiler launcher like ccache or distcc
+  for (std::string const& language : Languages) {
+    std::string const compilerLauncher =
+      cmCommonTargetGenerator::GetCompilerLauncher(language, Config);
+    LogMessage("compilerLauncher: " + compilerLauncher);
+    std::vector<std::string> expanded;
+    cmExpandList(compilerLauncher, expanded);
+
+    if (!expanded.empty()) {
+      std::string const exe = expanded[0];
+      expanded.erase(expanded.begin());
+      this->GetGlobalGenerator()->AddLauncher(FASTBUILD_LAUNCHER_PREFIX, exe,
+                                              language, cmJoin(expanded, " "));
+    } else if (!launchCompile.empty()) {
+      std::string exe;
+      std::string args;
+      cmSystemTools::SplitProgramFromArgs(launchCompile, exe, args);
+      this->GetGlobalGenerator()->AddLauncher(FASTBUILD_LAUNCHER_PREFIX, exe,
+                                              language, args);
+    }
+  }
+}
+void cmFastbuildNormalTargetGenerator::AddLinkerLauncher()
+{
+  std::string const linkerLauncher =
+    cmCommonTargetGenerator::GetLinkerLauncher(Config);
+  std::vector<std::string> args;
+#ifdef _WIN32
+  cmSystemTools::ParseWindowsCommandLine(linkerLauncher.c_str(), args);
+#else
+  cmSystemTools::ParseUnixCommandLine(linkerLauncher.c_str(), args);
+#endif
+  if (!args.empty()) {
+    std::string const exe = std::move(args[0]);
+    args.erase(args.begin());
+    this->GetGlobalGenerator()->AddLauncher(
+      FASTBUILD_LINKER_LAUNCHER_PREFIX, exe,
+      this->GeneratorTarget->GetLinkerLanguage(Config), cmJoin(args, " "));
+  }
+}
+void cmFastbuildNormalTargetGenerator::AddCMakeLauncher()
+{
+  // Add CMake launcher (might be used for static analysis).
+  this->GetGlobalGenerator()->AddLauncher(FASTBUILD_LAUNCHER_PREFIX,
+                                          cmSystemTools::GetCMakeCommand(),
+                                          CMAKE_LANGUAGE, "");
+}
+
+void cmFastbuildNormalTargetGenerator::ComputePaths(
+  FastbuildTarget& target) const
+{
+  std::string const objPath = GetGeneratorTarget()->GetSupportDirectory();
+  EnsureDirectoryExists(objPath);
+  target.Variables["TargetOutDir"] =
+    cmSystemTools::ConvertToOutputPath(this->ConvertToFastbuildPath(objPath));
+
+  if (GeneratorTarget->GetType() <= cmStateEnums::MODULE_LIBRARY) {
+    std::string const pdbDir = GeneratorTarget->GetPDBDirectory(Config);
+    LogMessage("GetPDBDirectory: " + pdbDir);
+    EnsureDirectoryExists(pdbDir);
+    std::string const linkerPDB =
+      cmStrCat(pdbDir, '/', this->GeneratorTarget->GetPDBName(Config));
+
+    if (!linkerPDB.empty()) {
+      target.Variables["LinkerPDB"] = cmSystemTools::ConvertToOutputPath(
+        this->ConvertToFastbuildPath(linkerPDB));
+    }
+  }
+  std::string const compilerPDB = this->ComputeTargetCompilePDB(this->Config);
+  if (!compilerPDB.empty()) {
+    LogMessage("ComputeTargetCompilePDB: " + compilerPDB);
+    std::string compilerPDBArg = cmSystemTools::ConvertToOutputPath(
+      this->ConvertToFastbuildPath(compilerPDB));
+    if (cmHasSuffix(compilerPDB, '/')) {
+      // The compiler will choose the .pdb file name.
+      this->EnsureDirectoryExists(compilerPDB);
+      // ConvertToFastbuildPath dropped the trailing slash.  Add it back.
+      // We do this after ConvertToOutputPath so that we can use a forward
+      // slash in the case that the argument is quoted.
+      if (cmHasSuffix(compilerPDBArg, '"')) {
+        // A quoted trailing backslash requires escaping, e.g., `/Fd"dir\\"`,
+        // but fbuild does not parse such arguments correctly as of 1.15.
+        // Always use a forward slash.
+        compilerPDBArg.insert(compilerPDBArg.size() - 1, 1, '/');
+      } else {
+        // An unquoted trailing slash or backslash is fine.
+        compilerPDBArg.push_back(kPATH_SLASH);
+      }
+    } else {
+      // We have an explicit .pdb path with file name.
+      this->EnsureParentDirectoryExists(compilerPDB);
+    }
+    target.Variables["CompilerPDB"] = std::move(compilerPDBArg);
+  }
+  std::string const impLibFullPath =
+    GeneratorTarget->GetFullPath(Config, cmStateEnums::ImportLibraryArtifact);
+  std::string impLibFile = ConvertToFastbuildPath(impLibFullPath);
+  cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(impLibFullPath));
+  if (!impLibFile.empty()) {
+    cmSystemTools::ConvertToOutputSlashes(impLibFile);
+    target.Variables["TargetOutputImplib"] = std::move(impLibFile);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::Generate()
+{
+  this->GeneratorTarget->CheckCxxModuleStatus(Config);
+
+  FastbuildTarget fastbuildTarget;
+  fastbuildTarget.Name = GetTargetName();
+  fastbuildTarget.BaseName = this->GeneratorTarget->GetName();
+
+  LogMessage("<-------------->");
+  LogMessage("Generate target: " + fastbuildTarget.Name);
+  LogMessage("Config: " + Config);
+
+  LogMessage("Deps: ");
+  for (cmTargetDepend const& dep : TargetDirectDependencies) {
+    auto const tname = dep->GetName();
+    LogMessage(tname);
+    FastbuildTargetDep targetDep{ tname };
+    if (dep->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+      targetDep.Type = FastbuildTargetDepType::ORDER_ONLY;
+    }
+    fastbuildTarget.PreBuildDependencies.emplace(std::move(targetDep));
+  }
+
+  ComputePaths(fastbuildTarget);
+  AddCompilerLaunchersForLanguages();
+  AddLinkerLauncher();
+  AddCMakeLauncher();
+
+  for (auto& cc : GenerateCommands(FastbuildBuildStep::PRE_BUILD).Nodes) {
+    fastbuildTarget.PreBuildExecNodes.PreBuildDependencies.emplace(cc.Name);
+    fastbuildTarget.PreBuildDependencies.emplace(cc.Name);
+    this->GetGlobalGenerator()->AddTarget(std::move(cc));
+  }
+  for (auto& cc : GenerateCommands(FastbuildBuildStep::PRE_LINK).Nodes) {
+    cc.PreBuildDependencies.emplace(fastbuildTarget.Name +
+                                    FASTBUILD_DEPS_ARTIFACTS_ALIAS_POSTFIX);
+    fastbuildTarget.PreLinkExecNodes.Nodes.emplace_back(std::move(cc));
+  }
+  for (auto& cc : GenerateCommands(FastbuildBuildStep::REST).Nodes) {
+    fastbuildTarget.ExecNodes.PreBuildDependencies.emplace(cc.Name);
+    this->GetGlobalGenerator()->AddTarget(std::move(cc));
+  }
+  for (auto& cc : GenerateCommands(FastbuildBuildStep::POST_BUILD).Nodes) {
+    fastbuildTarget.PostBuildExecNodes.Alias.PreBuildDependencies.emplace(
+      cc.Name);
+    fastbuildTarget.PostBuildExecNodes.Nodes.emplace_back(std::move(cc));
+  }
+
+  GenerateObjects(fastbuildTarget);
+
+  std::vector<std::string> objectDepends;
+  AddObjectDependencies(fastbuildTarget, objectDepends);
+
+  GenerateCudaDeviceLink(fastbuildTarget);
+
+  GenerateLink(fastbuildTarget, objectDepends);
+
+  if (fastbuildTarget.LinkerNode.size() > 1) {
+    if (!this->GeneratorTarget->IsApple()) {
+      cmSystemTools::Error(
+        "Can't handle more than 1 arch on non-Apple target");
+      return;
+    }
+    AddLipoCommand(fastbuildTarget);
+  }
+  fastbuildTarget.CopyNodes = std::move(this->CopyNodes);
+
+  // Generate symlink commands if real output name differs from "expected".
+  for (auto& symlink : GetSymlinkExecs()) {
+    fastbuildTarget.PostBuildExecNodes.Alias.PreBuildDependencies.emplace(
+      symlink.Name);
+    fastbuildTarget.PostBuildExecNodes.Nodes.emplace_back(std::move(symlink));
+  }
+  {
+    auto appleTextStubCommand = GetAppleTextStubCommand();
+    if (!appleTextStubCommand.Name.empty()) {
+      fastbuildTarget.PostBuildExecNodes.Alias.PreBuildDependencies.emplace(
+        appleTextStubCommand.Name);
+      fastbuildTarget.PostBuildExecNodes.Nodes.emplace_back(
+        std::move(appleTextStubCommand));
+    }
+  }
+
+  AddPrebuildDeps(fastbuildTarget);
+
+  fastbuildTarget.IsGlobal =
+    GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET;
+  fastbuildTarget.ExcludeFromAll =
+    this->GetGlobalGenerator()->IsExcluded(GeneratorTarget);
+  if (GeneratorTarget->GetPropertyAsBool("DONT_DISTRIBUTE")) {
+    fastbuildTarget.AllowDistribution = false;
+  }
+
+  GenerateModuleDefinitionInfo(fastbuildTarget);
+  // Needs to be called after we've added all PRE-LINK steps (like creation of
+  // .def files on Windows).
+  AddLinkerNodeDependencies(fastbuildTarget);
+
+  // Must be called after "GenerateObjects", since it also adds Prebuild deps
+  // to it.
+  // Also after "GenerateModuleDefinitionInfo", since uses PreLinkExecNodes.
+
+  fastbuildTarget.GenerateAliases();
+  if (!fastbuildTarget.ExecNodes.PreBuildDependencies.empty()) {
+    fastbuildTarget.DependenciesAlias.PreBuildDependencies.emplace(
+      fastbuildTarget.ExecNodes.Name);
+  }
+
+  fastbuildTarget.Hidden = false;
+
+  fastbuildTarget.BasePath = this->GetMakefile()->GetCurrentSourceDirectory();
+
+  this->GetGlobalGenerator()->AddIDEProject(fastbuildTarget, Config);
+
+  AddStampExeIfApplicable(fastbuildTarget);
+
+  // size 1 means that it's not a multi-arch lib (which can only be the case on
+  // Darwin).
+  if (fastbuildTarget.LinkerNode.size() == 1 &&
+      fastbuildTarget.LinkerNode[0].Type ==
+        FastbuildLinkerNode::STATIC_LIBRARY &&
+      !fastbuildTarget.PostBuildExecNodes.Nodes.empty()) {
+    ProcessPostBuildForStaticLib(fastbuildTarget);
+  }
+
+  AdditionalCleanFiles();
+
+  if (!fastbuildTarget.DependenciesAlias.PreBuildDependencies.empty()) {
+    for (FastbuildObjectListNode& objListNode :
+         fastbuildTarget.ObjectListNodes) {
+      objListNode.PreBuildDependencies.emplace(
+        fastbuildTarget.DependenciesAlias.Name);
+    }
+    for (auto& linkerNode : fastbuildTarget.LinkerNode) {
+      linkerNode.PreBuildDependencies.emplace(
+        fastbuildTarget.DependenciesAlias.Name);
+    }
+  }
+
+  this->GetGlobalGenerator()->AddTarget(std::move(fastbuildTarget));
+}
+
+void cmFastbuildNormalTargetGenerator::ProcessManifests(
+  FastbuildLinkerNode& linkerNode) const
+{
+  if (this->GetGlobalGenerator()->GetCMakeInstance()->GetIsInTryCompile()) {
+    return;
+  }
+  auto manifests = this->GetManifestsAsFastbuildPath();
+  if (manifests.empty()) {
+    return;
+  }
+  // Manifests should always be in .Libraries2, so we re-link when needed.
+  // Tested in RunCMake.BuildDepends
+  for (auto const& manifest : manifests) {
+    linkerNode.Libraries2.emplace_back(manifest);
+  }
+
+  if (this->Makefile->GetSafeDefinition("CMAKE_C_COMPILER_ID") != "MSVC") {
+    return;
+  }
+
+  for (auto const& manifest : manifests) {
+    linkerNode.LinkerOptions =
+      cmStrCat("/MANIFESTINPUT:", manifest, ' ', linkerNode.LinkerOptions);
+  }
+  // /MANIFESTINPUT only works with /MANIFEST:EMBED
+  linkerNode.LinkerOptions =
+    cmStrCat("/MANIFEST:EMBED ", linkerNode.LinkerOptions);
+}
+
+void cmFastbuildNormalTargetGenerator::AddStampExeIfApplicable(
+  FastbuildTarget& fastbuildTarget) const
+{
+  LogMessage("AddStampExeIfApplicable(...)");
+  if (fastbuildTarget.LinkerNode.empty() ||
+      (fastbuildTarget.LinkerNode[0].Type != FastbuildLinkerNode::EXECUTABLE &&
+       fastbuildTarget.LinkerNode[0].Type !=
+         FastbuildLinkerNode::SHARED_LIBRARY)) {
+    return;
+  }
+  // File which executes all POST_BUILD steps.
+  // We use it in .LinkerStampExeArgs in order to run POST_BUILD steps after
+  // the compilation.
+  if (!fastbuildTarget.PostBuildExecNodes.Nodes.empty()) {
+    std::string const AllPostBuildExecsScriptFile =
+      cmStrCat(this->Makefile->GetHomeOutputDirectory(), "/CMakeFiles/",
+               fastbuildTarget.Name,
+               "-all-postbuild-commands" FASTBUILD_SCRIPT_FILE_EXTENSION);
+
+    CollapseAllExecsIntoOneScriptfile(
+      AllPostBuildExecsScriptFile, fastbuildTarget.PostBuildExecNodes.Nodes);
+    auto& linkerNode = fastbuildTarget.LinkerNode.back();
+    // On macOS, a target may have multiple linker nodes (e.g., for different
+    // architectures). In that case, add the POST_BUILD step to only one node
+    // to avoid running lipo multiple times.
+    linkerNode.LinkerStampExe =
+      cmGlobalFastbuildGenerator::GetExternalShellExecutable();
+    linkerNode.LinkerStampExeArgs = FASTBUILD_SCRIPT_FILE_ARG;
+    linkerNode.LinkerStampExeArgs +=
+      cmGlobalFastbuildGenerator::QuoteIfHasSpaces(
+        AllPostBuildExecsScriptFile);
+
+  } else {
+    LogMessage("No POST_BUILD steps for target: " + fastbuildTarget.Name);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::ProcessPostBuildForStaticLib(
+  FastbuildTarget& fastbuildTarget) const
+{
+  // "Library" nodes do not have "LinkerStampExe" property, so we need to be
+  // clever here: create an alias that will refer to the binary as well as to
+  // all post-build steps. Also, make sure that post-build steps depend on the
+  // binary itself.
+  LogMessage("ProcessPostBuildForStaticLib(...)");
+  FastbuildAliasNode alias;
+  alias.Name = std::move(fastbuildTarget.LinkerNode[0].Name);
+  for (FastbuildExecNode& postBuildExec :
+       fastbuildTarget.PostBuildExecNodes.Nodes) {
+    postBuildExec.PreBuildDependencies.emplace(
+      fastbuildTarget.LinkerNode[0].LinkerOutput);
+    alias.PreBuildDependencies.emplace(postBuildExec.Name);
+  }
+  fastbuildTarget.AliasNodes.emplace_back(std::move(alias));
+}
+
+void cmFastbuildNormalTargetGenerator::CollapseAllExecsIntoOneScriptfile(
+  std::string const& scriptFileName,
+  std::vector<FastbuildExecNode> const& execs) const
+{
+  cmsys::ofstream scriptFile(scriptFileName.c_str());
+  if (!scriptFile.is_open()) {
+    cmSystemTools::Error("Failed to open: " + scriptFileName);
+    return;
+  }
+  LogMessage("Writing collapsed Execs to " + scriptFileName);
+  auto const shell = cmGlobalFastbuildGenerator::GetExternalShellExecutable();
+  for (auto const& exec : execs) {
+    if (exec.ScriptFile.empty()) {
+      scriptFile << cmSystemTools::ConvertToOutputPath(exec.ExecExecutable)
+                 << " " << exec.ExecArguments << '\n';
+    } else {
+#if defined(_WIN32)
+      scriptFile << "call "
+                 << cmSystemTools::ConvertToWindowsOutputPath(exec.ScriptFile)
+                 << '\n';
+#else
+      scriptFile << cmSystemTools::ConvertToOutputPath(shell) << " "
+                 << cmSystemTools::ConvertToOutputPath(exec.ScriptFile)
+                 << '\n';
+#endif
+    }
+  }
+}
+
+std::string cmFastbuildNormalTargetGenerator::ComputeCodeCheckOptions(
+  cmSourceFile const& srcFile)
+{
+  cmValue const srcSkipCodeCheckVal = srcFile.GetProperty("SKIP_LINTING");
+  bool const skipCodeCheck = srcSkipCodeCheckVal.IsSet()
+    ? srcSkipCodeCheckVal.IsOn()
+    : this->GetGeneratorTarget()->GetPropertyAsBool("SKIP_LINTING");
+
+  if (skipCodeCheck) {
+    return {};
+  }
+  std::string compilerLauncher;
+  std::string staticCheckRule = this->GenerateCodeCheckRules(
+    srcFile, compilerLauncher, "", Config, nullptr);
+  LogMessage(cmStrCat("CodeCheck: ", staticCheckRule));
+  return staticCheckRule;
+}
+
+void cmFastbuildNormalTargetGenerator::ComputeCompilerAndOptions(
+  std::string const& compilerOptions, std::string const& staticCheckOptions,
+  std::string const& language, FastbuildObjectListNode& outObjectList)
+{
+  auto& compilers = this->GetGlobalGenerator()->Compilers;
+  auto const compilerIter =
+    compilers.find(FASTBUILD_COMPILER_PREFIX + language);
+  auto const launcherIter =
+    compilers.find(FASTBUILD_LAUNCHER_PREFIX + language);
+  if (!staticCheckOptions.empty()) {
+    // If we want to run static checks - use CMake as a launcher.
+    // Tested in "RunCMake.ClangTidy", "RunCMake.IncludeWhatYouUse",
+    // "RunCMake.Cpplint", "RunCMake.Cppcheck", "RunCMake.MultiLint" tests.
+    outObjectList.Compiler = "." FASTBUILD_LAUNCHER_PREFIX + CMAKE_LANGUAGE;
+    outObjectList.CompilerOptions = staticCheckOptions;
+    // Add compile command which will be passed to the static analyzer via
+    // dash-dash.
+    if (compilerIter != compilers.end()) {
+      // Wrap in quotes to account for potential spaces in the path.
+      outObjectList.CompilerOptions +=
+        cmGlobalFastbuildGenerator::QuoteIfHasSpaces(
+          compilerIter->second.Executable);
+      outObjectList.CompilerOptions += compilerOptions;
+    }
+  } else if (launcherIter != compilers.end()) {
+    // Tested in "RunCMake.CompilerLauncher" test.
+    outObjectList.Compiler = "." + launcherIter->first;
+    outObjectList.CompilerOptions = launcherIter->second.Args;
+
+    auto vars = cmFastbuildNormalTargetGenerator::ComputeRuleVariables();
+    vars.Language = language.c_str();
+    std::string const targetSupportPath = this->ConvertToFastbuildPath(
+      this->GetGeneratorTarget()->GetCMFSupportDirectory());
+    vars.TargetSupportDir = targetSupportPath.c_str();
+    RulePlaceholderExpander->ExpandRuleVariables(
+      LocalCommonGenerator, outObjectList.CompilerOptions, vars);
+
+    // Add compiler executable explicitly to the compile options.
+    if (compilerIter != compilers.end()) {
+      outObjectList.CompilerOptions += " ";
+      // Wrap in quotes to account for potential spaces in the path.
+      outObjectList.CompilerOptions +=
+        cmGlobalFastbuildGenerator::QuoteIfHasSpaces(
+          compilerIter->second.Executable);
+      outObjectList.CompilerOptions += compilerOptions;
+    }
+  } else if (compilerIter != compilers.end()) {
+    outObjectList.Compiler = "." + compilerIter->first;
+    outObjectList.CompilerOptions = compilerOptions;
+  }
+  LogMessage(cmStrCat(".Compiler = ", outObjectList.Compiler));
+  LogMessage(cmStrCat(".CompilerOptions = ", outObjectList.CompilerOptions));
+}
+
+cmRulePlaceholderExpander::RuleVariables
+cmFastbuildNormalTargetGenerator::ComputeRuleVariables() const
+{
+  cmRulePlaceholderExpander::RuleVariables compileObjectVars;
+  compileObjectVars.CMTargetName = GeneratorTarget->GetName().c_str();
+  compileObjectVars.CMTargetType =
+    cmState::GetTargetTypeName(GeneratorTarget->GetType()).c_str();
+  compileObjectVars.Source = FASTBUILD_1_INPUT_PLACEHOLDER;
+  compileObjectVars.Object = FASTBUILD_2_INPUT_PLACEHOLDER;
+  compileObjectVars.ObjectDir =
+    FASTBUILD_DOLLAR_TAG "TargetOutDir" FASTBUILD_DOLLAR_TAG;
+  compileObjectVars.ObjectFileDir = "";
+  compileObjectVars.Flags = "";
+  compileObjectVars.Includes = "";
+  compileObjectVars.Defines = "";
+  compileObjectVars.Includes = "";
+  compileObjectVars.TargetCompilePDB =
+    FASTBUILD_DOLLAR_TAG "CompilerPDB" FASTBUILD_DOLLAR_TAG;
+  compileObjectVars.Config = Config.c_str();
+  return compileObjectVars;
+}
+
+std::vector<std::string> cmFastbuildNormalTargetGenerator::GetSourceProperty(
+  cmSourceFile const& srcFile, std::string const& prop) const
+{
+  std::vector<std::string> res;
+  if (cmValue val = srcFile.GetProperty(prop)) {
+    cmExpandList(*val, res);
+    return GetGlobalGenerator()->ConvertToFastbuildPath(res);
+  }
+  return res;
+}
+
+void cmFastbuildNormalTargetGenerator::AppendExtraResources(
+  std::set<std::string>& deps) const
+{
+  // Generate Fastbuild's "Copy" commands to copy resources.
+  auto const generateCopyCommands =
+    [this](std::vector<cmSourceFile const*>& frameworkDeps) {
+      this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+        frameworkDeps, this->MacOSXContentGenerator.get(), Config);
+    };
+
+  std::vector<cmSourceFile const*> headerSources;
+  this->GeneratorTarget->GetHeaderSources(headerSources, Config);
+  generateCopyCommands(headerSources);
+
+  std::vector<cmSourceFile const*> extraSources;
+  this->GeneratorTarget->GetExtraSources(extraSources, Config);
+  generateCopyCommands(extraSources);
+
+  std::vector<cmSourceFile const*> externalObjects;
+  this->GeneratorTarget->GetExternalObjects(externalObjects, Config);
+  generateCopyCommands(externalObjects);
+
+  for (FastbuildCopyNode const& node : this->CopyNodes) {
+    LogMessage("Adding resource: " + node.Name);
+    deps.emplace(node.Name);
+  }
+}
+
+std::string cmFastbuildNormalTargetGenerator::GetCompileOptions(
+  cmSourceFile const& srcFile, std::string const& arch)
+{
+  std::string const language = srcFile.GetLanguage();
+  cmRulePlaceholderExpander::RuleVariables compileObjectVars =
+    ComputeRuleVariables();
+  std::string const compilerFlags = DetectCompilerFlags(srcFile, arch);
+  std::string const compilerDefines = ComputeDefines(srcFile);
+  compileObjectVars.Flags = compilerFlags.c_str();
+  compileObjectVars.Defines = compilerDefines.c_str();
+  compileObjectVars.Language = language.c_str();
+  if (language == "CUDA") {
+    compileObjectVars.CudaCompileMode = this->CudaCompileMode.c_str();
+  }
+
+  std::string rule = CompileObjectCmakeRules.at(language);
+  RulePlaceholderExpander->ExpandRuleVariables(LocalCommonGenerator, rule,
+                                               compileObjectVars);
+
+  std::string compilerExecutable;
+  // Remove the compiler from .CompilerOptions, since it would be set as
+  // .Compiler in Fastbuild.
+  // See https://www.fastbuild.org/docs/functions/objectlist.html for a
+  // reference.
+  std::string options;
+  if (!cmSystemTools::SplitProgramFromArgs(rule, compilerExecutable,
+                                           options)) {
+    cmSystemTools::Error(cmStrCat("Failed to split compiler options: ", rule));
+  }
+  LogMessage("Expanded compile options = " + options);
+  LogMessage("Compiler executable = " + compilerExecutable);
+  return options;
+}
+
+std::vector<std::string> cmFastbuildNormalTargetGenerator::GetArches() const
+{
+  auto arches = this->GetGeneratorTarget()->GetAppleArchs(Config, {});
+  // Don't add any arch-specific logic if arch is only one.
+  if (arches.empty() || arches.size() == 1) {
+    arches.clear();
+    arches.emplace_back();
+  }
+  return arches;
+}
+
+void cmFastbuildNormalTargetGenerator::GetCudaDeviceLinkLinkerAndArgs(
+  std::string& linker, std::string& args) const
+{
+  std::string linkCmd =
+    this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_"
+                                       "LIBRARY");
+  auto vars = ComputeRuleVariables();
+  vars.Language = "CUDA";
+  vars.Objects = FASTBUILD_1_INPUT_PLACEHOLDER;
+  vars.Target = FASTBUILD_2_INPUT_PLACEHOLDER;
+  std::unique_ptr<cmLinkLineDeviceComputer> linkLineComputer(
+    new cmLinkLineDeviceComputer(
+      this->LocalGenerator,
+      this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+  std::string linkLibs;
+  std::string targetFlags;
+  std::string linkFlags;
+  std::string frameworkPath;
+  std::string linkPath;
+  // So that the call to "GetTargetFlags" does not pollute "LinkLibs" and
+  // "LinkFlags" with unneeded values.
+  std::string dummyLinkLibs;
+  std::string dummyLinkFlags;
+  this->LocalCommonGenerator->GetDeviceLinkFlags(
+    *linkLineComputer, Config, linkLibs, linkFlags, frameworkPath, linkPath,
+    this->GeneratorTarget);
+  this->LocalCommonGenerator->GetTargetFlags(
+    linkLineComputer.get(), Config, dummyLinkLibs, targetFlags, dummyLinkFlags,
+    frameworkPath, linkPath, this->GeneratorTarget);
+  vars.LanguageCompileFlags = "";
+  vars.LinkFlags = linkFlags.c_str();
+  vars.LinkLibraries = linkLibs.c_str();
+  vars.LanguageCompileFlags = targetFlags.c_str();
+  this->RulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
+                                                     linkCmd, vars);
+  SplitLinkerFromArgs(linkCmd, linker, args);
+}
+
+void cmFastbuildNormalTargetGenerator::GenerateCudaDeviceLink(
+  FastbuildTarget& target) const
+{
+  auto const arches = this->GetArches();
+  if (!requireDeviceLinking(*this->GeneratorTarget, *this->GetLocalGenerator(),
+                            Config)) {
+    return;
+  }
+  LogMessage("GenerateCudaDeviceLink(...)");
+  for (auto const& arch : arches) {
+    std::string linker;
+    std::string args;
+    GetCudaDeviceLinkLinkerAndArgs(linker, args);
+
+    FastbuildLinkerNode deviceLinkNode;
+    deviceLinkNode.Name = cmStrCat(target.Name, "_cuda_device_link");
+    deviceLinkNode.Type = FastbuildLinkerNode::SHARED_LIBRARY;
+    deviceLinkNode.Linker = std::move(linker);
+    deviceLinkNode.LinkerOptions = std::move(args);
+    // Output
+    deviceLinkNode.LinkerOutput = this->ConvertToFastbuildPath(cmStrCat(
+      FASTBUILD_DOLLAR_TAG "TargetOutDi"
+                           "r" FASTBUILD_DOLLAR_TAG "/cmake_device_link",
+      (args.empty() ? "" : "_" + arch),
+      this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_"
+                                        "EXTENSION")));
+
+    // Input
+    for (auto const& objList : target.ObjectListNodes) {
+      deviceLinkNode.LibrarianAdditionalInputs.push_back(objList.Name);
+    }
+    target.CudaDeviceLinkNode.emplace_back(std::move(deviceLinkNode));
+  }
+  LogMessage("GenerateCudaDeviceLink end");
+}
+
+void cmFastbuildNormalTargetGenerator::GenerateObjects(FastbuildTarget& target)
+{
+  this->GetGlobalGenerator()->AllFoldersToClean.insert(ObjectOutDir);
+
+  std::map<std::string, FastbuildObjectListNode> nodesPermutations;
+
+  cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+
+  std::vector<cmSourceFile const*> objectSources;
+  GeneratorTarget->GetObjectSources(objectSources, Config);
+
+  std::set<std::string> createdPCH;
+
+  // Directory level.
+  bool useUnity =
+    GeneratorTarget->GetLocalGenerator()->GetMakefile()->IsDefinitionSet(
+      CMAKE_UNITY_BUILD);
+  // Check if explicitly disabled for this target.
+  auto const targetProp = GeneratorTarget->GetProperty(UNITY_BUILD);
+  if (targetProp.IsSet() && targetProp.IsOff()) {
+    useUnity = false;
+  }
+
+  // List of sources isolated from the unity build if enabled.
+  std::set<std::string> isolatedFromUnity;
+
+  // Mapping from unity group (if any) to sources belonging to that group.
+  std::map<std::string, std::vector<std::string>> sourcesWithGroups;
+
+  for (cmSourceFile const* source : objectSources) {
+
+    cmSourceFile const& srcFile = *source;
+    std::string const pathToFile = srcFile.GetFullPath();
+    if (useUnity) {
+      // Check if the source should be added to "UnityInputIsolatedFiles".
+      if (srcFile.GetPropertyAsBool(SKIP_UNITY_BUILD_INCLUSION)) {
+        isolatedFromUnity.emplace(pathToFile);
+      }
+      std::string const perFileUnityGroup =
+        srcFile.GetSafeProperty(UNITY_GROUP);
+      if (!perFileUnityGroup.empty()) {
+        sourcesWithGroups[perFileUnityGroup].emplace_back(pathToFile);
+      }
+    }
+
+    this->GetGlobalGenerator()->AddFileToClean(cmStrCat(
+      ObjectOutDir, '/', this->GeneratorTarget->GetObjectName(source)));
+
+    // Do not generate separate node for PCH source file.
+    if (this->GeneratorTarget->GetPchSource(Config, srcFile.GetLanguage()) ==
+        pathToFile) {
+      continue;
+    }
+
+    std::string const language = srcFile.GetLanguage();
+    LogMessage(
+      cmStrCat("Source file: ", this->ConvertToFastbuildPath(pathToFile)));
+    LogMessage("Language: " + language);
+
+    std::string const staticCheckOptions = ComputeCodeCheckOptions(srcFile);
+
+    auto const isDisabled = [this](char const* prop) {
+      auto const propValue = this->GeneratorTarget->GetProperty(prop);
+      return propValue && propValue.IsOff();
+    };
+    bool const disableCaching = isDisabled("FASTBUILD_CACHING");
+    bool const disableDistribution = isDisabled("FASTBUILD_DISTRIBUTION");
+
+    for (auto const& arch : this->GetArches()) {
+      std::string const compileOptions = GetCompileOptions(srcFile, arch);
+
+      std::string objOutDirWithPossibleSubdir = ObjectOutDir;
+
+      // If object should be placed in some subdir in the output
+      // path. Tested in "SourceGroups" test.
+      auto const subdir = cmSystemTools::GetFilenamePath(
+        this->GeneratorTarget->GetObjectName(source));
+      if (!subdir.empty()) {
+        objOutDirWithPossibleSubdir += "/";
+        objOutDirWithPossibleSubdir += subdir;
+      }
+
+      std::string const objectListHash = hash.HashString(cmStrCat(
+        compileOptions, staticCheckOptions, objOutDirWithPossibleSubdir,
+        // If file does not need PCH - it must be in another ObjectList.
+        srcFile.GetProperty("SKIP_PRECOMPILE_HEADERS"),
+        srcFile.GetLanguage()));
+
+      LogMessage("ObjectList Hash: " + objectListHash);
+
+      FastbuildObjectListNode& objectListNode =
+        nodesPermutations[objectListHash];
+
+      // Absolute path needed in "RunCMake.SymlinkTrees" test.
+      objectListNode.CompilerInputFiles.push_back(pathToFile);
+
+      std::vector<std::string> const outputs =
+        GetSourceProperty(srcFile, "OBJECT_OUTPUTS");
+      objectListNode.ObjectOutputs.insert(outputs.begin(), outputs.end());
+
+      std::vector<std::string> const depends =
+        GetSourceProperty(srcFile, "OBJECT_DEPENDS");
+      objectListNode.ObjectDepends.insert(depends.begin(), depends.end());
+
+      // We have already computed properties that are computed below.
+      // (.CompilerOptions, .PCH*, etc.). Short circuit this iteration.
+      if (!objectListNode.CompilerOptions.empty()) {
+        continue;
+      }
+      if (disableCaching) {
+        objectListNode.AllowCaching = false;
+      }
+      if (disableDistribution) {
+        objectListNode.AllowDistribution = false;
+      }
+
+      objectListNode.CompilerOutputPath = objOutDirWithPossibleSubdir;
+      LogMessage(cmStrCat("Output path: ", objectListNode.CompilerOutputPath));
+
+      ComputeCompilerAndOptions(compileOptions, staticCheckOptions, language,
+                                objectListNode);
+      ComputePCH(*source, objectListNode, createdPCH);
+
+      objectListNode.Name = cmStrCat(this->GetName(), '_', language, "_Objs");
+      // TODO: Ask cmake the output objects and group by extension instead
+      // of doing this
+      if (language == "RC") {
+        objectListNode.CompilerOutputExtension = ".res";
+      } else {
+        if (!arch.empty()) {
+          objectListNode.CompilerOutputExtension = cmStrCat('.', arch);
+          objectListNode.arch = arch;
+        }
+        char const* customExt =
+          this->GeneratorTarget->GetCustomObjectExtension();
+
+        objectListNode.CompilerOutputExtension +=
+          this->GetMakefile()->GetSafeDefinition(
+            cmStrCat("CMAKE_", language, "_OUTPUT_EXTENSION"));
+        // Tested in "CudaOnly.ExportPTX" test.
+        if (customExt) {
+          objectListNode.CompilerOutputExtension += customExt;
+        }
+      }
+    }
+  }
+
+  int groupNameCount = 0;
+
+  for (auto& val : nodesPermutations) {
+    auto& objectListNode = val.second;
+    objectListNode.Name = cmStrCat(objectListNode.Name, "_", ++groupNameCount);
+    LogMessage(cmStrCat("ObjectList name: ", objectListNode.Name));
+  }
+  std::vector<FastbuildObjectListNode>& objects = target.ObjectListNodes;
+  objects.reserve(nodesPermutations.size());
+  for (auto& val : nodesPermutations) {
+    auto& node = val.second;
+    if (!node.PCHInputFile.empty()) {
+      // Node that produces PCH should be the first one, since other nodes
+      // might reuse this PCH.
+      // Note: we might have several such nodes for different languages.
+      objects.insert(objects.begin(), std::move(node));
+    } else {
+      objects.emplace_back(std::move(node));
+    }
+  }
+  if (useUnity) {
+    target.UnityNodes =
+      GenerateUnity(objects, isolatedFromUnity, sourcesWithGroups);
+  }
+}
+
+FastbuildUnityNode cmFastbuildNormalTargetGenerator::GetOneUnity(
+  std::set<std::string> const& isolatedFiles, std::vector<std::string>& files,
+  int unitySize) const
+{
+  FastbuildUnityNode result;
+  for (auto iter = files.begin(); iter != files.end();) {
+    std::string pathToFile = std::move(*iter);
+    iter = files.erase(iter);
+    // This source must be isolated
+    if (isolatedFiles.find(pathToFile) != isolatedFiles.end()) {
+      result.UnityInputFiles.emplace_back(pathToFile);
+      result.UnityInputIsolatedFiles.emplace_back(std::move(pathToFile));
+    } else {
+      result.UnityInputFiles.emplace_back(std::move(pathToFile));
+    }
+    if (int(result.UnityInputFiles.size() -
+            result.UnityInputIsolatedFiles.size()) == unitySize) {
+      break;
+    }
+  }
+  return result;
+}
+int cmFastbuildNormalTargetGenerator::GetUnityBatchSize() const
+{
+  int unitySize = 8;
+  try {
+    auto const perTargetSize =
+      GeneratorTarget->GetSafeProperty(UNITY_BUILD_BATCH_SIZE);
+    if (!perTargetSize.empty()) {
+      unitySize = std::stoi(perTargetSize);
+    }
+    // Per-directory level.
+    else {
+      unitySize = std::stoi(
+        GeneratorTarget->GetLocalGenerator()->GetMakefile()->GetDefinition(
+          CMAKE_UNITY_BUILD_BATCH_SIZE));
+    }
+  } catch (...) {
+    return unitySize;
+  }
+  return unitySize;
+}
+
+std::vector<FastbuildUnityNode>
+cmFastbuildNormalTargetGenerator::GenerateUnity(
+  std::vector<FastbuildObjectListNode>& objects,
+  std::set<std::string> const& isolatedSources,
+  std::map<std::string, std::vector<std::string>> const& sourcesWithGroups)
+{
+  int const unitySize = GetUnityBatchSize();
+  // Unity of size less than 2 doesn't make sense.
+  if (unitySize < 2) {
+    return {};
+  }
+
+  int unityNumber = 0;
+  int unityGroupNumber = 0;
+  std::vector<FastbuildUnityNode> result;
+
+  for (FastbuildObjectListNode& obj : objects) {
+    // Don't use unity for only 1 file.
+    if (obj.CompilerInputFiles.size() < 2) {
+      continue;
+    }
+    std::string const ext =
+      cmSystemTools::GetFilenameExtension(obj.CompilerInputFiles[0]);
+    // Process groups.
+    auto groupedNode = GenerateGroupedUnityNode(
+      obj.CompilerInputFiles, sourcesWithGroups, unityGroupNumber);
+    // We have at least 2 sources in the group.
+    if (groupedNode.UnityInputFiles.size() > 1) {
+      groupedNode.UnityOutputPath = obj.CompilerOutputPath;
+      obj.CompilerInputUnity.emplace_back(groupedNode.Name);
+      groupedNode.UnityOutputPattern = cmStrCat(groupedNode.Name, ext);
+      result.emplace_back(std::move(groupedNode));
+    }
+    // General unity batching of the remaining (non-grouped) sources.
+    while (!obj.CompilerInputFiles.empty()) {
+      FastbuildUnityNode node =
+        GetOneUnity(isolatedSources, obj.CompilerInputFiles, unitySize);
+      node.Name = cmStrCat(this->GetName(), "_Unity_", ++unityNumber);
+      node.UnityOutputPath = obj.CompilerOutputPath;
+      node.UnityOutputPattern = cmStrCat(node.Name, ext);
+
+      // Unity group of size 1 doesn't make sense - just isolate the source.
+      if (groupedNode.UnityInputFiles.size() == 1) {
+        node.UnityInputIsolatedFiles.emplace_back(
+          groupedNode.UnityInputFiles[0]);
+        node.UnityInputFiles.emplace_back(
+          std::move(groupedNode.UnityInputFiles[0]));
+        // Clear so we don't enter here on the next iteration.
+        groupedNode.UnityInputFiles.clear();
+      }
+
+      // We've got only 1 file left. No need to create a Unity node for it,
+      // just return it back to the ObjectList and exit.
+      if (node.UnityInputFiles.size() == 1) {
+        obj.CompilerInputFiles.emplace_back(
+          std::move(node.UnityInputFiles[0]));
+        break;
+      }
+
+      obj.CompilerInputUnity.emplace_back(node.Name);
+      result.emplace_back(std::move(node));
+    }
+  }
+  return result;
+}
+
+FastbuildUnityNode cmFastbuildNormalTargetGenerator::GenerateGroupedUnityNode(
+  std::vector<std::string>& inputFiles,
+  std::map<std::string, std::vector<std::string>> const& sourcesWithGroups,
+  int& groupId)
+{
+  std::vector<FastbuildUnityNode> result;
+  for (auto const& item : sourcesWithGroups) {
+    auto const& group = item.first;
+    auto const& sources = item.second;
+    FastbuildUnityNode node;
+    // Check if any of the sources belong to this group.
+    for (auto const& source : sources) {
+      auto const iter =
+        std::find(inputFiles.begin(), inputFiles.end(), source);
+      if (iter == inputFiles.end()) {
+        continue;
+      }
+      node.Name =
+        cmStrCat(this->GetName(), "_Unity_Group_", group, '_', ++groupId);
+      node.UnityInputFiles.emplace_back(source);
+
+      // Remove from the general batching.
+      inputFiles.erase(
+        std::remove(inputFiles.begin(), inputFiles.end(), source),
+        inputFiles.end());
+    }
+    if (!node.UnityInputFiles.empty()) {
+      // The unity group belongs to the ObjectLists that we're processing.
+      // We've grouped all the sources we could from the current ObjectList.
+      return node;
+    }
+  }
+  return {};
+}
+
+std::string cmFastbuildNormalTargetGenerator::ResolveIfAlias(
+  std::string const& targetName) const
+{
+  LogMessage("targetName: " + targetName);
+  std::map<std::string, std::string> const aliases =
+    this->Makefile->GetAliasTargets();
+  auto const iter = aliases.find(targetName);
+  if (iter != aliases.end()) {
+    LogMessage("Non alias name: " + iter->second);
+    return iter->second;
+  }
+  return targetName;
+}
+
+void cmFastbuildNormalTargetGenerator::AppendExternalObject(
+  FastbuildLinkerNode& linkerNode, std::set<std::string>& linkedDeps) const
+{
+  // Different aspects of this logic exercised in "ObjectLibrary" and
+  // "ExportImport" test. When making changes here - verify that both of those
+  // tests are still passing.
+  LogMessage("AppendExternalObject(...)");
+  std::vector<cmSourceFile const*> extObjects;
+  this->GeneratorTarget->GetExternalObjects(extObjects, Config);
+  for (cmSourceFile const* src : extObjects) {
+
+    std::string const pathToObj =
+      this->ConvertToFastbuildPath(src->GetFullPath());
+    LogMessage("EXT OBJ: " + pathToObj);
+    std::string const objLibName = ResolveIfAlias(src->GetObjectLibrary());
+    LogMessage("GetObjectLibrary: " + objLibName);
+    // Tested in "ExternalOBJ" test.
+    cmTarget const* target =
+      this->GlobalCommonGenerator->FindTarget(objLibName);
+    if (objLibName.empty()) {
+      linkerNode.LibrarianAdditionalInputs.emplace_back(pathToObj);
+    }
+    // We know how to generate this target and haven't added this dependency
+    // yet.
+    else if (target) {
+      if (!linkedDeps.emplace(objLibName + FASTBUILD_OBJECTS_ALIAS_POSTFIX)
+             .second) {
+        LogMessage("Object Target: " + objLibName +
+                   FASTBUILD_OBJECTS_ALIAS_POSTFIX " already linked");
+        continue;
+      }
+      linkerNode.LibrarianAdditionalInputs.emplace_back(
+        objLibName + FASTBUILD_OBJECTS_ALIAS_POSTFIX);
+    } else if (linkedDeps.emplace(pathToObj).second) {
+      LogMessage("Adding obj dep : " + pathToObj);
+      linkerNode.LibrarianAdditionalInputs.emplace_back(pathToObj);
+    }
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendExeToLink(
+  FastbuildLinkerNode& linkerNode,
+  cmComputeLinkInformation::Item const& item) const
+{
+  std::string const decorated =
+    item.GetFormattedItem(this->ConvertToFastbuildPath(item.Value.Value))
+      .Value;
+  LogMessage("Linking to executable : " + decorated);
+  // Tested in "InterfaceLinkLibrariesDirect" and "Plugin" test.
+  linkerNode.LinkerOptions +=
+    (" " + cmGlobalFastbuildGenerator::QuoteIfHasSpaces(decorated));
+}
+
+std::string cmFastbuildNormalTargetGenerator::GetImportedLoc(
+  cmComputeLinkInformation::Item const& item) const
+{
+  // Link to import library when possible.
+  // Tested in "StagingPrefix" test on Windows/MSVC.
+  cmStateEnums::ArtifactType const artifact =
+    item.Target->HasImportLibrary(Config)
+    ? cmStateEnums::ImportLibraryArtifact
+    : cmStateEnums::RuntimeBinaryArtifact;
+
+  std::string importedLoc = this->ConvertToFastbuildPath(
+    item.Target->GetFullPath(Config, artifact, true));
+  LogMessage("ImportedGetLocation: " + importedLoc);
+  return importedLoc;
+}
+
+void cmFastbuildNormalTargetGenerator::AppendTargetDep(
+  FastbuildLinkerNode& linkerNode, std::set<std::string>& linkedObjects,
+  cmComputeLinkInformation::Item const& item) const
+{
+  LogMessage("AppendTargetDep(...)");
+  cmStateEnums::TargetType const depType = item.Target->GetType();
+  LogMessage("Link dep type: " + std::to_string(depType));
+  LogMessage("Target name: " + item.Target->GetName());
+  auto const resolvedTargetName = ResolveIfAlias(item.Target->GetName());
+  LogMessage("Resolved: " + resolvedTargetName);
+  if (depType == cmStateEnums::INTERFACE_LIBRARY) {
+    return;
+  }
+  std::string const feature = item.GetFeatureName();
+
+  if (item.Target->IsImported()) {
+
+    if (feature == "FRAMEWORK") {
+      // Use just framework's name. The exact path where to look for the
+      // framework will be provided from "frameworkPath" in
+      // "cmFastbuildNormalTargetGenerator::DetectBaseLinkerCommand(...)".
+      // Tested in "RunCMake.Framework - ImportedFrameworkConsumption".
+      std::string const decorated =
+        item.GetFormattedItem(item.Value.Value).Value;
+      LogMessage("Adding framework dep <" + decorated + "> to command line");
+      linkerNode.LinkerOptions += (" " + decorated);
+      return;
+    }
+    if (depType == cmStateEnums::UNKNOWN_LIBRARY) {
+      LogMessage("Unknown library -- adding to LibrarianAdditionalInputs or "
+                 "Libraries2");
+      if (UsingCommandLine) {
+        AppendCommandLineDep(linkerNode, item);
+      } else {
+        AppendLinkDep(linkerNode, GetImportedLoc(item));
+      }
+      return;
+    }
+    // Tested in "ExportImport" test.
+    if (depType == cmStateEnums::EXECUTABLE) {
+      AppendExeToLink(linkerNode, item);
+      return;
+    }
+    // Skip exported objects.
+    // Tested in "ExportImport" test.
+    if (depType == cmStateEnums::OBJECT_LIBRARY) {
+      LogMessage("target : " + item.Target->GetName() +
+                 " already linked... Skipping");
+      return;
+    }
+    // Tested in "ExportImport" test.
+    cmList const list{ GetImportedLoc(item) };
+    for (std::string const& linkDep : list) {
+      AppendLinkDep(linkerNode, linkDep);
+    }
+  } else {
+    if (depType == cmStateEnums::SHARED_LIBRARY &&
+        this->GeneratorTarget->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED")) {
+      // It moves the dep outside of FASTBuild control, so the binary won't
+      // be re-built if the shared lib has changed.
+      // Tested in "BuildDepends" test.
+      LogMessage("LINK_DEPENDS_NO_SHARED is set on the target, adding dep" +
+                 item.Value.Value + " as is");
+      linkerNode.LinkerOptions +=
+        (" " + cmGlobalFastbuildGenerator::QuoteIfHasSpaces(item.Value.Value));
+      return;
+    }
+    // Just add path to binary artifact to command line (except for OBJECT
+    // libraries which we will link directly).
+    if (UsingCommandLine && depType != cmStateEnums::OBJECT_LIBRARY) {
+      AppendCommandLineDep(linkerNode, item);
+      return;
+    }
+    // This dep has a special way of linking to it (e.g.
+    // "CMAKE_LINK_LIBRARY_USING_<FEATURE>").
+    bool const isFeature = !feature.empty() && feature != "DEFAULT";
+    if (isFeature) {
+      std::string const decorated =
+        item.GetFormattedItem(this->ConvertToFastbuildPath(item.Value.Value))
+          .Value;
+      LogMessage("Prepending with feature: " + decorated);
+      linkerNode.LinkerOptions += (" " + decorated);
+    }
+
+    std::string dep = resolvedTargetName +
+      (depType == cmStateEnums::OBJECT_LIBRARY
+         ? FASTBUILD_OBJECTS_ALIAS_POSTFIX
+         : FASTBUILD_LINK_ARTIFACTS_ALIAS_POSTFIX);
+    if (!linkerNode.Arch.empty()) {
+      dep += cmStrCat('-', linkerNode.Arch);
+    }
+    // If we have a special way of linking the dep, we can't have it in
+    // ".Libraries" (since there might be multiple such deps, but
+    // FASTBuild expands ".Libraries" as a continuous array, so we can't
+    // inject any properties in between). Tested in
+    // "RunCMake.target_link_libraries-LINK_LIBRARY" test.
+    if (isFeature) {
+      LogMessage("AppendTargetDep: " + dep + " as prebuild");
+      linkerNode.PreBuildDependencies.emplace(dep);
+      return;
+    }
+
+    if (depType != cmStateEnums::OBJECT_LIBRARY ||
+        linkedObjects.emplace(dep).second) {
+      AppendLinkDep(linkerNode, dep);
+    }
+    AppendTransitivelyLinkedObjects(*item.Target, linkedObjects);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendPrebuildDeps(
+  FastbuildLinkerNode& linkerNode,
+  cmComputeLinkInformation::Item const& item) const
+{
+  if (!item.Target->IsImported()) {
+    return;
+  }
+  // In "RunCMake.FileAPI" imported object library "imported_object_lib" is
+  // added w/o import location...
+  if (item.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+    return;
+  }
+  cmList const list{ GetImportedLoc(item) };
+  for (std::string const& linkDep : list) {
+    // In case we know how to generate this file (needed for proper
+    // sorting by deps). Tested in "RunCMake.target_link_libraries-ALIAS"
+    // test.
+    auto fastbuildTarget =
+      this->GetGlobalGenerator()->GetTargetByOutputName(linkDep);
+    std::string fastbuildTargetName;
+    if (fastbuildTarget) {
+      fastbuildTargetName = std::move(fastbuildTarget->Name);
+    }
+    if (!fastbuildTargetName.empty()) {
+      LogMessage("Adding dep to " + fastbuildTargetName);
+      linkerNode.PreBuildDependencies.insert(std::move(fastbuildTargetName));
+    } else {
+      if (!cmIsNOTFOUND(linkDep)) {
+        LogMessage("Adding dep " + linkDep + " for sorting");
+        linkerNode.PreBuildDependencies.insert(linkDep);
+      }
+    }
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendTransitivelyLinkedObjects(
+  cmGeneratorTarget const& target, std::set<std::string>& linkedObjects) const
+{
+  std::vector<std::string> objs;
+  // Consider that all those object are now linked as well.
+  // Tested in "ExportImport" test.
+  target.GetTargetObjectNames(Config, objs);
+  for (std::string const& obj : objs) {
+    std::string const pathToObj = this->ConvertToFastbuildPath(
+      cmStrCat(target.GetObjectDirectory(Config), '/', obj));
+    linkedObjects.insert(pathToObj);
+  }
+  // Object libs should not be propagated transitively. It's especially
+  // important for LinkObjRHSObject2 test where the absence of the propagation
+  // is tested.
+  for (auto const& linkedTarget :
+       target.Target->GetLinkImplementationEntries()) {
+    auto objAlias = linkedTarget.Value + FASTBUILD_OBJECTS_ALIAS_POSTFIX;
+    LogMessage("Object target is linked transitively " + objAlias);
+    linkedObjects.emplace(std::move(objAlias));
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendCommandLineDep(
+  FastbuildLinkerNode& linkerNode,
+  cmComputeLinkInformation::Item const& item) const
+{
+  LogMessage("AppendCommandLineDep(...)");
+  // Tested in:
+  // "LinkDirectory" (TargetType::EXECUTABLE),
+  // "ObjC.simple-build-test" (TargetType::SHARED_LIBRARY),
+  // "XCTest" (TargetType::MODULE_LIBRARY) tests.
+
+  std::string formatted;
+  if (item.Target && item.Target->IsImported()) {
+    formatted = GetImportedLoc(item);
+  } else {
+    formatted = item.GetFormattedItem(item.Value.Value).Value;
+  }
+  formatted = this->ConvertToFastbuildPath(formatted);
+
+  LogMessage("Unknown link dep: " + formatted + ", adding to command line");
+
+  // Only add real artifacts to .Libraries2, otherwise Fastbuild will always
+  // consider the target out-of-date (since its input doesn't exist).
+  if (item.IsPath == cmComputeLinkInformation::ItemIsPath::Yes &&
+      item.GetFeatureName() == "DEFAULT") {
+    linkerNode.LinkerOptions +=
+      (" " + cmGlobalFastbuildGenerator::QuoteIfHasSpaces(formatted));
+    AppendToLibraries2IfApplicable(linkerNode, std::move(formatted));
+  } else {
+    // It's some link option, not a path.
+    linkerNode.LinkerOptions += (" " + formatted);
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendToLibraries2IfApplicable(
+  FastbuildLinkerNode& linkerNode, std::string dep) const
+{
+  // Strings like "-framework Cocoa" in .Libraries2 node will always make the
+  // target out-of-date (since it never exists).
+  if (this->GeneratorTarget->IsApple() &&
+      cmSystemTools::StringStartsWith(dep, "-framework")) {
+    LogMessage("Not adding framework: " + dep + " to .Libraries2");
+    return;
+  }
+
+  auto const target = this->GetGlobalGenerator()->GetTargetByOutputName(dep);
+  // Fastbuild doesn't support executables in .Libraries2, though we can use
+  // Executables via "-bundle_loader" on Apple.
+  if (this->GeneratorTarget->IsApple() && target &&
+      !target->LinkerNode.empty() &&
+      target->LinkerNode[0].Type == FastbuildLinkerNode::EXECUTABLE) {
+    LogMessage("Not adding DLL/Executable(" + linkerNode.Name +
+               " to .Libraries2");
+    return;
+  }
+
+  // Additing to .Libraries2 for tracking.
+  LogMessage("Adding " + dep + " .Libraries2");
+  linkerNode.Libraries2.emplace_back(std::move(dep));
+}
+
+void cmFastbuildNormalTargetGenerator::AppendLINK_DEPENDS(
+  FastbuildLinkerNode& linkerNode) const
+{
+  // LINK_DEPENDS and such.
+  // Tested in "BuildDepends" test.
+  for (std::string const& lang : Languages) {
+    for (BT<std::string> const& dep :
+         this->GeneratorTarget->GetLinkDepends(Config, lang)) {
+      // We can't add "LINK_DEPENDS" to .PreBuildDependencies, since FASTBuild
+      // only forces such targets to be built and doesn't force re-linking if
+      // they've changed.
+      linkerNode.Libraries2.emplace_back(
+        this->ConvertToFastbuildPath(dep.Value));
+    }
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendLinkDep(
+  FastbuildLinkerNode& linkerNode, std::string dep) const
+{
+  LogMessage("AppendLinkDep: " + dep +
+             " to .LibrarianAdditionalInputs/.Libraries");
+  linkerNode.LibrarianAdditionalInputs.emplace_back(std::move(dep));
+}
+
+void cmFastbuildNormalTargetGenerator::AppendDirectObjectLibs(
+  FastbuildLinkerNode& linkerNode, std::set<std::string>& linkedObjects)
+{
+  auto const srcs = this->GeneratorTarget->GetSourceFiles(Config);
+  for (auto const& entry : srcs) {
+    auto const objLib = entry.Value->GetObjectLibrary();
+    auto const objPath = entry.Value->GetFullPath();
+    LogMessage("Source obj entry: " + objPath);
+    if (!objLib.empty()) {
+      auto* const objTarget =
+        this->LocalGenerator->FindGeneratorTargetToUse(objLib);
+      if (objTarget) {
+        LogMessage("Imported: " + std::to_string(objTarget->IsImported()));
+        std::string fastbuildTarget;
+        // If target is imported - we don't have it in our build file, so can't
+        // refer to it by name. Use file path to the object then.
+        // Tested in "ExportImport" test.
+        if (objTarget->IsImported()) {
+          fastbuildTarget = entry.Value->GetFullPath();
+        } else {
+          // Mark all target objects as linked.
+          linkedObjects.emplace(this->ConvertToFastbuildPath(objPath));
+          fastbuildTarget =
+            objTarget->GetName() + FASTBUILD_OBJECTS_ALIAS_POSTFIX;
+        }
+        if (linkedObjects.emplace(fastbuildTarget).second) {
+          LogMessage("Adding object target: " + fastbuildTarget);
+          linkerNode.LibrarianAdditionalInputs.emplace_back(
+            std::move(fastbuildTarget));
+        }
+      }
+    }
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AppendLinkDeps(
+  std::set<FastbuildTargetDep>& preBuildDeps, FastbuildLinkerNode& linkerNode,
+  FastbuildLinkerNode& cudaDeviceLinkLinkerNode)
+{
+  std::set<std::string> linkedObjects;
+  cmComputeLinkInformation const* linkInfo =
+    this->GeneratorTarget->GetLinkInformation(Config);
+  if (!linkInfo) {
+    return;
+  }
+
+  UsingCommandLine = false;
+  AppendLINK_DEPENDS(linkerNode);
+  // Object libs that are linked directly to target (e.g.
+  // add_executable(test_exe archiveObjs)
+  AppendDirectObjectLibs(linkerNode, linkedObjects);
+  std::size_t numberOfDirectlyLinkedObjects =
+    linkerNode.LibrarianAdditionalInputs.size();
+  // target_link_libraries.
+  cmComputeLinkInformation::ItemVector const items = linkInfo->GetItems();
+
+  LogMessage(cmStrCat("Link items size: ", items.size()));
+  for (cmComputeLinkInformation::Item const& item : items) {
+    std::string const feature = item.GetFeatureName();
+    LogMessage("GetFeatureName: " + feature);
+    if (!feature.empty()) {
+      LogMessage("GetFormattedItem: " +
+                 item.GetFormattedItem(item.Value.Value).Value);
+    }
+    // We're linked to `$<TARGET_OBJECTS>`.
+    // Static libs transitively propagate such deps, see:
+    // https://cmake.org/cmake/help/latest/command/target_link_libraries.html#linking-object-libraries-via-target-objects
+    if (item.ObjectSource &&
+        linkerNode.Type != FastbuildLinkerNode::STATIC_LIBRARY) {
+      // Tested in "ObjectLibrary" test.
+      auto libName = item.ObjectSource->GetObjectLibrary();
+      std::string dep = libName + FASTBUILD_OBJECTS_ALIAS_POSTFIX;
+      if (linkedObjects.emplace(dep).second) {
+        FastbuildTargetDep targetDep{ std::move(libName) };
+        targetDep.Type = FastbuildTargetDepType::ORDER_ONLY;
+        preBuildDeps.emplace(std::move(targetDep));
+        linkerNode.LibrarianAdditionalInputs.emplace_back(std::move(dep));
+      }
+    } else if (linkerNode.Type == FastbuildLinkerNode::STATIC_LIBRARY) {
+      LogMessage("Skipping linking to STATIC_LIBRARY (" + linkerNode.Name +
+                 ")");
+      continue;
+    }
+    // We're linked to exact target.
+    else if (item.Target) {
+      AppendTargetDep(linkerNode, linkedObjects, item);
+      AppendPrebuildDeps(linkerNode, item);
+      if (!item.Target->IsImported() &&
+          item.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+        ++numberOfDirectlyLinkedObjects;
+        cudaDeviceLinkLinkerNode.LibrarianAdditionalInputs.emplace_back(
+          cmStrCat(item.Target->GetName(), FASTBUILD_OBJECTS_ALIAS_POSTFIX));
+      }
+
+    } else {
+      AppendCommandLineDep(linkerNode, item);
+      UsingCommandLine = true;
+    }
+  }
+  AppendExternalObject(linkerNode, linkedObjects);
+
+  if (!cudaDeviceLinkLinkerNode.Name.empty()) {
+    linkerNode.LibrarianAdditionalInputs.push_back(
+      cudaDeviceLinkLinkerNode.Name);
+    // CUDA device-link stub needs to go AFTER direct object dependencies, but
+    // BEFORE all other dependencies. Needed for the correct left-to-right
+    // symbols resolution on Linux.
+    std::swap(
+      linkerNode.LibrarianAdditionalInputs[numberOfDirectlyLinkedObjects],
+      linkerNode.LibrarianAdditionalInputs.back());
+  }
+}
+
+void cmFastbuildNormalTargetGenerator::AddLipoCommand(FastbuildTarget& target)
+{
+  static auto const lipo = cmSystemTools::FindProgram("lipo");
+  LogMessage("found lipo at " + lipo);
+  FastbuildExecNode exec;
+  exec.ExecExecutable = lipo;
+  exec.ExecOutput = target.RealOutput;
+  if (exec.ExecOutput != target.Name) {
+    exec.Name = target.Name;
+  }
+  for (auto const& ArchSpecificTarget : target.LinkerNode) {
+    exec.ExecInput.emplace_back(ArchSpecificTarget.LinkerOutput);
+  }
+  exec.ExecArguments +=
+    "-create -output " + target.RealOutput + " " + cmJoin(exec.ExecInput, " ");
+  target.PostBuildExecNodes.Alias.PreBuildDependencies.emplace(
+    exec.ExecOutput);
+  target.PostBuildExecNodes.Nodes.emplace_back(std::move(exec));
+}
+
+void cmFastbuildNormalTargetGenerator::GenerateLink(
+  FastbuildTarget& target, std::vector<std::string> const& objectDepends)
+{
+  std::string const targetName = this->GetTargetName();
+  cmGeneratorTarget::Names const targetNames = DetectOutput();
+  LogMessage("targetNames.Real: " + targetNames.Real);
+  LogMessage("targetNames.ImportOutput: " + targetNames.ImportOutput);
+  LogMessage("targetNames.SharedObject: " + targetNames.SharedObject);
+  LogMessage("targetNames.Base: " + targetNames.Base);
+
+  std::vector<std::string> allNodes;
+  auto const arches = this->GetArches();
+  for (std::size_t i = 0; i < arches.size(); ++i) {
+    auto const& arch = arches[i];
+    FastbuildLinkerNode linkerNode;
+    ProcessManifests(linkerNode);
+    // Objects built by the current target.
+    for (auto const& objectList : target.ObjectListNodes) {
+      if (objectList.arch.empty() || objectList.arch == arch) {
+        linkerNode.LibrarianAdditionalInputs.push_back(objectList.Name);
+      }
+    }
+
+    // Detection of the link command as follows:
+    auto const type = this->GeneratorTarget->GetType();
+    switch (type) {
+      case cmStateEnums::EXECUTABLE: {
+        LogMessage("Generating EXECUTABLE");
+        linkerNode.Type = FastbuildLinkerNode::EXECUTABLE;
+        break;
+      }
+      case cmStateEnums::MODULE_LIBRARY: {
+        LogMessage("Generating MODULE_LIBRARY");
+        linkerNode.Type = FastbuildLinkerNode::SHARED_LIBRARY;
+        break;
+      }
+      case cmStateEnums::SHARED_LIBRARY: {
+        LogMessage("Generating SHARED_LIBRARY");
+        linkerNode.Type = FastbuildLinkerNode::SHARED_LIBRARY;
+        break;
+      }
+      case cmStateEnums::STATIC_LIBRARY: {
+        LogMessage("Generating STATIC_LIBRARY");
+        linkerNode.Type = FastbuildLinkerNode::STATIC_LIBRARY;
+        break;
+      }
+      case cmStateEnums::OBJECT_LIBRARY: {
+        LogMessage("Generating OBJECT_LIBRARY");
+        return;
+      }
+      default: {
+        LogMessage("Skipping GenerateLink");
+        return;
+      }
+    }
+
+    std::string const targetOutput =
+      ConvertToFastbuildPath(GeneratorTarget->GetFullPath(Config));
+    std::string targetOutputReal = ConvertToFastbuildPath(
+      GeneratorTarget->GetFullPath(Config, cmStateEnums::RuntimeBinaryArtifact,
+                                   /*realname=*/true));
+    LogMessage("targetOutput: " + targetOutput);
+    LogMessage("targetOutputReal: " + targetOutputReal);
+
+    std::string const output =
+      cmSystemTools::GetFilenameName(targetNames.Output);
+    std::string const outputReal =
+      cmSystemTools::GetFilenameName(targetNames.Real);
+    // Generate "Copy" nodes for copying Framework / Bundle resources.
+    AppendExtraResources(linkerNode.PreBuildDependencies);
+
+    if (type == cmStateEnums::EXECUTABLE ||
+        type == cmStateEnums::SHARED_LIBRARY) {
+      // Tested in "RunCMake.BuildDepends" test (we need to rebuild when
+      // manifest  changes).
+      std::copy(objectDepends.begin(), objectDepends.end(),
+                std::back_inserter(linkerNode.Libraries2));
+    }
+
+    if (GeneratorTarget->IsAppBundleOnApple()) {
+      // Create the app bundle
+      std::string outpath = GeneratorTarget->GetDirectory(Config);
+      this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath,
+                                                Config);
+      targetOutputReal = outpath;
+      targetOutputReal += "/";
+      targetOutputReal += outputReal;
+      targetOutputReal = this->ConvertToFastbuildPath(targetOutputReal);
+    } else if (GeneratorTarget->IsFrameworkOnApple()) {
+      // Create the library framework.
+      this->OSXBundleGenerator->CreateFramework(
+        targetNames.Output, GeneratorTarget->GetDirectory(Config), Config);
+    } else if (GeneratorTarget->IsCFBundleOnApple()) {
+      // Create the core foundation bundle.
+      this->OSXBundleGenerator->CreateCFBundle(
+        targetNames.Output, GeneratorTarget->GetDirectory(Config), Config);
+    }
+
+    std::string linkCmd;
+    if (!DetectBaseLinkerCommand(linkCmd, arch, targetNames)) {
+      LogMessage("No linker command detected");
+      return;
+    }
+
+    std::string executable;
+    std::string linkerOptions;
+    std::string linkerType = "auto";
+
+    GetLinkerExecutableAndArgs(linkCmd, executable, linkerOptions);
+
+    linkerNode.Compiler = ".Compiler_dummy";
+    linkerNode.CompilerOptions = " ";
+
+    linkerNode.Name = targetName;
+    linkerNode.LinkerOutput = targetOutputReal;
+    this->GetGlobalGenerator()->AddFileToClean(linkerNode.LinkerOutput);
+    target.RealOutput = targetOutputReal;
+    if (!arch.empty()) {
+      linkerNode.Name += cmStrCat('-', arch);
+      linkerNode.LinkerOutput += cmStrCat('.', arch);
+      linkerNode.Arch = arch;
+    }
+    linkerNode.Linker = executable;
+    linkerNode.LinkerType = linkerType;
+    linkerNode.LinkerOptions += linkerOptions;
+
+    // Check if we have CUDA device link stub for this target.
+    FastbuildLinkerNode dummyCudaDeviceLinkNode;
+    AppendLinkDeps(target.PreBuildDependencies, linkerNode,
+                   target.CudaDeviceLinkNode.size() > i
+                     ? target.CudaDeviceLinkNode[i]
+                     : dummyCudaDeviceLinkNode);
+    ApplyLWYUToLinkerCommand(linkerNode);
+
+    // On macOS, only the last LinkerNode performs lipo in POST_BUILD.
+    // Make it depend on all previous nodes to ensure correct execution order.
+    if (i == arches.size() - 1) {
+      for (auto& prevNode : allNodes) {
+        linkerNode.PreBuildDependencies.emplace(std::move(prevNode));
+      }
+    } else {
+      allNodes.emplace_back(linkerNode.Name);
+    }
+    if (!target.ObjectListNodes.empty()) {
+      // Just reuse any of compiler options mainly for the correct IDE project
+      // generation.
+      linkerNode.CompilerOptions = target.ObjectListNodes[0].CompilerOptions;
+    }
+    target.LinkerNode.emplace_back(std::move(linkerNode));
+  }
+}
+
+std::vector<FastbuildExecNode>
+cmFastbuildNormalTargetGenerator::GetSymlinkExecs() const
+{
+  std::vector<FastbuildExecNode> res;
+  cmGeneratorTarget::Names const targetNames = DetectOutput();
+  LogMessage("targetNames.Real: " + targetNames.Real);
+  LogMessage("targetNames.ImportOutput: " + targetNames.ImportOutput);
+  LogMessage("targetNames.SharedObject: " + targetNames.SharedObject);
+  LogMessage("targetNames.Base: " + targetNames.Base);
+
+  std::string const targetOutput =
+    ConvertToFastbuildPath(GeneratorTarget->GetFullPath(Config));
+  std::string const targetOutputReal = ConvertToFastbuildPath(
+    GeneratorTarget->GetFullPath(Config, cmStateEnums::RuntimeBinaryArtifact,
+                                 /*realname=*/true));
+  LogMessage("targetOutput: " + targetOutput);
+
+  LogMessage("targetOutputReal: " + targetOutputReal);
+
+  if (targetOutput != targetOutputReal &&
+      !GeneratorTarget->IsFrameworkOnApple()) {
+    auto const generateSymlinkCommand = [&](std::string const& from,
+                                            std::string const& to) {
+      if (from.empty() || to.empty() || from == to) {
+        return;
+      }
+      LogMessage("Symlinking " + from + " -> " + to);
+      FastbuildExecNode postBuildExecNode;
+      postBuildExecNode.Name = "cmake_symlink_" + to;
+      postBuildExecNode.ExecOutput =
+        cmJoin({ GeneratorTarget->GetDirectory(Config), to }, "/");
+      postBuildExecNode.ExecExecutable = cmSystemTools::GetCMakeCommand();
+      postBuildExecNode.ExecArguments =
+        "-E cmake_symlink_executable " +
+        cmGlobalFastbuildGenerator::QuoteIfHasSpaces(from) + " " +
+        cmGlobalFastbuildGenerator::QuoteIfHasSpaces(
+          this->ConvertToFastbuildPath(postBuildExecNode.ExecOutput));
+      res.emplace_back(std::move(postBuildExecNode));
+    };
+    generateSymlinkCommand(targetNames.Real, targetNames.Output);
+    generateSymlinkCommand(targetNames.Real, targetNames.SharedObject);
+    generateSymlinkCommand(targetNames.ImportReal, targetNames.ImportOutput);
+  }
+  return res;
+}
diff --git a/Source/cmFastbuildNormalTargetGenerator.h b/Source/cmFastbuildNormalTargetGenerator.h
new file mode 100644
index 0000000..8a01f77
--- /dev/null
+++ b/Source/cmFastbuildNormalTargetGenerator.h
@@ -0,0 +1,161 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "cmComputeLinkInformation.h"
+#include "cmFastbuildTargetGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalFastbuildGenerator.h"
+#include "cmRulePlaceholderExpander.h"
+class cmSourceFile;
+
+class cmFastbuildNormalTargetGenerator : public cmFastbuildTargetGenerator
+{
+  std::unique_ptr<cmRulePlaceholderExpander> const RulePlaceholderExpander;
+  std::string const ObjectOutDir;
+  std::set<std::string> const Languages;
+  std::unordered_map<std::string, std::string> const CompileObjectCmakeRules;
+  std::string const CudaCompileMode;
+
+  // Now we're adding our link deps to command line and using .Libraries2 for
+  // tracking deps.
+  bool UsingCommandLine = false;
+
+  std::unordered_map<std::string, std::string> TargetIncludesByLanguage;
+  std::map<std::pair<std::string, std::string>, std::string>
+    CompileFlagsByLangAndArch;
+
+public:
+  cmFastbuildNormalTargetGenerator(cmGeneratorTarget* gt, std::string config);
+
+  void Generate() override;
+
+private:
+  void GenerateLink(FastbuildTarget& target,
+                    std::vector<std::string> const& objectDepends);
+  bool DetectBaseLinkerCommand(std::string& command, std::string const& arch,
+                               cmGeneratorTarget::Names const& targetNames);
+
+  // Get languages used by the target.
+  std::set<std::string> GetLanguages();
+  // Returns mapping from language to command how to compile object file for
+  // the it.
+  // Example return value: {"CXX" : "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES>
+  // <FLAGS> -o <OBJECT> -c <SOURCE>" }
+  std::unordered_map<std::string, std::string> GetCompileObjectCommand() const;
+  std::string GetCudaCompileMode() const;
+  std::string GetLinkCommand() const;
+
+  void AddCompilerLaunchersForLanguages();
+  void AddLinkerLauncher();
+  void AddCMakeLauncher();
+
+  void ComputePaths(FastbuildTarget& fastbuildTarget) const;
+
+  std::string ComputeCodeCheckOptions(cmSourceFile const& srcFile);
+
+  cmRulePlaceholderExpander::RuleVariables ComputeRuleVariables() const;
+
+  std::vector<std::string> GetSourceProperty(cmSourceFile const& srcFile,
+                                             std::string const& prop) const;
+
+  std::string GetCompileOptions(cmSourceFile const& srcFile,
+                                std::string const& arch);
+
+  std::vector<std::string> GetArches() const;
+
+  void GetCudaDeviceLinkLinkerAndArgs(std::string& linker,
+                                      std::string& args) const;
+  void GenerateCudaDeviceLink(FastbuildTarget& target) const;
+  void GenerateObjects(FastbuildTarget& target);
+  FastbuildUnityNode GetOneUnity(std::set<std::string> const& isolatedFiles,
+                                 std::vector<std::string>& files,
+                                 int unitySize) const;
+
+  int GetUnityBatchSize() const;
+  std::vector<FastbuildUnityNode> GenerateUnity(
+    std::vector<FastbuildObjectListNode>& objects,
+    std::set<std::string> const& isolatedSources,
+    std::map<std::string, std::vector<std::string>> const& sourcesWithGroups);
+  FastbuildUnityNode GenerateGroupedUnityNode(
+    std::vector<std::string>& inputFiles,
+    std::map<std::string, std::vector<std::string>> const& sourcesWithGroups,
+    int& groupId);
+
+  // Computes .CompilerOptions for the ObjectList node.
+  void ComputeCompilerAndOptions(std::string const& compilerOptions,
+                                 std::string const& staticCheckOptions,
+                                 std::string const& language,
+                                 FastbuildObjectListNode& outObjectList);
+
+  std::string GetImportedLoc(cmComputeLinkInformation::Item const& item) const;
+  std::string ResolveIfAlias(std::string const& targetName) const;
+
+  void AppendExtraResources(std::set<std::string>& deps) const;
+  void AppendExternalObject(FastbuildLinkerNode& linkerNode,
+                            std::set<std::string>& linkedObjects) const;
+  void AppendExeToLink(FastbuildLinkerNode& linkerNode,
+                       cmComputeLinkInformation::Item const& item) const;
+  void AppendTargetDep(FastbuildLinkerNode& linkerNode,
+                       std::set<std::string>& linkedObjects,
+                       cmComputeLinkInformation::Item const& item) const;
+  void AppendPrebuildDeps(FastbuildLinkerNode& linkerNode,
+                          cmComputeLinkInformation::Item const& item) const;
+  void AppendTransitivelyLinkedObjects(
+    cmGeneratorTarget const& target,
+    std::set<std::string>& linkedObjects) const;
+  void AppendCommandLineDep(FastbuildLinkerNode& linkerNode,
+                            cmComputeLinkInformation::Item const& item) const;
+  void AppendToLibraries2IfApplicable(FastbuildLinkerNode& linkerNode,
+                                      std::string dep) const;
+  void AppendLINK_DEPENDS(FastbuildLinkerNode& linkerNode) const;
+  void AppendLinkDep(FastbuildLinkerNode& linkerNode, std::string dep) const;
+  void AppendDirectObjectLibs(FastbuildLinkerNode& linkerNode,
+                              std::set<std::string>& linkedObjects);
+
+  void AppendLinkDeps(std::set<FastbuildTargetDep>& preBuildDeps,
+                      FastbuildLinkerNode& linkerNode,
+                      FastbuildLinkerNode& cudaDeviceLinkLinkerNode);
+  void AddLipoCommand(FastbuildTarget& target);
+  void GenerateModuleDefinitionInfo(FastbuildTarget& target) const;
+  std::vector<FastbuildExecNode> GetSymlinkExecs() const;
+  void ProcessManifests(FastbuildLinkerNode& linkerNode) const;
+  void AddStampExeIfApplicable(FastbuildTarget& fastbuildTarget) const;
+  void ProcessPostBuildForStaticLib(FastbuildTarget& fastbuildTarget) const;
+  void CollapseAllExecsIntoOneScriptfile(
+    std::string const& scriptFileName,
+    std::vector<FastbuildExecNode> const& execs) const;
+
+  void AddPrebuildDeps(FastbuildTarget& target) const;
+
+  std::string DetectCompilerFlags(cmSourceFile const& srcFile,
+                                  std::string const& arch);
+
+  void SplitLinkerFromArgs(std::string const& command,
+                           std::string& outLinkerExecutable,
+                           std::string& outLinkerArgs) const;
+  void GetLinkerExecutableAndArgs(std::string const& command,
+                                  std::string& outLinkerExecutable,
+                                  std::string& outLinkerArgs);
+
+  void ApplyLinkRuleLauncher(std::string& command);
+  void ApplyLWYUToLinkerCommand(FastbuildLinkerNode& linkerNode);
+
+  std::string ComputeDefines(cmSourceFile const& srcFile);
+
+  void ComputePCH(cmSourceFile const& srcFile, FastbuildObjectListNode& node,
+                  std::set<std::string>& createdPCH);
+
+  std::vector<std::string> GetManifestsAsFastbuildPath() const;
+
+  void EnsureDirectoryExists(std::string const& path) const;
+  void EnsureParentDirectoryExists(std::string const& path) const;
+};
diff --git a/Source/cmFastbuildTargetGenerator.cxx b/Source/cmFastbuildTargetGenerator.cxx
new file mode 100644
index 0000000..afcddb2
--- /dev/null
+++ b/Source/cmFastbuildTargetGenerator.cxx
@@ -0,0 +1,858 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#include "cmFastbuildTargetGenerator.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <unordered_map>
+#include <unordered_set>
+
+#include <cm/memory>
+#include <cm/optional>
+
+#include "cmCryptoHash.h"
+#include "cmCustomCommand.h"
+#include "cmCustomCommandGenerator.h"
+#include "cmCustomCommandLines.h"
+#include "cmFastbuildNormalTargetGenerator.h"
+#include "cmFastbuildUtilityTargetGenerator.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalCommonGenerator.h"
+#include "cmGlobalFastbuildGenerator.h"
+#include "cmList.h"
+#include "cmListFileCache.h"
+#include "cmLocalCommonGenerator.h"
+#include "cmLocalFastbuildGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmOSXBundleGenerator.h"
+#include "cmOutputConverter.h"
+#include "cmRulePlaceholderExpander.h"
+#include "cmSourceFile.h"
+#include "cmState.h"
+#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+#include "cmValue.h"
+
+#define FASTBUILD_DOLLAR_TAG "FASTBUILD_DOLLAR_TAG"
+
+constexpr auto FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT =
+  "CMAKE_FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT";
+constexpr auto FASTBUILD_DISABLE_OUTPUT_PRECHECK_EXEC =
+  "CMAKE_FASTBUILD_DISABLE_OUTPUT_PRECHECK_EXEC";
+
+cmFastbuildTargetGenerator* cmFastbuildTargetGenerator::New(
+  cmGeneratorTarget* target, std::string config)
+{
+  switch (target->GetType()) {
+    case cmStateEnums::EXECUTABLE:
+    case cmStateEnums::SHARED_LIBRARY:
+    case cmStateEnums::STATIC_LIBRARY:
+    case cmStateEnums::MODULE_LIBRARY:
+    case cmStateEnums::OBJECT_LIBRARY:
+      return new cmFastbuildNormalTargetGenerator(target, std::move(config));
+
+    case cmStateEnums::UTILITY:
+    case cmStateEnums::GLOBAL_TARGET:
+    case cmStateEnums::INTERFACE_LIBRARY:
+      return new cmFastbuildUtilityTargetGenerator(target, std::move(config));
+
+    default:
+      return nullptr;
+  }
+}
+
+cmFastbuildTargetGenerator::cmFastbuildTargetGenerator(
+  cmGeneratorTarget* target, std::string configParam)
+  : cmCommonTargetGenerator(target)
+  , LocalGenerator(
+      static_cast<cmLocalFastbuildGenerator*>(target->GetLocalGenerator()))
+  , TargetDirectDependencies(
+      this->GlobalCommonGenerator->GetTargetDirectDepends(GeneratorTarget))
+  , Config(std::move(configParam))
+{
+  this->MacOSXContentGenerator =
+    cm::make_unique<MacOSXContentGeneratorType>(this, Config);
+}
+
+void cmFastbuildTargetGenerator::LogMessage(std::string const& m) const
+{
+  this->GetGlobalGenerator()->LogMessage(m);
+}
+
+std::string cmFastbuildTargetGenerator::GetUtilityAliasFromBuildStep(
+  FastbuildBuildStep step) const
+{
+  if (step == FastbuildBuildStep::PRE_BUILD) {
+    return GetTargetName() + FASTBUILD_PRE_BUILD_ALIAS_POSTFIX;
+  }
+  if (step == FastbuildBuildStep::PRE_LINK) {
+    return GetTargetName() + FASTBUILD_PRE_LINK_ALIAS_POSTFIX;
+  }
+  if (step == FastbuildBuildStep::POST_BUILD) {
+    return GetTargetName() + FASTBUILD_POST_BUILD_ALIAS_POSTFIX;
+  }
+  return GetTargetName() + FASTBUILD_CUSTOM_COMMAND_ALIAS_POSTFIX;
+}
+
+void cmFastbuildTargetGenerator::MacOSXContentGeneratorType::operator()(
+  cmSourceFile const& source, char const* pkgloc,
+  std::string const& configName)
+{
+  // Skip OS X content when not building a Framework or Bundle.
+  if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
+    return;
+  }
+
+  // Get the input file location.
+  std::string input = source.GetFullPath();
+  input = this->Generator->GetGlobalGenerator()->ConvertToFastbuildPath(input);
+
+  // Get the output file location.
+  std::string output =
+    this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(
+      pkgloc, configName);
+
+  output += "/";
+  output += cmSystemTools::GetFilenameName(input);
+  output =
+    this->Generator->GetGlobalGenerator()->ConvertToFastbuildPath(output);
+
+  FastbuildCopyNode node;
+  node.Name = "Copy_" + output;
+  node.Source = std::move(input);
+  if (cmSystemTools::FileIsDirectory(node.Source)) {
+    node.CopyDir = true;
+  }
+  node.Dest = std::move(output);
+  // Just in case if "from" is generated by some custom command.
+  // Tested in "BundleTest" test.
+  node.PreBuildDependencies =
+    this->Generator->GetTargetName() + FASTBUILD_CUSTOM_COMMAND_ALIAS_POSTFIX;
+
+  this->Generator->CopyNodes.emplace_back(std::move(node));
+}
+
+std::string cmFastbuildTargetGenerator::GetCustomCommandTargetName(
+  cmCustomCommand const& cc, FastbuildBuildStep step) const
+{
+  std::string const extra = this->Makefile->GetCurrentBinaryDirectory();
+  std::string targetName = "cc";
+
+  std::string extras = extra;
+
+  // Compute hash based on commands & args & output.
+  for (cmCustomCommandLine const& commandLine : cc.GetCommandLines()) {
+    extras += cmJoin(commandLine, "");
+  }
+  for (std::string const& output : cc.GetOutputs()) {
+    extras += output;
+  }
+
+  extras += std::to_string(static_cast<int>(step));
+
+  cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+  targetName += "-" + hash.HashString(extras).substr(0, 14);
+
+  return targetName;
+}
+
+void cmFastbuildTargetGenerator::WriteScriptProlog(cmsys::ofstream& file) const
+{
+#ifdef _WIN32
+  file << "@echo off\n";
+#else
+  file << "set -e\n\n";
+#endif
+}
+void cmFastbuildTargetGenerator::WriteScriptEpilog(cmsys::ofstream& file) const
+{
+  (void)file;
+#ifdef _WIN32
+  file << "goto :EOF\n\n"
+          ":ABORT\n"
+          "set ERROR_CODE=%ERRORLEVEL%\n"
+          "echo Batch file failed at line %FAIL_LINE% "
+          "with errorcode %ERRORLEVEL%\n"
+          "exit /b %ERROR_CODE%";
+#endif
+}
+
+std::string cmFastbuildTargetGenerator::GetScriptWorkingDir(
+  cmCustomCommandGenerator const& ccg) const
+{
+  std::string workingDirectory = ccg.GetWorkingDirectory();
+  if (workingDirectory.empty()) {
+    return this->LocalCommonGenerator->GetCurrentBinaryDirectory();
+  }
+  return workingDirectory;
+}
+
+std::string cmFastbuildTargetGenerator::GetScriptFilename(
+  std::string const& utilityTargetName) const
+{
+  std::string scriptFileName = Makefile->GetCurrentBinaryDirectory();
+  scriptFileName += "/CMakeFiles/";
+  scriptFileName += utilityTargetName;
+  scriptFileName += FASTBUILD_SCRIPT_FILE_EXTENSION;
+  return scriptFileName;
+}
+
+void cmFastbuildTargetGenerator::AddCommentPrinting(
+  std::vector<std::string>& cmdLines,
+  cmCustomCommandGenerator const& ccg) const
+{
+  std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat(
+    cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
+  auto const comment = ccg.GetComment();
+  if (comment) {
+    // Comment printing should be first. Tested in
+    // RunCMake.ExternalProject:EnvVars-build test.
+    cmdLines.insert(
+      cmdLines.begin(),
+      cmakeCommand.append(" -E echo ")
+        .append(LocalGenerator->EscapeForShell(cmGeneratorExpression::Evaluate(
+          *comment, this->LocalGenerator, Config))));
+  }
+}
+
+std::string cmFastbuildTargetGenerator::GetCdCommand(
+  cmCustomCommandGenerator const& ccg) const
+{
+  return cmStrCat(FASTBUILD_SCRIPT_CD,
+                  this->LocalGenerator->ConvertToOutputFormat(
+                    GetScriptWorkingDir(ccg), cmOutputConverter::SHELL));
+}
+
+void cmFastbuildTargetGenerator::WriteCmdsToFile(
+  cmsys::ofstream& file, std::vector<std::string> const& cmds) const
+{
+#ifdef _WIN32
+  int line = 1;
+  for (auto cmd : cmds) {
+    // On Windows batch, '%' is a special character that needs to be
+    // doubled to be escaped
+    cmSystemTools::ReplaceString(cmd, "%", "%%");
+    file << cmd << " || (set FAIL_LINE=" << ++line << "& goto :ABORT)" << '\n';
+#else
+  for (auto const& cmd : cmds) {
+    file << cmd << '\n';
+#endif
+  }
+}
+
+void cmFastbuildTargetGenerator::AddOutput(cmCustomCommandGenerator const& ccg,
+                                           FastbuildExecNode& exec)
+{
+  std::string dummyOutput = cmSystemTools::JoinPath(
+    { LocalCommonGenerator->GetMakefile()->GetHomeOutputDirectory(),
+      "/_fbuild_dummy" });
+  this->GetGlobalGenerator()->AllFoldersToClean.insert(dummyOutput);
+
+  dummyOutput.append("/").append(exec.Name).append(
+    FASTBUILD_DUMMY_OUTPUT_EXTENSION);
+
+  std::vector<std::string> const& outputs = ccg.GetOutputs();
+  std::vector<std::string> const& byproducts = ccg.GetByproducts();
+
+  exec.OutputsAlias.Name = exec.Name + FASTBUILD_OUTPUTS_ALIAS_POSTFIX;
+  // If CC doesn't have any output - we should always run it.
+  // Tested in "RunCMake.CMakePresetsBuild" test.
+  bool hasAnyNonSymbolicOutput = false;
+
+  bool const trackByproducts =
+    this->Makefile->IsDefinitionSet(FASTBUILD_TRACK_BYPRODUCTS_AS_OUTPUT);
+
+  auto const isSymbolic = [this](std::string const& file) {
+    cmSourceFile* sf = this->Makefile->GetSource(file);
+    if (sf && sf->GetPropertyAsBool("SYMBOLIC")) {
+      LogMessage("Skipping symbolic file: " + file);
+      return true;
+    }
+    return false;
+  };
+
+  for (std::string const& output : outputs) {
+    // Tested in "RunCMake.BuildDepends".
+    if (isSymbolic(output)) {
+      continue;
+    }
+    hasAnyNonSymbolicOutput = true;
+    std::string const outputPath = this->ConvertToFastbuildPath(output);
+    LogMessage("CC's output: " + outputPath);
+    exec.OutputsAlias.PreBuildDependencies.emplace(outputPath);
+    // Ensure output path exists. For some reason, "CMake -E touch" fails with
+    // "cmake -E touch: failed to update "...
+    cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(outputPath));
+    this->GetGlobalGenerator()->AddFileToClean(outputPath);
+  }
+
+  exec.ByproductsAlias.Name = exec.Name + FASTBUILD_BYPRODUCTS_ALIAS_POSTFIX;
+  for (std::string const& byproduct : byproducts) {
+    if (trackByproducts) {
+      hasAnyNonSymbolicOutput = true;
+    }
+    std::string const byproductPath = this->ConvertToFastbuildPath(byproduct);
+    exec.ByproductsAlias.PreBuildDependencies.emplace(byproductPath);
+    this->GetGlobalGenerator()->AddFileToClean(byproductPath);
+  }
+
+  auto const addDummyOutput = [&] {
+    // So that the dummy file is always created.
+    exec.ExecUseStdOutAsOutput = true;
+    exec.ExecOutput = this->ConvertToFastbuildPath(dummyOutput);
+    for (auto const& output : exec.OutputsAlias.PreBuildDependencies) {
+      OutputsToReplace[output.Name] = exec.ExecOutput;
+      LogMessage("Adding replace from " + output.Name + " to " +
+                 exec.ExecOutput);
+    }
+  };
+
+  // We don't have any output that is expected to appear on disk -> run always.
+  // Tested in "RunCMake.ExternalProject":BUILD_ALWAYS
+  if (!hasAnyNonSymbolicOutput) {
+    exec.ExecAlways = true;
+    addDummyOutput();
+    return;
+  }
+
+  if (!exec.OutputsAlias.PreBuildDependencies.empty()) {
+    exec.ExecOutput = this->ConvertToFastbuildPath(
+      exec.OutputsAlias.PreBuildDependencies.begin()->Name);
+  } else {
+    exec.ExecOutput = this->ConvertToFastbuildPath(
+      exec.ByproductsAlias.PreBuildDependencies.begin()->Name);
+  }
+
+  // Optionally add the "deps-check" Exec if we have more than 1 OUTPUT, but
+  // allow user to opt out.
+  if (exec.OutputsAlias.PreBuildDependencies.size() > 1 &&
+      !this->Makefile->IsDefinitionSet(
+        FASTBUILD_DISABLE_OUTPUT_PRECHECK_EXEC)) {
+    exec.NeedsDepsCheckExec = true;
+  }
+}
+
+void cmFastbuildTargetGenerator::AddExecArguments(
+  FastbuildExecNode& exec, std::string const& scriptFilename) const
+{
+  exec.ExecArguments = FASTBUILD_SCRIPT_FILE_ARG;
+  exec.ExecArguments +=
+    cmGlobalFastbuildGenerator::QuoteIfHasSpaces(scriptFilename);
+
+  exec.ScriptFile = scriptFilename;
+  exec.ExecExecutable =
+    cmGlobalFastbuildGenerator::GetExternalShellExecutable();
+}
+
+void cmFastbuildTargetGenerator::GetDepends(
+  cmCustomCommandGenerator const& ccg, std::string const& currentCCName,
+  std::vector<std::string>& fileLevelDeps,
+  std::set<FastbuildTargetDep>& targetDep) const
+{
+  for (auto dep : ccg.GetDepends()) {
+    LogMessage("Dep: " + dep);
+    auto orig = dep;
+    if (this->LocalCommonGenerator->GetRealDependency(dep, Config, dep)) {
+      LogMessage("Real dep: " + dep);
+      if (!dep.empty()) {
+        LogMessage("Custom command real dep: " + dep);
+        for (auto const& item : cmList{ cmGeneratorExpression::Evaluate(
+               this->ConvertToFastbuildPath(dep), this->LocalGenerator,
+               Config) }) {
+          fileLevelDeps.emplace_back(item);
+        }
+      }
+    }
+    dep = this->ConvertToFastbuildPath(dep);
+    LogMessage("Real dep converted: " + dep);
+
+    auto const targetInfo = this->LocalGenerator->GetSourcesWithOutput(dep);
+    if (targetInfo.Target) {
+      LogMessage("dep: " + dep + ", target: " + targetInfo.Target->GetName());
+      auto const& target = targetInfo.Target;
+      auto const processCCs = [this, &currentCCName, &targetDep,
+                               dep](std::vector<cmCustomCommand> const& ccs,
+                                    FastbuildBuildStep step) {
+        for (auto const& cc : ccs) {
+          for (auto const& output : cc.GetOutputs()) {
+            LogMessage("dep: " + dep + ", post output: " +
+                       this->ConvertToFastbuildPath(output));
+            if (this->ConvertToFastbuildPath(output) == dep) {
+              auto ccName = this->GetCustomCommandTargetName(cc, step);
+              if (ccName != currentCCName) {
+                LogMessage("Additional CC dep from target: " + ccName);
+                targetDep.emplace(std::move(ccName));
+              }
+            }
+          }
+          for (auto const& byproduct : cc.GetByproducts()) {
+            LogMessage("dep: " + dep + ", post byproduct: " +
+                       this->ConvertToFastbuildPath(byproduct));
+            if (this->ConvertToFastbuildPath(byproduct) == dep) {
+              auto ccName = this->GetCustomCommandTargetName(cc, step);
+              if (ccName != currentCCName) {
+                LogMessage("Additional CC dep from target: " + ccName);
+                targetDep.emplace(std::move(ccName));
+              }
+            }
+          }
+        }
+      };
+      processCCs(target->GetPreBuildCommands(), FastbuildBuildStep::PRE_BUILD);
+      processCCs(target->GetPreLinkCommands(), FastbuildBuildStep::PRE_LINK);
+      processCCs(target->GetPostBuildCommands(),
+                 FastbuildBuildStep::POST_BUILD);
+      continue;
+    }
+    if (!targetInfo.Source) {
+      LogMessage("dep: " + dep + ", no source, byproduct: " +
+                 std::to_string(targetInfo.SourceIsByproduct));
+      // Tested in "OutDir" test.
+      if (!cmSystemTools::FileIsFullPath(orig)) {
+        targetDep.emplace(std::move(orig));
+      }
+      continue;
+    }
+    if (!targetInfo.Source->GetCustomCommand()) {
+      LogMessage("dep: " + dep + ", no GetCustomCommand");
+      continue;
+    }
+    if (targetInfo.Source && targetInfo.Source->GetCustomCommand()) {
+      auto ccName = this->GetCustomCommandTargetName(
+        *targetInfo.Source->GetCustomCommand(), FastbuildBuildStep::REST);
+      if (ccName != currentCCName) {
+        LogMessage("Additional CC dep: " + ccName);
+        targetDep.emplace(std::move(ccName));
+      }
+    }
+  }
+}
+
+void cmFastbuildTargetGenerator::ReplaceProblematicMakeVars(
+  std::string& command) const
+{
+  // TODO: fix problematic global targets.  For now, search and replace the
+  // makefile vars.
+  cmSystemTools::ReplaceString(
+    command, "$(CMAKE_SOURCE_DIR)",
+    this->LocalGenerator->ConvertToOutputFormat(
+      this->LocalGenerator->GetSourceDirectory(), cmOutputConverter::SHELL));
+  cmSystemTools::ReplaceString(
+    command, "$(CMAKE_BINARY_DIR)",
+    this->LocalGenerator->ConvertToOutputFormat(
+      this->LocalGenerator->GetBinaryDirectory(), cmOutputConverter::SHELL));
+  cmSystemTools::ReplaceString(command, "$(ARGS)", "");
+}
+
+FastbuildExecNode cmFastbuildTargetGenerator::GetAppleTextStubCommand() const
+{
+  FastbuildExecNode res;
+  if (!this->GeneratorTarget->IsApple() ||
+      !this->GeneratorTarget->HasImportLibrary(Config)) {
+    return res;
+  }
+
+  auto const names = DetectOutput();
+  std::string const outpathImp =
+    this->ConvertToFastbuildPath(this->GeneratorTarget->GetDirectory(
+      Config, cmStateEnums::ImportLibraryArtifact));
+
+  std::string const binPath =
+    this->ConvertToFastbuildPath(this->GeneratorTarget->GetDirectory(
+      Config, cmStateEnums::RuntimeBinaryArtifact));
+
+  cmSystemTools::MakeDirectory(outpathImp);
+
+  std::string rule = this->LocalGenerator->GetMakefile()->GetSafeDefinition(
+    "CMAKE_CREATE_TEXT_STUBS");
+  LogMessage("CMAKE_CREATE_TEXT_STUBS:" + rule);
+
+  auto rulePlaceholderExpander =
+    this->GetLocalGenerator()->CreateRulePlaceholderExpander();
+
+  cmRulePlaceholderExpander::RuleVariables vars;
+  res.ExecOutput = cmStrCat(outpathImp, '/', names.ImportReal);
+  res.ExecInput = { cmStrCat(binPath, '/', names.SharedObject) };
+
+  vars.Target = res.ExecInput[0].c_str();
+  rulePlaceholderExpander->SetTargetImpLib(res.ExecOutput);
+  rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), rule,
+                                               vars);
+
+  LogMessage("CMAKE_CREATE_TEXT_STUBS expanded:" + rule);
+  std::string executable;
+  std::string args;
+  if (!cmSystemTools::SplitProgramFromArgs(rule, executable, args)) {
+    cmSystemTools::Error("Failed to split program from args: " + rule);
+    return res;
+  }
+
+  res.Name = "create_" + names.ImportOutput + "_text_stub";
+  res.ExecExecutable = std::move(executable);
+  res.ExecArguments = std::move(args);
+  res.ExecWorkingDir = this->LocalCommonGenerator->GetCurrentBinaryDirectory();
+
+  // Wait for the build.
+  res.PreBuildDependencies.emplace(this->GetTargetName());
+  return res;
+}
+FastbuildExecNode cmFastbuildTargetGenerator::GetDepsCheckExec(
+  FastbuildExecNode const& depender)
+{
+  FastbuildExecNode exec;
+  exec.Name = depender.Name + "-check-depends";
+  exec.ExecAlways = true;
+  exec.ExecUseStdOutAsOutput = true;
+  exec.ExecOutput = depender.ExecOutput + ".deps-checker";
+  exec.ExecExecutable = cmSystemTools::GetCMakeCommand();
+  exec.ExecArguments += "-E cmake_fastbuild_check_depends ";
+  exec.ExecArguments += depender.ExecOutput + " ";
+  char const* sep = "";
+  for (auto const& dep : depender.OutputsAlias.PreBuildDependencies) {
+    exec.ExecArguments += sep;
+    exec.ExecArguments += dep.Name;
+    sep = " ";
+  }
+  for (auto const& dep : depender.ByproductsAlias.PreBuildDependencies) {
+    exec.ExecArguments += sep;
+    exec.ExecArguments += dep.Name;
+    sep = " ";
+  }
+  return exec;
+}
+
+FastbuildExecNodes cmFastbuildTargetGenerator::GenerateCommands(
+  FastbuildBuildStep buildStep)
+{
+  FastbuildExecNodes execs;
+  execs.Alias.Name = GetUtilityAliasFromBuildStep(buildStep);
+
+  std::vector<cmCustomCommand> commands;
+  if (buildStep == FastbuildBuildStep::PRE_BUILD) {
+    commands = GeneratorTarget->GetPreBuildCommands();
+    LogMessage("STEP: PRE_BUILD");
+  } else if (buildStep == FastbuildBuildStep::PRE_LINK) {
+    commands = GeneratorTarget->GetPreLinkCommands();
+    LogMessage("STEP: PRE_LINK");
+  } else if (buildStep == FastbuildBuildStep::POST_BUILD) {
+    commands = GeneratorTarget->GetPostBuildCommands();
+    LogMessage("STEP: POST_BUILD");
+  } else {
+    LogMessage("STEP: ALL CUSTOM COMMANDS");
+    std::vector<cmSourceFile const*> customCommands;
+    GeneratorTarget->GetCustomCommands(customCommands, Config);
+    for (cmSourceFile const* source : customCommands) {
+      cmCustomCommand const* cmd = source->GetCustomCommand();
+      if (!cmd->GetCommandLines().empty()) {
+        commands.emplace_back(*cmd);
+      }
+    }
+  }
+  LogMessage(cmStrCat("Number of custom commands: ", commands.size()));
+  for (cmCustomCommand const& customCommand : commands) {
+    cmCustomCommandGenerator ccg(customCommand, Config, LocalCommonGenerator);
+    std::string launcher = this->MakeCustomLauncher(ccg);
+
+    std::string const execName =
+      GetCustomCommandTargetName(customCommand, buildStep);
+
+    std::vector<std::string> cmdLines;
+    if (ccg.GetNumberOfCommands() > 0) {
+      cmdLines.push_back(GetCdCommand(ccg));
+    }
+
+    // Since we are not using FASTBuild Exec nodes natively, we need to
+    // have shell specific escape.
+    this->LocalGenerator->GetState()->SetFastbuildMake(false);
+    // To avoid replacing $ with $$ in the command line.
+    this->LocalGenerator->SetLinkScriptShell(true);
+    for (unsigned j = 0; j != ccg.GetNumberOfCommands(); ++j) {
+      std::string const command = ccg.GetCommand(j);
+      // Tested in "CustomCommand" ("empty_command") test.
+      if (!command.empty()) {
+
+        cmdLines.emplace_back(launcher +
+                              this->LocalGenerator->ConvertToOutputFormat(
+                                command, cmOutputConverter::SHELL));
+
+        std::string& cmd = cmdLines.back();
+        ccg.AppendArguments(j, cmd);
+        ReplaceProblematicMakeVars(cmd);
+        LogMessage("cmCustomCommandLine: " + cmd);
+      }
+    }
+    if (cmdLines.empty()) {
+      return {};
+    }
+    this->LocalGenerator->GetState()->SetFastbuildMake(true);
+
+    FastbuildExecNode execNode;
+    execNode.Name = execName;
+
+    // Add depncencies to "ExecInput" so that FASTBuild will re-run the Exec
+    // when needed, but also add to "PreBuildDependencies" for correct sorting.
+    // Tested in "ObjectLibrary / complexOneConfig" tests.
+    GetDepends(ccg, execName, execNode.ExecInput,
+               execNode.PreBuildDependencies);
+    for (auto const& util : ccg.GetUtilities()) {
+      auto const& utilTargetName = util.Value.first;
+      LogMessage("Util: " + utilTargetName +
+                 ", cross: " + std::to_string(util.Value.second));
+      auto* const target = this->Makefile->FindTargetToUse(utilTargetName);
+
+      if (target && target->IsImported()) {
+        std::string importedLoc =
+          this->ConvertToFastbuildPath(target->ImportedGetFullPath(
+            Config, cmStateEnums::ArtifactType::RuntimeBinaryArtifact));
+        if (importedLoc.empty()) {
+          importedLoc =
+            this->ConvertToFastbuildPath(target->ImportedGetFullPath(
+              Config, cmStateEnums::ArtifactType::ImportLibraryArtifact));
+        }
+        LogMessage("adding file level dep on imported target: " + importedLoc);
+        execNode.ExecInput.emplace_back(std::move(importedLoc));
+        continue;
+      }
+      // This CC uses some executable produced by another target. Add explicit
+      // dep. Tested in "CustomCommand" test.
+      if (util.Value.second) {
+        if (utilTargetName != customCommand.GetTarget()) {
+          LogMessage("Adding util dep: " + utilTargetName);
+          execNode.PreBuildDependencies.emplace(utilTargetName);
+        }
+      }
+    }
+
+    execs.Alias.PreBuildDependencies.emplace(execNode.Name);
+
+    LogMessage(cmStrCat("cmdLines size ", cmdLines.size()));
+
+    if (!cmdLines.empty()) {
+      std::string const scriptFileName = GetScriptFilename(execName);
+      cmsys::ofstream scriptFile(scriptFileName.c_str());
+
+      AddOutput(ccg, execNode);
+      AddExecArguments(execNode, scriptFileName);
+      AddCommentPrinting(cmdLines, ccg);
+
+      WriteScriptProlog(scriptFile);
+      WriteCmdsToFile(scriptFile, cmdLines);
+      WriteScriptEpilog(scriptFile);
+    }
+
+    if (buildStep == FastbuildBuildStep::POST_BUILD) {
+      // Execute POST_BUILD in order in which they are declared.
+      // Tested in "complex" test.
+      for (auto& exec : execs.Nodes) {
+        execNode.PreBuildDependencies.emplace(exec.Name);
+      }
+    }
+    for (auto const& out : execNode.OutputsAlias.PreBuildDependencies) {
+      LogMessage("Adding replace from " + out.Name + " to " + execName);
+      OutputToExecName[out.Name] = execName;
+    }
+    execs.Nodes.emplace_back(std::move(execNode));
+  }
+  for (auto& exec : execs.Nodes) {
+    for (auto& inputFile : exec.ExecInput) {
+      auto const iter = OutputsToReplace.find(inputFile);
+      if (iter != OutputsToReplace.end()) {
+        LogMessage("Replacing input: " + inputFile + " with " + iter->second);
+        inputFile = iter->second;
+      }
+      auto const depIter = std::find_if(
+        exec.PreBuildDependencies.begin(), exec.PreBuildDependencies.end(),
+        [this](FastbuildTargetDep const& dep) {
+          return !OutputToExecName[dep.Name].empty();
+        });
+      if (depIter != exec.PreBuildDependencies.end()) {
+        LogMessage("Replacing dep " + depIter->Name + " with " +
+                   OutputToExecName[depIter->Name]);
+        exec.PreBuildDependencies.emplace(OutputToExecName[depIter->Name]);
+        exec.PreBuildDependencies.erase(depIter);
+      }
+    }
+    if (exec.NeedsDepsCheckExec) {
+      auto depsCheckExec = GetDepsCheckExec(exec);
+      LogMessage("Adding deps check Exec: " + depsCheckExec.Name);
+      exec.PreBuildDependencies.emplace(depsCheckExec.Name);
+      this->GetGlobalGenerator()->AddTarget(std::move(depsCheckExec));
+    }
+  }
+  return execs;
+}
+
+std::string cmFastbuildTargetGenerator::MakeCustomLauncher(
+  cmCustomCommandGenerator const& ccg)
+{
+  // Copied from cmLocalNinjaGenerator::MakeCustomLauncher.
+  cmValue property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
+
+  if (!cmNonempty(property_value)) {
+    return std::string();
+  }
+
+  // Expand rule variables referenced in the given launcher command.
+  cmRulePlaceholderExpander::RuleVariables vars;
+
+  std::string output;
+  std::vector<std::string> const& outputs = ccg.GetOutputs();
+  for (size_t i = 0; i < outputs.size(); ++i) {
+    output =
+      cmStrCat(output,
+               this->LocalGenerator->ConvertToOutputFormat(
+                 ccg.GetWorkingDirectory().empty()
+                   ? this->LocalGenerator->MaybeRelativeToCurBinDir(outputs[i])
+                   : outputs[i],
+                 cmOutputConverter::SHELL));
+    if (i != outputs.size() - 1) {
+      output = cmStrCat(output, ',');
+    }
+  }
+  vars.Output = output.c_str();
+  vars.Role = ccg.GetCC().GetRole().c_str();
+  vars.CMTargetName = ccg.GetCC().GetTarget().c_str();
+  vars.Config = ccg.GetOutputConfig().c_str();
+
+  auto rulePlaceholderExpander =
+    this->LocalGenerator->CreateRulePlaceholderExpander();
+
+  std::string launcher = *property_value;
+  rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator, launcher,
+                                               vars);
+  if (!launcher.empty()) {
+    launcher += " ";
+  }
+
+  LogMessage("CC Launcher: " + launcher);
+  return launcher;
+}
+
+std::string cmFastbuildTargetGenerator::GetTargetName() const
+{
+  if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
+    return this->GetGlobalGenerator()->GetTargetName(GeneratorTarget);
+  }
+  return this->GeneratorTarget->GetName();
+}
+
+cmGeneratorTarget::Names cmFastbuildTargetGenerator::DetectOutput() const
+{
+  if (GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+    return GeneratorTarget->GetExecutableNames(Config);
+  }
+  return GeneratorTarget->GetLibraryNames(Config);
+}
+
+void cmFastbuildTargetGenerator::AddObjectDependencies(
+  FastbuildTarget& fastbuildTarget,
+  std::vector<std::string>& allObjectDepends) const
+{
+  auto const FindObjListWhichOutputs = [&fastbuildTarget](
+                                         std::string const& output) {
+    for (FastbuildObjectListNode const& objList :
+         fastbuildTarget.ObjectListNodes) {
+      if (objList.ObjectOutputs.find(output) != objList.ObjectOutputs.end()) {
+        return objList.Name;
+      }
+    }
+    return std::string{};
+  };
+
+  for (FastbuildObjectListNode& objList : fastbuildTarget.ObjectListNodes) {
+    for (auto const& objDep : objList.ObjectDepends) {
+      // Check if there is another object list which outputs (OBJECT_OUTPUTS)
+      // something that this object list needs (OBJECT_DEPENDS).
+      auto anotherObjList = FindObjListWhichOutputs(objDep);
+      if (!anotherObjList.empty()) {
+        LogMessage("Adding explicit <OBJECT_DEPENDS> dep: " + anotherObjList);
+        allObjectDepends.emplace_back(anotherObjList);
+        objList.PreBuildDependencies.emplace(std::move(anotherObjList));
+
+      } else {
+        LogMessage("Adding <OBJECT_DEPENDS> dep: " + objDep);
+        allObjectDepends.emplace_back(objDep);
+        objList.PreBuildDependencies.emplace(objDep);
+      }
+    }
+  }
+  cmGlobalFastbuildGenerator::TopologicalSort(fastbuildTarget.ObjectListNodes);
+}
+
+void cmFastbuildTargetGenerator::AddLinkerNodeDependencies(
+  FastbuildTarget& fastbuildTarget)
+{
+  for (auto& linkerNode : fastbuildTarget.LinkerNode) {
+    if (!fastbuildTarget.PreLinkExecNodes.Nodes.empty()) {
+      linkerNode.PreBuildDependencies.emplace(
+        fastbuildTarget.Name + FASTBUILD_PRE_LINK_ALIAS_POSTFIX);
+    }
+  }
+}
+
+std::string cmFastbuildTargetGenerator::GetClangTidyReplacementsFilePath(
+  std::string const& directory, cmSourceFile const& source,
+  std::string const& /*config*/) const
+{
+
+  std::string objectDir =
+    this->ConvertToFastbuildPath(this->GeneratorTarget->GetSupportDirectory());
+  std::string const& objectName =
+    this->GeneratorTarget->GetObjectName(&source);
+  std::string path =
+    cmStrCat(directory, '/', objectDir, '/', objectName, ".yaml");
+  LogMessage("ClangTidy replacements file: " + path);
+  return path;
+}
+
+void cmFastbuildTargetGenerator::AddIncludeFlags(std::string& languageFlags,
+                                                 std::string const& language,
+                                                 std::string const&)
+{
+  std::vector<std::string> includes;
+  this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
+                                              language, Config);
+  // Add include directory flags.
+  std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
+    includes, this->GeneratorTarget, language, Config, false);
+
+  this->LocalGenerator->AppendFlags(languageFlags, includeFlags);
+}
+
+std::string cmFastbuildTargetGenerator::GetName()
+{
+  return GeneratorTarget->GetName();
+}
+
+std::string cmFastbuildTargetGenerator::ConvertToFastbuildPath(
+  std::string const& path) const
+{
+  return GetGlobalGenerator()->ConvertToFastbuildPath(path);
+}
+
+cmGlobalFastbuildGenerator* cmFastbuildTargetGenerator::GetGlobalGenerator()
+  const
+{
+  return this->LocalGenerator->GetGlobalFastbuildGenerator();
+}
+
+void cmFastbuildTargetGenerator::AdditionalCleanFiles()
+{
+  if (cmValue prop_value =
+        this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
+    auto* lg = this->LocalGenerator;
+    cmList cleanFiles(cmGeneratorExpression::Evaluate(*prop_value, lg, Config,
+                                                      this->GeneratorTarget));
+    std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
+    auto* gg = lg->GetGlobalFastbuildGenerator();
+    for (auto const& cleanFile : cleanFiles) {
+      // Support relative paths
+      gg->AddFileToClean(gg->ConvertToFastbuildPath(
+        cmSystemTools::CollapseFullPath(cleanFile, binaryDir)));
+    }
+  }
+}
diff --git a/Source/cmFastbuildTargetGenerator.h b/Source/cmFastbuildTargetGenerator.h
new file mode 100644
index 0000000..f6f9697
--- /dev/null
+++ b/Source/cmFastbuildTargetGenerator.h
@@ -0,0 +1,156 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <memory>
+#include <set>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmCommonTargetGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalFastbuildGenerator.h"
+#include "cmGlobalGenerator.h"
+#include "cmOSXBundleGenerator.h"
+
+class cmCustomCommand;
+class cmCustomCommandGenerator;
+class cmLocalFastbuildGenerator;
+class cmMakefile;
+
+enum class FastbuildBuildStep
+{
+  PRE_BUILD,
+  PRE_LINK,
+  POST_BUILD,
+  REST,
+};
+
+class cmFastbuildTargetGenerator : public cmCommonTargetGenerator
+{
+public:
+  /// Create a cmFastbuildTargetGenerator according to the @a target's type and
+  /// config.
+  static cmFastbuildTargetGenerator* New(cmGeneratorTarget* target,
+                                         std::string config);
+
+  cmFastbuildTargetGenerator(cmGeneratorTarget* target, std::string config);
+
+  virtual void Generate() {}
+
+  std::string GetClangTidyReplacementsFilePath(
+    std::string const& directory, cmSourceFile const& source,
+    std::string const& Config) const override;
+
+  void AddIncludeFlags(std::string& languageFlags, std::string const& language,
+                       std::string const&) override;
+
+  cmGeneratorTarget::Names DetectOutput() const;
+
+  void AddObjectDependencies(FastbuildTarget& fastbuildTarget,
+                             std::vector<std::string>& allObjectDepends) const;
+  void AddLinkerNodeDependencies(FastbuildTarget& fastbuildTarget);
+
+  std::string ConvertToFastbuildPath(std::string const& path) const;
+
+  cmGlobalFastbuildGenerator* GetGlobalGenerator() const;
+
+  std::string GetName();
+
+  cmMakefile* GetMakefile() const { return this->Makefile; }
+
+  cmGeneratorTarget* GetGeneratorTarget() const
+  {
+    return this->GeneratorTarget;
+  }
+
+  void LogMessage(std::string const& m) const;
+
+private:
+  std::string GetUtilityAliasFromBuildStep(FastbuildBuildStep step) const;
+
+protected:
+  cmLocalFastbuildGenerator* GetLocalGenerator() const
+  {
+    return this->LocalGenerator;
+  }
+
+  std::string GetTargetName() const;
+  std::string GetCdCommand(cmCustomCommandGenerator const& ccg) const;
+  std::string GetScriptWorkingDir(cmCustomCommandGenerator const& ccg) const;
+  std::string GetScriptFilename(std::string const& utilityTargetName) const;
+  void GetDepends(cmCustomCommandGenerator const& ccg,
+                  std::string const& currentCCName,
+                  std::vector<std::string>& fileLevelDeps,
+                  std::set<FastbuildTargetDep>& targetDep) const;
+
+  void AddCommentPrinting(std::vector<std::string>& cmdLines,
+                          cmCustomCommandGenerator const& ccg) const;
+
+  void WriteCmdsToFile(cmsys::ofstream& file,
+                       std::vector<std::string> const& cmds) const;
+
+  void AddOutput(cmCustomCommandGenerator const& ccg, FastbuildExecNode& exec);
+
+  void AddExecArguments(FastbuildExecNode& exec,
+                        std::string const& scriptFilename) const;
+
+  void ReplaceProblematicMakeVars(std::string& command) const;
+
+  FastbuildExecNodes GenerateCommands(FastbuildBuildStep buildStep);
+  FastbuildExecNode GetAppleTextStubCommand() const;
+  FastbuildExecNode GetDepsCheckExec(FastbuildExecNode const& depender);
+
+  std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
+
+  std::string GetCustomCommandTargetName(cmCustomCommand const& cc,
+                                         FastbuildBuildStep step) const;
+
+  void WriteScriptProlog(cmsys::ofstream& file) const;
+  void WriteScriptEpilog(cmsys::ofstream& file) const;
+
+  void AdditionalCleanFiles();
+
+  // write rules for Mac OS X Application Bundle content.
+  struct MacOSXContentGeneratorType
+    : cmOSXBundleGenerator::MacOSXContentGeneratorType
+  {
+    MacOSXContentGeneratorType(cmFastbuildTargetGenerator* g, std::string cfg)
+      : Generator(g)
+      , Config(std::move(cfg))
+    {
+    }
+
+    void operator()(cmSourceFile const& source, char const* pkgloc,
+                    std::string const& config) override;
+
+  private:
+    cmFastbuildTargetGenerator* Generator;
+    std::string const Config;
+  };
+  friend struct MacOSXContentGeneratorType;
+
+  // "MacOSXContentGenerator" has to be per-config once multiconfig generator
+  // is implemented.
+  std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
+  std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
+  std::set<std::string> MacContentFolders;
+
+  std::vector<FastbuildCopyNode> CopyNodes;
+
+  cmLocalFastbuildGenerator* LocalGenerator;
+  cmGlobalGenerator::TargetDependSet const TargetDirectDependencies;
+  std::string const Config;
+
+  // Sometimes CMake adds equivalent custom commands to different targets.
+  // Not really supported by FBuild (can't have different exec nodes producing
+  // same output). So, in such cases we need to "re-map" the exec to produce a
+  // "dummy" output (and update all deps within the target).
+  // TODO: potentially 1 map should be enough?
+  std::unordered_map<std::string, std::string> OutputsToReplace;
+  std::unordered_map<std::string, std::string> OutputToExecName;
+};
diff --git a/Source/cmFastbuildUtilityTargetGenerator.cxx b/Source/cmFastbuildUtilityTargetGenerator.cxx
new file mode 100644
index 0000000..1936f7f
--- /dev/null
+++ b/Source/cmFastbuildUtilityTargetGenerator.cxx
@@ -0,0 +1,126 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+
+#include "cmFastbuildUtilityTargetGenerator.h"
+
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
+#include "cmFastbuildTargetGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalFastbuildGenerator.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmStateTypes.h"
+#include "cmTarget.h"
+#include "cmTargetDepend.h"
+
+cmFastbuildUtilityTargetGenerator::cmFastbuildUtilityTargetGenerator(
+  cmGeneratorTarget* gt, std::string configParam)
+  : cmFastbuildTargetGenerator(gt, std::move(configParam))
+{
+}
+
+void cmFastbuildUtilityTargetGenerator::Generate()
+{
+  std::string targetName = GeneratorTarget->GetName();
+
+  if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
+    targetName = GetGlobalGenerator()->GetTargetName(GeneratorTarget);
+  }
+
+  FastbuildAliasNode fastbuildTarget;
+  fastbuildTarget.Name = targetName;
+
+  LogMessage("<-------------->");
+  LogMessage("Generate Utility target: " + targetName);
+  LogMessage("Config: " + Config);
+  for (auto const& dep : TargetDirectDependencies) {
+    LogMessage("Dep: " + dep->GetName());
+  }
+
+  std::vector<std::string> nonImportedUtils;
+  for (BT<std::pair<std::string, bool>> const& util :
+       this->GeneratorTarget->GetUtilities()) {
+    if (util.Value.first == targetName) {
+      continue;
+    }
+    auto const& utilTargetName =
+      this->ConvertToFastbuildPath(util.Value.first);
+    LogMessage("Util: " + utilTargetName);
+    auto* const target = this->Makefile->FindTargetToUse(utilTargetName);
+    if (target && target->IsImported()) {
+      LogMessage("Skipping imported util target: " + utilTargetName);
+      continue;
+    }
+    // Since interface target don't appear in the generated build files,
+    // transitively propagate their deps (if any).
+    // Tested in "ExternalProjectSubdir" test.
+    if (target && target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      for (auto const& dep : target->GetUtilities()) {
+        auto const& depName = this->ConvertToFastbuildPath(dep.Value.first);
+        LogMessage("Transitively propagating iface dep: " + depName +
+                   ", is cross: " + std::to_string(dep.Value.second));
+        nonImportedUtils.emplace_back(depName);
+        fastbuildTarget.PreBuildDependencies.emplace(
+          this->ConvertToFastbuildPath(depName));
+      }
+    } else {
+      nonImportedUtils.emplace_back(utilTargetName);
+      fastbuildTarget.PreBuildDependencies.emplace(utilTargetName);
+    }
+  }
+  if (this->GetGlobalGenerator()->IsExcluded(this->GetGeneratorTarget())) {
+    LogMessage("Excluding " + targetName + " from ALL");
+    fastbuildTarget.ExcludeFromAll = true;
+  }
+  auto preBuild = GenerateCommands(FastbuildBuildStep::PRE_BUILD);
+
+  // Tested in "RunCMake.CPack*" tests.
+  // Utility target "package" has packaging steps as "POST_BUILD".
+  for (auto& exec : GenerateCommands(FastbuildBuildStep::POST_BUILD).Nodes) {
+    fastbuildTarget.PreBuildDependencies.emplace(exec.Name);
+    for (std::string const& util : nonImportedUtils) {
+      LogMessage("Adding: util " + util);
+      exec.PreBuildDependencies.emplace(util);
+    }
+    // So POST_BUILD is executed AFTER PRE_BUILD (tested in "CustomCommand"
+    // test).
+    for (auto const& pre : preBuild.Nodes) {
+      LogMessage("Adding: " + pre.Name);
+      exec.PreBuildDependencies.emplace(pre.Name);
+    }
+    this->GetGlobalGenerator()->AddTarget(std::move(exec));
+  }
+
+  for (auto& exec : preBuild.Nodes) {
+    LogMessage("Adding exec " + exec.Name);
+    fastbuildTarget.PreBuildDependencies.emplace(exec.Name);
+    this->GetGlobalGenerator()->AddTarget(std::move(exec));
+  }
+
+  for (auto& exec : GenerateCommands(FastbuildBuildStep::REST).Nodes) {
+    fastbuildTarget.PreBuildDependencies.emplace(exec.Name);
+    for (auto const& dep : TargetDirectDependencies) {
+      LogMessage("Direct dep " + dep->GetName() +
+                 "-all propagating to CC: " + exec.Name);
+      // All custom commands from within the target must be executed AFTER all
+      // the target's deps.
+      exec.PreBuildDependencies.emplace(dep->GetName());
+    }
+    this->GetGlobalGenerator()->AddTarget(std::move(exec));
+  }
+  if (fastbuildTarget.PreBuildDependencies.empty()) {
+    if (fastbuildTarget.ExcludeFromAll) {
+      return;
+    }
+    fastbuildTarget.PreBuildDependencies.emplace(FASTBUILD_NOOP_FILE_NAME);
+  }
+  fastbuildTarget.Hidden = false;
+  this->AdditionalCleanFiles();
+  this->GetGlobalGenerator()->AddTarget(std::move(fastbuildTarget));
+}
diff --git a/Source/cmFastbuildUtilityTargetGenerator.h b/Source/cmFastbuildUtilityTargetGenerator.h
new file mode 100644
index 0000000..257dee3
--- /dev/null
+++ b/Source/cmFastbuildUtilityTargetGenerator.h
@@ -0,0 +1,18 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+
+#include <cmFastbuildTargetGenerator.h>
+
+class cmGeneratorTarget;
+
+class cmFastbuildUtilityTargetGenerator : public cmFastbuildTargetGenerator
+{
+public:
+  cmFastbuildUtilityTargetGenerator(cmGeneratorTarget* gt,
+                                    std::string configParam);
+
+  void Generate() override;
+};
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index 6795c2f..c2b8042 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -29,6 +29,20 @@
 #include "cmTimestamp.h"
 #include "cmake.h"
 
+#if defined(__clang__) && defined(__has_warning)
+#  if __has_warning("-Wrange-loop-analysis")
+#    if defined(__apple_build_version__)
+#      if __apple_build_version__ < 13000000
+#        define CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#      endif
+#    else
+#      if __clang_major__ < 11
+#        define CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#      endif
+#    endif
+#  endif
+#endif
+
 cmFileAPI::cmFileAPI(cmake* cm)
   : CMakeInstance(cm)
 {
@@ -86,11 +100,18 @@
   }
 }
 
-std::vector<unsigned long> cmFileAPI::GetConfigureLogVersions()
+std::vector<unsigned int> cmFileAPI::GetConfigureLogVersions()
 {
-  std::vector<unsigned long> versions;
+  std::vector<unsigned int> versions;
   auto getConfigureLogVersions = [&versions](Query const& q) {
-    for (Object const& o : q.Known) {
+#ifdef CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#  pragma clang diagnostic push
+#  pragma clang diagnostic ignored "-Wrange-loop-analysis"
+#endif
+    for (Object const o : q.Known) {
+#ifdef CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#  pragma clang diagnostic pop
+#endif
       if (o.Kind == ObjectKind::ConfigureLog) {
         versions.emplace_back(o.Version);
       }
@@ -127,7 +148,7 @@
   std::vector<std::string> files;
   cmsys::Directory d;
   d.Load(dir);
-  for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
+  for (unsigned int i = 0; i < d.GetNumberOfFiles(); ++i) {
     std::string f = d.GetFile(i);
     if (f != "." && f != "..") {
       files.push_back(std::move(f));
@@ -447,7 +468,14 @@
 Json::Value cmFileAPI::BuildReply(Query const& q)
 {
   Json::Value reply = Json::objectValue;
-  for (Object const& o : q.Known) {
+#ifdef CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#  pragma clang diagnostic push
+#  pragma clang diagnostic ignored "-Wrange-loop-analysis"
+#endif
+  for (Object const o : q.Known) {
+#ifdef CM_CLANG_SUPPRESS_WARN_RANGE_LOOP_ANALYSIS
+#  pragma clang diagnostic pop
+#endif
     std::string const& name = ObjectName(o);
     reply[name] = this->BuildReplyEntry(o);
   }
@@ -458,7 +486,7 @@
   return reply;
 }
 
-Json::Value cmFileAPI::BuildReplyEntry(Object const& object)
+Json::Value cmFileAPI::BuildReplyEntry(Object object)
 {
   if (this->ReplyIndexFor != IndexFor::Success) {
     switch (object.Kind) {
@@ -482,7 +510,7 @@
   return e;
 }
 
-Json::Value const& cmFileAPI::AddReplyIndexObject(Object const& o)
+Json::Value const& cmFileAPI::AddReplyIndexObject(Object o)
 {
   Json::Value& indexEntry = this->ReplyIndexObjects[o];
   if (!indexEntry.isNull()) {
@@ -516,7 +544,7 @@
   return objectKindNames[static_cast<size_t>(kind)];
 }
 
-std::string cmFileAPI::ObjectName(Object const& o)
+std::string cmFileAPI::ObjectName(Object o)
 {
   std::string name = cmStrCat(ObjectKindName(o.Kind), "-v", o.Version);
   return name;
@@ -530,7 +558,7 @@
   return version;
 }
 
-Json::Value cmFileAPI::BuildObject(Object const& object)
+Json::Value cmFileAPI::BuildObject(Object object)
 {
   Json::Value value;
 
@@ -790,8 +818,10 @@
 
 // The "codemodel" object kind.
 
-// Update Help/manual/cmake-file-api.7.rst when updating this constant.
-static unsigned int const CodeModelV2Minor = 8;
+// Update the following files as well when updating this constant:
+//   Help/manual/cmake-file-api.7.rst
+//   Tests/RunCMake/FileAPI/codemodel-v2-check.py (check_objects())
+static unsigned int const CodeModelV2Minor = 9;
 
 void cmFileAPI::BuildClientRequestCodeModel(
   ClientRequest& r, std::vector<RequestVersion> const& versions)
@@ -808,9 +838,11 @@
   }
 }
 
-Json::Value cmFileAPI::BuildCodeModel(Object const& object)
+Json::Value cmFileAPI::BuildCodeModel(Object object)
 {
-  Json::Value codemodel = cmFileAPICodemodelDump(*this, object.Version);
+  assert(object.Version == 2);
+  Json::Value codemodel =
+    cmFileAPICodemodelDump(*this, object.Version, CodeModelV2Minor);
   codemodel["kind"] = this->ObjectKindName(object.Kind);
 
   Json::Value& version = codemodel["version"];
@@ -843,7 +875,7 @@
   }
 }
 
-Json::Value cmFileAPI::BuildConfigureLog(Object const& object)
+Json::Value cmFileAPI::BuildConfigureLog(Object object)
 {
   Json::Value configureLog = cmFileAPIConfigureLogDump(*this, object.Version);
   configureLog["kind"] = this->ObjectKindName(object.Kind);
@@ -877,7 +909,7 @@
   }
 }
 
-Json::Value cmFileAPI::BuildCache(Object const& object)
+Json::Value cmFileAPI::BuildCache(Object object)
 {
   Json::Value cache = cmFileAPICacheDump(*this, object.Version);
   cache["kind"] = this->ObjectKindName(object.Kind);
@@ -911,7 +943,7 @@
   }
 }
 
-Json::Value cmFileAPI::BuildCMakeFiles(Object const& object)
+Json::Value cmFileAPI::BuildCMakeFiles(Object object)
 {
   Json::Value cmakeFiles = cmFileAPICMakeFilesDump(*this, object.Version);
   cmakeFiles["kind"] = this->ObjectKindName(object.Kind);
@@ -945,7 +977,7 @@
   }
 }
 
-Json::Value cmFileAPI::BuildToolchains(Object const& object)
+Json::Value cmFileAPI::BuildToolchains(Object object)
 {
   Json::Value toolchains = cmFileAPIToolchainsDump(*this, object.Version);
   toolchains["kind"] = this->ObjectKindName(object.Kind);
@@ -981,7 +1013,7 @@
   }
 }
 
-Json::Value cmFileAPI::BuildInternalTest(Object const& object)
+Json::Value cmFileAPI::BuildInternalTest(Object object)
 {
   Json::Value test = Json::objectValue;
   test["kind"] = this->ObjectKindName(object.Kind);
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index 5b639ce..2e25111 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -25,7 +25,7 @@
   void ReadQueries();
 
   /** Get the list of configureLog object kind versions requested.  */
-  std::vector<unsigned long> GetConfigureLogVersions();
+  std::vector<unsigned int> GetConfigureLogVersions();
 
   /** Identify the situation in which WriteReplies is called.  */
   enum class IndexFor
@@ -64,6 +64,9 @@
   bool AddProjectQuery(ObjectKind kind, unsigned majorVersion,
                        unsigned minorVersion);
 
+  /** Build a JSON object with major and minor fields.  */
+  static Json::Value BuildVersion(unsigned int major, unsigned int minor);
+
 private:
   cmake* CMakeInstance;
 
@@ -83,22 +86,19 @@
   struct Object
   {
     ObjectKind Kind;
-    unsigned long Version = 0;
-    friend bool operator<(Object const& l, Object const& r)
+    unsigned int Version = 0;
+    friend bool operator<(Object l, Object r)
     {
       if (l.Kind != r.Kind) {
         return l.Kind < r.Kind;
       }
       return l.Version < r.Version;
     }
-    friend bool operator==(Object const& l, Object const& r)
+    friend bool operator==(Object l, Object r)
     {
       return l.Kind == r.Kind && l.Version == r.Version;
     }
-    friend bool operator!=(Object const& l, Object const& r)
-    {
-      return !(l == r);
-    }
+    friend bool operator!=(Object l, Object r) { return !(l == r); }
   };
 
   /** Represent content of a query directory.  */
@@ -189,16 +189,14 @@
   Json::Value BuildReplyIndex();
   Json::Value BuildCMake();
   Json::Value BuildReply(Query const& q);
-  Json::Value BuildReplyEntry(Object const& object);
+  Json::Value BuildReplyEntry(Object object);
   static Json::Value BuildReplyError(std::string const& error);
-  Json::Value const& AddReplyIndexObject(Object const& o);
+  Json::Value const& AddReplyIndexObject(Object o);
 
   static char const* ObjectKindName(ObjectKind kind);
-  static std::string ObjectName(Object const& o);
+  static std::string ObjectName(Object o);
 
-  static Json::Value BuildVersion(unsigned int major, unsigned int minor);
-
-  Json::Value BuildObject(Object const& object);
+  Json::Value BuildObject(Object object);
 
   ClientRequests BuildClientRequests(Json::Value const& requests);
   ClientRequest BuildClientRequest(Json::Value const& request);
@@ -222,25 +220,25 @@
 
   void BuildClientRequestCodeModel(
     ClientRequest& r, std::vector<RequestVersion> const& versions);
-  Json::Value BuildCodeModel(Object const& object);
+  Json::Value BuildCodeModel(Object object);
 
   void BuildClientRequestConfigureLog(
     ClientRequest& r, std::vector<RequestVersion> const& versions);
-  Json::Value BuildConfigureLog(Object const& object);
+  Json::Value BuildConfigureLog(Object object);
 
   void BuildClientRequestCache(ClientRequest& r,
                                std::vector<RequestVersion> const& versions);
-  Json::Value BuildCache(Object const& object);
+  Json::Value BuildCache(Object object);
 
   void BuildClientRequestCMakeFiles(
     ClientRequest& r, std::vector<RequestVersion> const& versions);
-  Json::Value BuildCMakeFiles(Object const& object);
+  Json::Value BuildCMakeFiles(Object object);
 
   void BuildClientRequestToolchains(
     ClientRequest& r, std::vector<RequestVersion> const& versions);
-  Json::Value BuildToolchains(Object const& object);
+  Json::Value BuildToolchains(Object object);
 
   void BuildClientRequestInternalTest(
     ClientRequest& r, std::vector<RequestVersion> const& versions);
-  Json::Value BuildInternalTest(Object const& object);
+  Json::Value BuildInternalTest(Object object);
 };
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index 68c13e8..2bb2083 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -22,7 +22,7 @@
 class CMakeFiles
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int Version;
   std::string CMakeModules;
   std::string const& TopSource;
   std::string const& TopBuild;
@@ -35,11 +35,11 @@
   Json::Value DumpGlobDependent(cmGlobCacheEntry const& entry);
 
 public:
-  CMakeFiles(cmFileAPI& fileAPI, unsigned long version);
+  CMakeFiles(cmFileAPI& fileAPI, unsigned int version);
   Json::Value Dump();
 };
 
-CMakeFiles::CMakeFiles(cmFileAPI& fileAPI, unsigned long version)
+CMakeFiles::CMakeFiles(cmFileAPI& fileAPI, unsigned int version)
   : FileAPI(fileAPI)
   , Version(version)
   , CMakeModules(cmSystemTools::GetCMakeRoot() + "/Modules")
@@ -150,7 +150,7 @@
 }
 }
 
-Json::Value cmFileAPICMakeFilesDump(cmFileAPI& fileAPI, unsigned long version)
+Json::Value cmFileAPICMakeFilesDump(cmFileAPI& fileAPI, unsigned int version)
 {
   CMakeFiles cmakeFiles(fileAPI, version);
   return cmakeFiles.Dump();
diff --git a/Source/cmFileAPICMakeFiles.h b/Source/cmFileAPICMakeFiles.h
index 06f6ff5..8e15f8e 100644
--- a/Source/cmFileAPICMakeFiles.h
+++ b/Source/cmFileAPICMakeFiles.h
@@ -9,4 +9,4 @@
 class cmFileAPI;
 
 extern Json::Value cmFileAPICMakeFilesDump(cmFileAPI& fileAPI,
-                                           unsigned long version);
+                                           unsigned int version);
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index 74b3aa5..10be5a1 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -19,7 +19,7 @@
 class Cache
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int Version;
   cmState* State;
 
   Json::Value DumpEntries();
@@ -29,11 +29,11 @@
                                 std::string const& prop);
 
 public:
-  Cache(cmFileAPI& fileAPI, unsigned long version);
+  Cache(cmFileAPI& fileAPI, unsigned int version);
   Json::Value Dump();
 };
 
-Cache::Cache(cmFileAPI& fileAPI, unsigned long version)
+Cache::Cache(cmFileAPI& fileAPI, unsigned int version)
   : FileAPI(fileAPI)
   , Version(version)
   , State(this->FileAPI.GetCMakeInstance()->GetState())
@@ -101,7 +101,7 @@
 }
 }
 
-Json::Value cmFileAPICacheDump(cmFileAPI& fileAPI, unsigned long version)
+Json::Value cmFileAPICacheDump(cmFileAPI& fileAPI, unsigned int version)
 {
   Cache cache(fileAPI, version);
   return cache.Dump();
diff --git a/Source/cmFileAPICache.h b/Source/cmFileAPICache.h
index dc179fa..d480cc2 100644
--- a/Source/cmFileAPICache.h
+++ b/Source/cmFileAPICache.h
@@ -9,4 +9,4 @@
 class cmFileAPI;
 
 extern Json::Value cmFileAPICacheDump(cmFileAPI& fileAPI,
-                                      unsigned long version);
+                                      unsigned int version);
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index eb1cb6c..35afd91 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -5,6 +5,7 @@
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
+#include <functional>
 #include <limits>
 #include <map>
 #include <memory>
@@ -41,6 +42,7 @@
 #include "cmInstallScriptGenerator.h"
 #include "cmInstallSubdirectoryGenerator.h"
 #include "cmInstallTargetGenerator.h"
+#include "cmLinkItem.h"
 #include "cmLinkLineComputer.h" // IWYU pragma: keep
 #include "cmList.h"
 #include "cmListFileCache.h"
@@ -224,21 +226,24 @@
 class Codemodel
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int VersionMajor;
+  unsigned int VersionMinor;
 
   Json::Value DumpPaths();
   Json::Value DumpConfigurations();
   Json::Value DumpConfiguration(std::string const& config);
 
 public:
-  Codemodel(cmFileAPI& fileAPI, unsigned long version);
+  Codemodel(cmFileAPI& fileAPI, unsigned int versionMajor,
+            unsigned int versionMinor);
   Json::Value Dump();
 };
 
 class CodemodelConfig
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int VersionMajor;
+  unsigned int VersionMinor;
   std::string const& Config;
   std::string TopSource;
   std::string TopBuild;
@@ -247,7 +252,8 @@
   {
     cmStateSnapshot Snapshot;
     cmLocalGenerator const* LocalGenerator = nullptr;
-    Json::Value TargetIndexes = Json::arrayValue;
+    Json::Value BuildSystemTargetIndexes = Json::arrayValue;
+    Json::Value AbstractTargetIndexes = Json::arrayValue;
     Json::ArrayIndex ProjectIndex;
     bool HasInstallRule = false;
   };
@@ -263,7 +269,8 @@
     Json::ArrayIndex ParentIndex = NoParentIndex;
     Json::Value ChildIndexes = Json::arrayValue;
     Json::Value DirectoryIndexes = Json::arrayValue;
-    Json::Value TargetIndexes = Json::arrayValue;
+    Json::Value BuildSystemTargetIndexes = Json::arrayValue;
+    Json::Value AbstractTargetIndexes = Json::arrayValue;
   };
   std::map<cmStateSnapshot, Json::ArrayIndex, cmStateSnapshot::StrictWeakOrder>
     ProjectMap;
@@ -271,6 +278,12 @@
 
   TargetIndexMapType TargetIndexMap;
 
+  struct DumpedTargets
+  {
+    Json::Value BuildSystemTargets = Json::arrayValue;
+    Json::Value AbstractTargets = Json::arrayValue;
+  };
+
   void ProcessDirectories();
 
   Json::ArrayIndex GetDirectoryIndex(cmLocalGenerator const* lg);
@@ -278,7 +291,7 @@
 
   Json::ArrayIndex AddProject(cmStateSnapshot s);
 
-  Json::Value DumpTargets();
+  DumpedTargets DumpTargets();
   Json::Value DumpTarget(cmGeneratorTarget* gt, Json::ArrayIndex ti);
 
   Json::Value DumpDirectories();
@@ -291,8 +304,8 @@
   Json::Value DumpMinimumCMakeVersion(cmStateSnapshot s);
 
 public:
-  CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
-                  std::string const& config);
+  CodemodelConfig(cmFileAPI& fileAPI, unsigned int versionMajor,
+                  unsigned int versionMinor, std::string const& config);
   Json::Value Dump();
 };
 
@@ -393,6 +406,8 @@
 class DirectoryObject
 {
   cmLocalGenerator const* LG = nullptr;
+  unsigned int VersionMajor;
+  unsigned int VersionMinor;
   std::string const& Config;
   TargetIndexMapType& TargetIndexMap;
   std::string TopSource;
@@ -410,7 +425,8 @@
                                 std::string const& toPath);
 
 public:
-  DirectoryObject(cmLocalGenerator const* lg, std::string const& config,
+  DirectoryObject(cmLocalGenerator const* lg, unsigned int versionMajor,
+                  unsigned int versionMinor, std::string const& config,
                   TargetIndexMapType& targetIndexMap);
   Json::Value Dump();
 };
@@ -418,6 +434,8 @@
 class Target
 {
   cmGeneratorTarget* GT;
+  unsigned int VersionMajor;
+  unsigned int VersionMinor;
   std::string const& Config;
   std::string TopSource;
   std::string TopBuild;
@@ -505,6 +523,13 @@
                                   std::string const& role = std::string());
   Json::Value DumpDependencies();
   Json::Value DumpDependency(cmTargetDepend const& td);
+
+  Json::Value DumpLinkItem(cmLinkItem const& linkItem);
+  Json::Value DumpLinkImplementationLibraries(cmGeneratorTarget::UseTo usage);
+  Json::Value DumpLinkInterfaceLibraries(cmGeneratorTarget::UseTo usage);
+  Json::Value DumpObjectDependencies();
+  Json::Value DumpOrderDependencies();
+
   Json::Value DumpFolder();
   Json::Value DumpLauncher(char const* name, char const* type);
   Json::Value DumpLaunchers();
@@ -512,13 +537,16 @@
   Json::Value DumpDebugger();
 
 public:
-  Target(cmGeneratorTarget* gt, std::string const& config);
+  Target(cmGeneratorTarget* gt, unsigned int versionMajor,
+         unsigned int versionMinor, std::string const& config);
   Json::Value Dump();
 };
 
-Codemodel::Codemodel(cmFileAPI& fileAPI, unsigned long version)
+Codemodel::Codemodel(cmFileAPI& fileAPI, unsigned int versionMajor,
+                     unsigned int versionMinor)
   : FileAPI(fileAPI)
-  , Version(version)
+  , VersionMajor(versionMajor)
+  , VersionMinor(versionMinor)
 {
 }
 
@@ -558,19 +586,21 @@
 
 Json::Value Codemodel::DumpConfiguration(std::string const& config)
 {
-  CodemodelConfig configuration(this->FileAPI, this->Version, config);
+  CodemodelConfig configuration(this->FileAPI, this->VersionMajor,
+                                this->VersionMinor, config);
   return configuration.Dump();
 }
 
-CodemodelConfig::CodemodelConfig(cmFileAPI& fileAPI, unsigned long version,
+CodemodelConfig::CodemodelConfig(cmFileAPI& fileAPI, unsigned int versionMajor,
+                                 unsigned int versionMinor,
                                  std::string const& config)
   : FileAPI(fileAPI)
-  , Version(version)
+  , VersionMajor(versionMajor)
+  , VersionMinor(versionMinor)
   , Config(config)
   , TopSource(this->FileAPI.GetCMakeInstance()->GetHomeDirectory())
   , TopBuild(this->FileAPI.GetCMakeInstance()->GetHomeOutputDirectory())
 {
-  static_cast<void>(this->Version);
 }
 
 Json::Value CodemodelConfig::Dump()
@@ -578,9 +608,14 @@
   Json::Value configuration = Json::objectValue;
   configuration["name"] = this->Config;
   this->ProcessDirectories();
-  configuration["targets"] = this->DumpTargets();
+
+  DumpedTargets dumpedTargets = this->DumpTargets();
+  configuration["targets"] = dumpedTargets.BuildSystemTargets;
+  configuration["abstractTargets"] = dumpedTargets.AbstractTargets;
+
   configuration["directories"] = this->DumpDirectories();
   configuration["projects"] = this->DumpProjects();
+
   return configuration;
 }
 
@@ -667,15 +702,16 @@
   return projectIndex;
 }
 
-Json::Value CodemodelConfig::DumpTargets()
+CodemodelConfig::DumpedTargets CodemodelConfig::DumpTargets()
 {
-  Json::Value targets = Json::arrayValue;
+  DumpedTargets dumpedTargets;
 
   std::vector<cmGeneratorTarget*> targetList;
   cmGlobalGenerator* gg =
     this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
   for (auto const& lg : gg->GetLocalGenerators()) {
     cm::append(targetList, lg->GetGeneratorTargets());
+    cm::append(targetList, lg->GetOwnedImportedGeneratorTargets());
   }
   std::sort(targetList.begin(), targetList.end(),
             [](cmGeneratorTarget* l, cmGeneratorTarget* r) {
@@ -683,8 +719,7 @@
             });
 
   for (cmGeneratorTarget* gt : targetList) {
-    if (gt->GetType() == cmStateEnums::GLOBAL_TARGET ||
-        !gt->IsInBuildSystem()) {
+    if (gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
       continue;
     }
 
@@ -693,17 +728,22 @@
       continue;
     }
 
+    Json::Value& targets = gt->IsInBuildSystem()
+      ? dumpedTargets.BuildSystemTargets
+      : dumpedTargets.AbstractTargets;
     targets.append(this->DumpTarget(gt, targets.size()));
   }
 
-  return targets;
+  return dumpedTargets;
 }
 
 Json::Value CodemodelConfig::DumpTarget(cmGeneratorTarget* gt,
                                         Json::ArrayIndex ti)
 {
-  Target t(gt, this->Config);
-  std::string prefix = "target-" + gt->GetName();
+  Target t(gt, this->VersionMajor, this->VersionMinor, this->Config);
+  std::string safeTargetName = gt->GetName();
+  std::replace(safeTargetName.begin(), safeTargetName.end(), ':', '_');
+  std::string prefix = "target-" + safeTargetName;
   if (!this->Config.empty()) {
     prefix += "-" + this->Config;
   }
@@ -714,12 +754,20 @@
   // Cross-reference directory containing target.
   Json::ArrayIndex di = this->GetDirectoryIndex(gt->GetLocalGenerator());
   target["directoryIndex"] = di;
-  this->Directories[di].TargetIndexes.append(ti);
+  if (gt->IsInBuildSystem()) {
+    this->Directories[di].BuildSystemTargetIndexes.append(ti);
+  } else {
+    this->Directories[di].AbstractTargetIndexes.append(ti);
+  }
 
   // Cross-reference project containing target.
   Json::ArrayIndex pi = this->Directories[di].ProjectIndex;
   target["projectIndex"] = pi;
-  this->Projects[pi].TargetIndexes.append(ti);
+  if (gt->IsInBuildSystem()) {
+    this->Projects[pi].BuildSystemTargetIndexes.append(ti);
+  } else {
+    this->Projects[pi].AbstractTargetIndexes.append(ti);
+  }
 
   this->TargetIndexMap[gt] = ti;
 
@@ -761,8 +809,11 @@
 
   directory["projectIndex"] = d.ProjectIndex;
 
-  if (!d.TargetIndexes.empty()) {
-    directory["targetIndexes"] = std::move(d.TargetIndexes);
+  if (!d.BuildSystemTargetIndexes.empty()) {
+    directory["targetIndexes"] = std::move(d.BuildSystemTargetIndexes);
+  }
+  if (!d.AbstractTargetIndexes.empty()) {
+    directory["abstractTargetIndexes"] = std::move(d.AbstractTargetIndexes);
   }
 
   Json::Value minimumCMakeVersion = this->DumpMinimumCMakeVersion(d.Snapshot);
@@ -798,7 +849,8 @@
     prefix += "-" + this->Config;
   }
 
-  DirectoryObject dir(d.LocalGenerator, this->Config, this->TargetIndexMap);
+  DirectoryObject dir(d.LocalGenerator, this->VersionMajor, this->VersionMinor,
+                      this->Config, this->TargetIndexMap);
   return this->FileAPI.MaybeJsonFile(dir.Dump(), prefix);
 }
 
@@ -827,8 +879,11 @@
 
   project["directoryIndexes"] = std::move(p.DirectoryIndexes);
 
-  if (!p.TargetIndexes.empty()) {
-    project["targetIndexes"] = std::move(p.TargetIndexes);
+  if (!p.BuildSystemTargetIndexes.empty()) {
+    project["targetIndexes"] = std::move(p.BuildSystemTargetIndexes);
+  }
+  if (!p.AbstractTargetIndexes.empty()) {
+    project["abstractTargetIndexes"] = std::move(p.AbstractTargetIndexes);
   }
 
   return project;
@@ -845,9 +900,13 @@
 }
 
 DirectoryObject::DirectoryObject(cmLocalGenerator const* lg,
+                                 unsigned int versionMajor,
+                                 unsigned int versionMinor,
                                  std::string const& config,
                                  TargetIndexMapType& targetIndexMap)
   : LG(lg)
+  , VersionMajor(versionMajor)
+  , VersionMinor(versionMinor)
   , Config(config)
   , TargetIndexMap(targetIndexMap)
   , TopSource(lg->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory())
@@ -860,6 +919,8 @@
 Json::Value DirectoryObject::Dump()
 {
   Json::Value directoryObject = Json::objectValue;
+  directoryObject["codemodelVersion"] =
+    cmFileAPI::BuildVersion(this->VersionMajor, this->VersionMinor);
   directoryObject["paths"] = this->DumpPaths();
   directoryObject["installers"] = this->DumpInstallers();
   directoryObject["backtraceGraph"] = this->Backtraces.Dump();
@@ -1186,8 +1247,11 @@
   return installPath;
 }
 
-Target::Target(cmGeneratorTarget* gt, std::string const& config)
+Target::Target(cmGeneratorTarget* gt, unsigned int versionMajor,
+               unsigned int versionMinor, std::string const& config)
   : GT(gt)
+  , VersionMajor(versionMajor)
+  , VersionMinor(versionMinor)
   , Config(config)
   , TopSource(gt->GetGlobalGenerator()->GetCMakeInstance()->GetHomeDirectory())
   , TopBuild(
@@ -1203,9 +1267,23 @@
 
   cmStateEnums::TargetType const type = this->GT->GetType();
 
+  target["codemodelVersion"] =
+    cmFileAPI::BuildVersion(this->VersionMajor, this->VersionMinor);
   target["name"] = this->GT->GetName();
   target["type"] = cmState::GetTargetTypeName(type);
   target["id"] = TargetId(this->GT, this->TopBuild);
+  if (this->GT->IsImported()) {
+    target["imported"] = true;
+    if (!this->GT->IsImportedGloballyVisible()) {
+      target["local"] = true;
+    }
+  }
+  if (this->GT->IsSymbolic()) {
+    target["symbolic"] = true;
+  }
+  if (!this->GT->IsInBuildSystem()) {
+    target["abstract"] = true;
+  }
   target["paths"] = this->DumpPaths();
   if (this->GT->Target->GetIsGeneratorProvided()) {
     target["isGeneratorProvided"] = true;
@@ -1228,10 +1306,14 @@
       type == cmStateEnums::SHARED_LIBRARY ||
       type == cmStateEnums::MODULE_LIBRARY) {
     target["nameOnDisk"] = this->GT->GetFullName(this->Config);
-    target["link"] = this->DumpLink();
+    if (!this->GT->IsImported()) {
+      target["link"] = this->DumpLink();
+    }
   } else if (type == cmStateEnums::STATIC_LIBRARY) {
     target["nameOnDisk"] = this->GT->GetFullName(this->Config);
-    target["archive"] = this->DumpArchive();
+    if (!this->GT->IsImported()) {
+      target["archive"] = this->DumpArchive();
+    }
   }
 
   if (type == cmStateEnums::EXECUTABLE) {
@@ -1241,13 +1323,47 @@
     }
   }
 
-  Json::Value dependencies = this->DumpDependencies();
-  if (!dependencies.empty()) {
-    target["dependencies"] = dependencies;
+  if (!this->GT->IsImported()) {
+    Json::Value dependencies = this->DumpDependencies();
+    if (!dependencies.empty()) {
+      target["dependencies"] = dependencies;
+    }
   }
 
   {
-    this->ProcessLanguages();
+    Json::Value linkLibraries =
+      this->DumpLinkImplementationLibraries(cmGeneratorTarget::UseTo::Link);
+    if (!linkLibraries.empty()) {
+      target["linkLibraries"] = std::move(linkLibraries);
+    }
+    Json::Value ifaceLinkLibraries =
+      this->DumpLinkInterfaceLibraries(cmGeneratorTarget::UseTo::Link);
+    if (!ifaceLinkLibraries.empty()) {
+      target["interfaceLinkLibraries"] = std::move(ifaceLinkLibraries);
+    }
+    Json::Value compileDependencies =
+      this->DumpLinkImplementationLibraries(cmGeneratorTarget::UseTo::Compile);
+    if (!compileDependencies.empty()) {
+      target["compileDependencies"] = std::move(compileDependencies);
+    }
+    Json::Value ifaceCompileDependencies =
+      this->DumpLinkInterfaceLibraries(cmGeneratorTarget::UseTo::Compile);
+    if (!ifaceCompileDependencies.empty()) {
+      target["interfaceCompileDependencies"] =
+        std::move(ifaceCompileDependencies);
+    }
+    Json::Value objectDependencies = this->DumpObjectDependencies();
+    if (!objectDependencies.empty()) {
+      target["objectDependencies"] = std::move(objectDependencies);
+    }
+    Json::Value orderDependencies = this->DumpOrderDependencies();
+    if (!orderDependencies.empty()) {
+      target["orderDependencies"] = std::move(orderDependencies);
+    }
+
+    if (!this->GT->IsImported()) {
+      this->ProcessLanguages();
+    }
 
     auto fileSetInfo = this->DumpFileSets();
 
@@ -1255,6 +1371,8 @@
       target["fileSets"] = fileSetInfo.first;
     }
 
+    // Even though some types of targets can't have sources, we have to always
+    // output a sources array to preserve backward compatibility
     target["sources"] = this->DumpSources(fileSetInfo.second);
 
     Json::Value folder = this->DumpFolder();
@@ -1262,22 +1380,26 @@
       target["folder"] = std::move(folder);
     }
 
-    Json::Value sourceGroups = this->DumpSourceGroups();
-    if (!sourceGroups.empty()) {
-      target["sourceGroups"] = std::move(sourceGroups);
-    }
+    if (!this->GT->IsImported()) {
+      Json::Value sourceGroups = this->DumpSourceGroups();
+      if (!sourceGroups.empty()) {
+        target["sourceGroups"] = std::move(sourceGroups);
+      }
 
-    Json::Value compileGroups = this->DumpCompileGroups();
-    if (!compileGroups.empty()) {
-      target["compileGroups"] = std::move(compileGroups);
+      Json::Value compileGroups = this->DumpCompileGroups();
+      if (!compileGroups.empty()) {
+        target["compileGroups"] = std::move(compileGroups);
+      }
     }
   }
 
   target["backtraceGraph"] = this->Backtraces.Dump();
 
-  Json::Value debugger = this->DumpDebugger();
-  if (!debugger.isNull()) {
-    target["debugger"] = std::move(debugger);
+  if (!this->GT->IsImported()) {
+    Json::Value debugger = this->DumpDebugger();
+    if (!debugger.isNull()) {
+      target["debugger"] = std::move(debugger);
+    }
   }
 
   return target;
@@ -1927,13 +2049,34 @@
   }
 
   // Add Windows-specific artifacts produced by the linker.
+  // NOTE: HasImportLibrary() only checks if the target SHOULD have an import
+  //       library, not whether it has one set.
   if (this->GT->HasImportLibrary(this->Config)) {
-    Json::Value artifact = Json::objectValue;
-    artifact["path"] =
-      RelativeIfUnder(this->TopBuild,
-                      this->GT->GetFullPath(
-                        this->Config, cmStateEnums::ImportLibraryArtifact));
-    artifacts.append(std::move(artifact)); // NOLINT(*)
+    std::string fullPath;
+    if (this->GT->IsImported()) {
+      // This imported target might not be well-formed. For Windows, it should
+      // have its IMPORTED_IMPLIB property set, and CMP0111's NEW behavior is
+      // intended to catch and report that. But if nothing uses the imported
+      // target, there won't have been any opportunity to detect that property
+      // being missing before here. Therefore, we tell ImportedGetFullPath()
+      // not to raise that CMP0111 error if it sees the problem. We don't want
+      // to trigger an error for a target that nothing uses, as that would be a
+      // regression compared to CMake 4.1 and earlier behavior.
+      fullPath = this->GT->Target->ImportedGetFullPath(
+        this->Config, cmStateEnums::ImportLibraryArtifact,
+        cmTarget::ImportArtifactMissingOk::Yes);
+      if (cmHasLiteralSuffix(fullPath, "-NOTFOUND")) {
+        fullPath.clear();
+      }
+    } else {
+      fullPath = this->GT->NormalGetFullPath(
+        this->Config, cmStateEnums::ImportLibraryArtifact, false);
+    }
+    if (!fullPath.empty()) {
+      Json::Value artifact = Json::objectValue;
+      artifact["path"] = RelativeIfUnder(this->TopBuild, fullPath);
+      artifacts.append(std::move(artifact)); // NOLINT(*)
+    }
   }
   if (this->GT->IsDLLPlatform() &&
       this->GT->GetType() != cmStateEnums::STATIC_LIBRARY) {
@@ -2087,6 +2230,115 @@
   return dependency;
 }
 
+Json::Value Target::DumpLinkItem(cmLinkItem const& linkItem)
+{
+  Json::Value itemJson = Json::objectValue;
+  if (linkItem.Target) {
+    itemJson["id"] = TargetId(linkItem.Target, this->TopBuild);
+  } else {
+    itemJson["fragment"] = linkItem.AsStr();
+  }
+  if (linkItem.InterfaceDirectFrom) {
+    Json::Value jsonDirectFrom = Json::objectValue;
+    jsonDirectFrom["id"] =
+      TargetId(linkItem.InterfaceDirectFrom, this->TopBuild);
+    itemJson["fromDependency"] = jsonDirectFrom;
+  }
+  this->AddBacktrace(itemJson, linkItem.Backtrace);
+  return itemJson;
+}
+
+Json::Value Target::DumpLinkImplementationLibraries(
+  cmGeneratorTarget::UseTo usage)
+{
+  Json::Value jsonLibs = Json::arrayValue;
+
+  cmLinkImplementationLibraries const* implLibs =
+    this->GT->GetLinkImplementationLibraries(this->Config, usage);
+  if (implLibs) {
+    for (cmLinkItem const& linkItem : implLibs->Libraries) {
+      // Non-target compile items are never used, so we drop them here too
+      if (usage == cmGeneratorTarget::UseTo::Link || linkItem.Target) {
+        jsonLibs.append(this->DumpLinkItem(linkItem));
+      }
+    }
+  }
+  return jsonLibs;
+}
+
+Json::Value Target::DumpLinkInterfaceLibraries(cmGeneratorTarget::UseTo usage)
+{
+  Json::Value jsonLibs = Json::arrayValue;
+
+  cmLinkInterfaceLibraries const* ifaceLibs =
+    this->GT->GetLinkInterfaceLibraries(this->Config, this->GT, usage);
+  if (ifaceLibs) {
+    for (cmLinkItem const& linkItem : ifaceLibs->Libraries) {
+      // Non-target compile items are never used, so we drop them here too
+      if (usage == cmGeneratorTarget::UseTo::Link || linkItem.Target) {
+        jsonLibs.append(this->DumpLinkItem(linkItem));
+      }
+    }
+  }
+  return jsonLibs;
+}
+
+Json::Value Target::DumpObjectDependencies()
+{
+  // Object dependencies are a special case. They cannot be config-specific
+  // because they are obtained by matching the pattern $<TARGET_OBJECTS:xxx>
+  // against the SOURCES property, and the matcher rejects any cases where
+  // "xxx" contains a generator expression. We can't use
+  // GetSourceObjectLibraries() either because that also returns object
+  // libraries added via LINK_LIBRARIES rather than $<TARGET_OBJECTS:xxx>,
+  // and the whole point of orderDependencies is to capture those that are
+  // not listed in LINK_LIBRARIES.
+  std::vector<BT<cmGeneratorTarget*>> objectLibraries;
+  this->GT->GetObjectLibrariesInSources(objectLibraries);
+
+  // We don't want to repeat the same target in the list. We will only
+  // retain one backtrace for cases where the same target is added multiple
+  // times from different commands. We also need a deterministic ordering,
+  // so we can't use cmGeneratorTarget* pointers in a std::set here.
+  using TargetIdMap = std::map<std::string, BT<cmGeneratorTarget*>>;
+  TargetIdMap uniqueObjectLibraries;
+  for (BT<cmGeneratorTarget*> const& target : objectLibraries) {
+    uniqueObjectLibraries[TargetId(target.Value, this->TopBuild)] = target;
+  }
+
+  Json::Value jsonDependencies = Json::arrayValue;
+  for (TargetIdMap::value_type const& idTargetPair : uniqueObjectLibraries) {
+    Json::Value jsonDependency = Json::objectValue;
+    jsonDependency["id"] = idTargetPair.first;
+    this->AddBacktrace(jsonDependency, idTargetPair.second.Backtrace);
+    jsonDependencies.append(jsonDependency);
+  }
+  return jsonDependencies;
+}
+
+Json::Value Target::DumpOrderDependencies()
+{
+  // The generated build systems don't account for per-config dependencies.
+  // This is due to limitations of Xcode and/or Visual Studio, which have
+  // (or at least once had) no way to express a per-config inter-target
+  // dependency.
+  Json::Value jsonDependencies = Json::arrayValue;
+  for (cmLinkItem const& linkItem : this->GT->GetUtilityItems()) {
+    // We don't want to dump dependencies on reserved targets like ZERO_CHECK.
+    // We shouldn't see link items that are not targets, but for backward
+    // compatibility reasons, they are currently allowed but silently ignored.
+    if (!linkItem.Target ||
+        cmGlobalGenerator::IsReservedTarget(linkItem.Target->GetName())) {
+      continue;
+    }
+    Json::Value jsonDependency = Json::objectValue;
+    jsonDependency["id"] = TargetId(linkItem.Target, this->TopBuild);
+    this->AddBacktrace(jsonDependency, linkItem.Backtrace);
+    jsonDependencies.append(jsonDependency);
+  }
+  return jsonDependencies;
+}
+
 Json::Value Target::DumpFolder()
 {
   Json::Value folder;
@@ -2155,8 +2407,10 @@
   return debuggerInformation;
 }
 
-Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI, unsigned long version)
+Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI,
+                                   unsigned int versionMajor,
+                                   unsigned int versionMinor)
 {
-  Codemodel codemodel(fileAPI, version);
+  Codemodel codemodel(fileAPI, versionMajor, versionMinor);
   return codemodel.Dump();
 }
diff --git a/Source/cmFileAPICodemodel.h b/Source/cmFileAPICodemodel.h
index 6a3d7b2..55632ca 100644
--- a/Source/cmFileAPICodemodel.h
+++ b/Source/cmFileAPICodemodel.h
@@ -9,4 +9,5 @@
 class cmFileAPI;
 
 extern Json::Value cmFileAPICodemodelDump(cmFileAPI& fileAPI,
-                                          unsigned long version);
+                                          unsigned int majorVersion,
+                                          unsigned int minorVersion);
diff --git a/Source/cmFileAPICommand.cxx b/Source/cmFileAPICommand.cxx
index 797d207..ca5389f 100644
--- a/Source/cmFileAPICommand.cxx
+++ b/Source/cmFileAPICommand.cxx
@@ -6,6 +6,7 @@
 #include <array>
 #include <cctype>
 #include <cstdlib>
+#include <utility>
 
 #include <cm/string_view>
 #include <cmext/string_view>
@@ -67,7 +68,7 @@
                         cmExecutionStatus& status)
 {
   if (args.empty()) {
-    status.SetError("QUERY subcommand called without required arguments.");
+    status.SetError("QUERY called without required arguments.");
     return false;
   }
 
@@ -96,21 +97,20 @@
     return true;
   }
   if (!unparsedArguments.empty()) {
-    status.SetError("QUERY subcommand given unknown argument \"" +
+    status.SetError("QUERY given unknown argument \"" +
                     unparsedArguments.front() + "\".");
     return false;
   }
 
   if (!std::all_of(arguments.ApiVersion.begin(), arguments.ApiVersion.end(),
                    isCharDigit)) {
-    status.SetError("QUERY subcommand given a non-integer API_VERSION.");
+    status.SetError("QUERY given non-integer API_VERSION.");
     return false;
   }
   int const apiVersion = std::atoi(arguments.ApiVersion.c_str());
   if (apiVersion != 1) {
     status.SetError(
-      cmStrCat("QUERY subcommand given an unsupported API_VERSION \"",
-               arguments.ApiVersion,
+      cmStrCat("QUERY given unsupported API_VERSION \"", arguments.ApiVersion,
                "\" (the only currently supported version is 1)."));
     return false;
   }
@@ -137,7 +137,7 @@
 
   if (!std::all_of(errors.begin(), errors.end(),
                    [](std::string const& s) -> bool { return s.empty(); })) {
-    std::string message("QUERY subcommand was given invalid arguments:");
+    std::string message("QUERY given invalid arguments:");
     for (std::string const& s : errors) {
       if (!s.empty()) {
         message = cmStrCat(message, "\n  ", s);
diff --git a/Source/cmFileAPIConfigureLog.cxx b/Source/cmFileAPIConfigureLog.cxx
index 3e5ba94..7cd3d97 100644
--- a/Source/cmFileAPIConfigureLog.cxx
+++ b/Source/cmFileAPIConfigureLog.cxx
@@ -13,17 +13,17 @@
 class ConfigureLog
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int Version;
 
   Json::Value DumpPath();
   Json::Value DumpEventKindNames();
 
 public:
-  ConfigureLog(cmFileAPI& fileAPI, unsigned long version);
+  ConfigureLog(cmFileAPI& fileAPI, unsigned int version);
   Json::Value Dump();
 };
 
-ConfigureLog::ConfigureLog(cmFileAPI& fileAPI, unsigned long version)
+ConfigureLog::ConfigureLog(cmFileAPI& fileAPI, unsigned int version)
   : FileAPI(fileAPI)
   , Version(version)
 {
@@ -62,8 +62,7 @@
 }
 }
 
-Json::Value cmFileAPIConfigureLogDump(cmFileAPI& fileAPI,
-                                      unsigned long version)
+Json::Value cmFileAPIConfigureLogDump(cmFileAPI& fileAPI, unsigned int version)
 {
   ConfigureLog configureLog(fileAPI, version);
   return configureLog.Dump();
diff --git a/Source/cmFileAPIConfigureLog.h b/Source/cmFileAPIConfigureLog.h
index b290828..b1da1f8 100644
--- a/Source/cmFileAPIConfigureLog.h
+++ b/Source/cmFileAPIConfigureLog.h
@@ -9,4 +9,4 @@
 class cmFileAPI;
 
 extern Json::Value cmFileAPIConfigureLogDump(cmFileAPI& fileAPI,
-                                             unsigned long version);
+                                             unsigned int version);
diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx
index 74d69bf..c156ca1 100644
--- a/Source/cmFileAPIToolchains.cxx
+++ b/Source/cmFileAPIToolchains.cxx
@@ -29,7 +29,7 @@
 class Toolchains
 {
   cmFileAPI& FileAPI;
-  unsigned long Version;
+  unsigned int Version;
 
   Json::Value DumpToolchains();
   Json::Value DumpToolchain(std::string const& lang);
@@ -41,11 +41,11 @@
                              ToolchainVariable const& variable);
 
 public:
-  Toolchains(cmFileAPI& fileAPI, unsigned long version);
+  Toolchains(cmFileAPI& fileAPI, unsigned int version);
   Json::Value Dump();
 };
 
-Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned long version)
+Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned int version)
   : FileAPI(fileAPI)
   , Version(version)
 {
@@ -143,7 +143,7 @@
 }
 }
 
-Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned long version)
+Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned int version)
 {
   Toolchains toolchains(fileAPI, version);
   return toolchains.Dump();
diff --git a/Source/cmFileAPIToolchains.h b/Source/cmFileAPIToolchains.h
index b6b48fb..b7676a8 100644
--- a/Source/cmFileAPIToolchains.h
+++ b/Source/cmFileAPIToolchains.h
@@ -9,4 +9,4 @@
 class cmFileAPI;
 
 extern Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI,
-                                           unsigned long version);
+                                           unsigned int version);
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 88f9f0c..057b3fa 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -3848,7 +3848,7 @@
   return true;
 }
 
-bool SetPermissions(std::string const& filename, mode_t const& perms,
+bool SetPermissions(std::string const& filename, mode_t perms,
                     cmExecutionStatus& status)
 {
   if (!cmSystemTools::SetPermissions(filename, perms)) {
@@ -3953,8 +3953,7 @@
 
     if (cmSystemTools::FileExists(i, true)) {
       bool success = true;
-      mode_t const& filePermissions =
-        parsedArgs.FilePermissions ? fperms : perms;
+      mode_t filePermissions = parsedArgs.FilePermissions ? fperms : perms;
       if (filePermissions) {
         success = SetPermissions(i, filePermissions, status);
       }
@@ -3965,7 +3964,7 @@
 
     else if (cmSystemTools::FileIsDirectory(i)) {
       bool success = true;
-      mode_t const& directoryPermissions =
+      mode_t directoryPermissions =
         parsedArgs.DirectoryPermissions ? dperms : perms;
       if (directoryPermissions) {
         success = SetPermissions(i, directoryPermissions, status);
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 65320aa..c848ed7 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -607,7 +607,7 @@
 
   // Copy the file.
   if (copy) {
-    auto copy_status = cmSystemTools::CopyAFile(fromFile, toFile, true);
+    auto copy_status = cmSystemTools::CopyAFile(fromFile, toFile);
     if (!copy_status) {
       std::ostringstream e;
       e << this->Name << " cannot copy file \"" << fromFile << "\" to \""
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index 6d88980..e95e694 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -6,6 +6,7 @@
 #include <map>
 #include <sstream>
 #include <utility>
+#include <vector>
 
 #include <cm/string_view>
 #include <cmext/string_view>
diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h
index dec135d..4aa10d1 100644
--- a/Source/cmFileInstaller.h
+++ b/Source/cmFileInstaller.h
@@ -5,7 +5,6 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
-#include <vector>
 
 #include "cmFileCopier.h"
 #include "cmInstallMode.h"
diff --git a/Source/cmFileTime.cxx b/Source/cmFileTime.cxx
index 04a0203..7430f66 100644
--- a/Source/cmFileTime.cxx
+++ b/Source/cmFileTime.cxx
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmFileTime.h"
 
+#include <ctime>
 #include <string>
 
 // Use a platform-specific API to get file times efficiently.
diff --git a/Source/cmFileTime.h b/Source/cmFileTime.h
index 52ecf50..7887bf1 100644
--- a/Source/cmFileTime.h
+++ b/Source/cmFileTime.h
@@ -22,10 +22,6 @@
   // unit time is 100 nanosecond
   static constexpr TimeType UtPerS = 10000000;
 #endif
-  cmFileTime() = default;
-  ~cmFileTime() = default;
-  cmFileTime(cmFileTime const&) = default;
-  cmFileTime& operator=(cmFileTime const&) = default;
 
   /**
    * @brief Loads the file time of fileName from the file system
@@ -36,34 +32,28 @@
   /**
    * @brief Return true if this is older than ftm
    */
-  bool Older(cmFileTime const& ftm) const
-  {
-    return (this->Time - ftm.Time) < 0;
-  }
+  bool Older(cmFileTime ftm) const { return (this->Time - ftm.Time) < 0; }
 
   /**
    * @brief Return true if this is newer than ftm
    */
-  bool Newer(cmFileTime const& ftm) const
-  {
-    return (ftm.Time - this->Time) < 0;
-  }
+  bool Newer(cmFileTime ftm) const { return (ftm.Time - this->Time) < 0; }
 
   /**
    * @brief Return true if this is the same as ftm
    */
-  bool Equal(cmFileTime const& ftm) const { return this->Time == ftm.Time; }
+  bool Equal(cmFileTime ftm) const { return this->Time == ftm.Time; }
 
   /**
    * @brief Return true if this is not the same as ftm
    */
-  bool Differ(cmFileTime const& ftm) const { return this->Time != ftm.Time; }
+  bool Differ(cmFileTime ftm) const { return this->Time != ftm.Time; }
 
   /**
    * @brief Compare file modification times.
    * @return -1, 0, +1 for this older, same, or newer than ftm.
    */
-  int Compare(cmFileTime const& ftm) const
+  int Compare(cmFileTime ftm) const
   {
     TimeType const diff = this->Time - ftm.Time;
     if (diff == 0) {
@@ -77,7 +67,7 @@
   /**
    * @brief Return true if this is at least a second older than ftm
    */
-  bool OlderS(cmFileTime const& ftm) const
+  bool OlderS(cmFileTime ftm) const
   {
     return (ftm.Time - this->Time) >= cmFileTime::UtPerS;
   }
@@ -85,7 +75,7 @@
   /**
    * @brief Return true if this is at least a second newer than ftm
    */
-  bool NewerS(cmFileTime const& ftm) const
+  bool NewerS(cmFileTime ftm) const
   {
     return (this->Time - ftm.Time) >= cmFileTime::UtPerS;
   }
@@ -93,7 +83,7 @@
   /**
    * @brief Return true if this is within the same second as ftm
    */
-  bool EqualS(cmFileTime const& ftm) const
+  bool EqualS(cmFileTime ftm) const
   {
     TimeType diff = this->Time - ftm.Time;
     if (diff < 0) {
@@ -105,7 +95,7 @@
   /**
    * @brief Return true if this is older or newer than ftm by at least a second
    */
-  bool DifferS(cmFileTime const& ftm) const
+  bool DifferS(cmFileTime ftm) const
   {
     TimeType diff = this->Time - ftm.Time;
     if (diff < 0) {
@@ -119,7 +109,7 @@
    * @return -1: this at least a second older, 0: this within the same second
    *         as ftm, +1: this at least a second newer than ftm.
    */
-  int CompareS(cmFileTime const& ftm) const
+  int CompareS(cmFileTime ftm) const
   {
     TimeType const diff = this->Time - ftm.Time;
     if (diff <= -cmFileTime::UtPerS) {
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index 0be2d73..540388f 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -11,9 +11,7 @@
 #include "cmFindCommon.h"
 #include "cmStateTypes.h"
 
-class cmConfigureLog;
 class cmExecutionStatus;
-class cmMakefile;
 
 /** \class cmFindBase
  * \brief Base class for most FIND_XXX commands.
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 23083b0..dd86644 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -28,6 +28,7 @@
 #include "cmDependencyProvider.h"
 #include "cmExecutionStatus.h"
 #include "cmExperimental.h"
+#include "cmFindPackageStack.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
@@ -42,7 +43,7 @@
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmValue.h"
-#include "cmVersion.h"
+#include "cmVersionMacros.h"
 #include "cmWindowsRegistry.h"
 
 #if defined(__HAIKU__)
@@ -630,6 +631,12 @@
     return false;
   }
 
+  if (this->Makefile->GetStateSnapshot().GetUnwindState() ==
+      cmStateEnums::UNWINDING) {
+    this->SetError("called while already in an UNWIND state");
+    return false;
+  }
+
   // Lookup required version of CMake.
   if (cmValue const rv =
         this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
@@ -839,6 +846,14 @@
           cmStrCat("given invalid value for REGISTRY_VIEW: ", args[i]));
         return false;
       }
+    } else if (args[i] == "UNWIND_INCLUDE") {
+      if (this->Makefile->GetStateSnapshot().GetUnwindType() !=
+          cmStateEnums::CAN_UNWIND) {
+        this->SetError("called with UNWIND_INCLUDE in an invalid context");
+        return false;
+      }
+      this->ScopeUnwind = true;
+      doing = DoingNone;
     } else if (this->CheckCommonArgument(args[i])) {
       configArgs.push_back(i);
       doing = DoingNone;
@@ -1053,8 +1068,18 @@
       this->VersionMaxPatch, this->VersionMaxTweak);
   }
 
-  return this->FindPackage(this->BypassProvider ? std::vector<std::string>{}
-                                                : args);
+  bool result = this->FindPackage(
+    this->BypassProvider ? std::vector<std::string>{} : args);
+
+  std::string const foundVar = cmStrCat(this->Name, "_FOUND");
+  bool const isFound = this->Makefile->IsOn(foundVar) ||
+    this->Makefile->IsOn(cmSystemTools::UpperCase(foundVar));
+
+  if (this->ScopeUnwind && (!result || !isFound)) {
+    this->Makefile->GetStateSnapshot().SetUnwindState(cmStateEnums::UNWINDING);
+  }
+
+  return result;
 }
 
 bool cmFindPackageCommand::FindPackage(
@@ -1146,7 +1171,7 @@
     }
     std::vector<cmListFileArgument> listFileArgs(argsForProvider.size() + 1);
     listFileArgs[0] =
-      cmListFileArgument("FIND_PACKAGE", cmListFileArgument::Unquoted, 0);
+      cmListFileArgument("FIND_PACKAGE"_s, cmListFileArgument::Unquoted, 0);
     std::transform(argsForProvider.begin(), argsForProvider.end(),
                    listFileArgs.begin() + 1, [](std::string const& arg) {
                      return cmListFileArgument(arg,
@@ -1197,8 +1222,9 @@
   FlushDebugBufferOnExit flushDebugBufferOnExit(*this);
   PushPopRootPathStack pushPopRootPathStack(*this);
   SetRestoreFindDefinitions setRestoreFindDefinitions(*this);
-  cmMakefile::FindPackageStackRAII findPackageStackRAII(this->Makefile,
-                                                        this->Name);
+  cmFindPackageStackRAII findPackageStackRAII(this->Makefile, this->Name);
+
+  findPackageStackRAII.BindTop(this->CurrentPackageInfo);
 
   // See if we have been told to delegate to FetchContent or some other
   // redirected config package first. We have to check all names that
@@ -1246,6 +1272,8 @@
       this->Names.clear();
       this->Names.emplace_back(overrideName); // Force finding this one
       this->Variable = cmStrCat(this->Name, "_DIR");
+      this->CurrentPackageInfo->Directory = redirectsDir;
+      this->CurrentPackageInfo->Version = this->VersionFound;
       this->SetConfigDirCacheVariable(redirectsDir);
       break;
     }
@@ -1318,7 +1346,6 @@
   }
 
   this->AppendSuccessInformation();
-
   return loadedPackage;
 }
 
@@ -1762,7 +1789,8 @@
 
         for (ConfigFileInfo const& info :
              cmMakeRange(this->ConsideredConfigs.cbegin(), duplicate_end)) {
-          e << "  " << info.filename << ", version: " << info.version << '\n';
+          e << "  " << info.filename << ", version: " << info.version
+            << "\n    " << info.message << '\n';
         }
       } else {
         std::string requestedVersionString;
@@ -1947,6 +1975,8 @@
   std::string init;
   if (found) {
     init = cmSystemTools::GetFilenamePath(this->FileFound);
+    this->CurrentPackageInfo->Directory = init;
+    this->CurrentPackageInfo->Version = this->VersionFound;
   } else {
     init = this->Variable + "-NOTFOUND";
   }
@@ -2025,8 +2055,11 @@
         continue;
       }
 
+      cmMakefile::CallRAII cs{ this->Makefile, extra, this->Status };
+
       std::unique_ptr<cmPackageInfoReader> reader =
-        cmPackageInfoReader::Read(extra, &baseReader);
+        cmPackageInfoReader::Read(this->Makefile, extra, &baseReader);
+
       if (reader && reader->GetName() == this->Name) {
         std::vector<std::string> components = reader->GetComponentNames();
         Appendix appendix{ std::move(reader), std::move(components) };
@@ -2047,12 +2080,24 @@
   ITScope scope = this->GlobalScope ? ITScope::Global : ITScope::Local;
   cmMakefile::SetGlobalTargetImportScope globScope(this->Makefile, scope);
 
-  if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
-    return true;
+  auto oldUnwind = this->Makefile->GetStateSnapshot().GetUnwindType();
+
+  // This allows child snapshots to inherit the CAN_UNWIND state from us, we'll
+  // reset it immediately after the dependent file is done
+  this->Makefile->GetStateSnapshot().SetUnwindType(cmStateEnums::CAN_UNWIND);
+  bool result = this->Makefile->ReadDependentFile(f, noPolicyScope);
+
+  this->Makefile->GetStateSnapshot().SetUnwindType(oldUnwind);
+  this->Makefile->GetStateSnapshot().SetUnwindState(
+    cmStateEnums::NOT_UNWINDING);
+
+  if (!result) {
+    std::string const e =
+      cmStrCat("Error reading CMake code from \"", f, "\".");
+    this->SetError(e);
   }
-  std::string const e = cmStrCat("Error reading CMake code from \"", f, "\".");
-  this->SetError(e);
-  return false;
+
+  return result;
 }
 
 bool cmFindPackageCommand::ReadPackage()
@@ -2066,7 +2111,10 @@
   bool const hasComponentsRequested =
     !this->RequiredComponents.empty() || !this->OptionalComponents.empty();
 
-  cmMakefile::CallRAII scope{ this->Makefile, this->FileFound, this->Status };
+  cmMakefile::CallRAII cs{ this->Makefile, this->FileFound, this->Status };
+  cmMakefile::PolicyPushPop ps{ this->Makefile };
+
+  this->Makefile->SetPolicy(cmPolicies::CMP0200, cmPolicies::NEW);
 
   // Loop over appendices.
   auto iter = this->CpsAppendices.begin();
@@ -2204,8 +2252,10 @@
 
     // Try to read supplemental data from each file found.
     for (std::string const& extra : glob.GetFiles()) {
+      cmMakefile::CallRAII cs{ this->Makefile, extra, this->Status };
+
       std::unique_ptr<cmPackageInfoReader> configReader =
-        cmPackageInfoReader::Read(extra, &reader);
+        cmPackageInfoReader::Read(this->Makefile, extra, &reader);
       if (configReader && configReader->GetName() == this->Name) {
         if (!configReader->ImportTargetConfigurations(this->Makefile,
                                                       this->Status)) {
@@ -2883,9 +2933,10 @@
         foundMode = cmFindPackageCommand::FoundMode(config.Type);
         return true;
       }
-      this->ConsideredPaths.emplace_back(file,
-                                         cmFindPackageCommand::FoundMode(type),
-                                         SearchResult::InsufficientVersion);
+      this->ConsideredPaths.emplace_back(
+        file, cmFindPackageCommand::FoundMode(type),
+        this->ConsideredConfigs.back().result,
+        this->ConsideredConfigs.back().message);
     } else {
       this->ConsideredPaths.emplace_back(
         file, cmFindPackageCommand::FoundMode(type), SearchResult::NoExist);
@@ -2899,14 +2950,19 @@
   bool result = false; // by default, assume the version is not ok.
   bool haveResult = false;
   std::string version = "unknown";
+  std::string message;
+  SearchResult reason = SearchResult::InsufficientVersion;
 
   // Get the file extension.
   std::string::size_type pos = config_file.rfind('.');
   std::string ext = cmSystemTools::LowerCase(config_file.substr(pos));
 
   if (ext == ".cps"_s) {
+    cmMakefile::CallRAII cs{ this->Makefile, config_file, this->Status };
+
     std::unique_ptr<cmPackageInfoReader> reader =
-      cmPackageInfoReader::Read(config_file);
+      cmPackageInfoReader::Read(this->Makefile, config_file);
+
     if (reader && reader->GetName() == this->Name) {
       // Read version information.
       cm::optional<std::string> cpsVersion = reader->GetVersion();
@@ -2953,6 +3009,14 @@
                     this->VersionMax, version);
                 }
               }
+
+              if (!result) {
+                message =
+                  cmStrCat("Version \""_s, version,
+                           "\" (compatibility version \""_s, *compatVersion,
+                           "\") is not compatible "
+                           "with the version requested."_s);
+              }
             } else {
               // If no, compat_version is assumed to be exactly the actual
               // version, so the result is whether the requested version is
@@ -2963,6 +3027,12 @@
             }
           }
         }
+
+        if (!result && message.empty()) {
+          message =
+            cmStrCat("Version \""_s, version,
+                     "\" is not compatible with the version requested."_s);
+        }
       }
 
       if (result) {
@@ -2993,7 +3063,13 @@
                             allComponents.end(),
                             std::back_inserter(missingComponents));
         if (!missingComponents.empty()) {
+          bool const single = (missingComponents.size() == 1);
           result = false;
+          message =
+            cmStrCat((single ? "Required component was not found: "_s
+                             : "Required components were not found: "_s),
+                     cmJoin(missingComponents, ", "_s), '.');
+          reason = SearchResult::InsufficientComponents;
         }
 
         if (result && hasVersion) {
@@ -3029,6 +3105,14 @@
         this->CpsAppendices = std::move(appendices);
         this->RequiredComponents = std::move(requiredComponents);
       }
+    } else if (reader) {
+      message =
+        cmStrCat("The file describes the package \""_s, reader->GetName(),
+                 "\", which is not the requested package."_s);
+      reason = SearchResult::Ignored;
+    } else {
+      message = "The package description file could not be read.";
+      reason = SearchResult::Error;
     }
   } else {
     // Get the filename without the .cmake extension.
@@ -3048,15 +3132,26 @@
       haveResult = true;
     }
 
+    if (haveResult && !result) {
+      message =
+        "The version found is not compatible with the version requested.";
+    }
+
     // If no version was requested a versionless package is acceptable.
     if (!haveResult && this->Version.empty()) {
       result = true;
     }
   }
 
+  if (result) {
+    reason = SearchResult::Acceptable;
+  }
+
   ConfigFileInfo configFileInfo;
   configFileInfo.filename = config_file;
   configFileInfo.version = version;
+  configFileInfo.message = message;
+  configFileInfo.result = reason;
   this->ConsideredConfigs.push_back(std::move(configFileInfo));
 
   return result;
@@ -3694,8 +3789,14 @@
     auto search_result =
       [](cmFindPackageCommand::SearchResult type) -> std::string {
       switch (type) {
+        case cmFindPackageCommand::SearchResult::Acceptable:
+          return "acceptable";
         case cmFindPackageCommand::SearchResult::InsufficientVersion:
           return "insufficient_version";
+        case cmFindPackageCommand::SearchResult::InsufficientComponents:
+          return "insufficient_components";
+        case cmFindPackageCommand::SearchResult::Error:
+          return "error";
         case cmFindPackageCommand::SearchResult::NoExist:
           return "no_exist";
         case cmFindPackageCommand::SearchResult::Ignored:
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 10448a8..4ac057e 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -32,11 +32,10 @@
 /* clang-format on */
 #endif
 
-class cmConfigureLog;
 class cmExecutionStatus;
-class cmMakefile;
 class cmPackageState;
 class cmSearchPath;
+class cmPackageInformation;
 
 /** \class cmFindPackageCommand
  * \brief Load settings from an external project.
@@ -276,6 +275,7 @@
   bool PolicyScope = true;
   bool GlobalScope = false;
   bool RegistryViewDefined = false;
+  bool ScopeUnwind = false;
   std::string LibraryArchitecture;
   std::vector<std::string> Names;
   std::set<std::string> IgnoredPaths;
@@ -285,9 +285,14 @@
   std::set<std::string> OptionalComponents;
   std::set<std::string> RequiredTargets;
   std::string DebugBuffer;
+  cmPackageInformation* CurrentPackageInfo;
+
   enum class SearchResult
   {
+    Acceptable,
     InsufficientVersion,
+    InsufficientComponents,
+    Error,
     NoExist,
     Ignored,
     NoConfigFile,
@@ -296,10 +301,11 @@
   struct ConsideredPath
   {
     ConsideredPath(std::string path, FoundPackageMode mode,
-                   SearchResult reason)
+                   SearchResult result, std::string message = {})
       : Path(std::move(path))
       , Mode(mode)
-      , Reason(reason)
+      , Reason(result)
+      , Message(std::move(message))
     {
     }
 
@@ -334,15 +340,17 @@
 
   class FlushDebugBufferOnExit;
 
-  /*! the selected sortOrder (None by default)*/
-  SortOrderType SortOrder = None;
-  /*! the selected sortDirection (Asc by default)*/
-  SortDirectionType SortDirection = Asc;
+  /*! the selected sortOrder (Natural by default)*/
+  SortOrderType SortOrder = Natural;
+  /*! the selected sortDirection (Dec by default)*/
+  SortDirectionType SortDirection = Dec;
 
   struct ConfigFileInfo
   {
     std::string filename;
     std::string version;
+    std::string message;
+    SearchResult result;
 
     bool operator<(ConfigFileInfo const& rhs) const
     {
diff --git a/Source/cmFindPackageStack.cxx b/Source/cmFindPackageStack.cxx
index 0803049..6f5045a 100644
--- a/Source/cmFindPackageStack.cxx
+++ b/Source/cmFindPackageStack.cxx
@@ -3,5 +3,13 @@
 #define cmFindPackageStack_cxx
 #include "cmFindPackageStack.h"
 
-#include "cmConstStack.tcc" // IWYU pragma: keep
-template class cmConstStack<cmFindPackageCall, cmFindPackageStack>;
+#include "cmStack.tcc" // IWYU pragma: keep
+template class cmStack<cmFindPackageCall, cmFindPackageStack>;
+
+template cmFindPackageCall&
+cmStack<cmFindPackageCall, cmFindPackageStack>::Top<true>();
+
+cmFindPackageCall const& cmFindPackageStack::Top() const
+{
+  return this->cmStack::Top();
+}
diff --git a/Source/cmFindPackageStack.h b/Source/cmFindPackageStack.h
index e281b51..e7fb9a6 100644
--- a/Source/cmFindPackageStack.h
+++ b/Source/cmFindPackageStack.h
@@ -5,9 +5,32 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <memory>
+#include <set>
 #include <string>
 
-#include "cmConstStack.h"
+#include <cm/optional>
+
+#include "cmStack.h"
+
+class cmMakefile;
+
+/**
+ * This data represents the actual contents of find_package
+ * <PACKAGE>-Config.cmake or <PACKAGE>.cps file, and not what is passed
+ * to the find_package command. They can be the same, but it is not guaranteed.
+ */
+
+class cmPackageInformation
+{
+public:
+  cm::optional<std::string> Directory;
+  cm::optional<std::string> Version;
+  cm::optional<std::string> Description;
+  cm::optional<std::string> License;
+  cm::optional<std::string> Website;
+  cm::optional<std::string> PackageUrl;
+  std::set<std::string> Components;
+};
 
 /**
  * Represents one call to find_package.
@@ -15,19 +38,53 @@
 class cmFindPackageCall
 {
 public:
-  std::string Name;
+  std::string const Name;
+  cmPackageInformation PackageInfo;
   unsigned int Index;
 };
 
 /**
+ * RAII type to manage the find_package call stack.
+ */
+// Note: implemented in cmMakefile.cxx
+class cmFindPackageStackRAII
+{
+  cmMakefile* Makefile;
+  cmPackageInformation** Value = nullptr;
+
+public:
+  cmFindPackageStackRAII(cmMakefile* mf, std::string const& pkg);
+  ~cmFindPackageStackRAII();
+
+  cmFindPackageStackRAII(cmFindPackageStackRAII const&) = delete;
+  cmFindPackageStackRAII& operator=(cmFindPackageStackRAII const&) = delete;
+
+  /** Get a mutable pointer to the top of the stack.
+      The pointer is invalidated if BindTop is called again or when the
+      cmFindPackageStackRAII goes out of scope.  */
+  void BindTop(cmPackageInformation*& value);
+};
+
+/**
  * Represents a stack of find_package calls with efficient value semantics.
  */
 class cmFindPackageStack
-  : public cmConstStack<cmFindPackageCall, cmFindPackageStack>
+  : protected cmStack<cmFindPackageCall, cmFindPackageStack>
 {
-  using cmConstStack::cmConstStack;
-  friend class cmConstStack<cmFindPackageCall, cmFindPackageStack>;
+  using cmStack::cmStack;
+  friend cmFindPackageStack::Base;
+  friend class cmFindPackageStackRAII;
+
+public:
+  using cmStack::Push;
+  using cmStack::Pop;
+  using cmStack::Empty;
+
+  cmFindPackageCall const& Top() const;
 };
 #ifndef cmFindPackageStack_cxx
-extern template class cmConstStack<cmFindPackageCall, cmFindPackageStack>;
+extern template class cmStack<cmFindPackageCall, cmFindPackageStack>;
+
+extern template cmFindPackageCall&
+cmStack<cmFindPackageCall, cmFindPackageStack>::Top<true>();
 #endif
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 96867e2..8b74118 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -100,6 +100,9 @@
 bool cmForEachFunctionBlocker::Replay(
   std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
 {
+  if (this->Args.size() == this->IterationVarsCount) {
+    return true;
+  }
   return this->ZipLists ? this->ReplayZipLists(functions, inStatus)
                         : this->ReplayItems(functions, inStatus);
 }
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index a835e19..c9e4e87 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -163,6 +163,9 @@
   // Lexical scanner instance.
   yyscan_t Scanner;
 
+  // List of full paths to already processed files.
+  std::set<std::string> VisitedFilePaths;
+
   // Stack of open files in the translation unit.
   std::stack<cmFortranFile> FileStack;
 
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index 4c0d5dd..08dab98 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -87,17 +87,22 @@
 
 bool cmFortranParser_FilePush(cmFortranParser* parser, char const* fname)
 {
-  // Open the new file and push it onto the stack.  Save the old
-  // buffer with it on the stack.
-  if (FILE* file = cmsys::SystemTools::Fopen(fname, "rb")) {
-    YY_BUFFER_STATE current = cmFortranLexer_GetCurrentBuffer(parser->Scanner);
-    std::string dir = cmSystemTools::GetParentDirectory(fname);
-    cmFortranFile f(file, current, dir);
-    YY_BUFFER_STATE buffer =
-      cmFortran_yy_create_buffer(nullptr, 16384, parser->Scanner);
-    cmFortran_yy_switch_to_buffer(buffer, parser->Scanner);
-    parser->FileStack.push(f);
-    return true;
+  // Do not revisit already processed files; treat them as non-existing.
+  // Avoids infinite recursion caused by misinterpreted include guards.
+  if (parser->VisitedFilePaths.insert(fname).second) {
+    // Open the new file and push it onto the stack.  Save the old
+    // buffer with it on the stack.
+    if (FILE* file = cmsys::SystemTools::Fopen(fname, "rb")) {
+      YY_BUFFER_STATE current =
+        cmFortranLexer_GetCurrentBuffer(parser->Scanner);
+      std::string dir = cmSystemTools::GetParentDirectory(fname);
+      cmFortranFile f(file, current, dir);
+      YY_BUFFER_STATE buffer =
+        cmFortran_yy_create_buffer(nullptr, 16384, parser->Scanner);
+      cmFortran_yy_switch_to_buffer(buffer, parser->Scanner);
+      parser->FileStack.push(f);
+      return true;
+    }
   }
   return false;
 }
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 8ea6c4d..a629438 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -2,6 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmFunctionCommand.h"
 
+#include <functional>
 #include <utility>
 
 #include <cm/memory>
diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx
index e5b86ad..6624c76 100644
--- a/Source/cmGccDepfileReader.cxx
+++ b/Source/cmGccDepfileReader.cxx
@@ -2,7 +2,6 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmGccDepfileReader.h"
 
-#include <type_traits>
 #include <utility>
 #include <vector>
 
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index dd4c886..b3ae9d7 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -226,7 +226,7 @@
 }
 
 static void prefixItems(std::string const& content, std::string& result,
-                        cm::string_view const& prefix)
+                        cm::string_view prefix)
 {
   std::vector<std::string> entries;
   cmGeneratorExpression::Split(content, entries);
@@ -413,8 +413,7 @@
   return extractAllGeneratorExpressions(input, &collected);
 }
 
-cm::string_view::size_type cmGeneratorExpression::Find(
-  cm::string_view const& input)
+cm::string_view::size_type cmGeneratorExpression::Find(cm::string_view input)
 {
   cm::string_view::size_type const openpos = input.find("$<");
   if (openpos != cm::string_view::npos &&
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 1389144..3897e67 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -76,7 +76,7 @@
   static void Split(std::string const& input,
                     std::vector<std::string>& output);
 
-  static cm::string_view::size_type Find(cm::string_view const& input);
+  static cm::string_view::size_type Find(cm::string_view input);
 
   static bool IsValidTargetName(std::string const& input);
 
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 082fd3d..9230746 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -36,6 +36,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmLinkItem.h"
 #include "cmList.h"
+#include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -52,6 +53,31 @@
 #include "cmValue.h"
 #include "cmake.h"
 
+namespace {
+
+bool HasKnownObjectFileLocation(cm::GenEx::Evaluation* eval,
+                                GeneratorExpressionContent const* content,
+                                std::string const& genex,
+                                cmGeneratorTarget const* target)
+{
+  std::string reason;
+  if (!eval->EvaluateForBuildsystem &&
+      !target->Target->HasKnownObjectFileLocation(&reason)) {
+    std::ostringstream e;
+    e << "The evaluation of the " << genex
+      << " generator expression "
+         "is only suitable for consumption by CMake (limited"
+      << reason
+      << ").  "
+         "It is not suitable for writing out elsewhere.";
+    reportError(eval, content->GetOriginalExpression(), e.str());
+    return false;
+  }
+  return true;
+}
+
+} // namespace
+
 std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
   std::string const& prop, cm::GenEx::Evaluation* eval,
   cmGeneratorTarget const* headTarget,
@@ -690,7 +716,7 @@
 }
 bool CheckPathParameters(cm::GenEx::Evaluation* eval,
                          GeneratorExpressionContent const* cnt,
-                         cm::string_view option, Arguments const& args,
+                         cm::string_view option, Arguments args,
                          int required = 1)
 {
   return CheckPathParametersEx(eval, cnt, option, args.size(), required);
@@ -1147,7 +1173,7 @@
 }
 inline bool CheckListParameters(cm::GenEx::Evaluation* eval,
                                 GeneratorExpressionContent const* cnt,
-                                cm::string_view option, Arguments const& args,
+                                cm::string_view option, Arguments args,
                                 int required = 1)
 {
   return CheckListParametersEx(eval, cnt, option, args.size(), required);
@@ -1182,7 +1208,7 @@
 
 bool GetNumericArguments(
   cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* cnt,
-  Arguments const& args, std::vector<cmList::index_type>& indexes,
+  Arguments args, std::vector<cmList::index_type>& indexes,
   cmList::ExpandElements expandElements = cmList::ExpandElements::No)
 {
   using IndexRange = cmRange<Arguments::const_iterator>;
@@ -2157,11 +2183,11 @@
     if (parameters.empty()) {
       return configurationNode.Evaluate(parameters, eval, content, nullptr);
     }
-    static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
-    if (!configValidator.find(parameters.front())) {
-    }
 
     eval->HadContextSensitiveCondition = true;
+
+    // First, validate our arguments.
+    static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
     bool firstParam = true;
     for (auto const& param : parameters) {
       if (!configValidator.find(param)) {
@@ -2181,42 +2207,122 @@
         eval->Context.LG->GetCMakeInstance()->IssueMessage(
           MessageType::WARNING, e.str(), eval->Backtrace);
       }
-
       firstParam = false;
-      if (eval->Context.Config.empty()) {
-        if (param.empty()) {
+    }
+
+    // Partially determine the context(s) in which the expression should be
+    // evaluated.
+    //
+    // If CMPxxxx is NEW, the context is exactly one of the imported target's
+    // selected configuration, if applicable and if the target was imported
+    // from CPS, or the consuming target's configuration otherwise. Here, we
+    // determine if we are in that 'otherwise' branch.
+    //
+    // Longer term, we need a way for non-CPS users to match the selected
+    // configuration of the imported target. At that time, CPS should switch
+    // to that mechanism and the CPS-specific logic here should be dropped.
+    // (We can do that because CPS doesn't use generator expressions directly;
+    // rather, CMake generates them on import.)
+    bool const targetIsImported =
+      (eval->CurrentTarget && eval->CurrentTarget->IsImported());
+    bool const useConsumerConfig =
+      (targetIsImported &&
+       eval->CurrentTarget->Target->GetOrigin() != cmTarget::Origin::Cps);
+
+    if (!targetIsImported || useConsumerConfig) {
+      // Does the consuming target's configuration match any of the arguments?
+      for (auto const& param : parameters) {
+        if (eval->Context.Config.empty()) {
+          if (param.empty()) {
+            return "1";
+          }
+        } else if (cmsysString_strcasecmp(param.c_str(),
+                                          eval->Context.Config.c_str()) == 0) {
           return "1";
         }
-      } else if (cmsysString_strcasecmp(param.c_str(),
-                                        eval->Context.Config.c_str()) == 0) {
-        return "1";
       }
     }
 
-    if (eval->CurrentTarget && eval->CurrentTarget->IsImported()) {
+    if (targetIsImported) {
       cmValue loc = nullptr;
       cmValue imp = nullptr;
       std::string suffix;
       if (eval->CurrentTarget->Target->GetMappedConfig(eval->Context.Config,
                                                        loc, imp, suffix)) {
-        // This imported target has an appropriate location
-        // for this (possibly mapped) config.
-        // Check if there is a proper config mapping for the tested config.
-        cmList mappedConfigs;
-        std::string mapProp =
-          cmStrCat("MAP_IMPORTED_CONFIG_",
-                   cmSystemTools::UpperCase(eval->Context.Config));
-        if (cmValue mapValue = eval->CurrentTarget->GetProperty(mapProp)) {
-          mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));
-
-          for (auto const& param : parameters) {
-            if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
-              return "1";
-            }
+        // Finish determine the context(s) in which the expression should be
+        // evaluated. Note that we use the consumer's policy, so that end users
+        // can override the imported target's policy. This may be needed if
+        // upstream has changed their policy version without realizing that
+        // consumers were depending on the OLD behavior.
+        bool const oldPolicy = [&] {
+          if (!useConsumerConfig) {
+            // Targets imported from CPS shall use only the selected
+            // configuration of the imported target.
+            return false;
           }
-        } else if (!suffix.empty()) {
-          // There is no explicit mapping for the tested config, so use
-          // the configuration of the imported location that was selected.
+          cmLocalGenerator const* const lg = eval->Context.LG;
+          switch (eval->HeadTarget->GetPolicyStatusCMP0199()) {
+            case cmPolicies::WARN:
+              if (lg->GetMakefile()->PolicyOptionalWarningEnabled(
+                    "CMAKE_POLICY_WARNING_CMP0199")) {
+                std::string const err =
+                  cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0199),
+                           "\nEvaluation of $<CONFIG> for imported target  \"",
+                           eval->CurrentTarget->GetName(), "\", used by \"",
+                           eval->HeadTarget->GetName(),
+                           "\", may match multiple configurations.\n");
+                lg->GetCMakeInstance()->IssueMessage(
+                  MessageType ::AUTHOR_WARNING, err, eval->Backtrace);
+              }
+              CM_FALLTHROUGH;
+            case cmPolicies::OLD:
+              return true;
+            case cmPolicies::NEW:
+              return false;
+          }
+
+          // Should be unreachable
+          assert(false);
+          return false;
+        }();
+
+        if (oldPolicy) {
+          // If CMPxxxx is OLD (and we aren't dealing with a target imported
+          // form CPS), we already evaluated in the context of the consuming
+          // target. Next, for imported targets, we will evaluate based on the
+          // mapped configurations.
+          //
+          // If the target has a MAP_IMPORTED_CONFIG_<CONFIG> property for the
+          // consumer's <CONFIG>, we will match *any* config in that list,
+          // regardless of whether it's valid or of what GetMappedConfig
+          // actually picked. This will result in $<CONFIG> producing '1' for
+          // multiple configs, and is almost certainly wrong, but it's what
+          // CMake did for a very long time, and... Hyrum's Law.
+          cmList mappedConfigs;
+          std::string mapProp =
+            cmStrCat("MAP_IMPORTED_CONFIG_",
+                     cmSystemTools::UpperCase(eval->Context.Config));
+          if (cmValue mapValue = eval->CurrentTarget->GetProperty(mapProp)) {
+            mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));
+
+            for (auto const& param : parameters) {
+              if (cm::contains(mappedConfigs,
+                               cmSystemTools::UpperCase(param))) {
+                return "1";
+              }
+            }
+
+            return "0";
+          }
+        }
+
+        // Finally, check if we selected (possibly via mapping) a configuration
+        // for this imported target, and if we should evaluate the expression
+        // in the context of the same.
+        //
+        // For targets imported from CPS, this is the only context we evaluate
+        // the expression.
+        if (!suffix.empty()) {
           for (auto const& param : parameters) {
             if (cmStrCat('_', cmSystemTools::UpperCase(param)) == suffix) {
               return "1";
@@ -2225,6 +2331,7 @@
         }
       }
     }
+
     return "0";
   }
 } configurationTestNode;
@@ -2275,6 +2382,7 @@
         genName.find("Visual Studio") == std::string::npos &&
         genName.find("Xcode") == std::string::npos &&
         genName.find("Watcom WMake") == std::string::npos &&
+        genName.find("FASTBuild") == std::string::npos &&
         genName.find("Green Hills MULTI") == std::string::npos) {
       reportError(eval, content->GetOriginalExpression(),
                   "$<COMPILE_LANGUAGE:...> not supported for this generator.");
@@ -2321,6 +2429,7 @@
     std::string genName = gg->GetName();
     if (genName.find("Makefiles") == std::string::npos &&
         genName.find("Ninja") == std::string::npos &&
+        genName.find("FASTBuild") == std::string::npos &&
         genName.find("Visual Studio") == std::string::npos &&
         genName.find("Xcode") == std::string::npos &&
         genName.find("Watcom WMake") == std::string::npos &&
@@ -2374,6 +2483,7 @@
     std::string genName = gg->GetName();
     if (genName.find("Makefiles") == std::string::npos &&
         genName.find("Ninja") == std::string::npos &&
+        genName.find("FASTBuild") == std::string::npos &&
         genName.find("Visual Studio") == std::string::npos &&
         genName.find("Xcode") == std::string::npos &&
         genName.find("Watcom WMake") == std::string::npos &&
@@ -2464,6 +2574,7 @@
     std::string genName = gg->GetName();
     if (genName.find("Makefiles") == std::string::npos &&
         genName.find("Ninja") == std::string::npos &&
+        genName.find("FASTBuild") == std::string::npos &&
         genName.find("Visual Studio") == std::string::npos &&
         genName.find("Xcode") == std::string::npos &&
         genName.find("Watcom WMake") == std::string::npos &&
@@ -2489,6 +2600,144 @@
   }
 } linkLanguageAndIdNode;
 
+struct CompilerLinkerIdNode : public cmGeneratorExpressionNode
+{
+  CompilerLinkerIdNode(char const* lang)
+    : Language(lang)
+  {
+  }
+
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
+    GeneratorExpressionContent const* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!eval->HeadTarget) {
+      reportError(
+        eval, content->GetOriginalExpression(),
+        cmStrCat(
+          "$<", this->Language,
+          "_COMPILER_LINKER_ID> may only be used with binary targets. It may "
+          "not be used with add_custom_command or add_custom_target."));
+      return {};
+    }
+    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
+                                      this->Language);
+  }
+
+  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
+                                   cm::GenEx::Evaluation* eval,
+                                   GeneratorExpressionContent const* content,
+                                   cmGeneratorExpressionDAGChecker* /*unused*/,
+                                   std::string const& lang) const
+  {
+    std::string const& compilerLinkerId =
+      eval->Context.LG->GetMakefile()->GetSafeDefinition(
+        cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_ID"));
+    if (parameters.empty()) {
+      return compilerLinkerId;
+    }
+    if (compilerLinkerId.empty()) {
+      return parameters.front().empty() ? "1" : "0";
+    }
+    static cmsys::RegularExpression compilerLinkerIdValidator(
+      "^[A-Za-z0-9_]*$");
+
+    for (auto const& param : parameters) {
+      if (!compilerLinkerIdValidator.find(param)) {
+        reportError(eval, content->GetOriginalExpression(),
+                    "Expression syntax not recognized.");
+        return std::string();
+      }
+
+      if (param == compilerLinkerId) {
+        return "1";
+      }
+    }
+    return "0";
+  }
+
+  char const* const Language;
+};
+
+static CompilerLinkerIdNode const cCompilerLinkerIdNode("C"),
+  cxxCompilerLinkerIdNode("CXX"), cudaCompilerLinkerIdNode("CUDA"),
+  objcCompilerLinkerIdNode("OBJC"), objcxxCompilerLinkerIdNode("OBJCXX"),
+  fortranCompilerLinkerIdNode("Fortran"), hipCompilerLinkerIdNode("HIP");
+
+struct CompilerLinkerFrontendVariantNode : public cmGeneratorExpressionNode
+{
+  CompilerLinkerFrontendVariantNode(char const* lang)
+    : Language(lang)
+  {
+  }
+
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
+    GeneratorExpressionContent const* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  {
+    if (!eval->HeadTarget) {
+      reportError(
+        eval, content->GetOriginalExpression(),
+        cmStrCat(
+          "$<", this->Language,
+          "_COMPILER_LINKER_FRONTEND_VARIANT> may only be used with binary "
+          "targets. It may not be used with add_custom_command or "
+          "add_custom_target."));
+      return {};
+    }
+    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
+                                      this->Language);
+  }
+
+  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
+                                   cm::GenEx::Evaluation* eval,
+                                   GeneratorExpressionContent const* content,
+                                   cmGeneratorExpressionDAGChecker* /*unused*/,
+                                   std::string const& lang) const
+  {
+    std::string const& compilerLinkerFrontendVariant =
+      eval->Context.LG->GetMakefile()->GetSafeDefinition(
+        cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_FRONTEND_VARIANT"));
+    if (parameters.empty()) {
+      return compilerLinkerFrontendVariant;
+    }
+    if (compilerLinkerFrontendVariant.empty()) {
+      return parameters.front().empty() ? "1" : "0";
+    }
+    static cmsys::RegularExpression compilerLinkerFrontendVariantValidator(
+      "^[A-Za-z0-9_]*$");
+
+    for (auto const& param : parameters) {
+      if (!compilerLinkerFrontendVariantValidator.find(param)) {
+        reportError(eval, content->GetOriginalExpression(),
+                    "Expression syntax not recognized.");
+        return {};
+      }
+      if (param == compilerLinkerFrontendVariant) {
+        return "1";
+      }
+    }
+    return "0";
+  }
+
+  char const* const Language;
+};
+
+static CompilerLinkerFrontendVariantNode const
+  cCompilerLinkerFrontendVariantNode("C"),
+  cxxCompilerLinkerFrontendVariantNode("CXX"),
+  cudaCompilerLinkerFrontendVariantNode("CUDA"),
+  objcCompilerLinkerFrontendVariantNode("OBJC"),
+  objcxxCompilerLinkerFrontendVariantNode("OBJCXX"),
+  fortranCompilerLinkerFrontendVariantNode("Fortran"),
+  hipCompilerLinkerFrontendVariantNode("HIP");
+
 static const struct LinkLibraryNode : public cmGeneratorExpressionNode
 {
   LinkLibraryNode() {} // NOLINT(modernize-use-equals-default)
@@ -2711,7 +2960,7 @@
   if (cmLinkImplementationLibraries const* impl =
         target->GetLinkImplementationLibraries(
           eval->Context.Config, cmGeneratorTarget::UseTo::Compile)) {
-    for (cmLinkImplItem const& lib : impl->Libraries) {
+    for (cmLinkItem const& lib : impl->Libraries) {
       if (lib.Target) {
         // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
         // caller's property and hand-evaluate it as if it were compiled.
@@ -3017,6 +3266,71 @@
   }
 } targetPropertyNode;
 
+static const struct targetIntermediateDirNode
+  : public cmGeneratorExpressionNode
+{
+  targetIntermediateDirNode() {} // NOLINT(modernize-use-equals-default)
+
+  static char const* GetErrorText(std::string const& targetName)
+  {
+    static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
+    if (targetName.empty()) {
+      return "$<TARGET_INTERMEDIATE_DIR:tgt> expression requires a non-empty "
+             "target name.";
+    }
+    if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
+      return "Target name not supported.";
+    }
+    return nullptr;
+  }
+
+  std::string Evaluate(
+    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
+    GeneratorExpressionContent const* content,
+    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  {
+    cmGeneratorTarget const* target = nullptr;
+    std::string targetName;
+
+    if (parameters.size() == 1) {
+      targetName = parameters[0];
+
+      if (char const* e = GetErrorText(targetName)) {
+        reportError(eval, content->GetOriginalExpression(), e);
+        return std::string();
+      }
+      cmLocalGenerator const* lg = eval->CurrentTarget
+        ? eval->CurrentTarget->GetLocalGenerator()
+        : eval->Context.LG;
+      target = lg->FindGeneratorTargetToUse(targetName);
+
+      if (!target) {
+        std::ostringstream e;
+        e << "Target \"" << targetName << "\" not found.";
+        reportError(eval, content->GetOriginalExpression(), e.str());
+        return std::string();
+      }
+      eval->AllTargets.insert(target);
+
+    } else {
+      reportError(
+        eval, content->GetOriginalExpression(),
+        "$<TARGET_INTERMEDIATE_DIR:...> expression requires one parameter");
+      return std::string();
+    }
+
+    assert(target);
+
+    if (!HasKnownObjectFileLocation(eval, content, "TARGET_INTERMEDIATE_DIR",
+                                    target)) {
+      return std::string();
+    }
+
+    return cmSystemTools::CollapseFullPath(
+      target->GetObjectDirectory(eval->Context.Config));
+  }
+} targetIntermediateDirNode;
+
 static const struct TargetNameNode : public cmGeneratorExpressionNode
 {
   TargetNameNode() {} // NOLINT(modernize-use-equals-default)
@@ -3072,19 +3386,8 @@
       return std::string();
     }
     cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
-    {
-      std::string reason;
-      if (!eval->EvaluateForBuildsystem &&
-          !gt->Target->HasKnownObjectFileLocation(&reason)) {
-        std::ostringstream e;
-        e << "The evaluation of the TARGET_OBJECTS generator expression "
-             "is only suitable for consumption by CMake (limited"
-          << reason
-          << ").  "
-             "It is not suitable for writing out elsewhere.";
-        reportError(eval, content->GetOriginalExpression(), e.str());
-        return std::string();
-      }
+    if (!HasKnownObjectFileLocation(eval, content, "TARGET_OBJECTS", gt)) {
+      return std::string();
     }
 
     cmList objects;
@@ -3954,12 +4257,20 @@
 //
 // To retrieve base name for various artifacts
 //
+enum class Postfix
+{
+  Unspecified,
+  Exclude,
+  Include
+};
+
 template <typename ArtifactT>
 struct TargetOutputNameArtifactResultGetter
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* content);
+                         GeneratorExpressionContent const* content,
+                         Postfix postfix);
 };
 
 template <>
@@ -3967,11 +4278,14 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* /*unused*/)
+                         GeneratorExpressionContent const* /*unused*/,
+                         Postfix postfix)
   {
-    return target->GetOutputName(eval->Context.Config,
-                                 cmStateEnums::RuntimeBinaryArtifact) +
-      target->GetFilePostfix(eval->Context.Config);
+    auto output = target->GetOutputName(eval->Context.Config,
+                                        cmStateEnums::RuntimeBinaryArtifact);
+    return postfix != Postfix::Exclude
+      ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+      : output;
   }
 };
 
@@ -3980,12 +4294,15 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* /*unused*/)
+                         GeneratorExpressionContent const* /*unused*/,
+                         Postfix postfix)
   {
     if (target->HasImportLibrary(eval->Context.Config)) {
-      return target->GetOutputName(eval->Context.Config,
-                                   cmStateEnums::ImportLibraryArtifact) +
-        target->GetFilePostfix(eval->Context.Config);
+      auto output = target->GetOutputName(eval->Context.Config,
+                                          cmStateEnums::ImportLibraryArtifact);
+      return postfix != Postfix::Exclude
+        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+        : output;
     }
     return std::string{};
   }
@@ -3996,7 +4313,8 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* content)
+                         GeneratorExpressionContent const* content,
+                         Postfix postfix)
   {
     // The library file used to link to the target (.so, .lib, .a) or import
     // file (.lin,  .tbd).
@@ -4010,8 +4328,10 @@
       target->HasImportLibrary(eval->Context.Config)
       ? cmStateEnums::ImportLibraryArtifact
       : cmStateEnums::RuntimeBinaryArtifact;
-    return target->GetOutputName(eval->Context.Config, artifact) +
-      target->GetFilePostfix(eval->Context.Config);
+    auto output = target->GetOutputName(eval->Context.Config, artifact);
+    return postfix != Postfix::Exclude
+      ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+      : output;
   }
 };
 
@@ -4020,7 +4340,8 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* content)
+                         GeneratorExpressionContent const* content,
+                         Postfix postfix)
   {
     // The library file used to link to the target (.so, .lib, .a).
     if (!target->IsLinkable() ||
@@ -4033,9 +4354,11 @@
 
     if (!target->IsDLLPlatform() ||
         target->GetType() == cmStateEnums::STATIC_LIBRARY) {
-      return target->GetOutputName(eval->Context.Config,
-                                   cmStateEnums::ImportLibraryArtifact) +
-        target->GetFilePostfix(eval->Context.Config);
+      auto output = target->GetOutputName(eval->Context.Config,
+                                          cmStateEnums::ImportLibraryArtifact);
+      return postfix != Postfix::Exclude
+        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+        : output;
     }
     return std::string{};
   }
@@ -4046,7 +4369,8 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* content)
+                         GeneratorExpressionContent const* content,
+                         Postfix postfix)
   {
     // The import file used to link to the target (.lib, .tbd).
     if (!target->IsLinkable()) {
@@ -4057,9 +4381,11 @@
     }
 
     if (target->HasImportLibrary(eval->Context.Config)) {
-      return target->GetOutputName(eval->Context.Config,
-                                   cmStateEnums::ImportLibraryArtifact) +
-        target->GetFilePostfix(eval->Context.Config);
+      auto output = target->GetOutputName(eval->Context.Config,
+                                          cmStateEnums::ImportLibraryArtifact);
+      return postfix != Postfix::Exclude
+        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+        : output;
     }
     return std::string{};
   }
@@ -4070,7 +4396,8 @@
 {
   static std::string Get(cmGeneratorTarget* target,
                          cm::GenEx::Evaluation* eval,
-                         GeneratorExpressionContent const* content)
+                         GeneratorExpressionContent const* content,
+                         Postfix postfix)
   {
     if (target->IsImported()) {
       ::reportError(
@@ -4101,7 +4428,26 @@
       return std::string();
     }
 
-    return target->GetPDBOutputName(eval->Context.Config);
+    auto output = target->GetPDBOutputName(eval->Context.Config);
+
+    if (target->GetPolicyStatusCMP0202() == cmPolicies::NEW) {
+      return postfix != Postfix::Exclude
+        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
+        : output;
+    }
+
+    if (target->GetPolicyStatusCMP0202() == cmPolicies::WARN &&
+        postfix != Postfix::Unspecified) {
+      eval->Context.LG->GetCMakeInstance()->IssueMessage(
+        MessageType::AUTHOR_WARNING,
+        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0202), '\n',
+                 "\"POSTFIX\" option is recognized only when the policy is "
+                 "set to NEW. Since the policy is not set, the OLD behavior "
+                 "will be used."),
+        eval->Backtrace);
+    }
+
+    return output;
   }
 };
 
@@ -4110,21 +4456,40 @@
 {
   TargetFileBaseNameArtifact() {} // NOLINT(modernize-use-equals-default)
 
-  int NumExpectedParameters() const override { return 1; }
+  int NumExpectedParameters() const override { return OneOrMoreParameters; }
 
   std::string Evaluate(
     std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
     GeneratorExpressionContent const* content,
     cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
+    if (parameters.size() > 2) {
+      ::reportError(eval, content->GetOriginalExpression(),
+                    "Unexpected parameters, require one or two parameters.");
+      return std::string{};
+    }
+
     cmGeneratorTarget* target =
       this->GetTarget(parameters, eval, content, dagChecker);
     if (!target) {
       return std::string();
     }
 
+    Postfix postfix = Postfix::Unspecified;
+    if (parameters.size() == 2) {
+      if (parameters[1] == "POSTFIX:INCLUDE") {
+        postfix = Postfix::Include;
+      } else if (parameters[1] == "POSTFIX:EXCLUDE") {
+        postfix = Postfix::Exclude;
+      } else {
+        ::reportError(eval, content->GetOriginalExpression(),
+                      "Wrong second parameter: \"POSTFIX:INCLUDE\" or "
+                      "\"POSTFIX:EXCLUDE\" is expected");
+      }
+    }
+
     std::string result = TargetOutputNameArtifactResultGetter<ArtifactT>::Get(
-      target, eval, content);
+      target, eval, content, postfix);
     if (eval->HadError) {
       return std::string();
     }
@@ -4537,6 +4902,7 @@
     { "SEMICOLON", &semicolonNode },
     { "QUOTE", &quoteNode },
     { "TARGET_PROPERTY", &targetPropertyNode },
+    { "TARGET_INTERMEDIATE_DIR", &targetIntermediateDirNode },
     { "TARGET_NAME", &targetNameNode },
     { "TARGET_OBJECTS", &targetObjectsNode },
     { "TARGET_POLICY", &targetPolicyNode },
@@ -4557,6 +4923,27 @@
     { "COMPILE_LANGUAGE", &languageNode },
     { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
     { "LINK_LANGUAGE", &linkLanguageNode },
+    { "C_COMPILER_LINKER_ID", &cCompilerLinkerIdNode },
+    { "CXX_COMPILER_LINKER_ID", &cxxCompilerLinkerIdNode },
+    { "OBJC_COMPILER_LINKER_ID", &objcCompilerLinkerIdNode },
+    { "OBJCXX_COMPILER_LINKER_ID", &objcxxCompilerLinkerIdNode },
+    { "CUDA_COMPILER_LINKER_ID", &cudaCompilerLinkerIdNode },
+    { "Fortran_COMPILER_LINKER_ID", &fortranCompilerLinkerIdNode },
+    { "HIP_COMPILER_LINKER_ID", &hipCompilerLinkerIdNode },
+    { "C_COMPILER_LINKER_FRONTEND_VARIANT",
+      &cCompilerLinkerFrontendVariantNode },
+    { "CXX_COMPILER_LINKER_FRONTEND_VARIANT",
+      &cxxCompilerLinkerFrontendVariantNode },
+    { "CUDA_COMPILER_LINKER_FRONTEND_VARIANT",
+      &cudaCompilerLinkerFrontendVariantNode },
+    { "OBJC_COMPILER_LINKER_FRONTEND_VARIANT",
+      &objcCompilerLinkerFrontendVariantNode },
+    { "OBJCXX_COMPILER_LINKER_FRONTEND_VARIANT",
+      &objcxxCompilerLinkerFrontendVariantNode },
+    { "Fortran_COMPILER_LINKER_FRONTEND_VARIANT",
+      &fortranCompilerLinkerFrontendVariantNode },
+    { "HIP_COMPILER_LINKER_FRONTEND_VARIANT",
+      &hipCompilerLinkerFrontendVariantNode },
     { "LINK_LIBRARY", &linkLibraryNode },
     { "LINK_GROUP", &linkGroupNode },
     { "HOST_LINK", &hostLinkNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7a3f1dc..a59186c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -10,7 +10,6 @@
 #include <cstdio>
 #include <cstring>
 #include <sstream>
-#include <type_traits>
 #include <unordered_set>
 #include <utility>
 
@@ -46,6 +45,7 @@
 #include "cmStandardLevel.h"
 #include "cmStandardLevelResolver.h"
 #include "cmState.h"
+#include "cmStateTypes.h"
 #include "cmStringAlgorithms.h"
 #include "cmSyntheticTargetCache.h"
 #include "cmSystemTools.h"
@@ -80,7 +80,7 @@
   bool evaluateForBuildsystem = false)
 {
   for (auto const& entry : entries) {
-    items.push_back(cmGeneratorTarget::TargetPropertyEntry::Create(
+    items.emplace_back(cmGeneratorTarget::TargetPropertyEntry::Create(
       cmakeInstance, entry, evaluateForBuildsystem));
   }
 }
@@ -566,10 +566,11 @@
   this->ClearSourcesCache();
 }
 
-void cmGeneratorTarget::AddSource(std::string const& src, bool before)
+cmSourceFile* cmGeneratorTarget::AddSource(std::string const& src, bool before)
 {
-  this->Target->AddSource(src, before);
+  auto* sf = this->Target->AddSource(src, before);
   this->AddSourceCommon(src, before);
+  return sf;
 }
 
 void cmGeneratorTarget::AddTracedSources(std::vector<std::string> const& srcs)
@@ -697,7 +698,7 @@
     this->Objects[it];
   }
 
-  this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
+  this->LocalGenerator->ComputeObjectFilenames(this->Objects, config, this);
   this->VisitedConfigsForObjects.insert(config);
 }
 
@@ -857,7 +858,10 @@
 std::string const& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
 {
   this->ComputeObjectMapping();
-  return this->Objects[file];
+  auto const useShortPaths = this->GetUseShortObjectNames()
+    ? cmObjectLocations::UseShortPath::Yes
+    : cmObjectLocations::UseShortPath::No;
+  return this->Objects[file].GetPath(useShortPaths);
 }
 
 char const* cmGeneratorTarget::GetCustomObjectExtension() const
@@ -1010,6 +1014,10 @@
           cmLinkItem(i.Value.first, i.Value.second, i.Backtrace));
       }
     }
+    if (cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget()) {
+      this->UtilityItems.insert(
+        cmLinkItem(reuseTarget, false, cmListFileBacktrace()));
+    }
   }
   return this->UtilityItems;
 }
@@ -1144,6 +1152,11 @@
   return this->Target->IsImportedGloballyVisible();
 }
 
+bool cmGeneratorTarget::IsSymbolic() const
+{
+  return this->Target->IsSymbolic();
+}
+
 bool cmGeneratorTarget::IsForeign() const
 {
   return this->Target->IsForeign();
@@ -1272,6 +1285,12 @@
 std::string cmGeneratorTarget::GetCompilePDBName(
   std::string const& config) const
 {
+  if (cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget()) {
+    if (reuseTarget != this) {
+      return reuseTarget->GetCompilePDBName(config);
+    }
+  }
+
   // Check for a per-configuration output directory target property.
   std::string configUpper = cmSystemTools::UpperCase(config);
   std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
@@ -1293,7 +1312,17 @@
     return components.prefix + pdbName + ".pdb";
   }
 
-  return "";
+  // If the target is PCH-reused or PCH-reuses, we need a stable name for the
+  // PDB file so that reusing targets can construct a stable name for it.
+  cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
+  bool const hasReuse = reuseTarget && reuseTarget != this;
+  if (this->PchReused || hasReuse) {
+    NameComponents const& components = GetFullNameInternalComponents(
+      config, cmStateEnums::RuntimeBinaryArtifact);
+    return cmStrCat(components.prefix, this->GetName(), ".pdb");
+  }
+
+  return std::string{};
 }
 
 std::string cmGeneratorTarget::GetCompilePDBPath(
@@ -1821,6 +1850,36 @@
   return nullptr;
 }
 
+cmList const& cmGeneratorTarget::GetSharedLibraryCompileDefs(
+  std::string const& config) const
+{
+  {
+    auto it = this->SharedLibraryCompileDefs.find(config);
+    if (it != this->SharedLibraryCompileDefs.end()) {
+      return it->second;
+    }
+  }
+
+  auto emplaceResult =
+    this->SharedLibraryCompileDefs.emplace(config, cmList{});
+  auto& defs = emplaceResult.first->second;
+  if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+      this->GetType() != cmStateEnums::MODULE_LIBRARY) {
+    return defs;
+  }
+
+  if (this->GetPolicyStatusCMP0203() != cmPolicies::NEW) {
+    return defs;
+  }
+
+  auto linkerLang = this->GetLinkerLanguage(config);
+  auto definitionVar =
+    cmStrCat("CMAKE_", linkerLang, "_SHARED_LIBRARY_COMPILE_DEFINITIONS");
+  defs = this->Makefile->GetSafeDefinition(definitionVar);
+
+  return defs;
+}
+
 cmGeneratorTarget::NameComponents const&
 cmGeneratorTarget::GetFullNameComponents(
   std::string const& config, cmStateEnums::ArtifactType artifact) const
@@ -2042,14 +2101,6 @@
   return std::move(archList.data());
 }
 
-std::string const& cmGeneratorTarget::GetTargetLabelsString()
-{
-  this->targetLabelsString = this->GetSafeProperty("LABELS");
-  std::replace(this->targetLabelsString.begin(),
-               this->targetLabelsString.end(), ';', ',');
-  return this->targetLabelsString;
-}
-
 namespace {
 
 bool IsSupportedClassifiedFlagsLanguage(std::string const& lang)
@@ -2314,7 +2365,6 @@
   cmRulePlaceholderExpander::RuleVariables vars;
   vars.CMTargetName = this->GetName().c_str();
   vars.CMTargetType = cmState::GetTargetTypeName(this->GetType()).c_str();
-  vars.CMTargetLabels = this->GetTargetLabelsString().c_str();
   vars.Language = lang.c_str();
 
   auto const sfPath = this->LocalGenerator->ConvertToOutputFormat(
@@ -2344,6 +2394,7 @@
     vars.Object = sfVars.ObjectFileDir.c_str();
     vars.ObjectDir = sfVars.ObjectDir.c_str();
     vars.ObjectFileDir = sfVars.ObjectFileDir.c_str();
+    vars.TargetSupportDir = sfVars.TargetSupportDir.c_str();
     vars.Flags = PlaceholderFlags.c_str();
     vars.DependencyFile = sfVars.DependencyFile.c_str();
     vars.DependencyTarget = sfVars.DependencyTarget.c_str();
@@ -2424,12 +2475,16 @@
 
   // Object settings.
   {
+    std::string const targetSupportDir = lg->MaybeRelativeToTopBinDir(
+      gg->ConvertToOutputPath(this->GetCMFSupportDirectory()));
     std::string const objectDir = gg->ConvertToOutputPath(
       cmStrCat(this->GetSupportDirectory(), gg->GetConfigDirectory(config)));
     std::string const objectFileName = this->GetObjectName(sf);
     std::string const objectFilePath =
       cmStrCat(objectDir, '/', objectFileName);
 
+    vars.TargetSupportDir =
+      lg->ConvertToOutputFormat(targetSupportDir, cmOutputConverter::SHELL);
     vars.ObjectDir =
       lg->ConvertToOutputFormat(objectDir, cmOutputConverter::SHELL);
     vars.ObjectFileDir =
@@ -2803,6 +2858,122 @@
   return cmSystemTools::CollapseFullPath(path);
 }
 
+struct CycleWatcher
+{
+  CycleWatcher(bool& flag)
+    : Flag(flag)
+  {
+    this->Flag = true;
+  }
+  ~CycleWatcher() { this->Flag = false; }
+  bool& Flag;
+};
+
+cmGeneratorTarget const* cmGeneratorTarget::GetPchReuseTarget() const
+{
+  if (this->ComputingPchReuse) {
+    // TODO: Get the full cycle.
+    if (!this->PchReuseCycleDetected) {
+      this->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("Circular PCH reuse target involving '", this->GetName(),
+                 '\''));
+    }
+    this->PchReuseCycleDetected = true;
+    return nullptr;
+  }
+  CycleWatcher watch(this->ComputingPchReuse);
+  (void)watch;
+  cmValue pchReuseFrom = this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+  if (!pchReuseFrom) {
+    return nullptr;
+  }
+  cmGeneratorTarget const* generatorTarget =
+    this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
+  if (!generatorTarget) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat(
+        "Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
+        R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property does not exist.)"));
+  }
+  if (this->GetProperty("PRECOMPILE_HEADERS").IsOn()) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("PRECOMPILE_HEADERS property is already set on target (\"",
+               this->GetName(), "\")\n"));
+  }
+
+  if (generatorTarget) {
+    if (generatorTarget->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
+      this->Makefile->IssueMessage(
+        MessageType::WARNING,
+        cmStrCat(
+          "Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
+          R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property has set "DISABLE_PRECOMPILE_HEADERS"; ignoring.)"));
+      return nullptr;
+    }
+
+    if (auto const* recurseReuseTarget =
+          generatorTarget->GetPchReuseTarget()) {
+      return recurseReuseTarget;
+    }
+  }
+  return generatorTarget;
+}
+
+cmGeneratorTarget* cmGeneratorTarget::GetPchReuseTarget()
+{
+  if (this->ComputingPchReuse) {
+    // TODO: Get the full cycle.
+    if (!this->PchReuseCycleDetected) {
+      this->Makefile->IssueMessage(
+        MessageType::FATAL_ERROR,
+        cmStrCat("Circular PCH reuse target involving '", this->GetName(),
+                 '\''));
+    }
+    this->PchReuseCycleDetected = true;
+    return nullptr;
+  }
+  CycleWatcher watch(this->ComputingPchReuse);
+  (void)watch;
+  cmValue pchReuseFrom = this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+  if (!pchReuseFrom) {
+    return nullptr;
+  }
+  cmGeneratorTarget* generatorTarget =
+    this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
+  if (!generatorTarget) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat(
+        "Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
+        R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property does not exist.)"));
+  }
+  if (this->GetProperty("PRECOMPILE_HEADERS").IsOn()) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("PRECOMPILE_HEADERS property is already set on target (\"",
+               this->GetName(), "\")\n"));
+  }
+
+  if (generatorTarget) {
+    if (generatorTarget->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
+      this->Makefile->IssueMessage(
+        MessageType::WARNING,
+        cmStrCat(
+          "Target \"", *pchReuseFrom, "\" for the \"", this->GetName(),
+          R"(" target's "PRECOMPILE_HEADERS_REUSE_FROM" property has set "DISABLE_PRECOMPILE_HEADERS"; ignoring.)"));
+      return nullptr;
+    }
+
+    if (auto* recurseReuseTarget = generatorTarget->GetPchReuseTarget()) {
+      return recurseReuseTarget;
+    }
+  }
+  return generatorTarget;
+}
+
 std::vector<std::string> cmGeneratorTarget::GetPchArchs(
   std::string const& config, std::string const& lang) const
 {
@@ -2830,24 +3001,22 @@
     return std::string();
   }
   cmGeneratorTarget const* generatorTarget = this;
-  cmValue pchReuseFrom =
-    generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+  cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
+  bool const haveReuseTarget = reuseTarget && reuseTarget != this;
+  if (reuseTarget) {
+    generatorTarget = reuseTarget;
+  }
 
   auto const inserted =
     this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
   if (inserted.second) {
     std::vector<BT<std::string>> const headers =
       this->GetPrecompileHeaders(config, language);
-    if (headers.empty() && !pchReuseFrom) {
+    if (headers.empty() && !haveReuseTarget) {
       return std::string();
     }
     std::string& filename = inserted.first->second;
 
-    if (pchReuseFrom) {
-      generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
-    }
-
     std::map<std::string, std::string> const languageToExtension = {
       { "C", ".h" },
       { "CXX", ".hxx" },
@@ -2861,12 +3030,13 @@
       filename = cmStrCat(filename, '/', config);
     }
 
+    // This is acceptable as its the source file, won't have a rename/hash
     filename =
       cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat('_', arch),
                languageToExtension.at(language));
 
     std::string const filename_tmp = cmStrCat(filename, ".tmp");
-    if (!pchReuseFrom) {
+    if (!haveReuseTarget) {
       cmValue pchPrologue =
         this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
       cmValue pchEpilogue =
@@ -2941,11 +3111,10 @@
     std::string& filename = inserted.first->second;
 
     cmGeneratorTarget const* generatorTarget = this;
-    cmValue pchReuseFrom =
-      generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
-    if (pchReuseFrom) {
-      generatorTarget =
-        this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
+    cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
+    bool const haveReuseTarget = reuseTarget && reuseTarget != this;
+    if (reuseTarget) {
+      generatorTarget = reuseTarget;
     }
 
     filename =
@@ -2972,7 +3141,7 @@
     }
 
     std::string const filename_tmp = cmStrCat(filename, ".tmp");
-    if (!pchReuseFrom) {
+    if (!haveReuseTarget) {
       {
         cmGeneratedFileStream file(filename_tmp);
         file << "/* generated by CMake */\n";
@@ -3003,12 +3172,10 @@
 
     auto* pchSf = this->Makefile->GetOrCreateSource(
       pchSource, false, cmSourceFileLocationKind::Known);
-
-    filename = cmStrCat(this->ObjectDirectory, this->GetObjectName(pchSf));
-    if (this->GetGlobalGenerator()->IsMultiConfig()) {
-      cmSystemTools::ReplaceString(
-        filename, this->GetGlobalGenerator()->GetCMakeCFGIntDir(), config);
-    }
+    pchSf->SetSpecialSourceType(cmSourceFile::SpecialSourceType::PchSource);
+    pchSf->ResolveFullPath();
+    filename = cmStrCat(this->GetObjectDirectory(config), '/',
+                        this->GetObjectName(pchSf));
   }
   return inserted.first->second;
 }
@@ -3038,11 +3205,9 @@
       };
 
       cmGeneratorTarget* generatorTarget = this;
-      cmValue pchReuseFrom =
-        generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
-      if (pchReuseFrom) {
-        generatorTarget =
-          this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
+      cmGeneratorTarget* reuseTarget = this->GetPchReuseTarget();
+      if (reuseTarget) {
+        generatorTarget = reuseTarget;
       }
 
       std::string const pchFileObject =
@@ -3051,8 +3216,24 @@
         pchFile = replaceExtension(pchFileObject, pchExtension);
       }
     } else {
-      pchFile = this->GetPchHeader(config, language, arch);
-      pchFile += pchExtension;
+      if (this->GetUseShortObjectNames() && !pchExtension.empty()) {
+        auto pchSource = this->GetPchSource(config, language, arch);
+        auto* pchSf = this->Makefile->GetOrCreateSource(
+          pchSource, false, cmSourceFileLocationKind::Known);
+        pchSf->SetSpecialSourceType(
+          cmSourceFile::SpecialSourceType::PchSource);
+        pchSf->ResolveFullPath();
+        std::string cfgSubdir;
+        if (this->GetGlobalGenerator()->IsMultiConfig()) {
+          cfgSubdir = cmStrCat(config, '/');
+        }
+        pchFile = cmStrCat(
+          this->GetSupportDirectory(), '/', cfgSubdir,
+          this->LocalGenerator->GetShortObjectFileName(*pchSf), pchExtension);
+      } else {
+        pchFile =
+          cmStrCat(this->GetPchHeader(config, language, arch), pchExtension);
+      }
     }
   }
   return inserted.first->second;
@@ -3091,8 +3272,17 @@
     std::string const pchHeader = this->GetPchHeader(config, language, arch);
     std::string const pchFile = this->GetPchFile(config, language, arch);
 
-    cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
-    cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
+    if (GlobalGenerator->IsFastbuild()) {
+      // Account for potential spaces in a shell-friendly way.
+      cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>",
+                                   '"' + pchHeader + '"');
+      cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>",
+                                   '"' + pchFile + '"');
+    } else {
+      cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>",
+                                   pchHeader);
+      cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
+    }
   }
   return inserted.first->second;
 }
@@ -3126,8 +3316,16 @@
     std::string const pchHeader = this->GetPchHeader(config, language, arch);
     std::string const pchFile = this->GetPchFile(config, language, arch);
 
-    cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
-    cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
+    if (GlobalGenerator->IsFastbuild()) {
+      // Account for potential spaces in a shell-friendly way.
+      cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>",
+                                   '"' + pchHeader + '"');
+      cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>",
+                                   '"' + pchFile + '"');
+    } else {
+      cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
+      cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
+    }
   }
   return inserted.first->second;
 }
@@ -3808,9 +4006,11 @@
 
     // Now evaluate genex and update the previously-prepared map entry.
     if (outName.empty()) {
-      i->second =
-        this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact) +
-        this->GetFilePostfix(config);
+      i->second = cmStrCat(
+        this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact),
+        this->GetPolicyStatusCMP0202() != cmPolicies::NEW
+          ? this->GetFilePostfix(config)
+          : "");
     } else {
       i->second =
         cmGeneratorExpression::Evaluate(outName, this->LocalGenerator, config);
@@ -3833,7 +4033,11 @@
 
   std::string base = this->GetPDBOutputName(config);
 
-  return parts.prefix + base + ".pdb";
+  return cmStrCat(parts.prefix, base,
+                  this->GetPolicyStatusCMP0202() == cmPolicies::NEW
+                    ? this->GetFilePostfix(config)
+                    : "",
+                  ".pdb");
 }
 
 std::string cmGeneratorTarget::GetObjectDirectory(
@@ -3856,22 +4060,43 @@
 void cmGeneratorTarget::GetTargetObjectNames(
   std::string const& config, std::vector<std::string>& objects) const
 {
+  this->GetTargetObjectLocations(
+    config,
+    [&objects](cmObjectLocation const& buildLoc, cmObjectLocation const&) {
+      objects.push_back(buildLoc.GetPath());
+    });
+}
+
+void cmGeneratorTarget::GetTargetObjectLocations(
+  std::string const& config,
+  std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb)
+  const
+{
   std::vector<cmSourceFile const*> objectSources;
   this->GetObjectSources(objectSources, config);
-  std::map<cmSourceFile const*, std::string> mapping;
+  std::map<cmSourceFile const*, cmObjectLocations> mapping;
 
   for (cmSourceFile const* sf : objectSources) {
     mapping[sf];
   }
 
-  this->LocalGenerator->ComputeObjectFilenames(mapping, this);
+  this->LocalGenerator->ComputeObjectFilenames(mapping, config, this);
+
+  auto const buildUseShortPaths = this->GetUseShortObjectNames()
+    ? cmObjectLocations::UseShortPath::Yes
+    : cmObjectLocations::UseShortPath::No;
+  auto const installUseShortPaths = this->GetUseShortObjectNamesForInstall();
 
   for (cmSourceFile const* src : objectSources) {
     // Find the object file name corresponding to this source file.
     auto map_it = mapping.find(src);
+    auto const& buildLoc = map_it->second.GetLocation(buildUseShortPaths);
+    auto const& installLoc =
+      map_it->second.GetInstallLocation(installUseShortPaths, config);
     // It must exist because we populated the mapping just above.
-    assert(!map_it->second.empty());
-    objects.push_back(map_it->second);
+    assert(!buildLoc.GetPath().empty());
+    assert(!installLoc.GetPath().empty());
+    cb(buildLoc, installLoc);
   }
 
   // We need to compute the relative path from the root of
@@ -3881,7 +4106,9 @@
   auto ispcObjects = this->GetGeneratedISPCObjects(config);
   for (std::string const& output : ispcObjects) {
     auto relativePathFromObjectDir = output.substr(rootObjectDir.size());
-    objects.push_back(relativePathFromObjectDir);
+    cmObjectLocation ispcLoc(relativePathFromObjectDir);
+    // FIXME: apply short path to this object if needed.
+    cb(ispcLoc, ispcLoc);
   }
 }
 
@@ -4432,7 +4659,14 @@
     }
   }
   if (out.empty()) {
-    return false;
+    cmGeneratorTarget const* reuseTarget = this->GetPchReuseTarget();
+    bool const hasReuse = reuseTarget && reuseTarget != this;
+    // Compiler-generated PDB output always needed for REUSE_FROM.
+    if (kind == "COMPILE_PDB"_s && (this->PchReused || hasReuse)) {
+      out = this->GetSupportDirectory();
+    } else {
+      return false;
+    }
   }
 
   // Convert the output path to a full path in case it is
@@ -4722,7 +4956,7 @@
 }
 
 void cmGeneratorTarget::GetObjectLibrariesInSources(
-  std::vector<cmGeneratorTarget*>& objlibs) const
+  std::vector<BT<cmGeneratorTarget*>>& objlibs) const
 {
   // FIXME: This searches SOURCES for TARGET_OBJECTS for backwards
   // compatibility with the OLD behavior of CMP0026 since this
@@ -4743,7 +4977,7 @@
         cmGeneratorTarget* objLib =
           this->LocalGenerator->FindGeneratorTargetToUse(objLibName);
         if (objLib) {
-          objlibs.push_back(objLib);
+          objlibs.emplace_back(objLib, entry.Backtrace);
         }
       }
     }
@@ -5220,22 +5454,49 @@
       this->GetType() == cmStateEnums::MODULE_LIBRARY));
 }
 
-std::string cmGeneratorTarget::GetSupportDirectory() const
+bool cmGeneratorTarget::GetUseShortObjectNames(
+  cmStateEnums::IntermediateDirKind kind) const
 {
-  cmLocalGenerator* lg = this->GetLocalGenerator();
-  return cmStrCat(lg->GetObjectOutputRoot(), '/',
-                  lg->GetTargetDirectory(this));
+  return this->LocalGenerator->UseShortObjectNames(kind);
 }
 
-std::string cmGeneratorTarget::GetCMFSupportDirectory() const
+cmObjectLocations::UseShortPath
+cmGeneratorTarget::GetUseShortObjectNamesForInstall() const
+{
+  auto prop = this->Target->GetProperty("INSTALL_OBJECT_NAME_STRATEGY");
+  if (prop == "SHORT"_s) {
+    return cmObjectLocations::UseShortPath::Yes;
+  }
+  if (prop == "FULL"_s) {
+    return cmObjectLocations::UseShortPath::No;
+  }
+  if (prop.IsSet()) {
+    this->Makefile->IssueMessage(
+      MessageType::FATAL_ERROR,
+      cmStrCat("Property INSTALL_OBJECT_NAME_STRATEGY of target \"",
+               this->GetName(), "\" set to the unsupported strategy ", prop));
+  }
+  return cmObjectLocations::UseShortPath::No;
+}
+
+std::string cmGeneratorTarget::GetSupportDirectory(
+  cmStateEnums::IntermediateDirKind kind) const
+{
+  cmLocalGenerator* lg = this->GetLocalGenerator();
+  return cmStrCat(lg->GetObjectOutputRoot(kind), '/',
+                  lg->GetTargetDirectory(this, kind));
+}
+
+std::string cmGeneratorTarget::GetCMFSupportDirectory(
+  cmStateEnums::IntermediateDirKind kind) const
 {
   cmLocalGenerator* lg = this->GetLocalGenerator();
   if (!lg->AlwaysUsesCMFPaths()) {
     return cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
-                    lg->GetTargetDirectory(this));
+                    lg->GetTargetDirectory(this, kind));
   }
-  return cmStrCat(lg->GetObjectOutputRoot(), '/',
-                  lg->GetTargetDirectory(this));
+  return cmStrCat(lg->GetObjectOutputRoot(kind), '/',
+                  lg->GetTargetDirectory(this, kind));
 }
 
 bool cmGeneratorTarget::IsLinkable() const
@@ -5580,6 +5841,8 @@
     this->LocalGenerator->GetCurrentBinaryDirectory(), '/', this->GetName(),
     "_verify_interface_header_sets/", headerFilename, extension);
   auto* verificationSource = this->Makefile->GetOrCreateSource(filename);
+  source.SetSpecialSourceType(
+    cmSourceFile::SpecialSourceType::HeaderSetVerificationSource);
   verificationSource->SetProperty("LANGUAGE", language);
 
   cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(filename));
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 6fd29de..94c16b5 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -5,6 +5,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <cstddef>
+#include <functional>
 #include <map>
 #include <memory>
 #include <set>
@@ -19,8 +20,11 @@
 
 #include "cmAlgorithms.h"
 #include "cmLinkItem.h"
+#include "cmList.h"
 #include "cmListFileCache.h"
+#include "cmObject